Salome HOME
merge master
authorPaul RASCLE <paul.rascle@edf.fr>
Thu, 7 Jan 2016 17:15:04 +0000 (18:15 +0100)
committerPaul RASCLE <paul.rascle@edf.fr>
Thu, 7 Jan 2016 17:15:04 +0000 (18:15 +0100)
1155 files changed:
CMakeLists.txt
SMESH_version.h.in
SalomeSMESHConfig.cmake.in
adm_local/CMakeLists.txt
adm_local/cmake_files/CMakeLists.txt
adm_local/cmake_files/FindCGNS.cmake
adm_local/cmake_files/FindSMESH.cmake
adm_local/cmake_files/FindSalomeCGNS.cmake
adm_local/cmake_files/FindSalomeSMESH.cmake
adm_local/cmake_files/FindSalomeTBB.cmake
adm_local/cmake_files/FindSalomef2c.cmake
adm_local/cmake_files/FindTBB.cmake
adm_local/cmake_files/Findf2c.cmake
adm_local/unix/CMakeLists.txt
adm_local/unix/config_files/CMakeLists.txt
adm_local/unix/config_files/check_Platform.m4
adm_local/unix/config_files/check_SMESH.m4
adm_local/unix/config_files/check_cgal.m4
adm_local/unix/config_files/check_cgns.m4
adm_local/unix/config_files/check_f77.m4
adm_local/unix/config_files/check_padder.m4
adm_local/unix/config_files/check_qwt.m4
bin/CMakeLists.txt
bin/smesh_setenv.py
doc/CMakeLists.txt
doc/salome/CMakeLists.txt
doc/salome/examples/CMakeLists.txt
doc/salome/examples/CTestTestfileInstall.cmake [new file with mode: 0644]
doc/salome/examples/creating_meshes_ex07.py
doc/salome/examples/filters_belong2group.py [new file with mode: 0644]
doc/salome/examples/filters_ex01.py
doc/salome/examples/filters_ex36.py
doc/salome/examples/grouping_elements_ex08.py
doc/salome/examples/split_biquad.py [new file with mode: 0644]
doc/salome/examples/testme.py
doc/salome/examples/transforming_meshes_ex01.py
doc/salome/examples/transforming_meshes_ex05.py
doc/salome/examples/transforming_meshes_ex09.py
doc/salome/examples/transforming_meshes_ex10.py
doc/salome/gui/CMakeLists.txt
doc/salome/gui/SMESH/CMakeLists.txt
doc/salome/gui/SMESH/collect_mesh_methods.py
doc/salome/gui/SMESH/doxyfile.in
doc/salome/gui/SMESH/doxyfile_py.in
doc/salome/gui/SMESH/images/2d_from_3d_example.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/a-arithmetic1d.png [changed mode: 0755->0644]
doc/salome/gui/SMESH/images/a-creategroup.png [changed mode: 0755->0644]
doc/salome/gui/SMESH/images/a-geometric1d.png
doc/salome/gui/SMESH/images/a-nbsegments2.png [changed mode: 0755->0644]
doc/salome/gui/SMESH/images/a-startendlength.png [changed mode: 0755->0644]
doc/salome/gui/SMESH/images/b-flection1d.png [changed mode: 0755->0644]
doc/salome/gui/SMESH/images/buildcompound.png [changed mode: 0755->0644]
doc/salome/gui/SMESH/images/buildcompound_groups.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/create_groups_from_geometry.png
doc/salome/gui/SMESH/images/dimgroup_2d.png
doc/salome/gui/SMESH/images/dimgroup_dlg.png
doc/salome/gui/SMESH/images/distributionwithanalyticdensity.png
doc/salome/gui/SMESH/images/distributionwithtabledensity.png
doc/salome/gui/SMESH/images/extru_rib_segs.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/extrusion_along_path_dlg.png
doc/salome/gui/SMESH/images/extrusion_box.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/extrusion_groups.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/extrusion_groups_res.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/extrusionalongaline1.png
doc/salome/gui/SMESH/images/extrusionalongaline2.png
doc/salome/gui/SMESH/images/extrusionalongaline3.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/extrusionbynormal_alongavgnorm.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/extrusionbynormal_useonly.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/free_borders1.png [changed mode: 0755->0644]
doc/salome/gui/SMESH/images/groups_in_OB.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/hexa_ijk_mesh.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/hypo_fixedpnt_dlg.png [changed mode: 0755->0644]
doc/salome/gui/SMESH/images/image152.png [changed mode: 0755->0644]
doc/salome/gui/SMESH/images/image160.gif [changed mode: 0755->0644]
doc/salome/gui/SMESH/images/image56.jpg
doc/salome/gui/SMESH/images/image58.gif [deleted file]
doc/salome/gui/SMESH/images/image58.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/image59.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/image75.jpg [new file with mode: 0644]
doc/salome/gui/SMESH/images/image76.jpg [changed mode: 0755->0644]
doc/salome/gui/SMESH/images/image77.jpg [changed mode: 0755->0644]
doc/salome/gui/SMESH/images/image88.jpg [changed mode: 0755->0644]
doc/salome/gui/SMESH/images/image90.jpg [changed mode: 0755->0644]
doc/salome/gui/SMESH/images/mergeelems.png [changed mode: 0755->0644]
doc/salome/gui/SMESH/images/mergeelems_auto.png
doc/salome/gui/SMESH/images/mergenodes.png [changed mode: 0755->0644]
doc/salome/gui/SMESH/images/mergenodes_auto.png
doc/salome/gui/SMESH/images/merging_nodes1.png [changed mode: 0755->0644]
doc/salome/gui/SMESH/images/merging_nodes2.png [changed mode: 0755->0644]
doc/salome/gui/SMESH/images/pref21.png
doc/salome/gui/SMESH/images/pref22.png
doc/salome/gui/SMESH/images/pref23.png
doc/salome/gui/SMESH/images/pref24.png
doc/salome/gui/SMESH/images/preview_tmp_data.png
doc/salome/gui/SMESH/images/propagation_chain.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/quad_from_ma_medial_axis.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/quad_from_ma_mesh.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/quad_mesh_invalid.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/quad_meshes.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/rev_edges_helper_dlg.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/revolution1.png [changed mode: 0755->0644]
doc/salome/gui/SMESH/images/revolutionsn1.png
doc/salome/gui/SMESH/images/revolutionsn2.png
doc/salome/gui/SMESH/images/sew_after_merge.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/sew_using_merge.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/sewing1.png [changed mode: 0755->0644]
doc/salome/gui/SMESH/images/sewing2.png [changed mode: 0755->0644]
doc/salome/gui/SMESH/images/sewing3.png [changed mode: 0755->0644]
doc/salome/gui/SMESH/images/sewing4.png [changed mode: 0755->0644]
doc/salome/gui/SMESH/images/sewing_auto.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/sewing_manual.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/smesh_sort_groups.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/split_biquad_to_linear_dlg.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/split_biquad_to_linear_icon.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/split_biquad_to_linear_mesh.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/swap.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/viscous_layers_2d_hyp.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/viscous_layers_extrusion_method.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/viscous_layers_hyp.png
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
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/basic_meshing_algos.doc
doc/salome/gui/SMESH/input/borders_at_multi_connection.doc
doc/salome/gui/SMESH/input/borders_at_multi_connection_2d.doc
doc/salome/gui/SMESH/input/building_compounds.doc
doc/salome/gui/SMESH/input/cartesian_algo.doc
doc/salome/gui/SMESH/input/changing_orientation_of_elements.doc
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
doc/salome/gui/SMESH/input/create_groups_from_geometry.doc [changed mode: 0755->0644]
doc/salome/gui/SMESH/input/creating_groups.doc
doc/salome/gui/SMESH/input/cutting_quadrangles.doc
doc/salome/gui/SMESH/input/define_mesh_by_script.doc
doc/salome/gui/SMESH/input/deleting_groups.doc
doc/salome/gui/SMESH/input/diagonal_inversion_of_elements.doc
doc/salome/gui/SMESH/input/display_entity.doc
doc/salome/gui/SMESH/input/double_nodes_page.doc
doc/salome/gui/SMESH/input/editing_groups.doc
doc/salome/gui/SMESH/input/editing_meshes.doc
doc/salome/gui/SMESH/input/extrusion.doc
doc/salome/gui/SMESH/input/extrusion_along_path.doc
doc/salome/gui/SMESH/input/free_borders.doc
doc/salome/gui/SMESH/input/free_edges.doc
doc/salome/gui/SMESH/input/group_of_underlying_elements.doc
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
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
doc/salome/gui/SMESH/input/mesh_through_point.doc
doc/salome/gui/SMESH/input/modifying_meshes.doc [changed mode: 0755->0644]
doc/salome/gui/SMESH/input/pattern_mapping.doc
doc/salome/gui/SMESH/input/quad_from_ma_algo.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/quad_ijk_algo.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/removing_nodes_and_elements.doc
doc/salome/gui/SMESH/input/renumbering_nodes_and_elements.doc [deleted file]
doc/salome/gui/SMESH/input/reorient_faces.doc
doc/salome/gui/SMESH/input/revolution.doc
doc/salome/gui/SMESH/input/segments_around_vertex_algo.doc
doc/salome/gui/SMESH/input/selection_filter_library.doc
doc/salome/gui/SMESH/input/sewing_meshes.doc
doc/salome/gui/SMESH/input/smesh_migration.doc
doc/salome/gui/SMESH/input/smoothing.doc
doc/salome/gui/SMESH/input/split_biquad_to_linear.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/split_to_tetra.doc
doc/salome/gui/SMESH/input/symmetry.doc
doc/salome/gui/SMESH/input/taper.doc
doc/salome/gui/SMESH/input/tui_filters.doc
doc/salome/gui/SMESH/input/tui_modifying_meshes.doc
doc/salome/gui/SMESH/input/uniting_set_of_triangles.doc
doc/salome/gui/SMESH/input/uniting_two_triangles.doc
doc/salome/gui/SMESH/input/using_operations_on_groups.doc
doc/salome/gui/SMESH/input/viewing_meshes_overview.doc
doc/salome/gui/SMESH/static/footer.html
doc/salome/tui/CMakeLists.txt
doc/salome/tui/doxyfile.in
doc/salome/tui/static/footer.html
idl/CMakeLists.txt
idl/SMESH_BasicHypothesis.idl
idl/SMESH_Filter.idl
idl/SMESH_Gen.idl
idl/SMESH_Group.idl
idl/SMESH_Hypothesis.idl
idl/SMESH_Measurements.idl
idl/SMESH_Mesh.idl
idl/SMESH_MeshEditor.idl
idl/SMESH_Pattern.idl
resources/CMakeLists.txt
resources/SMESHCatalog.xml.in
resources/SalomeApp.xml.in
resources/StdMeshers.xml.in
resources/mesh_evaluate.png [new file with mode: 0644]
resources/mesh_extmeth_face_offset.png [new file with mode: 0644]
resources/mesh_extmeth_node_offset.png [new file with mode: 0644]
resources/mesh_extmeth_surf_offset_smooth.png [new file with mode: 0644]
resources/mesh_order.png [new file with mode: 0644]
resources/mesh_quad_polygon.png [new file with mode: 0644]
resources/mesh_tree_algo_polygon.png [new file with mode: 0644]
resources/split_biquad.png [new file with mode: 0644]
src/CMakeLists.txt
src/Controls/CMakeLists.txt
src/Controls/SMESH_Controls.cxx
src/Controls/SMESH_ControlsDef.hxx
src/Driver/CMakeLists.txt
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/DriverCGNS/CMakeLists.txt
src/DriverCGNS/DriverCGNS_Read.cxx
src/DriverCGNS/DriverCGNS_Read.hxx
src/DriverCGNS/DriverCGNS_Write.cxx
src/DriverCGNS/DriverCGNS_Write.hxx
src/DriverCGNS/SMESH_DriverCGNS.hxx
src/DriverDAT/CMakeLists.txt
src/DriverDAT/DriverDAT_R_SMDS_Mesh.cxx
src/DriverDAT/DriverDAT_R_SMDS_Mesh.h
src/DriverDAT/DriverDAT_W_SMDS_Mesh.cxx
src/DriverDAT/DriverDAT_W_SMDS_Mesh.h
src/DriverDAT/SMESH_DriverDAT.hxx
src/DriverGMF/CMakeLists.txt
src/DriverGMF/DriverGMF.cxx
src/DriverGMF/DriverGMF.hxx
src/DriverGMF/DriverGMF_Read.cxx
src/DriverGMF/DriverGMF_Read.hxx
src/DriverGMF/DriverGMF_Write.cxx
src/DriverGMF/DriverGMF_Write.hxx
src/DriverGMF/SMESH_DriverGMF.hxx
src/DriverMED/CMakeLists.txt
src/DriverMED/DriverMED.hxx
src/DriverMED/DriverMED_Family.cxx
src/DriverMED/DriverMED_Family.h
src/DriverMED/DriverMED_R_SMESHDS_Mesh.cxx
src/DriverMED/DriverMED_R_SMESHDS_Mesh.h
src/DriverMED/DriverMED_W_Field.cxx
src/DriverMED/DriverMED_W_Field.h
src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx
src/DriverMED/DriverMED_W_SMESHDS_Mesh.h
src/DriverMED/SMESH_DriverMED.hxx
src/DriverSTL/CMakeLists.txt
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/SMESH_DriverSTL.hxx
src/DriverUNV/CMakeLists.txt
src/DriverUNV/DriverUNV_R_SMDS_Mesh.cxx
src/DriverUNV/DriverUNV_R_SMDS_Mesh.h
src/DriverUNV/DriverUNV_W_SMDS_Mesh.cxx
src/DriverUNV/DriverUNV_W_SMDS_Mesh.h
src/DriverUNV/SMESH_DriverUNV.hxx
src/DriverUNV/UNV164_Structure.cxx
src/DriverUNV/UNV164_Structure.hxx
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
src/DriverUNV/UNV2420_Structure.hxx
src/DriverUNV/UNV_Utilities.cxx
src/DriverUNV/UNV_Utilities.hxx
src/MEDWrapper/Base/CMakeLists.txt
src/MEDWrapper/Base/MED_Algorithm.cxx
src/MEDWrapper/Base/MED_Algorithm.hxx
src/MEDWrapper/Base/MED_Common.hxx
src/MEDWrapper/Base/MED_CoordUtils.cxx
src/MEDWrapper/Base/MED_CoordUtils.hxx
src/MEDWrapper/Base/MED_GaussDef.cxx
src/MEDWrapper/Base/MED_GaussDef.hxx
src/MEDWrapper/Base/MED_GaussUtils.cxx
src/MEDWrapper/Base/MED_GaussUtils.hxx
src/MEDWrapper/Base/MED_SharedPtr.hxx
src/MEDWrapper/Base/MED_SliceArray.hxx
src/MEDWrapper/Base/MED_Structures.cxx
src/MEDWrapper/Base/MED_Structures.hxx
src/MEDWrapper/Base/MED_TStructures.hxx
src/MEDWrapper/Base/MED_TWrapper.hxx
src/MEDWrapper/Base/MED_Utilities.cxx
src/MEDWrapper/Base/MED_Utilities.hxx
src/MEDWrapper/Base/MED_Vector.hxx
src/MEDWrapper/Base/MED_Wrapper.cxx
src/MEDWrapper/Base/MED_Wrapper.hxx
src/MEDWrapper/Base/MED_WrapperBase.hxx
src/MEDWrapper/CMakeLists.txt
src/MEDWrapper/Factory/CMakeLists.txt
src/MEDWrapper/Factory/MED_Factory.cxx
src/MEDWrapper/Factory/MED_Factory.hxx
src/MEDWrapper/Factory/MED_Test.cxx
src/MEDWrapper/Factory/MED_WrapperFactory.hxx
src/MEDWrapper/Factory/mprint_version.cxx
src/MEDWrapper/V2_2/CMakeLists.txt
src/MEDWrapper/V2_2/MED_V2_2_Wrapper.cxx
src/MEDWrapper/V2_2/MED_V2_2_Wrapper.hxx
src/MEFISTO2/CMakeLists.txt
src/MEFISTO2/Rn.h
src/MEFISTO2/aptrte.cxx
src/MEFISTO2/aptrte.h
src/MEFISTO2/areteideale.f
src/MEFISTO2/trte.f
src/OBJECT/CMakeLists.txt
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
src/OBJECT/SMESH_CellLabelActor.h
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
src/OBJECT/SMESH_NodeLabelActor.h
src/OBJECT/SMESH_Object.cxx
src/OBJECT/SMESH_Object.h
src/OBJECT/SMESH_ObjectDef.h
src/OBJECT/SMESH_PreviewActorsCollection.cxx
src/OBJECT/SMESH_PreviewActorsCollection.h
src/OBJECT/SMESH_SVTKActor.cxx
src/OBJECT/SMESH_SVTKActor.h
src/OBJECT/SMESH_ScalarBarActor.cxx
src/OBJECT/SMESH_ScalarBarActor.h
src/PluginUtils/CMakeLists.txt
src/PluginUtils/GeomSelectionTools.cxx
src/PluginUtils/GeomSelectionTools.h
src/SMDS/CMakeLists.txt
src/SMDS/ObjectPool.hxx
src/SMDS/SMDSAbs_ElementType.hxx
src/SMDS/SMDS_BallElement.cxx
src/SMDS/SMDS_BallElement.hxx
src/SMDS/SMDS_Downward.cxx
src/SMDS/SMDS_Downward.hxx
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
src/SMDS/SMDS_LinearEdge.cxx
src/SMDS/SMDS_LinearEdge.hxx
src/SMDS/SMDS_MemoryLimit.cxx
src/SMDS/SMDS_Mesh.cxx
src/SMDS/SMDS_Mesh.hxx
src/SMDS/SMDS_Mesh0DElement.cxx
src/SMDS/SMDS_Mesh0DElement.hxx
src/SMDS/SMDS_MeshCell.cxx
src/SMDS/SMDS_MeshCell.hxx
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
src/SMDS/SMDS_MeshNodeIDFactory.hxx
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
src/SMDS/SMDS_TypeOfPosition.hxx
src/SMDS/SMDS_UnstructuredGrid.cxx
src/SMDS/SMDS_UnstructuredGrid.hxx
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
src/SMDS/SMDS_VtkCellIterator.hxx
src/SMDS/SMDS_VtkEdge.cxx
src/SMDS/SMDS_VtkEdge.hxx
src/SMDS/SMDS_VtkFace.cxx
src/SMDS/SMDS_VtkFace.hxx
src/SMDS/SMDS_VtkVolume.cxx
src/SMDS/SMDS_VtkVolume.hxx
src/SMDS/SMESH_SMDS.hxx
src/SMDS/chrono.cxx
src/SMDS/chrono.hxx
src/SMESH/CMakeLists.txt
src/SMESH/SMESH_Algo.cxx
src/SMESH/SMESH_Algo.hxx
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_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_Pattern.cxx
src/SMESH/SMESH_Pattern.hxx
src/SMESH/SMESH_ProxyMesh.cxx
src/SMESH/SMESH_ProxyMesh.hxx
src/SMESH/SMESH_SMESH.hxx
src/SMESH/SMESH_subMesh.cxx
src/SMESH/SMESH_subMesh.hxx
src/SMESH/SMESH_subMeshEventListener.hxx
src/SMESH/memoire.h
src/SMESHClient/CMakeLists.txt
src/SMESHClient/SMESHClientBin.cxx
src/SMESHClient/SMESH_Client.cxx
src/SMESHClient/SMESH_Client.hxx
src/SMESHDS/CMakeLists.txt
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
src/SMESHDS/SMESHDS_GroupOnFilter.hxx
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/SMESHDS_TSubMeshHolder.hxx
src/SMESHDS/SMESH_Controls.hxx
src/SMESHDS/SMESH_SMESHDS.hxx
src/SMESHFiltersSelection/CMakeLists.txt
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/CMakeLists.txt
src/SMESHGUI/SMESHGUI.cxx
src/SMESHGUI/SMESHGUI.h
src/SMESHGUI/SMESHGUI_Add0DElemsOnAllNodesDlg.cxx
src/SMESHGUI/SMESHGUI_Add0DElemsOnAllNodesDlg.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
src/SMESHGUI/SMESHGUI_CopyMeshDlg.h
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_DisplayEntitiesDlg.cxx
src/SMESHGUI/SMESHGUI_DisplayEntitiesDlg.h
src/SMESHGUI/SMESHGUI_Displayer.cxx
src/SMESHGUI/SMESHGUI_Displayer.h
src/SMESHGUI/SMESHGUI_DuplicateNodesDlg.cxx
src/SMESHGUI/SMESHGUI_DuplicateNodesDlg.h
src/SMESHGUI/SMESHGUI_ExtrusionAlongPathDlg.cxx
src/SMESHGUI/SMESHGUI_ExtrusionAlongPathDlg.h
src/SMESHGUI/SMESHGUI_ExtrusionDlg.cxx
src/SMESHGUI/SMESHGUI_ExtrusionDlg.h
src/SMESHGUI/SMESHGUI_FieldSelectorWdg.cxx
src/SMESHGUI/SMESHGUI_FieldSelectorWdg.h
src/SMESHGUI/SMESHGUI_FileInfoDlg.cxx
src/SMESHGUI/SMESHGUI_FileInfoDlg.h
src/SMESHGUI/SMESHGUI_FileValidator.cxx
src/SMESHGUI/SMESHGUI_FileValidator.h
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
src/SMESHGUI/SMESHGUI_FindElemByPointDlg.h
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_IdPreview.cxx [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_IdPreview.h [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_IdValidator.h
src/SMESHGUI/SMESHGUI_Make2DFrom3DOp.cxx
src/SMESHGUI/SMESHGUI_Make2DFrom3DOp.h
src/SMESHGUI/SMESHGUI_MakeNodeAtPointDlg.cxx
src/SMESHGUI/SMESHGUI_MakeNodeAtPointDlg.h
src/SMESHGUI/SMESHGUI_Measurements.cxx
src/SMESHGUI/SMESHGUI_Measurements.h
src/SMESHGUI/SMESHGUI_MergeDlg.cxx
src/SMESHGUI/SMESHGUI_MergeDlg.h
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
src/SMESHGUI/SMESHGUI_MeshInfo.h
src/SMESHGUI/SMESHGUI_MeshInfosBox.cxx
src/SMESHGUI/SMESHGUI_MeshInfosBox.h
src/SMESHGUI/SMESHGUI_MeshOp.cxx
src/SMESHGUI/SMESHGUI_MeshOp.h
src/SMESHGUI/SMESHGUI_MeshOrderDlg.cxx
src/SMESHGUI/SMESHGUI_MeshOrderDlg.h
src/SMESHGUI/SMESHGUI_MeshOrderOp.cxx
src/SMESHGUI/SMESHGUI_MeshOrderOp.h
src/SMESHGUI/SMESHGUI_MeshPatternDlg.cxx
src/SMESHGUI/SMESHGUI_MeshPatternDlg.h
src/SMESHGUI/SMESHGUI_MeshUtils.cxx
src/SMESHGUI/SMESHGUI_MeshUtils.h
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_Operations.h
src/SMESHGUI/SMESHGUI_PatternUtils.cxx
src/SMESHGUI/SMESHGUI_PatternUtils.h
src/SMESHGUI/SMESHGUI_PatternWidget.cxx
src/SMESHGUI/SMESHGUI_PatternWidget.h
src/SMESHGUI/SMESHGUI_PreVisualObj.cxx [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_PreVisualObj.h [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.cxx
src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.h
src/SMESHGUI/SMESHGUI_PreviewDlg.cxx
src/SMESHGUI/SMESHGUI_PreviewDlg.h
src/SMESHGUI/SMESHGUI_PropertiesDlg.cxx
src/SMESHGUI/SMESHGUI_PropertiesDlg.h
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
src/SMESHGUI/SMESHGUI_ReorientFacesDlg.h
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
src/SMESHGUI/SMESHGUI_ScaleDlg.h
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_SplitBiQuad.cxx [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_SplitBiQuad.h [new file with mode: 0644]
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_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
src/SMESHGUI/SMESH_msg_ja.ts
src/SMESHUtils/CMakeLists.txt
src/SMESHUtils/SMESH_Block.cxx
src/SMESHUtils/SMESH_Block.hxx
src/SMESHUtils/SMESH_Comment.hxx
src/SMESHUtils/SMESH_ComputeError.hxx
src/SMESHUtils/SMESH_File.cxx
src/SMESHUtils/SMESH_File.hxx
src/SMESHUtils/SMESH_FreeBorders.cxx [new file with mode: 0644]
src/SMESHUtils/SMESH_MAT2d.cxx [new file with mode: 0644]
src/SMESHUtils/SMESH_MAT2d.hxx [new file with mode: 0644]
src/SMESHUtils/SMESH_MeshAlgos.cxx
src/SMESHUtils/SMESH_MeshAlgos.hxx
src/SMESHUtils/SMESH_Octree.cxx
src/SMESHUtils/SMESH_Octree.hxx
src/SMESHUtils/SMESH_OctreeNode.cxx
src/SMESHUtils/SMESH_OctreeNode.hxx
src/SMESHUtils/SMESH_Quadtree.cxx
src/SMESHUtils/SMESH_Quadtree.hxx
src/SMESHUtils/SMESH_Tree.hxx
src/SMESHUtils/SMESH_TryCatch.cxx
src/SMESHUtils/SMESH_TryCatch.hxx
src/SMESHUtils/SMESH_TypeDefs.hxx
src/SMESHUtils/SMESH_Utils.hxx
src/SMESH_I/CMakeLists.txt
src/SMESH_I/SMESH.hxx
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_Measurements_i.cxx
src/SMESH_I/SMESH_Measurements_i.hxx
src/SMESH_I/SMESH_MeshEditor_i.cxx
src/SMESH_I/SMESH_MeshEditor_i.hxx
src/SMESH_I/SMESH_MeshPartDS.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
src/SMESH_I/SMESH_PreMeshInfo.hxx
src/SMESH_I/SMESH_PythonDump.hxx
src/SMESH_I/SMESH_subMesh_i.cxx
src/SMESH_I/SMESH_subMesh_i.hxx
src/SMESH_PY/CMakeLists.txt
src/SMESH_PY/__init__.py
src/SMESH_PY/smeshstudytools.py
src/SMESH_SWIG/CMakeLists.txt
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/StdMeshersBuilder.py
src/SMESH_SWIG/__init__.py
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/smeshBuilder.py
src/SMESH_SWIG/smesh_algorithm.py
src/SMESH_SWIG/smesh_selection.py [new file with mode: 0644]
src/SMESH_SWIG_WITHIHM/CMakeLists.txt
src/SMESH_SWIG_WITHIHM/libSMESH_Swig.cxx
src/SMESH_SWIG_WITHIHM/libSMESH_Swig.h
src/SMESH_SWIG_WITHIHM/libSMESH_Swig.i
src/StdMeshers/CMakeLists.txt
src/StdMeshers/SMESH_StdMeshers.hxx
src/StdMeshers/StdMeshers_Adaptive1D.cxx
src/StdMeshers/StdMeshers_Adaptive1D.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
src/StdMeshers/StdMeshers_CartesianParameters3D.hxx
src/StdMeshers/StdMeshers_Cartesian_3D.cxx
src/StdMeshers/StdMeshers_Cartesian_3D.hxx
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
src/StdMeshers/StdMeshers_FixedPoints1D.hxx
src/StdMeshers/StdMeshers_Geometric1D.cxx
src/StdMeshers/StdMeshers_Geometric1D.hxx
src/StdMeshers/StdMeshers_HexaFromSkin_3D.cxx
src/StdMeshers/StdMeshers_HexaFromSkin_3D.hxx
src/StdMeshers/StdMeshers_Hexa_3D.cxx
src/StdMeshers/StdMeshers_Hexa_3D.hxx
src/StdMeshers/StdMeshers_ImportSource.cxx
src/StdMeshers/StdMeshers_ImportSource.hxx
src/StdMeshers/StdMeshers_Import_1D.cxx
src/StdMeshers/StdMeshers_Import_1D.hxx
src/StdMeshers/StdMeshers_Import_1D2D.cxx
src/StdMeshers/StdMeshers_Import_1D2D.hxx
src/StdMeshers/StdMeshers_LayerDistribution.cxx
src/StdMeshers/StdMeshers_LayerDistribution.hxx
src/StdMeshers/StdMeshers_LayerDistribution2D.cxx
src/StdMeshers/StdMeshers_LayerDistribution2D.hxx
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
src/StdMeshers/StdMeshers_NumberOfLayers2D.hxx
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_PolygonPerFace_2D.cxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_PolygonPerFace_2D.hxx [new file with mode: 0644]
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
src/StdMeshers/StdMeshers_Projection_1D2D.hxx
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_QuadFromMedialAxis_1D2D.cxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_QuadFromMedialAxis_1D2D.hxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_QuadToTriaAdaptor.cxx
src/StdMeshers/StdMeshers_QuadToTriaAdaptor.hxx
src/StdMeshers/StdMeshers_QuadrangleParams.cxx
src/StdMeshers/StdMeshers_QuadrangleParams.hxx
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
src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.hxx
src/StdMeshers/StdMeshers_Regular_1D.cxx
src/StdMeshers/StdMeshers_Regular_1D.hxx
src/StdMeshers/StdMeshers_Reversible1D.cxx
src/StdMeshers/StdMeshers_Reversible1D.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_UseExisting_1D2D.cxx
src/StdMeshers/StdMeshers_UseExisting_1D2D.hxx
src/StdMeshers/StdMeshers_ViscousLayers.cxx
src/StdMeshers/StdMeshers_ViscousLayers.hxx
src/StdMeshers/StdMeshers_ViscousLayers2D.cxx
src/StdMeshers/StdMeshers_ViscousLayers2D.hxx
src/StdMeshersGUI/CMakeLists.txt
src/StdMeshersGUI/SMESH_StdMeshersGUI.hxx
src/StdMeshersGUI/StdMeshersGUI.cxx
src/StdMeshersGUI/StdMeshersGUI_CartesianParamCreator.cxx
src/StdMeshersGUI/StdMeshersGUI_CartesianParamCreator.h
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
src/StdMeshersGUI/StdMeshersGUI_FixedPointsParamWdg.h
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_PropagationHelperWdg.cxx [new file with mode: 0644]
src/StdMeshersGUI/StdMeshersGUI_PropagationHelperWdg.h [new file with mode: 0644]
src/StdMeshersGUI/StdMeshersGUI_QuadrangleParamWdg.cxx
src/StdMeshersGUI/StdMeshersGUI_QuadrangleParamWdg.h
src/StdMeshersGUI/StdMeshersGUI_RadioButtonsGrpWdg.cxx
src/StdMeshersGUI/StdMeshersGUI_RadioButtonsGrpWdg.h
src/StdMeshersGUI/StdMeshersGUI_StdHypothesisCreator.cxx
src/StdMeshersGUI/StdMeshersGUI_StdHypothesisCreator.h
src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.cxx
src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.h
src/StdMeshersGUI/StdMeshers_images.ts
src/StdMeshersGUI/StdMeshers_msg_en.ts
src/StdMeshersGUI/StdMeshers_msg_fr.ts
src/StdMeshersGUI/StdMeshers_msg_ja.ts
src/StdMeshers_I/CMakeLists.txt
src/StdMeshers_I/SMESH_StdMeshers_I.hxx
src/StdMeshers_I/StdMeshers_Adaptive1D_i.cxx
src/StdMeshers_I/StdMeshers_Adaptive1D_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
src/StdMeshers_I/StdMeshers_CartesianParameters3D_i.hxx
src/StdMeshers_I/StdMeshers_Cartesian_3D_i.cxx
src/StdMeshers_I/StdMeshers_Cartesian_3D_i.hxx
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
src/StdMeshers_I/StdMeshers_FixedPoints1D_i.hxx
src/StdMeshers_I/StdMeshers_Geometric1D_i.cxx
src/StdMeshers_I/StdMeshers_Geometric1D_i.hxx
src/StdMeshers_I/StdMeshers_Hexa_3D_i.cxx
src/StdMeshers_I/StdMeshers_Hexa_3D_i.hxx
src/StdMeshers_I/StdMeshers_ImportSource1D_i.cxx
src/StdMeshers_I/StdMeshers_ImportSource1D_i.hxx
src/StdMeshers_I/StdMeshers_ImportSource2D_i.cxx
src/StdMeshers_I/StdMeshers_ImportSource2D_i.hxx
src/StdMeshers_I/StdMeshers_Import_1D2D_i.cxx
src/StdMeshers_I/StdMeshers_Import_1D2D_i.hxx
src/StdMeshers_I/StdMeshers_Import_1D_i.cxx
src/StdMeshers_I/StdMeshers_Import_1D_i.hxx
src/StdMeshers_I/StdMeshers_LayerDistribution2D_i.cxx
src/StdMeshers_I/StdMeshers_LayerDistribution2D_i.hxx
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
src/StdMeshers_I/StdMeshers_NumberOfLayers2D_i.hxx
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_PolygonPerFace_2D_i.cxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_PolygonPerFace_2D_i.hxx [new file with mode: 0644]
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
src/StdMeshers_I/StdMeshers_QuadrangleParams_i.hxx
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
src/StdMeshers_I/StdMeshers_RadialQuadrangle_1D2D_i.hxx
src/StdMeshers_I/StdMeshers_Regular_1D_i.cxx
src/StdMeshers_I/StdMeshers_Regular_1D_i.hxx
src/StdMeshers_I/StdMeshers_Reversible1D_i.cxx
src/StdMeshers_I/StdMeshers_Reversible1D_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_UseExisting_1D2D_i.cxx
src/StdMeshers_I/StdMeshers_UseExisting_1D2D_i.hxx
src/StdMeshers_I/StdMeshers_ViscousLayers2D_i.cxx
src/StdMeshers_I/StdMeshers_ViscousLayers2D_i.hxx
src/StdMeshers_I/StdMeshers_ViscousLayers_i.cxx
src/StdMeshers_I/StdMeshers_ViscousLayers_i.hxx
src/StdMeshers_I/StdMeshers_i.cxx
src/Tools/CMakeLists.txt
src/Tools/MGCleanerPlug/CMakeLists.txt
src/Tools/MGCleanerPlug/MGCleanerMonPlugDialog.py
src/Tools/MGCleanerPlug/MGCleanerMonViewText.py
src/Tools/MGCleanerPlug/MGCleanerplug_plugin.py
src/Tools/MGCleanerPlug/doc/CMakeLists.txt
src/Tools/MGCleanerPlug/doc/conf.py.in
src/Tools/MacMesh/CMakeLists.txt
src/Tools/MacMesh/Example/PressureValve.py.in
src/Tools/MacMesh/MacMesh/Alarms.py
src/Tools/MacMesh/MacMesh/CentralUnrefine.py
src/Tools/MacMesh/MacMesh/CompositeBox.py
src/Tools/MacMesh/MacMesh/CompositeBoxF.py
src/Tools/MacMesh/MacMesh/Config.py
src/Tools/MacMesh/MacMesh/CutnGroup.py
src/Tools/MacMesh/MacMesh/Cylinder.py
src/Tools/MacMesh/MacMesh/GenFunctions.py
src/Tools/MacMesh/MacMesh/MacObject.py
src/Tools/MacMesh/MacMesh/PublishGroups.py
src/Tools/MacMesh/MacMesh/SharpAngle.py
src/Tools/MeshCut/AUTHORS
src/Tools/MeshCut/CMakeLists.txt
src/Tools/MeshCut/MeshCut_Carre.cxx
src/Tools/MeshCut/MeshCut_Carre.hxx
src/Tools/MeshCut/MeshCut_Cas.cxx
src/Tools/MeshCut/MeshCut_Cas.hxx
src/Tools/MeshCut/MeshCut_Cube.cxx
src/Tools/MeshCut/MeshCut_Cube.hxx
src/Tools/MeshCut/MeshCut_DC.cxx
src/Tools/MeshCut/MeshCut_Fonctions.cxx
src/Tools/MeshCut/MeshCut_Fonctions.hxx
src/Tools/MeshCut/MeshCut_Globals.hxx
src/Tools/MeshCut/MeshCut_Maillage.cxx
src/Tools/MeshCut/MeshCut_Maillage.hxx
src/Tools/MeshCut/MeshCut_Utils.cxx
src/Tools/MeshCut/MeshCut_Utils.hxx
src/Tools/MeshCut/meshcut_plugin.py
src/Tools/Verima/Base/CMakeLists.txt
src/Tools/Verima/Base/__init__.py
src/Tools/Verima/Base/importFromCSV.py
src/Tools/Verima/Base/tablePerfs.py
src/Tools/Verima/CMakeLists.txt
src/Tools/Verima/CreeDocuments/CMakeLists.txt
src/Tools/Verima/CreeDocuments/__init__.py
src/Tools/Verima/CreeDocuments/templatesHtml/CMakeLists.txt
src/Tools/Verima/Doc/CMakeLists.txt
src/Tools/Verima/Doc/conf.py
src/Tools/Verima/Doc/conf.py.in
src/Tools/Verima/Doc/makefile
src/Tools/Verima/Gui/CMakeLists.txt
src/Tools/Verima/Gui/__init__.py
src/Tools/Verima/Stats/CMakeLists.txt
src/Tools/Verima/Stats/__init__.py
src/Tools/Verima/__init__.py
src/Tools/YamsPlug/CMakeLists.txt
src/Tools/YamsPlug/doc/CMakeLists.txt
src/Tools/YamsPlug/doc/conf.py.in
src/Tools/YamsPlug/monViewText.py
src/Tools/YamsPlug/monYamsPlugDialog.py
src/Tools/YamsPlug/yamsplug_plugin.py
src/Tools/ZCracksPlug/CMakeLists.txt
src/Tools/ZCracksPlug/doc/CMakeLists.txt
src/Tools/ZCracksPlug/doc/conf.py.in
src/Tools/ZCracksPlug/zcracks_plugin.py
src/Tools/blocFissure/CMakeLists.txt
src/Tools/blocFissure/CasTests/CMakeLists.txt
src/Tools/blocFissure/gmu/CMakeLists.txt
src/Tools/blocFissure/gmu/triedreBase.py
src/Tools/blocFissure/ihm/CMakeLists.txt
src/Tools/blocFissure/ihm/fissureCoude_plugin.py
src/Tools/blocFissure/materielCasTests/CMakeLists.txt
src/Tools/padder/CMakeLists.txt
src/Tools/padder/doc/CMakeLists.txt
src/Tools/padder/doc/doxyfile.in
src/Tools/padder/meshjob/CMakeLists.txt
src/Tools/padder/meshjob/idl/CMakeLists.txt
src/Tools/padder/meshjob/idl/MESHJOB.idl
src/Tools/padder/meshjob/idl/SPADDERPluginTest.idl
src/Tools/padder/meshjob/impl/CMakeLists.txt
src/Tools/padder/meshjob/impl/MeshJobManager_i.cxx
src/Tools/padder/meshjob/impl/MeshJobManager_i.hxx
src/Tools/padder/meshjob/impl/SPADDERPluginTester_i.cxx
src/Tools/padder/meshjob/impl/SPADDERPluginTester_i.hxx
src/Tools/padder/meshjob/impl/testhelper.hxx
src/Tools/padder/resources/CMakeLists.txt
src/Tools/padder/resources/testdata/buildparticules.py
src/Tools/padder/spadderpy/CMakeLists.txt
src/Tools/padder/spadderpy/__init__.py
src/Tools/padder/spadderpy/configreader.py
src/Tools/padder/spadderpy/gui/CMakeLists.txt
src/Tools/padder/spadderpy/gui/__init__.py
src/Tools/padder/spadderpy/gui/inputdata.py
src/Tools/padder/spadderpy/gui/inputdialog.py
src/Tools/padder/spadderpy/gui/plugindialog.py
src/Tools/padder/spadderpy/plugin/CMakeLists.txt
src/Tools/padder/spadderpy/plugin/envPlugins.sh.in
src/Tools/padder/spadderpy/plugin/spadderPlugin.py
src/Tools/padder/unittests/CMakeLists.txt
src/Tools/padder/unittests/__init__.py
src/Tools/padder/unittests/autotest.sh.in
src/Tools/padder/unittests/usecase_meshJobManager.py
src/Tools/padder/unittests/usecase_spadderPluginTester.py
src/Tools/smesh_plugins.py

index a88f8c23a473c4e13cefb8f8d2bbec713a5608b0..03e0f5357cbdc8cb7a02034f0d382f57c62cb589 100755 (executable)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2012-2015  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
@@ -28,8 +28,8 @@ CMAKE_POLICY(SET CMP0003 NEW)
 STRING(TOUPPER ${PROJECT_NAME} PROJECT_NAME_UC)
 
 SET(${PROJECT_NAME_UC}_MAJOR_VERSION 7)
-SET(${PROJECT_NAME_UC}_MINOR_VERSION 4)
-SET(${PROJECT_NAME_UC}_PATCH_VERSION 1)
+SET(${PROJECT_NAME_UC}_MINOR_VERSION 7)
+SET(${PROJECT_NAME_UC}_PATCH_VERSION 0)
 SET(${PROJECT_NAME_UC}_VERSION
   ${${PROJECT_NAME_UC}_MAJOR_VERSION}.${${PROJECT_NAME_UC}_MINOR_VERSION}.${${PROJECT_NAME_UC}_PATCH_VERSION})
 SET(${PROJECT_NAME_UC}_VERSION_DEV 1)
@@ -42,6 +42,8 @@ IF(EXISTS ${KERNEL_ROOT_DIR})
   INCLUDE(SalomeMacros)
   FIND_PACKAGE(SalomeKERNEL REQUIRED)
   KERNEL_WITH_CORBA() #check whether KERNEL builded with CORBA
+  ADD_DEFINITIONS(${KERNEL_DEFINITIONS})
+  INCLUDE_DIRECTORIES(${KERNEL_INCLUDE_DIRS})
 ELSE(EXISTS ${KERNEL_ROOT_DIR})
   MESSAGE(FATAL_ERROR "We absolutely need a Salome KERNEL, please define KERNEL_ROOT_DIR")
 ENDIF(EXISTS ${KERNEL_ROOT_DIR})
@@ -101,9 +103,6 @@ FIND_PACKAGE(SalomeLibXml2 REQUIRED)
 FIND_PACKAGE(SalomeHDF5 REQUIRED COMPONENTS C)
 
 # Other KERNEL optionals:
-IF(SALOME_USE_MPI)
-  FIND_PACKAGE(SalomeMPI) # needed for doc generation by Sphinx
-ENDIF()
 IF(SALOME_BUILD_TESTS)
   ENABLE_TESTING()
   FIND_PACKAGE(SalomeCppUnit)
@@ -122,7 +121,9 @@ IF(SALOME_BUILD_GUI)
   IF(EXISTS ${GUI_ROOT_DIR})
     LIST(APPEND CMAKE_MODULE_PATH "${GUI_ROOT_DIR}/adm_local/cmake_files")
     FIND_PACKAGE(SalomeGUI)
-    FULL_GUI(TRUE) #check whether GUI builded in full mode and with CORBA
+    SALOME_GUI_WITH_CORBA() #check whether GUI builded with CORBA
+    SALOME_GUI_MODE(SALOME_USE_VTKVIEWER SALOME_USE_SALOMEOBJECT 
+                    OPTIONAL SALOME_USE_PLOT2DVIEWER SALOME_USE_PYCONSOLE)
     ##
     ## Prerequisites From GUI:
     ##
index ddf1bff09bf1680f690e5341c03c2e2dd61123cd..79e9367d37d218e0a7408f9e513563a6a4a431ad 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 204cb88162a051b1673d7112f1d9748c78d7bbd8..8a8827406dd0d49927917387f86492bccb759362 100644 (file)
@@ -5,7 +5,7 @@
 #
 
 ###############################################################
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index bedde74e07b3952b1f6c5378ce3ee85bfbfcca7d..3f181513f71f75288e596271c67c21f89659c986 100755 (executable)
@@ -1,4 +1,4 @@
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 3ccd4f39dff0f6c9f8a569897f7d59a080fb7921..9be31435bc03fcd5dbb459f2c22fd8add9614aba 100755 (executable)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2012-2015  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
index 84471e6312fb68196f219695e376c8ec5a001f8f..94535f27e2cf1103ba192f4244efd999e62882c0 100644 (file)
@@ -5,7 +5,7 @@
 #
 
 #########################################################################
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index aeb4ee6e09de46104f0881e39fb8f350bd11a5b7..e05012824d0050520ba28348c634b9140b5e543b 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  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
index 1f5ced5b4c550a96e3a1a89736883f4dc284d9ff..a492391686aa1115cd2bbe8065d2d43521920933 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2013-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2013-2015  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
index c433652b2a5737b047819cf01fe10847140161ff..dc63bd2fa51305e0e08daa6b9d06cfe5b9934bb9 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  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
index c7486e9a1b1c4e35ec77e4c2a92594d6f097ebbd..0fc8270ee35fdc28e921f64740514bf6b20e8842 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2013-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2013-2015  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
index 1de9cd94c48b484dc6270eda5bdabfd09a0c6ec5..4deefa22e535be61f005280a1146c95113fa81b4 100755 (executable)
@@ -1,4 +1,4 @@
-# Copyright (C) 2013-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2013-2015  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
index 2fa30c576d71309010c0bd4ebfc158aab3fa6b4e..a1592539ff10f343c405adbf84bcf92664d2b323 100644 (file)
@@ -5,7 +5,7 @@
 #
 
 #########################################################################
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -41,21 +41,65 @@ ENDIF(TBB_ROOT_DIR)
 
 FIND_PATH(TBB_INCLUDE_DIRS tbb/tbb.h PATH_SUFFIXES include)
 
-SET(TBBKERNEL cc4.1.0_libc2.4_kernel2.6.16.21)
-
 IF(MACHINE_IS_64)
-  SET(LIB_SUFFIX lib/intel64/${TBBKERNEL})
+  SET(PLT_SUFFIX intel64)
 ELSE(MACHINE_IS_64)
-  SET(LIB_SUFFIX lib/ia32/${TBBKERNEL})
+  SET(PLT_SUFFIX ia32)
 ENDIF(MACHINE_IS_64)
 
-FIND_LIBRARY(TBB_LIBRARY_tbb NAMES tbb PATH_SUFFIXES "${LIB_SUFFIX}")
-FIND_LIBRARY(TBB_LIBRATY_tbbmalloc NAMES tbbmalloc PATH_SUFFIXES "${LIB_SUFFIX}")
+include(CheckCXXSourceCompiles)
+
+FOREACH(_kernel cc4.1.0_libc2.4_kernel2.6.16.21 gcc4.4 gcc4.1)
+
+  FIND_LIBRARY(_tbb_library_tbb${_kernel}       NAMES tbb       PATH_SUFFIXES lib/${PLT_SUFFIX}/${_kernel})
+  FIND_LIBRARY(_tbb_library_tbbmalloc${_kernel} NAMES tbbmalloc PATH_SUFFIXES lib/${PLT_SUFFIX}/${_kernel})
+
+  SET(_tbb_libraries${_kernel} ${_tbb_library_tbb${_kernel}} ${_tbb_library_tbbmalloc${_kernel}})
+
+  IF(_tbb_libraries${_kernel})
+
+    SET(CMAKE_REQUIRED_INCLUDES_SAVE  ${CMAKE_REQUIRED_INCLUDES})
+    SET(CMAKE_REQUIRED_LIBRARIES_SAVE ${CMAKE_REQUIRED_LIBRARIES})
+    SET(CMAKE_REQUIRED_INCLUDES  "${CMAKE_REQUIRED_INCLUDES} ${TBB_INCLUDE_DIRS}")
+    SET(CMAKE_REQUIRED_LIBRARIES "${_tbb_libraries${_kernel}}")
+
+    CHECK_CXX_SOURCE_COMPILES("
+      #include <tbb/tbb.h>
+      using namespace tbb;
+      size_t testme(size_t n)
+      {
+        return n*n;
+      }
+      int main(int argc, char* argv[])
+      {
+        parallel_for<size_t>( 1, 10, 1, testme );
+      }
+      "
+      _tbb_link_ok${_kernel}
+      )
+    
+    SET(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES_SAVE})
+    SET(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES_SAVE})
+
+    IF(_tbb_link_ok${_kernel})
+      SET(_tbb_link_ok ${_tbb_link_ok${_kernel}})
+      SET(TBB_LIBRARY_tbb       ${_tbb_library_tbb${_kernel}}       CACHE FILEPATH "Path to a library")
+      SET(TBB_LIBRARY_tbbmalloc ${_tbb_library_tbbmalloc${_kernel}} CACHE FILEPATH "Path to a library")
+      SET(TBB_LIBRARIES ${TBB_LIBRARY_tbb} ${TBB_LIBRARY_tbbmalloc})
+    ENDIF()
+
+    UNSET(_tbb_link_ok${_kernel} CACHE)
+
+  ENDIF(_tbb_libraries${_kernel})
+
+  UNSET(_tbb_library_tbb${_kernel} CACHE)
+  UNSET(_tbb_library_tbbmalloc${_kernel} CACHE)
+
+  IF(_tbb_link_ok)
+    BREAK()
+  ENDIF()
 
-SET(TBB_LIBRARIES
-  ${TBB_LIBRARY_tbb}
-  ${TBB_LIBRATY_tbbmalloc}
-)
+ENDFOREACH()
 
 INCLUDE(FindPackageHandleStandardArgs)
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(TBB REQUIRED_VARS TBB_INCLUDE_DIRS TBB_LIBRARY_tbb TBB_LIBRATY_tbbmalloc)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(TBB REQUIRED_VARS TBB_INCLUDE_DIRS TBB_LIBRARY_tbb TBB_LIBRARY_tbbmalloc)
index 896f1e34981de3712392270cb540edb62539a80a..8510af1c767923b0edd80e0d03c81f296f3a995a 100755 (executable)
@@ -6,7 +6,7 @@
 #
 
 #########################################################################
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index eb508c1f49f2df961ef7e6fbc2a80dae66c28a35..0e752193100775013c5b51b4161e438070edef0e 100755 (executable)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2012-2015  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
index a734dfab33cb322d1c172a16a4fcf1a2f10bc2f6..28926ce57a04f8a4dd669ec0507598189e7a760e 100755 (executable)
@@ -1,4 +1,4 @@
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 16344da790476665de7c07b6b5a153613fb07849..37cb272884054d6574d903399712bc12a6feb722 100755 (executable)
@@ -1,4 +1,4 @@
-dnl Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+dnl Copyright (C) 2007-2015  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
index 7e9d4eefa647b511712afb15f2d7312e0da24c90..189e12c8539b51fa451ccda2de29fad1bfb02ed8 100644 (file)
@@ -1,4 +1,4 @@
-dnl Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+dnl Copyright (C) 2007-2015  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
index ca787993ff563a0750d1edbb210ddec8ccb328ee..3f5d6b0eb619ab1e9a514e3a869b0b8065ae98c3 100644 (file)
@@ -1,4 +1,4 @@
-dnl Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+dnl Copyright (C) 2007-2015  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
index 4f27dc6bd330f31d91c260d2402537f699066eb7..27d5741bc224663d346b72233e5a3f7e756cdcaf 100644 (file)
@@ -1,4 +1,4 @@
-dnl Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+dnl Copyright (C) 2007-2015  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
index 99f34c0fab8b85515da3ef57123a8070e228533f..9c74dee1950189ca4e1d473f50150a60100aad83 100644 (file)
@@ -1,4 +1,4 @@
-dnl Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+dnl Copyright (C) 2007-2015  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
index ca8ace8bad388db97f7d4ae3e17ffbd27d986c54..5c65463f28856db38731e0b0616a8e69876740f8 100644 (file)
@@ -1,4 +1,4 @@
-dnl Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+dnl Copyright (C) 2007-2015  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
index 8990bffad4a5418c5f480c5adb58c41b88cf284e..43595035ba712a2f8c2c22c8b69f11682290c851 100644 (file)
@@ -1,4 +1,4 @@
-dnl Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+dnl Copyright (C) 2007-2015  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
index 4af8a501ec515a79382ca7ce08572f359277a3ea..1b651f73d3334c80d1813d541d3668c83c59f07a 100755 (executable)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2012-2015  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
index b58c8e4125783d4f50d86750433ab1ef3e92704a..bdb3afd23d4f1214fc026ddd55b68e4266af745c 100644 (file)
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  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
index 27aa5730ad3c0f920b3fb11eb6bd16cb656cb8ea..8bfe7cab7739f622848769ec102405c24fa5888e 100755 (executable)
@@ -1,4 +1,4 @@
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 197a24a4f8ae7029626bd058e14cd55749fb4cc6..1ccad11e2426e17b517103ba9c588ece63df21bd 100755 (executable)
@@ -1,4 +1,4 @@
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 7aa0636896d74818d7515d8e56d0f36ad144f9e8..65d8e52e2ec78b1db9e43316cbcfe7c7ca3aff33 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2012-2015  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
@@ -49,121 +49,123 @@ SET(GOOD_TESTS
   creating_meshes_ex02.py
   creating_meshes_ex04.py
   creating_meshes_ex06.py
-  creating_meshes_ex07.py 
-  creating_meshes_ex08.py 
-  defining_hypotheses_ex01.py 
-  defining_hypotheses_ex02.py 
-  defining_hypotheses_ex03.py 
-  defining_hypotheses_ex04.py 
-  defining_hypotheses_ex05.py 
-  defining_hypotheses_ex07.py 
-  defining_hypotheses_ex08.py 
-  defining_hypotheses_ex10.py 
-  defining_hypotheses_ex11.py 
-  defining_hypotheses_ex12.py 
-  defining_hypotheses_ex13.py 
-  defining_hypotheses_ex14.py 
-  defining_hypotheses_ex15.py 
-  defining_hypotheses_ex16.py 
+  creating_meshes_ex07.py
+  creating_meshes_ex08.py
+  defining_hypotheses_ex01.py
+  defining_hypotheses_ex02.py
+  defining_hypotheses_ex03.py
+  defining_hypotheses_ex04.py
+  defining_hypotheses_ex05.py
+  defining_hypotheses_ex07.py
+  defining_hypotheses_ex08.py
+  defining_hypotheses_ex10.py
+  defining_hypotheses_ex11.py
+  defining_hypotheses_ex12.py
+  defining_hypotheses_ex13.py
+  defining_hypotheses_ex14.py
+  defining_hypotheses_ex15.py
+  defining_hypotheses_ex16.py
   defining_hypotheses_adaptive1d.py
-  filters_ex01.py 
-  filters_ex03.py 
-  filters_ex04.py 
-  filters_ex05.py 
-  filters_ex06.py 
-  filters_ex07.py 
-  filters_ex09.py 
-  filters_ex10.py 
-  filters_ex11.py 
-  filters_ex12.py 
-  filters_ex13.py 
-  filters_ex14.py 
-  filters_ex15.py 
-  filters_ex16.py 
-  filters_ex17.py 
-  filters_ex18.py 
-  filters_ex19.py 
-  filters_ex20.py 
-  filters_ex21.py 
-  filters_ex22.py 
-  filters_ex26.py 
-  filters_ex27.py 
-  filters_ex28.py 
-  filters_ex29.py 
-  filters_ex30.py 
-  filters_ex31.py 
-  filters_ex33.py 
-  filters_ex34.py 
-  filters_ex36.py 
-  grouping_elements_ex01.py 
-  grouping_elements_ex02.py 
-  grouping_elements_ex03.py 
-  grouping_elements_ex04.py 
-  grouping_elements_ex05.py 
-  grouping_elements_ex06.py 
-  grouping_elements_ex07.py 
-  grouping_elements_ex08.py 
-  measurements_ex01.py 
-  measurements_ex02.py 
-  modifying_meshes_ex01.py 
-  modifying_meshes_ex02.py 
-  modifying_meshes_ex03.py 
-  modifying_meshes_ex04.py 
-  modifying_meshes_ex05.py 
-  modifying_meshes_ex06.py 
-  modifying_meshes_ex07.py 
-  modifying_meshes_ex08.py 
-  modifying_meshes_ex09.py 
-  modifying_meshes_ex10.py 
-  modifying_meshes_ex11.py 
-  modifying_meshes_ex12.py 
-  modifying_meshes_ex13.py 
-  modifying_meshes_ex14.py 
-  modifying_meshes_ex15.py 
-  modifying_meshes_ex16.py 
-  modifying_meshes_ex17.py 
-  modifying_meshes_ex18.py 
-  modifying_meshes_ex19.py 
-  modifying_meshes_ex20.py 
-  modifying_meshes_ex21.py 
-  modifying_meshes_ex22.py 
-  modifying_meshes_ex23.py 
-  modifying_meshes_ex24.py 
-  modifying_meshes_ex25.py 
-  prism_3d_algo.py 
-  quality_controls_ex01.py 
-  quality_controls_ex02.py 
-  quality_controls_ex03.py 
-  quality_controls_ex04.py 
-  quality_controls_ex05.py 
-  quality_controls_ex07.py 
-  quality_controls_ex08.py 
-  quality_controls_ex09.py 
-  quality_controls_ex10.py 
-  quality_controls_ex11.py 
-  quality_controls_ex12.py 
-  quality_controls_ex13.py 
-  quality_controls_ex14.py 
-  quality_controls_ex15.py 
-  quality_controls_ex16.py 
-  quality_controls_ex17.py 
-  quality_controls_ex18.py 
-  quality_controls_ex19.py 
-  transforming_meshes_ex01.py 
-  transforming_meshes_ex02.py 
-  transforming_meshes_ex03.py 
-  transforming_meshes_ex04.py 
-  transforming_meshes_ex05.py 
-  transforming_meshes_ex06.py 
-  transforming_meshes_ex07.py 
-  transforming_meshes_ex08.py 
-  transforming_meshes_ex09.py 
-  transforming_meshes_ex10.py 
-  transforming_meshes_ex11.py 
-  transforming_meshes_ex12.py 
-  transforming_meshes_ex13.py 
-  use_existing_faces.py 
+  filters_ex01.py
+  filters_ex03.py
+  filters_ex04.py
+  filters_ex05.py
+  filters_ex06.py
+  filters_ex07.py
+  filters_ex09.py
+  filters_ex10.py
+  filters_ex11.py
+  filters_ex12.py
+  filters_ex13.py
+  filters_ex14.py
+  filters_ex15.py
+  filters_ex16.py
+  filters_ex17.py
+  filters_ex18.py
+  filters_ex19.py
+  filters_ex20.py
+  filters_ex21.py
+  filters_ex22.py
+  filters_ex26.py
+  filters_ex27.py
+  filters_ex28.py
+  filters_ex29.py
+  filters_ex30.py
+  filters_ex31.py
+  filters_ex33.py
+  filters_ex34.py
+  filters_ex36.py
+  filters_belong2group.py
+  grouping_elements_ex01.py
+  grouping_elements_ex02.py
+  grouping_elements_ex03.py
+  grouping_elements_ex04.py
+  grouping_elements_ex05.py
+  grouping_elements_ex06.py
+  grouping_elements_ex07.py
+  grouping_elements_ex08.py
+  measurements_ex01.py
+  measurements_ex02.py
+  modifying_meshes_ex01.py
+  modifying_meshes_ex02.py
+  modifying_meshes_ex03.py
+  modifying_meshes_ex04.py
+  modifying_meshes_ex05.py
+  modifying_meshes_ex06.py
+  modifying_meshes_ex07.py
+  modifying_meshes_ex08.py
+  modifying_meshes_ex09.py
+  modifying_meshes_ex10.py
+  modifying_meshes_ex11.py
+  modifying_meshes_ex12.py
+  modifying_meshes_ex13.py
+  modifying_meshes_ex14.py
+  modifying_meshes_ex15.py
+  modifying_meshes_ex16.py
+  modifying_meshes_ex17.py
+  modifying_meshes_ex18.py
+  modifying_meshes_ex19.py
+  modifying_meshes_ex20.py
+  modifying_meshes_ex21.py
+  modifying_meshes_ex22.py
+  modifying_meshes_ex23.py
+  modifying_meshes_ex24.py
+  modifying_meshes_ex25.py
+  prism_3d_algo.py
+  quality_controls_ex01.py
+  quality_controls_ex02.py
+  quality_controls_ex03.py
+  quality_controls_ex04.py
+  quality_controls_ex05.py
+  quality_controls_ex07.py
+  quality_controls_ex08.py
+  quality_controls_ex09.py
+  quality_controls_ex10.py
+  quality_controls_ex11.py
+  quality_controls_ex12.py
+  quality_controls_ex13.py
+  quality_controls_ex14.py
+  quality_controls_ex15.py
+  quality_controls_ex16.py
+  quality_controls_ex17.py
+  quality_controls_ex18.py
+  quality_controls_ex19.py
+  transforming_meshes_ex01.py
+  transforming_meshes_ex02.py
+  transforming_meshes_ex03.py
+  transforming_meshes_ex04.py
+  transforming_meshes_ex05.py
+  transforming_meshes_ex06.py
+  transforming_meshes_ex07.py
+  transforming_meshes_ex08.py
+  transforming_meshes_ex09.py
+  transforming_meshes_ex10.py
+  transforming_meshes_ex11.py
+  transforming_meshes_ex12.py
+  transforming_meshes_ex13.py
+  use_existing_faces.py
   viewing_meshes_ex02.py
+  split_biquad.py
 )
 
 SET(EXAMPLES_TESTS ${BAD_TESTS} ${GOOD_TESTS} testme.py)
@@ -172,10 +174,19 @@ SALOME_GENERATE_TESTS_ENVIRONMENT(tests_env)
 
 FOREACH(test ${GOOD_TESTS})
   GET_FILENAME_COMPONENT(testname ${test} NAME_WE)
-  ADD_TEST(NAME ${testname} 
+  ADD_TEST(NAME ${testname}
            COMMAND ${PYTHON_EXECUTABLE} -B ${CMAKE_SOURCE_DIR}/doc/salome/examples/testme.py ${CMAKE_CURRENT_SOURCE_DIR}/${test})
   SET_TESTS_PROPERTIES(${testname} PROPERTIES ENVIRONMENT "${tests_env}")
 ENDFOREACH()
 
 # install Python scripts
 SALOME_INSTALL_SCRIPTS("${EXAMPLES_TESTS}" ${SALOME_INSTALL_DOC}/examples/SMESH)
+
+# Application tests
+
+SET(TEST_INSTALL_DIRECTORY ${SALOME_INSTALL_SCRIPT_SCRIPTS}/test)
+INSTALL(FILES ${GOOD_TESTS} DESTINATION ${TEST_INSTALL_DIRECTORY})
+
+INSTALL(FILES CTestTestfileInstall.cmake
+        DESTINATION ${TEST_INSTALL_DIRECTORY}
+        RENAME CTestTestfile.cmake)
diff --git a/doc/salome/examples/CTestTestfileInstall.cmake b/doc/salome/examples/CTestTestfileInstall.cmake
new file mode 100644 (file)
index 0000000..ef512ff
--- /dev/null
@@ -0,0 +1,150 @@
+# Copyright (C) 2015  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, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# 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(SALOME_TEST_DRIVER "$ENV{ABSOLUTE_APPLI_PATH}/bin/salome/appliskel/salome_test_driver.py")
+SET(COMPONENT_NAME SMESH)
+SET(TIMEOUT        300)
+
+SET(GOOD_TESTS
+  cartesian_algo
+  creating_meshes_ex02
+  creating_meshes_ex04
+  creating_meshes_ex06
+  creating_meshes_ex07
+  creating_meshes_ex08
+  defining_hypotheses_ex01
+  defining_hypotheses_ex02
+  defining_hypotheses_ex03
+  defining_hypotheses_ex04
+  defining_hypotheses_ex05
+  defining_hypotheses_ex07
+  defining_hypotheses_ex08
+  defining_hypotheses_ex10
+  defining_hypotheses_ex11
+  defining_hypotheses_ex12
+  defining_hypotheses_ex13
+  defining_hypotheses_ex14
+  defining_hypotheses_ex15
+  defining_hypotheses_ex16
+  defining_hypotheses_adaptive1d
+  filters_ex01
+  filters_ex03
+  filters_ex04
+  filters_ex05
+  filters_ex06
+  filters_ex07
+  filters_ex09
+  filters_ex10
+  filters_ex11
+  filters_ex12
+  filters_ex13
+  filters_ex14
+  filters_ex15
+  filters_ex16
+  filters_ex17
+  filters_ex18
+  filters_ex19
+  filters_ex20
+  filters_ex21
+  filters_ex22
+  filters_ex26
+  filters_ex27
+  filters_ex28
+  filters_ex29
+  filters_ex30
+  filters_ex31
+  filters_ex33
+  filters_ex34
+  filters_ex36
+  grouping_elements_ex01
+  grouping_elements_ex02
+  grouping_elements_ex03
+  grouping_elements_ex04
+  grouping_elements_ex05
+  grouping_elements_ex06
+  grouping_elements_ex07
+  grouping_elements_ex08
+  measurements_ex01
+  measurements_ex02
+  modifying_meshes_ex01
+  modifying_meshes_ex02
+  modifying_meshes_ex03
+  modifying_meshes_ex04
+  modifying_meshes_ex05
+  modifying_meshes_ex06
+  modifying_meshes_ex07
+  modifying_meshes_ex08
+  modifying_meshes_ex09
+  modifying_meshes_ex10
+  modifying_meshes_ex11
+  modifying_meshes_ex12
+  modifying_meshes_ex13
+  modifying_meshes_ex14
+  modifying_meshes_ex15
+  modifying_meshes_ex16
+  modifying_meshes_ex17
+  modifying_meshes_ex18
+  modifying_meshes_ex19
+  modifying_meshes_ex20
+  modifying_meshes_ex21
+  modifying_meshes_ex22
+  modifying_meshes_ex23
+  modifying_meshes_ex24
+  modifying_meshes_ex25
+  prism_3d_algo
+  quality_controls_ex01
+  quality_controls_ex02
+  quality_controls_ex03
+  quality_controls_ex04
+  quality_controls_ex05
+  quality_controls_ex07
+  quality_controls_ex08
+  quality_controls_ex09
+  quality_controls_ex10
+  quality_controls_ex11
+  quality_controls_ex12
+  quality_controls_ex13
+  quality_controls_ex14
+  quality_controls_ex15
+  quality_controls_ex16
+  quality_controls_ex17
+  quality_controls_ex18
+  quality_controls_ex19
+  transforming_meshes_ex01
+  transforming_meshes_ex02
+  transforming_meshes_ex03
+  transforming_meshes_ex04
+  transforming_meshes_ex05
+  transforming_meshes_ex06
+  transforming_meshes_ex07
+  transforming_meshes_ex08
+  transforming_meshes_ex09
+  transforming_meshes_ex10
+  transforming_meshes_ex11
+  transforming_meshes_ex12
+  transforming_meshes_ex13
+  use_existing_faces
+  viewing_meshes_ex02
+)
+
+FOREACH(tfile ${GOOD_TESTS})
+  SET(TEST_NAME SMESH_${tfile})
+  ADD_TEST(${TEST_NAME} python ${SALOME_TEST_DRIVER} ${TIMEOUT} ${tfile}.py)
+  SET_TESTS_PROPERTIES(${TEST_NAME} PROPERTIES LABELS "${COMPONENT_NAME}")
+ENDFOREACH()
index 65a4f742efcbc78d80f789f7c139e4aa9ee2f817..3b003961eeda009be9b6eb9196ac29871c25c56d 100644 (file)
@@ -1,5 +1,4 @@
 # Building a compound of meshes
-# Note: it is a copy of 'SMESH_BuildCompound.py' from SMESH_SWIG
 
 import salome
 salome.salome_init()
@@ -69,11 +68,14 @@ Gsup2=Mesh_sup.Group(Fsup2, "Sup")
 Ginf2=Mesh_sup.Group(Finf2, "Inf")
 
 ## create compounds
-# create a compound of two meshes with renaming groups with the same names and
+# create a compound of two meshes with renaming namesake groups and
 # merging of elements with the given tolerance
-Compound1 = smesh.Concatenate([Mesh_inf.GetMesh(), Mesh_sup.GetMesh()], 0, 1, 1e-05)
-smesh.SetName(Compound1, 'Compound_with_RenamedGrps_and_MergeElems')
-# create a compound of two meshes with uniting groups with the same names and
+Compound1 = smesh.Concatenate([Mesh_inf, Mesh_sup], 0, 1, 1e-05,
+                              name='Compound_with_RenamedGrps_and_MergeElems')
+# create a compound of two meshes with uniting namesake groups and
 # creating groups of all elements
-Compound2 = smesh.Concatenate([Mesh_inf.GetMesh(), Mesh_sup.GetMesh()], 1, 0, 1e-05, True)
-smesh.SetName(Compound2, 'Compound_with_UniteGrps_and_GrpsOfAllElems')
+Compound2 = smesh.Concatenate([Mesh_inf, Mesh_sup], 1, 0, 1e-05, True,
+                              name='Compound_with_UniteGrps_and_GrpsOfAllElems')
+
+if salome.sg.hasDesktop():
+    salome.sg.updateObjBrowser(1)
diff --git a/doc/salome/examples/filters_belong2group.py b/doc/salome/examples/filters_belong2group.py
new file mode 100644 (file)
index 0000000..889c0ae
--- /dev/null
@@ -0,0 +1,18 @@
+# Belong to Mesh Group criterion
+
+# create mesh
+from SMESH_mechanic import *
+
+# create a group of all faces (quadrangles) generated on sub_face3
+faces_on_face3 = mesh.MakeGroup("faces_on_face3", SMESH.FACE, SMESH.FT_BelongToGeom,'=',sub_face3)
+print "There are %s quadrangles generated on '%s' and included in the group '%s'" % ( faces_on_face3.Size(), sub_face3.GetName(), faces_on_face3.GetName() )
+
+# create a group of all the rest quadrangles, generated on other faces by combining 2 criteria:
+# - negated FT_BelongToMeshGroup to select elements not included in faces_on_face3
+# - FT_ElemGeomType to select quadrangles
+not_on_face3 = smesh.GetCriterion( SMESH.FACE, SMESH.FT_BelongToMeshGroup,'=',faces_on_face3, SMESH.FT_LogicalNOT )
+quadrangles  = smesh.GetCriterion( SMESH.FACE, SMESH.FT_ElemGeomType,'=',SMESH.Geom_QUADRANGLE )
+
+rest_quads = mesh.MakeGroupByCriteria("rest_quads", [ not_on_face3, quadrangles ])
+print "'%s' group includes all the rest %s quadrangles" % ( rest_quads.GetName(), rest_quads.Size() )
+
index 03f6c7477913aa069c759aa77bb7d1e718815952..88305c97f9523b52ad8809b37456bf7bf1d031a1 100644 (file)
@@ -9,12 +9,12 @@ ids = mesh.GetIdsFromFilter(filter)
 print "Number of faces with aspect ratio > 1.5:", len(ids)
 
 # copy the faces with aspect ratio > 1.5 to another mesh;
-# this demostrates that a filter can be used where usually a group or submesh is acceptable
+# this demostrates that a filter can be used where usually a group or sub-mesh is acceptable
 filter.SetMesh( mesh.GetMesh() )
 mesh2 = smesh.CopyMesh( filter, "AR > 1.5" )
 print "Number of copied faces with aspect ratio > 1.5:", mesh2.NbFaces()
 
-# create a Group of faces with Aspect Ratio < 1.5
+# create a group (Group on Filter) of faces with Aspect Ratio < 1.5
 group = mesh.MakeGroup("AR < 1.5", SMESH.FACE, SMESH.FT_AspectRatio, '<', 1.5)
 print "Number of faces with aspect ratio < 1.5:", group.Size()
 
@@ -22,7 +22,13 @@ print "Number of faces with aspect ratio < 1.5:", group.Size()
 # note that contents of a GroupOnFilter is dynamically updated as the mesh changes
 crit = [ smesh.GetCriterion( SMESH.FACE, SMESH.FT_AspectRatio, '<', 1.5, BinaryOp=SMESH.FT_LogicalAND ),
          smesh.GetCriterion( SMESH.FACE, SMESH.FT_ElemGeomType,'=', SMESH.Geom_TRIANGLE ) ]
-filter = smesh.GetFilterFromCriteria( crit )
-triaGroup = mesh.GroupOnFilter( SMESH.FACE, "Tria AR < 1.5", filter )
+triaGroup = mesh.MakeGroupByCriteria( "Tria AR < 1.5", crit )
 print "Number of triangles with aspect ratio < 1.5:", triaGroup.Size()
 
+# get range of values of Aspect Ratio of all faces in the mesh
+aspects = mesh.GetMinMax( SMESH.FT_AspectRatio )
+print "MESH: Min aspect = %s, Max aspect = %s" % ( aspects[0], aspects[1] )
+
+# get max value of Aspect Ratio of faces in triaGroup
+grAspects = mesh.GetMinMax( SMESH.FT_AspectRatio, triaGroup )
+print "GROUP: Max aspect = %s" % grAspects[1]
index 3dc8e4fc6443614f2e6deacf038496b63a41e97e..ec1e2b4fbfc786b08ba5cb60773da10ee956be7c 100644 (file)
@@ -1,13 +1,17 @@
-# Combine filters with Criterion structures using of "criteria".
+# Combine several criteria into a filter
 
 # 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
+# ... but 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)
+quadFilter = smesh.GetFilterFromCriteria([criterion1,criterion2])
+
+# get faces satisfying the criteria
+ids = mesh.GetIdsFromFilter(quadFilter)
+
+# create a group of faces satisfying the criteria
+myGroup = mesh.GroupOnFilter(SMESH.FACE,"Quads_on_cylindrical_faces",quadFilter)
index fa78d72f3f82c6f33bdcc5fb541716a7ded0c1e4..92dd71ce06141316870ccbbacb77320505fa3c5e 100644 (file)
@@ -1,4 +1,4 @@
-# Creating groups of entities from existing groups of superior dimensions
+# Creating groups of entities basing on nodes of other groups
 
 import SMESH_mechanic
 import SMESH
@@ -10,22 +10,17 @@ salome = SMESH_mechanic.salome
 # Criterion : AREA > 100
 aFilter = smesh.GetFilter(SMESH.FACE, SMESH.FT_Area, SMESH.FT_MoreThan, 100.)
 
-anIds = mesh.GetIdsFromFilter(aFilter)
-
-print "Criterion: Area > 100, Nb = ", len(anIds) 
-
 # create a group by adding elements with area > 100
-aSrcGroup1 = mesh.MakeGroupByIds("Area > 100", SMESH.FACE, anIds)
+aSrcGroup1 = mesh.GroupOnFilter(SMESH.FACE, "Area > 100", aFilter)
+print "Criterion: Area > 100, Nb = ", aSrcGroup1.Size()
 
 # Criterion : AREA < 30
 aFilter = smesh.GetFilter(SMESH.FACE, SMESH.FT_Area, SMESH.FT_LessThan, 30.)
 
-anIds = mesh.GetIdsFromFilter(aFilter)
-
-print "Criterion: Area < 30, Nb = ", len(anIds) 
-
 # create a group by adding elements with area < 30
-aSrcGroup2 = mesh.MakeGroupByIds("Area < 30", SMESH.FACE, anIds)
+aSrcGroup2 = mesh.GroupOnFilter(SMESH.FACE, "Area < 30", aFilter)
+print "Criterion: Area < 30, Nb = ", aSrcGroup2.Size()
+
 
 # Create group of edges using source groups of faces
 aGrp = mesh.CreateDimGroup( [aSrcGroup1, aSrcGroup2], SMESH.EDGE, "Edges" )
diff --git a/doc/salome/examples/split_biquad.py b/doc/salome/examples/split_biquad.py
new file mode 100644 (file)
index 0000000..e53e7b0
--- /dev/null
@@ -0,0 +1,37 @@
+# Split bi-quadratic to linear
+
+import salome
+salome.salome_init()
+
+from salome.geom import geomBuilder
+geompy = geomBuilder.New(salome.myStudy)
+
+from salome.smesh import smeshBuilder
+smesh = smeshBuilder.New(salome.myStudy)
+
+# make a shape consisting of two quadranges
+OY  = geompy.MakeVectorDXDYDZ(0, 1, 0)
+OY1 = geompy.MakeTranslation( OY, 1, 0, 0 )
+OY2 = geompy.MakeTranslation( OY, 2, 0, 0 )
+q1  = geompy.MakeQuad2Edges( OY, OY1 )
+q2  = geompy.MakeQuad2Edges( OY1, OY2 )
+
+shape = geompy.Partition( [q1,q2], theName='shape' )
+ff    = geompy.SubShapeAll( shape, geompy.ShapeType["FACE"], theName="quad" )
+
+# mesh one quadrange with quadrangless and the other with triangles
+mesh = smesh.Mesh( shape )
+mesh.Segment().NumberOfSegments(1)
+mesh.Quadrangle()
+mesh.Triangle( ff[1] )
+mesh.Compute()
+
+# make group of quadrangles and extrude them into a hexahedron
+quadGroup = mesh.Group( ff[0], "quads")
+mesh.ExtrusionSweepObject2D( quadGroup, [0,0,1], 1 )
+
+# make the mesh bi-quadratic
+mesh.ConvertToQuadratic( theToBiQuad=True )
+
+# split all elements into linear ones
+mesh.SplitBiQuadraticIntoLinear()
index 7fca21f061903ba35b94aadaaa9e42bcc12e9c80..cd74c44959f351fd6963101670401544f9c44c0c 100755 (executable)
@@ -1,4 +1,4 @@
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  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
@@ -24,11 +24,21 @@ import unittest, sys, os
 class SalomeSession(object):
     def __init__(self, script):
         import runSalome
-        sys.argv  = ["runSalome.py"]
+        run_script = "runSalome.py"
+        if sys.platform == 'win32':
+            module_dir = os.getenv("KERNEL_ROOT_DIR")
+            if module_dir: run_script = os.path.join(module_dir, "bin", "salome", run_script)
+            pass
+        sys.argv  = [run_script]
         sys.argv += ["--terminal"]
         sys.argv += ["--modules=GEOM,MED,SMESH"]
         sys.argv += ["%s" % script]
+        if sys.platform == 'win32':
+            main_module_path = sys.modules['__main__'].__file__
+            sys.modules['__main__'].__file__ = ''
         clt, d = runSalome.main()
+        if sys.platform == 'win32':
+            sys.modules['__main__'].__file__ = main_module_path
         return
 
     def __del__(self):
index dc61324eccecfb125f7e104030a14a51048ad257..93f5196c0b0e59530d82bc560be1cb3b95bffcaa 100644 (file)
@@ -1,16 +1,11 @@
 # Translation
 
 import SMESH_mechanic
-import SMESH
 
-smesh = SMESH_mechanic.smesh 
 mesh = SMESH_mechanic.mesh 
 
 # define translation vector
-point = SMESH.PointStruct(-150., -150., 0.)
-vector =SMESH.DirStruct(point)
+vector = [-150., -150., 0.]
 
-# translate a mesh
-doCopy = 1
-
-mesh.Translate([], vector, doCopy)
+# make a translated copy of all elements of the mesh
+mesh.TranslateObject(mesh, vector, Copy=True)
index f99d50b6a97cc551004bbdd475db9c7996c46eb2..deba1c407c5e6c6827c5ed38635f8076a66113ee 100644 (file)
@@ -1,10 +1,14 @@
 # Merging Nodes
 
-import SMESH_mechanic
+import SMESH_mechanic, SMESH
 mesh = SMESH_mechanic.mesh
 
 # merge nodes
-Tolerance = 25.0
+Tolerance = 4.0
+
+# prevent nodes located on geom edges from removal during merge:
+# create a group including all nodes on edges
+allSegs = mesh.MakeGroup( "all segments", SMESH.EDGE, SMESH.FT_ElemGeomType,'=', SMESH.Geom_EDGE )
 
 GroupsOfNodes =  mesh.FindCoincidentNodes(Tolerance)
-mesh.MergeNodes(GroupsOfNodes)  
+mesh.MergeNodes(GroupsOfNodes, NodesToKeep=allSegs)
index 62fea88d108e92317decf710324bbabe073968a9..9264a5c4c508aa81410e9db22f167098ddb7a7b4 100644 (file)
@@ -11,35 +11,40 @@ import SMESH, SALOMEDS
 from salome.smesh import smeshBuilder
 smesh =  smeshBuilder.New(salome.myStudy)
 
-# create two faces of the box
-box1 = geompy.MakeBox(0., 0., 0., 20., 20., 15.)
-facesList1 = geompy.SubShapeAll(box1, geompy.ShapeType["FACE"])
-face1 = facesList1[2]
-
-box2 = geompy.MakeBox(0., 5., 0., 20., 20., 15.)
-facesList2 = geompy.SubShapeAll(box2, geompy.ShapeType["FACE"])
-face2 = facesList2[1]
-
-edgesList = geompy.SubShapeAll(face2, geompy.ShapeType["EDGE"])
-edge1 = edgesList[2]
-
-aComp = geompy.MakeCompound([face1, face2])
-geompy.addToStudy(aComp, "Two faces")
+# make two not sewed quadranges
+OY0 = geompy.MakeVectorDXDYDZ(0, 1, 0)
+OY1 = geompy.MakeTranslation( OY0, 1, 0, 0, theName="OY1" )
+OY2 = geompy.MakeTranslation( OY0, 1.01, 0, 0, theName="OY2" )
+OY3 = geompy.MakeTranslation( OY0, 2, 0, 0 )
+q1  = geompy.MakeQuad2Edges( OY0, OY1 )
+q2  = geompy.MakeQuad2Edges( OY2, OY3 )
+
+shape = geompy.MakeCompound( [q1,q2], theName='shape' )
+
+# make a non-uniform quadrangle mesh on two faces
+mesh = smesh.Mesh(shape, "Two faces : quadrangle mesh")
+mesh.Segment().Arithmetic1D( 0.1, 0.4 )
+mesh.Segment(q1).NumberOfSegments( 5 )
+mesh.Quadrangle()
+mesh.Compute()
 
-# create a mesh on two faces
-mesh = smesh.Mesh(aComp, "Two faces : quadrangle mesh")
+# sew free borders
 
-algo1D = mesh.Segment()
-algo1D.NumberOfSegments(4)
-algo2D = mesh.Quadrangle()
+segs1 = mesh.GetSubMeshElementsId( OY1 ) # mesh segments generated on borders
+segs2 = mesh.GetSubMeshElementsId( OY2 )
 
-algo_local = mesh.Segment(edge1)
-algo_local.Arithmetic1D(1, 4)
-algo_local.Propagation()
+FirstNodeID1  = mesh.GetElemNode( segs1[0], 0 )
+SecondNodeID1 = mesh.GetElemNode( segs1[0], 1 )
+LastNodeID1   = mesh.GetElemNode( segs1[-1], 1 )
+FirstNodeID2  = mesh.GetElemNode( segs2[0], 0 )
+SecondNodeID2 = mesh.GetElemNode( segs2[0], 1 )
+LastNodeID2   = mesh.GetElemNode( segs2[-1], 1 )
+CreatePolygons = True
+CreatePolyedrs = False
 
-mesh.Compute()
+res = mesh.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
+                          FirstNodeID2, SecondNodeID2, LastNodeID2,
+                          CreatePolygons, CreatePolyedrs )
+print res
+print "nb polygons:", mesh.NbPolygons()
 
-# sew free borders
-# FirstNodeID1, SecondNodeID1, LastNodeID1,
-# FirstNodeID2, SecondNodeID2, LastNodeID2, CreatePolygons, CreatePolyedrs
-mesh.SewFreeBorders(6, 21, 5, 1, 12, 3, 0, 0)
index 426a011a6b94616b51b1a67eadbb2ed5bdb45ddc..e0120b4810f5dc87b5a03dfc88aac0dc32bf8cfa 100644 (file)
@@ -20,7 +20,7 @@ aComp = geompy.MakeCompound([box1, box2])
 geompy.addToStudy(aComp, "Two boxes")
 
 # create a mesh on two boxes
-mesh = smesh.Mesh(aComp, "Two faces : quadrangle mesh")
+mesh = smesh.Mesh(aComp, "Sew Side Elements")
 
 algo1D = mesh.Segment()
 algo1D.NumberOfSegments(2)
@@ -33,6 +33,31 @@ algo_local.Propagation()
 mesh.Compute()
 
 # sew side elements
-# IDsOfSide1Elements, IDsOfSide2Elements,
-# NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge, NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge
-mesh.SewSideElements([69, 70, 71, 72], [91, 92, 89, 90], 8, 38, 23, 58)
+
+# find elements to sew
+face1 = geompy.GetFaceNearPoint( aComp, geompy.MakeVertex( 5, 10, 5 ))
+IDsOfSide1Elements = mesh.GetSubMeshElementsId( face1 )
+print "side faces 1:",IDsOfSide1Elements
+
+face1Translated = geompy.MakeTranslation( face1, 0,5,0 )
+faceFilter = smesh.GetFilter( SMESH.FACE, SMESH.FT_BelongToGeom,'=', face1Translated )
+IDsOfSide2Elements = mesh.GetIdsFromFilter( faceFilter )
+print "side faces 2:",IDsOfSide2Elements
+
+# find corresponding nodes on sides
+edge1 = geompy.GetEdgeNearPoint( aComp, geompy.MakeVertex( 0, 10, 5 ))
+segs1 = mesh.GetSubMeshElementsId( edge1 ) # mesh segments generated on edge1
+NodeID1OfSide1ToMerge = mesh.GetElemNode( segs1[0], 0 )
+NodeID2OfSide1ToMerge = mesh.GetElemNode( segs1[0], 1 )
+print "nodes of side1:", [NodeID1OfSide1ToMerge,NodeID2OfSide1ToMerge]
+
+edge2 = geompy.GetEdgeNearPoint( aComp, geompy.MakeVertex( 0, 15, 5 ))
+segs2 = mesh.GetSubMeshElementsId( edge2 ) # mesh segments generated on edge2
+NodeID1OfSide2ToMerge = mesh.GetElemNode( segs2[0], 0 )
+NodeID2OfSide2ToMerge = mesh.GetElemNode( segs2[0], 1 )
+print "nodes of side2:", [NodeID1OfSide2ToMerge,NodeID2OfSide2ToMerge]
+
+res = mesh.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
+                           NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
+                           NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
+print res
index 3347fdcc5f9c9ac182b3ace1a37c7fe63e6c77a0..1a8d6cf4d4c2a2941ddf7b91b71dc4d573e3cac5 100755 (executable)
@@ -1,4 +1,4 @@
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 380fb6bbd595d33fc494a16b6ab9d9e09c0faa81..47c517cfffb1fefb5790fe7b433a3000cda6a425 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2012-2015  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
index 6e2b7a4813de48ed600369c7a3efd6b71b5008a3..0d55a3c74c2b0865d4f992197c1cd98e43b39b96 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2012-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2012-2015  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
index e3b5ae87f5113938167e7874c120f961de884331..03d6398e0c08019319993b275320e09e5e631ac5 100755 (executable)
@@ -1,4 +1,4 @@
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -41,7 +41,7 @@ WARNINGS          = YES
 INPUT             = @CMAKE_CURRENT_SOURCE_DIR@/input @CMAKE_SOURCE_DIR@/src/Tools/padder/doc/input $(GEOM_ROOT_DIR)/share/doc/salome/gui/GEOM/input
 FILE_PATTERNS     = *.doc
 EXCLUDE           = 
-IMAGE_PATH        = @CMAKE_CURRENT_SOURCE_DIR@/images @CMAKE_SOURCE_DIR@/src/Tools/padder/doc/images $(GEOM_ROOT_DIR)/share/doc/salome/gui/GEOM
+IMAGE_PATH        = $(GEOM_ROOT_DIR)/share/doc/salome/gui/GEOM @CMAKE_SOURCE_DIR@/src/Tools/padder/doc/images @CMAKE_CURRENT_SOURCE_DIR@/images
 EXAMPLE_PATH      = @CMAKE_SOURCE_DIR@/doc/salome/examples @CMAKE_SOURCE_DIR@/src/SMESH_SWIG
 
 #---------------------------------------------------------------------------
index da7bdc731fbffc015fe20e69194cdad570172b9b..6cb04289bc74aff4eb38cf598d735a562ba9c309 100755 (executable)
@@ -1,4 +1,4 @@
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
diff --git a/doc/salome/gui/SMESH/images/2d_from_3d_example.png b/doc/salome/gui/SMESH/images/2d_from_3d_example.png
new file mode 100644 (file)
index 0000000..d01efd5
Binary files /dev/null and b/doc/salome/gui/SMESH/images/2d_from_3d_example.png differ
old mode 100755 (executable)
new mode 100644 (file)
index aa43beb..9bc67b0
Binary files a/doc/salome/gui/SMESH/images/a-arithmetic1d.png and b/doc/salome/gui/SMESH/images/a-arithmetic1d.png differ
old mode 100755 (executable)
new mode 100644 (file)
index 734e6c8..553fb98
Binary files a/doc/salome/gui/SMESH/images/a-creategroup.png and b/doc/salome/gui/SMESH/images/a-creategroup.png differ
index a60be94a4a8ff4f2220b53154b6285878001469b..cb5b9ccfa63497ec03d0da19b1329cee1ac1f54a 100644 (file)
Binary files a/doc/salome/gui/SMESH/images/a-geometric1d.png and b/doc/salome/gui/SMESH/images/a-geometric1d.png differ
old mode 100755 (executable)
new mode 100644 (file)
index 2a7c9fc..d9f9c56
Binary files a/doc/salome/gui/SMESH/images/a-nbsegments2.png and b/doc/salome/gui/SMESH/images/a-nbsegments2.png differ
old mode 100755 (executable)
new mode 100644 (file)
index ba29d91..33293d3
Binary files a/doc/salome/gui/SMESH/images/a-startendlength.png and b/doc/salome/gui/SMESH/images/a-startendlength.png differ
old mode 100755 (executable)
new mode 100644 (file)
index e160cf5..b0e366b
Binary files a/doc/salome/gui/SMESH/images/b-flection1d.png and b/doc/salome/gui/SMESH/images/b-flection1d.png differ
old mode 100755 (executable)
new mode 100644 (file)
index a618351..d3534fe
Binary files a/doc/salome/gui/SMESH/images/buildcompound.png and b/doc/salome/gui/SMESH/images/buildcompound.png differ
diff --git a/doc/salome/gui/SMESH/images/buildcompound_groups.png b/doc/salome/gui/SMESH/images/buildcompound_groups.png
new file mode 100644 (file)
index 0000000..ee12892
Binary files /dev/null and b/doc/salome/gui/SMESH/images/buildcompound_groups.png differ
index f20d4a724a4309b6fd280df05509d2da36e25df2..7da08fca577c84b62182a9282ba28bea92c74bb5 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 6ca49a6a9157d1e18176b2408877be28708ed9a8..bbfa059d8779b64d44e6557adb47028c5207e46d 100644 (file)
Binary files a/doc/salome/gui/SMESH/images/dimgroup_2d.png and b/doc/salome/gui/SMESH/images/dimgroup_2d.png differ
index 21cdb058ab12971300c8aec97ce6589f09840ceb..22bdbc60fcdfb475f4d4f797c9bee78505d1acf5 100644 (file)
Binary files a/doc/salome/gui/SMESH/images/dimgroup_dlg.png and b/doc/salome/gui/SMESH/images/dimgroup_dlg.png differ
index 170428dc2808afd7d89c417d7cfaf6c71ed13c0b..53c618ce077cc605e7aaf2e7683b4eb22995b413 100644 (file)
Binary files a/doc/salome/gui/SMESH/images/distributionwithanalyticdensity.png and b/doc/salome/gui/SMESH/images/distributionwithanalyticdensity.png differ
index 5fa982c4c453c93dc74fffc12780f25d35fa3de1..75bd6981d6e09e336c0d2cd1332da556eae2b499 100644 (file)
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/extru_rib_segs.png b/doc/salome/gui/SMESH/images/extru_rib_segs.png
new file mode 100644 (file)
index 0000000..24f04cf
Binary files /dev/null and b/doc/salome/gui/SMESH/images/extru_rib_segs.png differ
index 540bce24a2cb7a31e0f5e1491eca0a46f3009fcc..bdc1eff88c7f175904f644fd8bcd23f1d2dba8ea 100644 (file)
Binary files a/doc/salome/gui/SMESH/images/extrusion_along_path_dlg.png and b/doc/salome/gui/SMESH/images/extrusion_along_path_dlg.png differ
diff --git a/doc/salome/gui/SMESH/images/extrusion_box.png b/doc/salome/gui/SMESH/images/extrusion_box.png
new file mode 100644 (file)
index 0000000..fb08486
Binary files /dev/null and b/doc/salome/gui/SMESH/images/extrusion_box.png differ
diff --git a/doc/salome/gui/SMESH/images/extrusion_groups.png b/doc/salome/gui/SMESH/images/extrusion_groups.png
new file mode 100644 (file)
index 0000000..c58e397
Binary files /dev/null and b/doc/salome/gui/SMESH/images/extrusion_groups.png differ
diff --git a/doc/salome/gui/SMESH/images/extrusion_groups_res.png b/doc/salome/gui/SMESH/images/extrusion_groups_res.png
new file mode 100644 (file)
index 0000000..7063c82
Binary files /dev/null and b/doc/salome/gui/SMESH/images/extrusion_groups_res.png differ
index 0cc13d518ed9e653b7267f4434d7ea11ba41d1c7..5f0d13039f1082c3c0e498abefb40c61dcbfe7b7 100644 (file)
Binary files a/doc/salome/gui/SMESH/images/extrusionalongaline1.png and b/doc/salome/gui/SMESH/images/extrusionalongaline1.png differ
index 987a66c610799fa8bb688d5f2e7ab8c134c97460..f0e6d9e939cbad17fee99225115d22d1fe457d66 100644 (file)
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/extrusionalongaline3.png b/doc/salome/gui/SMESH/images/extrusionalongaline3.png
new file mode 100644 (file)
index 0000000..75c359b
Binary files /dev/null and b/doc/salome/gui/SMESH/images/extrusionalongaline3.png differ
diff --git a/doc/salome/gui/SMESH/images/extrusionbynormal_alongavgnorm.png b/doc/salome/gui/SMESH/images/extrusionbynormal_alongavgnorm.png
new file mode 100644 (file)
index 0000000..ecb550e
Binary files /dev/null and b/doc/salome/gui/SMESH/images/extrusionbynormal_alongavgnorm.png differ
diff --git a/doc/salome/gui/SMESH/images/extrusionbynormal_useonly.png b/doc/salome/gui/SMESH/images/extrusionbynormal_useonly.png
new file mode 100644 (file)
index 0000000..1c63a2b
Binary files /dev/null and b/doc/salome/gui/SMESH/images/extrusionbynormal_useonly.png differ
old mode 100755 (executable)
new mode 100644 (file)
index 6e73c93..871beba
Binary files a/doc/salome/gui/SMESH/images/free_borders1.png and b/doc/salome/gui/SMESH/images/free_borders1.png differ
diff --git a/doc/salome/gui/SMESH/images/groups_in_OB.png b/doc/salome/gui/SMESH/images/groups_in_OB.png
new file mode 100644 (file)
index 0000000..1ffb96a
Binary files /dev/null and b/doc/salome/gui/SMESH/images/groups_in_OB.png differ
diff --git a/doc/salome/gui/SMESH/images/hexa_ijk_mesh.png b/doc/salome/gui/SMESH/images/hexa_ijk_mesh.png
new file mode 100644 (file)
index 0000000..577ee8e
Binary files /dev/null and b/doc/salome/gui/SMESH/images/hexa_ijk_mesh.png differ
old mode 100755 (executable)
new mode 100644 (file)
index 74276bd..d1c131a
Binary files a/doc/salome/gui/SMESH/images/hypo_fixedpnt_dlg.png and b/doc/salome/gui/SMESH/images/hypo_fixedpnt_dlg.png differ
old mode 100755 (executable)
new mode 100644 (file)
index 604a150..d30ae67
Binary files a/doc/salome/gui/SMESH/images/image152.png and b/doc/salome/gui/SMESH/images/image152.png differ
old mode 100755 (executable)
new mode 100644 (file)
index 6baffdb..5aff389
Binary files a/doc/salome/gui/SMESH/images/image160.gif and b/doc/salome/gui/SMESH/images/image160.gif differ
index 5fba91a2f95e56c2fc3e829cb51bb51e96b4f9ed..6f19970738464bbeb9e69f178efa3055b7cd1cc3 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/image56.jpg and b/doc/salome/gui/SMESH/images/image56.jpg differ
diff --git a/doc/salome/gui/SMESH/images/image58.gif b/doc/salome/gui/SMESH/images/image58.gif
deleted file mode 100755 (executable)
index 45e2856..0000000
Binary files a/doc/salome/gui/SMESH/images/image58.gif and /dev/null differ
diff --git a/doc/salome/gui/SMESH/images/image58.png b/doc/salome/gui/SMESH/images/image58.png
new file mode 100644 (file)
index 0000000..a496170
Binary files /dev/null and b/doc/salome/gui/SMESH/images/image58.png differ
diff --git a/doc/salome/gui/SMESH/images/image59.png b/doc/salome/gui/SMESH/images/image59.png
new file mode 100644 (file)
index 0000000..5b8106e
Binary files /dev/null and b/doc/salome/gui/SMESH/images/image59.png differ
diff --git a/doc/salome/gui/SMESH/images/image75.jpg b/doc/salome/gui/SMESH/images/image75.jpg
new file mode 100644 (file)
index 0000000..54718d4
Binary files /dev/null and b/doc/salome/gui/SMESH/images/image75.jpg differ
old mode 100755 (executable)
new mode 100644 (file)
index 88ec89f..cdeb880
Binary files a/doc/salome/gui/SMESH/images/image76.jpg and b/doc/salome/gui/SMESH/images/image76.jpg differ
old mode 100755 (executable)
new mode 100644 (file)
index c253eac..9205644
Binary files a/doc/salome/gui/SMESH/images/image77.jpg and b/doc/salome/gui/SMESH/images/image77.jpg differ
old mode 100755 (executable)
new mode 100644 (file)
index 3b2a973..9499ab2
Binary files a/doc/salome/gui/SMESH/images/image88.jpg and b/doc/salome/gui/SMESH/images/image88.jpg differ
old mode 100755 (executable)
new mode 100644 (file)
index 4f4c301..a78c439
Binary files a/doc/salome/gui/SMESH/images/image90.jpg and b/doc/salome/gui/SMESH/images/image90.jpg differ
old mode 100755 (executable)
new mode 100644 (file)
index 3f59269..40d614f
Binary files a/doc/salome/gui/SMESH/images/mergeelems.png and b/doc/salome/gui/SMESH/images/mergeelems.png differ
index 904d234637a0af9ad75aa018c4b1f5055e53f20b..6e2b306971de80f9708dec533dfe4063909490cc 100644 (file)
Binary files a/doc/salome/gui/SMESH/images/mergeelems_auto.png and b/doc/salome/gui/SMESH/images/mergeelems_auto.png differ
old mode 100755 (executable)
new mode 100644 (file)
index 05286a5..5b34361
Binary files a/doc/salome/gui/SMESH/images/mergenodes.png and b/doc/salome/gui/SMESH/images/mergenodes.png differ
index 6a2a92830dcc0c4d8c7c20242e388087fb2cea98..4f177f605fbce3dcea99859915a1fc8e84681e8b 100644 (file)
Binary files a/doc/salome/gui/SMESH/images/mergenodes_auto.png and b/doc/salome/gui/SMESH/images/mergenodes_auto.png differ
old mode 100755 (executable)
new mode 100644 (file)
index f64bdcb..05c8175
Binary files a/doc/salome/gui/SMESH/images/merging_nodes1.png and b/doc/salome/gui/SMESH/images/merging_nodes1.png differ
old mode 100755 (executable)
new mode 100644 (file)
index 8d7cfdd..862ed17
Binary files a/doc/salome/gui/SMESH/images/merging_nodes2.png and b/doc/salome/gui/SMESH/images/merging_nodes2.png differ
index ddacc63325118a9226d76648666d6cc7e7c14085..7fb82e4d06fa7792fdbd49126c7f0a1720948944 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/pref21.png and b/doc/salome/gui/SMESH/images/pref21.png differ
index d557d2515bb949022c9ba8a152c94ee3b262ccd7..cf086214eaa26e0181e1364c357997635cf9fda6 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/pref22.png and b/doc/salome/gui/SMESH/images/pref22.png differ
index c715ee4825e971be3eb7f6720d7f47fa7388de47..23d804b8dcdd3c1c081527bd62a250d4eaac183c 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/pref23.png and b/doc/salome/gui/SMESH/images/pref23.png differ
index 167cc0bf065bc6b101f2c7e0f585e15a0fe4e75d..9a7a5a8f02df6c7949eb8047029849d0ee6d5cbb 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/pref24.png and b/doc/salome/gui/SMESH/images/pref24.png differ
index be1a1251562de42593c67ae14cf5dadf0b956e35..6f9fb31b351633fc697d0277def3506cdcc02577 100644 (file)
Binary files a/doc/salome/gui/SMESH/images/preview_tmp_data.png and b/doc/salome/gui/SMESH/images/preview_tmp_data.png differ
diff --git a/doc/salome/gui/SMESH/images/propagation_chain.png b/doc/salome/gui/SMESH/images/propagation_chain.png
new file mode 100644 (file)
index 0000000..420dee0
Binary files /dev/null and b/doc/salome/gui/SMESH/images/propagation_chain.png differ
diff --git a/doc/salome/gui/SMESH/images/quad_from_ma_medial_axis.png b/doc/salome/gui/SMESH/images/quad_from_ma_medial_axis.png
new file mode 100644 (file)
index 0000000..b02ceab
Binary files /dev/null and b/doc/salome/gui/SMESH/images/quad_from_ma_medial_axis.png differ
diff --git a/doc/salome/gui/SMESH/images/quad_from_ma_mesh.png b/doc/salome/gui/SMESH/images/quad_from_ma_mesh.png
new file mode 100644 (file)
index 0000000..3e3c63b
Binary files /dev/null and b/doc/salome/gui/SMESH/images/quad_from_ma_mesh.png differ
diff --git a/doc/salome/gui/SMESH/images/quad_mesh_invalid.png b/doc/salome/gui/SMESH/images/quad_mesh_invalid.png
new file mode 100644 (file)
index 0000000..cce9980
Binary files /dev/null and b/doc/salome/gui/SMESH/images/quad_mesh_invalid.png differ
diff --git a/doc/salome/gui/SMESH/images/quad_meshes.png b/doc/salome/gui/SMESH/images/quad_meshes.png
new file mode 100644 (file)
index 0000000..c6cbd0c
Binary files /dev/null and b/doc/salome/gui/SMESH/images/quad_meshes.png differ
diff --git a/doc/salome/gui/SMESH/images/rev_edges_helper_dlg.png b/doc/salome/gui/SMESH/images/rev_edges_helper_dlg.png
new file mode 100644 (file)
index 0000000..e8790a1
Binary files /dev/null and b/doc/salome/gui/SMESH/images/rev_edges_helper_dlg.png differ
old mode 100755 (executable)
new mode 100644 (file)
index c4a4c17..5f75d5d
Binary files a/doc/salome/gui/SMESH/images/revolution1.png and b/doc/salome/gui/SMESH/images/revolution1.png differ
index 6564c7fc615da0cfda3999f4393d0d55278945d2..3e7a7a1aafe3dcade08a79f52a031ea29cbf8caf 100644 (file)
Binary files a/doc/salome/gui/SMESH/images/revolutionsn1.png and b/doc/salome/gui/SMESH/images/revolutionsn1.png differ
index 67a673144f6f9e4471b54d0afc1dc10cac90c115..064dd6c2da4561b772a4327c58ebbcd032d669ed 100644 (file)
Binary files a/doc/salome/gui/SMESH/images/revolutionsn2.png and b/doc/salome/gui/SMESH/images/revolutionsn2.png differ
diff --git a/doc/salome/gui/SMESH/images/sew_after_merge.png b/doc/salome/gui/SMESH/images/sew_after_merge.png
new file mode 100644 (file)
index 0000000..43d6869
Binary files /dev/null and b/doc/salome/gui/SMESH/images/sew_after_merge.png differ
diff --git a/doc/salome/gui/SMESH/images/sew_using_merge.png b/doc/salome/gui/SMESH/images/sew_using_merge.png
new file mode 100644 (file)
index 0000000..80cc44c
Binary files /dev/null and b/doc/salome/gui/SMESH/images/sew_using_merge.png differ
old mode 100755 (executable)
new mode 100644 (file)
index daef959..55e0d83
Binary files a/doc/salome/gui/SMESH/images/sewing1.png and b/doc/salome/gui/SMESH/images/sewing1.png differ
old mode 100755 (executable)
new mode 100644 (file)
index b7563f9..2ba3e43
Binary files a/doc/salome/gui/SMESH/images/sewing2.png and b/doc/salome/gui/SMESH/images/sewing2.png differ
old mode 100755 (executable)
new mode 100644 (file)
index da2972f..d2d97d5
Binary files a/doc/salome/gui/SMESH/images/sewing3.png and b/doc/salome/gui/SMESH/images/sewing3.png differ
old mode 100755 (executable)
new mode 100644 (file)
index 748237c..ad66682
Binary files a/doc/salome/gui/SMESH/images/sewing4.png and b/doc/salome/gui/SMESH/images/sewing4.png differ
diff --git a/doc/salome/gui/SMESH/images/sewing_auto.png b/doc/salome/gui/SMESH/images/sewing_auto.png
new file mode 100644 (file)
index 0000000..f81cfe2
Binary files /dev/null and b/doc/salome/gui/SMESH/images/sewing_auto.png differ
diff --git a/doc/salome/gui/SMESH/images/sewing_manual.png b/doc/salome/gui/SMESH/images/sewing_manual.png
new file mode 100644 (file)
index 0000000..ff125bc
Binary files /dev/null and b/doc/salome/gui/SMESH/images/sewing_manual.png differ
diff --git a/doc/salome/gui/SMESH/images/smesh_sort_groups.png b/doc/salome/gui/SMESH/images/smesh_sort_groups.png
new file mode 100644 (file)
index 0000000..0176a30
Binary files /dev/null and b/doc/salome/gui/SMESH/images/smesh_sort_groups.png differ
diff --git a/doc/salome/gui/SMESH/images/split_biquad_to_linear_dlg.png b/doc/salome/gui/SMESH/images/split_biquad_to_linear_dlg.png
new file mode 100644 (file)
index 0000000..c3df009
Binary files /dev/null and b/doc/salome/gui/SMESH/images/split_biquad_to_linear_dlg.png differ
diff --git a/doc/salome/gui/SMESH/images/split_biquad_to_linear_icon.png b/doc/salome/gui/SMESH/images/split_biquad_to_linear_icon.png
new file mode 100644 (file)
index 0000000..0b9b7a0
Binary files /dev/null and b/doc/salome/gui/SMESH/images/split_biquad_to_linear_icon.png differ
diff --git a/doc/salome/gui/SMESH/images/split_biquad_to_linear_mesh.png b/doc/salome/gui/SMESH/images/split_biquad_to_linear_mesh.png
new file mode 100644 (file)
index 0000000..4a25e8f
Binary files /dev/null and b/doc/salome/gui/SMESH/images/split_biquad_to_linear_mesh.png differ
diff --git a/doc/salome/gui/SMESH/images/swap.png b/doc/salome/gui/SMESH/images/swap.png
new file mode 100644 (file)
index 0000000..6470710
Binary files /dev/null and b/doc/salome/gui/SMESH/images/swap.png differ
diff --git a/doc/salome/gui/SMESH/images/viscous_layers_2d_hyp.png b/doc/salome/gui/SMESH/images/viscous_layers_2d_hyp.png
new file mode 100644 (file)
index 0000000..4ad6ee0
Binary files /dev/null and b/doc/salome/gui/SMESH/images/viscous_layers_2d_hyp.png differ
diff --git a/doc/salome/gui/SMESH/images/viscous_layers_extrusion_method.png b/doc/salome/gui/SMESH/images/viscous_layers_extrusion_method.png
new file mode 100644 (file)
index 0000000..cf6fe21
Binary files /dev/null and b/doc/salome/gui/SMESH/images/viscous_layers_extrusion_method.png differ
index 717819138f562b963c2216308af12346e1f883cd..aaf9ad6588b7d531709855adedb204795e043562 100644 (file)
Binary files a/doc/salome/gui/SMESH/images/viscous_layers_hyp.png and b/doc/salome/gui/SMESH/images/viscous_layers_hyp.png differ
index 8c38c8ddfa1e645374989affaa7a24a80e9e1e85..01deffbcd3dd5030cb77f5859b5571bc3367a912 100644 (file)
@@ -2,18 +2,39 @@
 
 \page a1d_meshing_hypo_page 1D Meshing Hypotheses
 
-<br>
+Basic 1D hypothesis specifies:
 <ul>
-<li>\ref adaptive_1d_anchor "Adaptive"</li>
-<li>\ref arithmetic_1d_anchor "Arithmetic 1D"</li>
-<li>\ref geometric_1d_anchor "Geometric Progression"</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>
+<li>how \ref a1d_algos_anchor "Wire Discretization" should divide the edge;</li>
+<li>how \ref a1d_algos_anchor "Composite Side Discretization" should divide the group of C1-continuous edges.</li>
+</ul>
+
+1D hypotheses can be categorized by type of nodes distribution as follows:
+<ul>
+<li>Uniform distribution:
+  <ul>
+    <li>\ref average_length_anchor "Local Length"</li>
+    <li>\ref max_length_anchor "Max Size"</li>
+    <li>\ref number_of_segments_anchor "Number of segments" with Equidistant distribution</li>
+    <li>\ref automatic_length_anchor "Automatic Length"</li>
+</ul></li>
+<li>Constantly increasing or decreasing length of segments:
+  <ul>
+    <li>\ref arithmetic_1d_anchor "Arithmetic 1D"</li>
+    <li>\ref geometric_1d_anchor "Geometric Progression"</li>
+    <li>\ref start_and_end_length_anchor "Start and end length"</li>
+    <li>\ref number_of_segments_anchor "Number of segments" with Scale distribution</li>
+</ul></li>
+<li>Distribution depending on curvature:
+  <ul>
+    <li>\ref adaptive_1d_anchor "Adaptive"</li>
+    <li>\ref deflection_1d_anchor "Deflection 1D"</li>
+</ul></li>
+<li>Arbitrary distribution:
+  <ul>
+    <li>\ref fixed_points_1d_anchor "Fixed points 1D"</li>
+    <li>\ref number_of_segments_anchor "Number of segments" with
+    \ref analyticdensity_anchor "Analytic Density Distribution" or Table Density Distribution</li>
+</ul></li>
 </ul>
 
 <br>
@@ -55,6 +76,10 @@ be reversed either directly picking them in the 3D viewer or by
 selecting the edges or groups of edges in the Object Browser. Use \b
 Add button to add the selected edges to the list.
 
+\ref reversed_edges_helper_anchor "Helper" group assists you in
+defining <b>Reversed Edges</b> parameter.
+
+
 \image html a-arithmetic1d.png
 
 \image html b-ithmetic1d.png "Arithmetic 1D hypothesis - the size of mesh elements gradually increases"
@@ -81,6 +106,9 @@ be reversed either directly picking them in the 3D viewer or by
 selecting the edges or groups of edges in the Object Browser. Use \b
 Add button to add the selected edges to the list.
 
+\ref reversed_edges_helper_anchor "Helper" group assists you in
+defining <b>Reversed Edges</b> parameter.
+
 \image html a-geometric1d.png
 
 <b>See Also</b> a sample TUI Script of a 
@@ -91,13 +119,14 @@ Add button to add the selected edges to the list.
 <h2>Deflection 1D hypothesis</h2>
 
 <b>Deflection 1D</b> hypothesis can be applied for meshing curvilinear edges
-composing your geometrical object. It uses only one parameter: the
-value of deflection.  
-\n A geometrical edge is divided into equal segments. The maximum
-distance between a point on the edge within a segment and the line
-connecting the ends of the segment should not exceed the specified
-value of deflection . Then mesh nodes are constructed at end segment
-locations and 1D mesh elements are constructed on segments.
+composing your geometrical object. It defines only one parameter: the
+value of deflection (or chord error).
+
+A geometrical edge is divided into segments of length depending on
+edge curvature. The more curved the edge, the shorter the
+segment. Nodes on the edge are placed so that the maximum distance
+between the edge and a segment approximating a part of edge between
+two nodes should not exceed the value of deflection.
 
 \image html a-deflection1d.png
 
@@ -112,25 +141,26 @@ locations and 1D mesh elements are constructed on segments.
 
 <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
-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 \b precision parameter is used to allow rounding a number of
-segments, calculated from the edge length and average length of
-segment, to the lower integer, if this value outstands from it in
-bounds of the precision. Otherwise, the number of segments is rounded
-to the higher integer. Use value 0.5 to provide rounding to the
-nearest integer, 1.0 for the lower integer, 0.0 for the higher
-integer. Default value is 1e-07.
+consists of setting the \b length of segments, which will approximate these
+edges, and the \b precision of rounding.
+
+The \b precision parameter is used to round a <em>number of segments</em>,
+calculated by dividing the <em>edge length</em> by the specified \b length of
+segment, to the higher integer if the \a remainder exceeds the \b precision
+and to the lower integer otherwise. <br>
+Use value 0.5 to provide rounding to the nearest integer, 1.0 for the lower integer, 0.0 for the higher integer. Default value is 1e-07.
+
+For example: if <em>edge length</em> is 10.0 and the segment \b length
+is 3.0 then their division gives 10./3. = 3.33(3) and the \a remainder is 0.33(3).
+If \b precision is less than 0.33(3) then the edge is divided into 3 segments.
+If \b precision is more than 0.33(3) then the edge is divided into 4 segments.
+
 
 \image html image41.gif
 
 \image html a-averagelength.png
 
-\image html b-erage_length.png "Local Length hypothesis - all 1D mesh elements are roughly equal"
+\image html b-erage_length.png "Local Length hypothesis - all 1D mesh segments are equal"
 
 <b>See Also</b> a sample TUI Script of a 
 \ref tui_average_length "Defining Local Length" hypothesis
@@ -141,7 +171,7 @@ operation.
 <b>Max Size</b> hypothesis allows splitting geometrical edges into
 segments not longer than the given length. Definition of this hypothesis
 consists of setting the maximal allowed \b length of segments.
-<b>Use preestimated length</b> check box lets you specify \b length
+<b>Use preestimated length</b> check box lets you use \b length
 automatically calculated basing on size of your geometrical object,
 namely as diagonal of bounding box divided by ten. The divider can be
 changed via "Ratio Bounding Box Diagonal / Max Size"
@@ -155,27 +185,23 @@ geometrical object has been selected before hypothesis definition.
 \anchor number_of_segments_anchor
 <h2>Number of segments hypothesis</h2>
 
-<b>Number of segments</b> hypothesis can be applied for meshing of edges
-composing your geometrical object. Definition of this hypothesis
-consists of setting the number of segments, which will split these
-edges. In other words your edges will be split into a definite number
-of segments with approximately the same length. The points on the
-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.
+<b>Number of segments</b> hypothesis can be applied for approximating
+edges by a definite number of mesh segments with length depending on
+the selected type of distribution of nodes.
 
 The direction of the splitting is defined by the orientation of the
-underlying geometrical edge. <b>"Reverse Edges"</b> list box allows to
+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 by directly picking them
+if the geometry object is selected for the meshing. In this case it is 
+possible to select edges to be reversed either by directly picking them
 in the 3D viewer or by selecting the edges or groups of edges in the
 Object Browser.
 
-\image html image46.gif
+\ref reversed_edges_helper_anchor "Helper" group assists you in
+defining <b>Reversed Edges</b> parameter.
 
-You can set the type of distribution for this hypothesis in the
+You can set the type of node distribution for this hypothesis in the
 <b>Hypothesis Construction</b> dialog bog :
 
 \image html a-nbsegments1.png
@@ -212,11 +238,11 @@ integral on the range between two nodes equal for all segments.
 pairs <b>t - F(t)</b>, where \b t ranges from 0 to 1, and the module computes the
 formula, which will rule the change of length of segments and shows
 in the plot the density function curve in red and the node
-distribution as blue crosses. The node distribution is computed the
+distribution as blue crosses. The node distribution is computed in the
 same way as for 
 \ref analyticdensity_anchor "Distribution with Analytic Density". You
-can select the <b>Conversion mode</b> from\b Exponent and <b>Cut
-negative</b>. 
+can select the <b>Conversion mode</b> from \b Exponent and <b>Cut
+negative</b>.
 
 \image html distributionwithtabledensity.png
 
@@ -224,6 +250,7 @@ negative</b>.
 \ref tui_deflection_1d "Defining Number of Segments" hypothesis
 operation.
 
+\note The plot functionality is available only if GUI module is built with Plot 2D Viewer (option SALOME_USE_PLOT2DVIEWER is ON when building GUI module).
 
 <br>
 \anchor start_and_end_length_anchor
@@ -232,19 +259,21 @@ 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 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.
+geometric progression.
 
 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
+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 by directly picking them
+if the geometry object is selected for the meshing. In this case it is 
+possible to select edges to be reversed either by directly picking them
 in the 3D viewer or by selecting the edges or groups of edges in the
 Object Browser.
 
+\ref reversed_edges_helper_anchor "Helper" group assists you in
+defining <b>Reversed Edges</b> parameter.
+
+
 \image html a-startendlength.png
 
 \image html b-art_end_length.png "The lengths of the first and the last segment are strictly defined"
@@ -259,33 +288,33 @@ hypothesis operation.
 
 The dialog box prompts you to define the quality of the future mesh by
 only one parameter, which is \b Fineness, ranging from 0 (coarse mesh,
-low number of elements) to 1 (extremely fine mesh, great number of
-elements). 
+low number of segments) to 1 (extremely fine mesh, great number of
+segments). 
 
 \image html automaticlength.png
 
 Compare one and the same object (sphere) meshed with
 minimum and maximum value of this parameter.
 
-\image html image147.gif "Example of a very rough mesh. Automatic Length works for 0."
+\image html image147.gif "Example of a rough mesh at Automatic Length Fineness of 0."
 
-\image html image148.gif "Example of a very fine mesh. Automatic Length works for 1."
+\image html image148.gif "Example of a fine mesh at Automatic Length Fineness of 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.
+set of points parametrized 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 
+\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
+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
@@ -293,9 +322,46 @@ 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"
+\ref reversed_edges_helper_anchor "Helper" group assists in
+defining <b>Reversed Edges</b> parameter.
+
+
+\image html mesh_fixedpnt.png "Example of a sub-mesh 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.
 
+\anchor reversed_edges_helper_anchor
+<h2>Reversed Edges Helper</h2>
+
+\image html rev_edges_helper_dlg.png
+
+\b Helper group assists in defining <b>Reversed Edges</b>
+parameter of the hypotheses depending on edge direction.
+
+<b>Show whole geometry</b> check-box allows seeing the whole
+geometrical model in the 3D Viewer, which can help to understand the
+location of a set of edges within the model.
+
+<b>Propagation chains</b> group allows defining <b>Reversed Edges</b>
+for splitting opposite edges of quadrilateral faces in a logically
+uniform direction. When this group is activated, the list is filled
+with propagation chains found within the shape on which a hypothesis
+is assigned. When a chain is selected in the list its edges are shown
+in the Viewer with arrows, which enables choosing a common direction
+for all chain edges. \b Reverse button inverts the common direction of
+chain edges. \b Add button is active if some edges of a chain have a
+different direction, so you can click \b Add button to add them
+to <b>Reversed Edges</b> list.
+
+\image html propagation_chain.png "The whole geometry and a propagation chain"
+
+\note Alternatively, uniform direction of edges of one propagation
+chain can be achieved by 
+\ref constructing_submeshes_page "definition of a sub-mesh" on one
+edge of the chain and assigning a 
+\ref propagation_anchor "Propagation" additional hypothesis.
+Orientation of this edge (and hence of all the rest edges of the chain) can be
+controlled by using <b>Reversed Edges</b> field.
+
 */
index 05b8d5a39eaff5d547459f907681d5b0b398834f..308a6899ad1abbb854117cf134461fd32f26987c 100644 (file)
@@ -11,7 +11,7 @@
 
 <b>Max Element Area</b> hypothesis is applied for meshing of faces
 composing your geometrical object. Definition of this hypothesis
-consists of setting the <b>maximum area</b> of mesh elements,
+consists of setting the <b>maximum area</b> of mesh faces,
 which will compose the mesh of these faces.
 
 \image html a-maxelarea.png
@@ -26,9 +26,9 @@ which will compose the mesh of these faces.
 \anchor length_from_edges_anchor
 <h2>Length from Edges</h2>
 
-<b>Length from edges</b> hypothesis builds 2D mesh elements having a
-maximum linear size calculated as an average segment length for a wire
-of a given face.
+<b>Length from edges</b> hypothesis defines the maximum linear size of
+mesh faces as an average length of mesh edges approximating
+the meshed face boundary.
 
 <b>See Also</b> a sample TUI Script of a 
 \ref tui_length_from_edges "Length from Edges" hypothesis operation.
@@ -38,10 +38,10 @@ of a given face.
 
 \image html hypo_quad_params_dialog.png "Quadrangle parameters: Transition"
 
-<b>Quadrangle parameters</b> is a hypothesis for Quadrangle (Mapping) algorithm.
+<b>Quadrangle parameters</b> is a hypothesis for \ref quad_ijk_algo_page.
 
 <b>Transition</b> tab is used to define the algorithm of transition
-between opposite sides of faces with a different number of
+between opposite sides of the face with a different number of
 segments on them. The following types of transition
 algorithms are available:
 
@@ -54,7 +54,7 @@ algorithms are available:
 - <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).
+  four face sides must be even (divisible by 2).
   \note This type corresponds to <b>Quadrangle Preference</b> additional hypothesis,
   which is obsolete now.
 - <b>Quadrangle preference (reversed)</b> works in the same way and
@@ -63,9 +63,9 @@ algorithms are available:
 - <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. In addition, the number
-  of rows between sides with different discretization
+  the same number of segments, the other pair must have an even total
+  number of segments. In addition, the number of rows
+  between sides with different discretization
   should be enough for the transition. Following the fastest transition
   pattern, three segments become one (see the image below), hence
   the least number of face rows needed to reduce from Nmax segments
@@ -77,8 +77,8 @@ algorithms are available:
 
 <b>Base vertex</b> tab allows using Quadrangle (Mapping)
 algorithm for meshing of trilateral faces. In this case it is
-necessary to select the vertex, which will be used as the fourth edge
-(degenerated).
+necessary to select the vertex, which will be used as the forth
+degenerated side of quadrangle.
 
 \image html hypo_quad_params_dialog_vert.png "Quadrangle parameters: Base Vertex"
 
@@ -113,7 +113,7 @@ of the enforced nodes.
     projected to the meshed face and located close enough to the
     meshed face will be used to create the enforced nodes.</li>
 </ul>
-\note <b>Enforced nodes</b> can't be created at \b Reduced transition type.
+\note <b>Enforced nodes</b> cannot be created at \b Reduced transition type.
 
 Let us see how the algorithm works:
 <ul>
index 22d88635f7e3f2f95e3fd21adef34b7dc2f992a2..f331fa4be3bb4aa521de3c7884b501ae093e06eb 100644 (file)
@@ -7,25 +7,26 @@ 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
+Several criteria 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"
+Some filtering criteria 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
+- In GUI, filters are available in some dialog boxes via
 "Set Filters" button, clicking on which opens the dialog box
-allowing to specify the list of filter criterions to be applied to the
+allowing to specify the list of filter criteria 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
+  entities (nodes 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
+  nodes/elements, etc) and for the operations, which accept objects
+  as input parameter. The page \ref tui_filters_page provides
   examples of the filters usage in Python scripts.
 */
index 65d5c7ad0b24550bdb198ab9d10499364296cd4f..12f5c02e14967d774b2a93e68988c1bf77263f6d 100644 (file)
@@ -3,12 +3,27 @@
 \page about_hypo_page About Hypotheses
 
 \b Hypotheses represent boundary conditions which will be taken into
-account at calculations of meshes or sub-meshes. 
-These hypotheses allow you to manage the level of detail of
-the resulting meshes or sub-meshes: when applying different hypotheses
+account by meshing algorithms.
+The hypotheses allow you to manage the level of detail of
+the resulting mesh: when applying different hypotheses
 with different parameters you can preset the quantity or size of
 elements which will compose your mesh. So, it will be possible to
-generate a coarse or a more refined mesh or sub-mesh.
+generate a coarse or a more refined mesh.
+
+The choice of a hypothesis depends on the selected algorithm.
+
+Hypotheses are created during creation and edition of 
+\ref constructing_meshes_page "meshes" and
+\ref constructing_submeshes_page "sub-meshes". 
+Once created a hypotheses can be reused during creation and edition of
+other meshes and sub-meshes. All created hypotheses and algorithms are
+present in the Object Browser in \a Hypotheses and \a Algorithms
+folders correspondingly. It is possible to open a dialog to modify the
+parameters of a hypothesis from its context menu. This menu also
+provides \b Unassign command that will unassign the hypothesis from
+all meshes and sub-meshes using it. Modification of any parameter of a
+hypothesis and its unassignment leads to automatic removal of elements
+generated using it.
 
 In \b MESH there are the following Basic Hypotheses:
 <ul>
@@ -20,10 +35,11 @@ In \b MESH there are the following Basic Hypotheses:
 <li>\ref max_length_anchor "Max Size"</li>
 <li>\ref adaptive_1d_anchor "Adaptive"</li>
 <li>\ref arithmetic_1d_anchor "Arithmetic 1D"</li>
-<li>\ref geometric_1d_anchor "Geometric 1D"</li>
+<li>\ref geometric_1d_anchor "Geometric Progression"</li>
 <li>\ref start_and_end_length_anchor "Start and end length"</li>
 <li>\ref deflection_1d_anchor "Deflection 1D"</li>
 <li>\ref automatic_length_anchor "Automatic Length"</li>
+<li>\ref fixed_points_1d_anchor "Fixed points 1D"</li>
 </ul>
 <li>\subpage a2d_meshing_hypo_page "2D Hypotheses" (for meshing of <b>faces</b>):</li>
 <ul>
@@ -37,22 +53,14 @@ In \b MESH there are the following Basic Hypotheses:
 </ul>
 </ul>
 
-There also exist  
-\subpage additional_hypo_page "Additional Hypotheses" used together
-with other hypotheses:
+There also exist
+\subpage additional_hypo_page "Additional Hypotheses":
 <ul>
 <li>\ref propagation_anchor "Propagation of 1D Hypothesis on opposite edges"</li>
 <li>\ref propagofdistribution_anchor "Propagation of Node Distribution 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:
-<ul>
-<li>the algorithm, which will be selected for meshing of this geometrical object (shape)</li>
-<li>the geometrical object (shape) which will be meshed</li>
-</ul>
-
 */
index 65201ac6422e54c9a72469a622bcd5f3f6d8dc6a..9d92487c510fd12b36fbd3e8602e0731f1026556 100644 (file)
 
 \page about_meshes_page About meshes
 
-\n \b MESH represents a discretization of a geometrical CAD model into
-a set of entities with a simple topology. 
+\n \b MESH represents a discrete approximation of a subset of the
+three-dimensional space by \ref mesh_entities "elementary geometrical
+elements".
 
-It is possible to \subpage constructing_meshes_page "construct meshes" 
-on the basis of geometrical shapes produced in the GEOM module.
-Construction of \subpage constructing_submeshes_page "sub-meshes"
-allows to mesh parts of the geometrical object, for example a face,
-with different meshing parameters or using another meshing algorithm
-than other parts.
+A SALOME study can contain multiple meshes, but they do not
+implicitly compose one super-mesh, and finally each of them
+can be used (e.g. exported) only individually.
 
-3D mesh can be generated basing on a 2D closed mesh.
-
-Several created meshes can be \subpage building_compounds_page "combined into another mesh".
-
-The whole mesh or its part can be \subpage copy_mesh_page "copied" into another mesh.
+Mesh module provides several ways to create the mesh:
+<ul>
+  <li>The main way is to \subpage constructing_meshes_page "construct the mesh" 
+    on the basis of the geometrical shape produced in the Geometry
+    module. This way implies selection of 
+    - a geometrical object (<em>main shape</em>) and
+    - <em>meshing parameters</em> (\ref
+      basic_meshing_algos_page "meshing algorithms" and
+    characteristics (e.g. element size) of a
+    required mesh encapsulated in \ref about_hypo_page "hypothesis"
+    objects).
 
-Meshing parameters of meshes and sub-meshes can be 
-\subpage editing_meshes_page "edited", then only the mesh part
-depending on the changed parameters will be re-computed.
+    Construction of \subpage constructing_submeshes_page "sub-meshes"
+    allows to discretize some sub-shapes of the main shape, for example a face,
+    using the meshing parameters that differ from those used for other sub-shapes.<br>
+    Meshing parameters of meshes and sub-meshes can be 
+    \subpage editing_meshes_page "edited". (Upon edition only mesh entities
+    generated using changed meshing parameters are removed and will be
+    re-computed).<br>
+    \note Algorithms and hypotheses used at mesh level are referred to as
+    \a global ones and those used at sub-mesh level are referred to as \a
+    local ones.
+  </li>
+  <li>Bottom-up way, using \ref modifying_meshes_page "mesh modification"
+    operations, especially \ref extrusion_page "extrusion" and \ref
+    revolution_page "revolution". To create an empty mesh not based on a
+    geometry, use the same dialog as to \ref constructing_meshes_page
+    "construct the mesh on geometry" but do not specify a geometry
+    or a meshing algorithm.
+  </li>
+  <li>The mesh can be \subpage importing_exporting_meshes_page "imported" from
+    (and exported to) the file in MED, UNV, STL, CGNS, DAT, GMF and
+    SAUVE formats.
+  </li>
+  <li>The 3D mesh can be generated from the 2D mesh, which was \ref
+    importing_exporting_meshes_page "imported" or manually created. To
+    setup the meshing parameters of a mesh not based on a geometry, just
+    invoke \ref editing_meshes_page "Edit mesh / sub-mesh" command on
+    your 2D mesh.
+  </li>
+  <li>Several meshes can be \subpage building_compounds_page "combined"
+    into a new mesh.
+  </li>
+  <li>The whole mesh or its part (sub-mesh or group) can be 
+    \subpage copy_mesh_page "copied" into a new mesh.
+  </li>
+  <li>A new mesh can be created from a transformed, e.g. \ref
+    translation_page "translated", part of the mesh.</li>
+</ul>
 
 Meshes can be edited using the MESH functions destined for 
-\ref modifying_meshes_page "modification" of generated meshes.
+\ref modifying_meshes_page "modification" of meshes.
 
-Meshes are stored in DAT, MED, UNV, STL, CGNS, GMF and SAUVE formats and can be
-\subpage importing_exporting_meshes_page "imported from and exported to"
- the file in these formats.
+Attractive meshing capabilities include:
+- 3D and 2D \ref viscous_layers_anchor "Viscous Layers" (boundary
+  layers of highly stretched elements beneficial for high quality
+  viscous computations);
+- automatic conformal transition between tetrahedral and hexahedral
+  sub-meshes.
 
-The \b topology of a mesh is described by the relationships between its
-entities including:
+The \b structure of a SALOME mesh is described by nodes and elements based on
+these nodes. The geometry of an element is defined by the sequence of
+nodes constituting it and
+the <a href="http://www.code-aster.org/outils/med/html/connectivites.html">
+  connectivity convention </a> (adopted from MED library). Definition of
+the element basing on the elements of a lower dimension is NOT supported.
 
+\anchor mesh_entities
+The mesh can include the following entities:
 <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>
+<li>\b Node &mdash; a mesh entity defining a position in 3D
+  space with coordinates (x, y, z).</li>
+<li>\b Edge (or segment) &mdash; 1D mesh element linking two nodes.</li>
+<li>\b Face &mdash; 2D mesh element representing a part of
+  surface bound by links between face nodes. A face can be a
+  triangle, quadrangle or polygon.</li>
+<li>\b Volume &mdash; 3D mesh element representing a part of 3D
+  space bound by volume facets. Nodes of a volume describing each
+  facet are defined by
+  the <a href="http://www.code-aster.org/outils/med/html/connectivites.html">
+  MED connectivity convention.</a> A volume can be a tetrahedron, hexahedron,
+  pentahedron, pyramid, hexagonal prism or polyhedron.</li>
+<li>\b 0D element &mdash; mesh element defined by one node.</li>
+<li>\b Ball element &mdash; discrete mesh element 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
-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:
+Every mesh entity has an attribute associating it to a sub-shape it is
+generated on (if any). The node generated on the geometrical edge or
+surface in addition stores its position in parametric space of the
+associated geometrical entity.
 
-<ul>
-<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>
-<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>
-<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>
-</ul>
+Mesh entities are identified by integer IDs starting from 1.
+Nodes and elements are counted separately, i.e. there can be a node
+and element with the same ID.
+
+SALOME supports elements of second order, without a central node
+(quadratic triangle, quadrangle, polygon, tetrahedron, hexahedron,
+pentahedron and pyramid) and with central nodes (bi-quadratic triangle
+and quadrangle and tri-quadratic hexahedron).<br>
+Quadratic mesh can be obtained in two ways:
+- Using a global \ref quadratic_mesh_anchor "Quadratic Mesh"
+hypothesis. (Elements with the central node are not generated in this way).
+- Using \ref convert_to_from_quadratic_mesh_page operation.
 
 */
index 1e170e440bd0e15ecf80d7bfdeae228b887845e9..9dbb5c9923cff006424fe84e3a5c4867d98aa570 100644 (file)
@@ -24,7 +24,6 @@ Node quality controls:
 
 Edge quality controls:
 <ul>
-<li>\subpage free_edges_page "Free edges"</li>
 <li>\subpage free_borders_page "Free borders"</li>
 <li>\subpage length_page "Length"</li>
 <li>\subpage borders_at_multi_connection_page "Borders at multi-connection"</li>
@@ -33,6 +32,7 @@ Edge 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>
index e46385b2d204371c8a43f853f0b9d2900dbe3f67..855b7e5ea364c0a35c3baafc46974fd91f4bd6eb 100644 (file)
@@ -32,7 +32,7 @@ nodal connectivity of elements in the documentation on MED library or
   <li>From the \b Modification menu choose the \b Add item, the
     following associated sub-menu will appear:</li>
 
-  \image html image146.png
+  \image html image152.png
 
 From this sub-menu select the type of element which you would like to add to your mesh.
 
@@ -47,10 +47,13 @@ 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".
+combo box lists groups of all the 
+\ref grouping_elements_page "three types": both 
+\ref standalone_group "standalone groups",
+\ref group_on_filter "groups on filter", and 
+\ref group_on_geom "groups on geometry". If the user chooses a
+group on geometry or on filter, he is warned and proposed to
+convert this group to standalone.
 If the user rejects conversion operation, it is cancelled and
 a new node/element is not created!
 
@@ -87,29 +90,35 @@ selecting them in the 3D viewer and click the \b Apply or
 \anchor adding_0delems_on_all_nodes_anchor
 <h2>Making 0D elements on Element Nodes</h2>
 
-There is another way to create 0D elements. It is possible to create 
+There is another way to create 0D elements. It is possible to create
 0D elements on all nodes of the selected mesh, sub-mesh, or a group of elements or nodes.
 
 \image html dlg_0D_on_all_nodes.png
 
-In this dialog 
+In this dialog
 <ul>
   <li> The radio-buttons allow choosing the type of object to create 0D elements on.
     <ul>
-      <li><b> Mesh, sub-mesh, group </b> -  this button allows selecting
-       a mesh, a sub-mesh or a group to create 0D elements on the nodes of its
+      <li><b> Mesh, sub-mesh, group </b> - this button allows selecting
+        a mesh, a sub-mesh or a group to create 0D elements on the nodes of its
         elements. The name of the selected object is shown in the dialog. </li>
       <li><b> Elements </b> - this button allows selecting elements in the
         VTK viewer or typing their IDs in the dialog.</li>
       <li><b> Nodes </b> - this button allows selecting nodes to create
         0D elements on in the VTK viewer or typing their IDs in the dialog.</li>
   </ul></li>
-  <li><b> Set Filter </b> button allows selecting elements or nodes 
-by filtering mesh elements or nodes with different criteria
-(see \ref filtering_elements "Filter usage").</li>
-<li> Switching on <b>Add to group</b> check-box allows specifying the
-  name of the group to which all created or found 0D elements  will be added. You can either select an existing group from
-  a drop-down list, or enter the name of the group to be created.</li>
+  <li><b> Set Filter </b> button allows selecting elements or nodes
+    by filtering mesh elements or nodes with different criteria
+    (see \ref filtering_elements "Filter usage").</li>
+  <li> Switching on <b>Add to group</b> check-box allows specifying the
+    name of the group to which all created or found (existing) 0D elements will
+    be added. You can either select an existing group from a drop-down
+    list, or enter the name of the group to be created. If a selected
+    existing \ref grouping_elements_page "group" is not Standalone
+    (Group On Geometry or Group On Filter) it will be converted to
+    Standalone.
+    \warning If <b>Add to group</b> is activated it has to be filled in.
+</li>
 </ul>
 
 
@@ -121,7 +130,7 @@ by filtering mesh elements or nodes with different criteria
 In this dialog box specify the nodes, which will form your ball elements,
 either by selecting them in the 3D viewer or by manually entering their IDs,
 specify the ball diameter and click the \b Apply or <b>Apply and
-Close</b> button.
+  Close</b> button.
 
 \image html add_ball.png
 
index 6a9527b5d04ac4326f901108010db5c04035004b..2fd906bafbde6abd91d248ca97f7e08ce7be0a9f 100644 (file)
@@ -36,7 +36,7 @@ one of the following:
 
 \image html image152.png
 
-\note All dialogs for quadratic element adding to the mesh
+\note All dialogs for adding quadratic element 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
@@ -47,23 +47,29 @@ 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".
+combo box lists groups of all the 
+\ref grouping_elements_page "three types": both 
+\ref standalone_group "standalone groups",
+\ref group_on_filter "groups on filter", and 
+\ref group_on_geom "groups on geometry". If the user chooses a
+group on geometry or on filter, he is warned and proposed to
+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
-element by selecting them in the 3D viewer with pressed Shift
-button. Their numbers will appear in the dialog box as <b>Corner Nodes</b>
-(alternatively you can just input numbers in this field without
-selection). The edges formed by the corner nodes will appear in the
-table. To define the middle nodes for each edge, double-click on the
-respective field and input the number of the node (or pick the node in
-the viewer). For bi-quadratic and tri-quadratic elements, your also
-need to specify central nodes.
+To create any <b>Quadratic Element</b> specify the nodes which will
+form your element by selecting them in the 3D viewer with pressed
+Shift button and click \a Selection button to the right of 
+<b>Corner Nodes</b> label. Their numbers will appear in the dialog box
+as <b>Corner Nodes</b> (alternatively you can just input numbers in
+this field without selection; note that to use this way the mesh
+should be selected before invoking this operation). The edges formed
+by the corner nodes will appear in the table. To define the middle
+nodes for each edge, double-click on the respective field and input
+the number of the node (or pick the node in the viewer). For
+bi-quadratic and tri-quadratic elements, your also need to specify
+central nodes.
 As soon as all needed nodes are specified, a preview of a new
 quadratic element will be displayed in the 3D viewer. Then
 you will be able to click \b Apply or <b>Apply and Close</b> button to
index 5c5c204eff554dfaa4fffab44bf22c2c308a53fa..5904e87d49e6211649a58be1cfb1dae0b896ea64 100644 (file)
@@ -5,37 +5,45 @@
 \n <b>Additional Hypotheses</b> can be applied as a supplement to the
 main hypotheses, introducing additional concepts to mesh creation.
 
-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>
+An <b>Additional Hypothesis</b> can be defined in the same way as any
+main hypothesis in \ref create_mesh_anchor "Create Mesh" or 
+\ref constructing_submeshes_page "Create Sub-Mesh" dialog.
+
+The following additional hypothesis are available:
+<ul> 
+<li>\ref propagation_anchor "Propagation of 1D Hypothesis on opposite edges" 
+  and \ref propagofdistribution_anchor "Propagation of Node Distribution on Opposite Edges"
+  hypotheses are useful for creation of quadrangle and hexahedral
+  meshes.</li>
+<li>\ref viscous_layers_anchor "Viscous Layers" and 
+  \ref viscous_layers_anchor "Viscous Layers 2D"
+  hypotheses allow creation of layers of highly stretched
+  elements near mesh boundary, which is beneficial for high quality
+  viscous computations.</li>
+<li>\ref quadratic_mesh_anchor "Quadratic Mesh" hypothesis allows
+  generation of second order meshes.</li> 
+<li>\ref quadrangle_preference_anchor "Quadrangle Preference"
+  enables generation of quadrangles.</li>
+</ul>
 
-Quadratic Mesh hypothesis allows to build a quadratic mesh (whose
-edges are not straight but curved lines and can be defined by three
-points: first, middle and last instead of an ordinary two).
-
-See \ref adding_quadratic_elements_page
-for more information about quadratic meshes.
 
 \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
-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 
+<b>Propagation of 1D Hypothesis on opposite edges</b> allows to mesh
+opposite sides of a quadrangle face and other adjacent quadrangles,
+using the same hypothesis assigned to only one edge.<br>
+Thus you define a sub-mesh on the edge where you define 1D meshing
+parameters and the \b Propagation hypothesis. These local meshing
+parameters will be propagated via opposite sides of quadrangles to the
+whole geometry, and this propagation stops at an edge with other local
+meshing parameters.
+
+This hypothesis can be taken into account by 
+\ref a1d_algos_anchor "Wire Discretization" and 
+\ref a1d_algos_anchor "Composite Side Discretization" algorithms.
+
+<b>See Also</b> a sample TUI Script of a 
 \ref tui_propagation "Propagation hypothesis" operation
 
 \anchor propagofdistribution_anchor
@@ -48,25 +56,18 @@ opposite edge will have the same number of nodes and the same
 relations between segment lengths, 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
-
-\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.
+This hypothesis can be taken into account by 
+\ref a1d_algos_anchor "Wire Discretization" and 
+\ref a1d_algos_anchor "Composite Side Discretization" algorithms.
 
-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).
+<b>See Also</b> a sample TUI Script of a 
+\ref tui_propagation "Propagation hypothesis" operation
 
 \anchor viscous_layers_anchor
 <h2>Viscous Layers and Viscous Layers 2D</h2>
 
 <b>Viscous Layers</b> and <b>Viscous Layers 2D </b> additional
-hypotheses can be used together with either some 3D algorithms, for example
+hypotheses can be used by several 3D algorithms, for example
 Hexahedron(i,j,k), or 2D algorithms, for example Triangle
 (MEFISTO), correspondingly. These hypotheses allow creation of layers
 of highly stretched elements, prisms in 3D and quadrilaterals in 2D,
@@ -75,12 +76,29 @@ computations.
 
 \image html viscous_layers_hyp.png
 
+\image html viscous_layers_2d_hyp.png
+
 <ul>
 <li><b>Name</b> - allows to define the name of the hypothesis.</li>
 <li><b>Total thickness</b> - gives the total thickness of element layers.</li>
 <li><b>Number of layers</b> - defines the number of element layers.</li>
 <li><b>Stretch factor</b> - defines the growth factor of element height
   from the mesh boundary inwards.</li>
+<li><b>Extrusion method</b> (available in 3D only) - defines how
+  positions of nodes are found during prism construction and how
+  the creation of distorted and intersecting prisms is prevented.
+<ul><li><b>Surface offset + smooth</b> method extrudes nodes along the normal
+    to the underlying geometrical surface. Smoothing of the internal surface of
+    element layers is possible to avoid creation of invalid prisms.</li>
+  <li><b>Face offset</b> method extrudes nodes along the average normal of
+    surrounding mesh faces to the intersection with a neighbor mesh face
+    translated along its own normal by the thickness of layers. The thickness
+    of layers can be limited to avoid creation of invalid prisms.</li>
+  <li><b>Node offset</b> method extrudes nodes along the average normal of
+    surrounding mesh faces by the thickness of layers. The thickness of
+    layers can be limited to avoid creation of invalid prisms.</li> 
+\image html viscous_layers_extrusion_method.png "Prisms created by the tree extrusion methods at the same other parameters"
+</ul></li>
 <li><b>Specified Faces/Edges are</b> - defines how the shapes specified by
   the next parameter are used.
 <li><b> Faces/Edges with/without layers</b> - 
@@ -90,11 +108,15 @@ computations.
   Faces (or edges) can be selected either in the Object Browser or in
   the VTK Viewer.
   \note A mesh shown in the 3D Viewer can prevent selection of faces
-  and edges, just hide the mesh to avoid this. To avoid a long wait when a
+  and edges, just hide the mesh to avoid this. If a face, which should be
+  selected, is hidden by other faces, consider creating a
+  group of faces to be selected in the Geometry module.<br>
+  To avoid a long wait when a
   geometry with many faces (or edges) is displayed, the number of faces
   (edges) shown at a time is limited by the value of "Sub-shapes
   preview chunk size" preference (in Preferences/Mesh/General tab).
 
+
   If faces/edges without layers are specified, the element layers are
   not constructed on geometrical faces shared by several solids in 3D
   case and edges shared by several faces in 2D case. In other words,
@@ -123,4 +145,37 @@ computations.
 <br><b>See also</b> a sample TUI script of a \ref tui_viscous_layers
 "Viscous layers construction".
 
+
+\anchor quadratic_mesh_anchor
+<h2>Quadratic Mesh</h2>
+
+Quadratic Mesh hypothesis allows to build a quadratic mesh (in which
+links between element nodes are not straight but curved lines due to
+presence of an additional mid-side node).
+
+This 1D hypothesis can be taken into account by 
+\ref a1d_algos_anchor "Wire Discretization" and 
+\ref a1d_algos_anchor "Composite Side Discretization" algorithms. To
+create a quadratic mesh assign this hypothesis at 
+\ref constructing_meshes_page "mesh construction".
+
+See \ref adding_quadratic_elements_page
+for more information about quadratic meshes.
+
+
+\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.
+
+Usage of this hypothesis with "Quadrangle (Mapping)" meshing algorithm
+is obsolete since introducing
+\ref hypo_quad_params_anchor "Quadrangle parameters" hypothesis.
+Usage of this hypothesis with "Quadrangle (Mapping)" meshing algorithm
+corresponds to specifying "Quadrangle Preference" transition type of
+\ref hypo_quad_params_anchor "Quadrangle parameters" hypothesis.
+\note "Quadrangle Preference" transition type can be used only if the
+total quantity of segments on all sides of the face is even (divisible
+by 2), else "Standard" transition type is used.
 */
index f650a3fd65b1b867cd932b75fd99cdbf9560104e..765d4d4f407fd96e4eb654f2fee07481f67d14e2 100644 (file)
@@ -3,9 +3,7 @@
 \page area_page Area
 
 \n \b Area mesh quality control is based on the algorithm of area
-calculation of  meshing elements. It can be applied to meshes
-consisting of 2D meshing elements with 3 and 4 nodes (triangles and
-quadrangles).
+calculation of mesh faces.
 
 <em>To apply the Area quality control to your mesh:</em>
 <ol>
@@ -17,7 +15,7 @@ quadrangles).
 \image html image35.png
 <center><em>"Area" button</em></center>
 
-Your mesh will be displayed in the viewer with its elements colored
+Your mesh will be displayed in the viewer with its faces colored
 according to the applied mesh quality control criterion:
 
 \image html image5.jpg
index 977b505dbad674d72220d8e33e9aaf5a4363c7bb..080727462dc2113a6b5a95b6cab6f0b67a91641b 100644 (file)
@@ -3,27 +3,33 @@
 \page basic_meshing_algos_page Basic meshing algorithms
 
 \n The MESH module contains a set of meshing algorithms, which are
-used for meshing entities (1D, 2D, 3D) composing geometrical objects.
+used for meshing entities (1D, 2D, 3D sub-shapes) composing
+geometrical objects.
+
+An algorithm represents either an implementation of a certain meshing
+technique or an interface to the whole meshing program generating elements
+of several dimensions.
 
 <ul>
 <li>For meshing of 1D entities (<b>edges</b>):</li>
-
+\anchor a1d_algos_anchor
 <ul>
-<li>Wire Discretization meshing algorithm - splits a wire into a
-number of mesh segments following any 1D hypothesis.</li>
-<li>Composite Side Discretization algorithm - allows to apply any 1D
-hypothesis to a whole side of a geometrical face even if it is
-composed of several edges provided that they form C1 curve, have the
-same hypotheses assigned and form one side in all faces of the main
-shape of a mesh.</li>
+<li><b>Wire Discretization</b> meshing algorithm - splits an edge into a
+number of mesh segments following an 1D hypothesis.
+</li>
+<li><b>Composite Side Discretization</b> algorithm - allows to apply a 1D
+  hypothesis to a whole side of a geometrical face even if it is
+  composed of several edges provided that they form C1 curve in all
+  faces of the main shape.</li>
 </ul>
 
 <li>For meshing of 2D entities (<b>faces</b>):</li>
 
 <ul>
-<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>
+<li><b>Triangle (Mefisto)</b> meshing algorithm - splits faces
+  into triangular elements.</li>
+<li>\subpage quad_ijk_algo_page "Quadrangle (Mapping)" meshing
+  algorithm - splits faces into quadrangular elements.</li>
 </ul>
 
 \image html image123.gif "Example of a triangular 2D mesh"
@@ -33,12 +39,19 @@ quadrangular elements.</li>
 <li>For meshing of 3D entities (<b>solid objects</b>):</li>
 
 <ul>
-<li>Hexahedron meshing algorithm (i,j,k) - 6-sided Solids are split into
-hexahedral (cubic) elements.</li>
-<li>\subpage cartesian_algo_page</li>
-- internal parts of Solids 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>
+<li><b>Hexahedron (i,j,k)</b> meshing algorithm - solids are
+  split into hexahedral elements thus forming a structured 3D
+  mesh. The algorithm requires that 2D mesh generated on a solid could
+  be considered as a mesh of a box, i.e. there should be eight nodes
+  shared by three quadrangles and the rest nodes should be shared by
+  four quadrangles.
+\image html hexa_ijk_mesh.png "Structured mesh generated by Hexahedron (i,j,k) on a solid bound by 16 faces"
+</li>
+
+<li>\subpage cartesian_algo_page "Body Fitting" meshing
+  algorithm - solids 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"
@@ -46,21 +59,25 @@ where the geometrical boundary intersects Cartesian cells.</li>
 \image html image126.gif "Example of a hexahedral 3D mesh"
 </ul>
 
-Some 3D meshing algorithms, such as Hexahedron(i,j,k) and some
-commercial ones, also can generate 3D meshes from 2D meshes, working without
-geometrical objects. 
+Some 3D meshing algorithms, such as Hexahedron(i,j,k) also can
+generate 3D meshes from 2D meshes, working without geometrical
+objects.
 
 There is also a number of more specific algorithms:
 <ul>
-<li>\subpage prism_3d_algo_page "for meshing prismatic shapes"</li>
+<li>\subpage prism_3d_algo_page "for meshing prismatic 3D shapes with hexahedra and prisms"</li>
+<li>\subpage quad_from_ma_algo_page "for quadrangle meshing of faces with sinuous borders"</li>
+<li> <b>Polygon per Face</b> meshing algorithm - generates one mesh
+  face (either a triangle, a quadrangle or a polygon) per a geometrical
+  face using all nodes from the face boundary.</li>
 <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 radial_quadrangle_1D2D_algo_page "for meshing special 2d faces (circles and part of circles)"</li>
+<li>\subpage radial_prism_algo_page "for meshing 3D geometrical objects with cavities with hexahedra and prisms"</li>
+<li>\subpage radial_quadrangle_1D2D_algo_page "for quadrangle meshing of disks and parts of disks"</li>
 <li>\subpage use_existing_page "Use Edges to be Created Manually" and 
-\ref use_existing_page "Use Faces to be Created Manually" algorithms can be
-used to create a 1D or a 2D mesh in a python script.</li>
-<li>\subpage segments_around_vertex_algo_page "for defining the local size of elements around a certain node"</li>
+  \ref use_existing_page "Use Faces to be Created Manually" algorithms can be
+  used to create a 1D or a 2D mesh in a python script.</li>
+<li>\subpage segments_around_vertex_algo_page "for defining the length of mesh segments around certain vertices"</li>
 </ul>
 
 \ref constructing_meshes_page "Constructing meshes" page describes in
index 8f92d3995f3db08ca621e6d4ef32b8892c259f75..46fbc6047dc7baf1fb4c32cec4e40fb77b9b9fc8 100644 (file)
@@ -2,9 +2,8 @@
 
 \page borders_at_multi_connection_page Borders at multi-connection
 
-\n This mesh quality control highlights borders of faces consisting of
-edges belonging to several faces. The amount of faces is specified by
-user.
+\n This mesh quality control highlights segments according to the number
+of elements, faces and volumes, to which the segment belongs.
 
 \image html image151.gif
 
@@ -13,4 +12,4 @@ In this picture the borders at multi-connection are displayed in blue.
 <br><b>See Also</b> a sample TUI Script of a 
 \ref tui_borders_at_multiconnection "Borders at Multi-Connection quality control" operation.
 
-*/
\ No newline at end of file
+*/
index a0fe042901e342e59449695a0bee67095cf0336c..77a439130e71118f795a4553d988a2470f098b7a 100644 (file)
@@ -2,12 +2,12 @@
 
 \page borders_at_multi_connection_2d_page Borders at multi-connection 2D
 
-\n This mesh quality control highlights borders of elements of mesh,
-consisting of edges belonging to several elements of mesh.
+\n This mesh quality control highlights borders of faces (links
+between nodes) according to the number of faces, to which the link belongs.
 
 \image html image127.gif
 
 <br><b>See Also</b> a sample TUI Script of a 
 \ref tui_borders_at_multiconnection_2d "Borders at Multi-Connection quality control" operation.
 
-*/
\ No newline at end of file
+*/
index 98a20c470fcfc6443d4b45339683f8151287c8ec..ce5f3ce505e578a40cc03b60814cc0cb98ced66f 100644 (file)
@@ -1,14 +1,19 @@
 /*!
 
-\page building_compounds_page Building Compounds
+\page building_compounds_page Building Compound Meshes
 
-\n Compound Mesh is a combination of several meshes.
+\n Compound Mesh is a combination of several meshes. All elements and
+groups present in input meshes are present in the compound
+mesh. However, it does not use geometry or hypotheses of the initial meshes. 
+The links between the input meshes and the compound mesh are not
+supported, consequently the modification of an input mesh does not lead to
+the update of the compound mesh.
 
-<em>To Build a compound:</em>
+<em>To Build a compound mesh:</em>
 
 \par
 From the \b Mesh menu select <b>Build Compound</b> or click <em>"Build
-Compound Mesh"</em> button in the toolbar.
+  Compound Mesh"</em> button in the toolbar.
 
 \image html image161.png
 <center><em>"Build Compound Mesh" button</em></center>
@@ -20,33 +25,36 @@ The following dialog box will appear:
 
 \par
 <ul>
-<li>\b Name - allows selecting the name of the resulting \b Compound.</li>
-<li>\b Meshes - allows selecting the meshes which will be
-concatenated. They can be chosen in the Object Browser while holding
-\b Ctrl button.</li>
-<li><b>Processing identical groups</b> - allows selecting the method
-of processing the namesake existing on the united meshes.
-\n They can be either</li>
-<ul>
-<li>\b United - all elements of Group1 on Mesh_1 and Group1 on Mesh_2
-become the elements of Group1 on the Compound_Mesh, or</li>
-<li>\b Renamed - Group1 on Mesh_1 becomes Group1_1 and Group1 on Mesh_2
-becomes Group1_2. See \ref grouping_elements_page "Creating Groups"
-for more information about groups.</li>
-</ul>
-<li><b>Create common groups for initial meshes</b> checkbox permits to
-automatically create groups of all elements of the same type
-(nodes, edges, faces and volumes) for the resulting mesh from the
-elements
-of the initial meshes.
-</li>
-<li>You can simply unite meshes or choose to <b>Merge coincident nodes
-and elements</b>, in which case it is possible to define the \b Tolerance
-for this operation.</li>
+  <li>\b Name - allows selecting the name of the resulting \b Compound mesh.</li>
+  <li><b>Meshes, sub-meshes, groups</b> - allows selecting the meshes,
+    sub-meshes and groups to be concatenated. They can be
+    chosen in the Object Browser while holding \b Ctrl button.</li>
+  <li><b>Processing identical groups</b> - allows selecting the method
+    of processing the namesake groups existing in the input meshes.
+    They can be either <ul>
+      <li>\b United - all elements of \em Group1 of \em Mesh_1 and \em
+      Group1 of \em Mesh_2 become the elements of \em Group1 of the
+      \em Compound_Mesh, or</li>
+      <li>\b Renamed - \em Group1 of \em Mesh_1 becomes \em Group1_1
+      and \em Group1 of \em Mesh_2 becomes \em Group1_2.</li>
+    </ul>
+    See \ref grouping_elements_page "Creating Groups" for more information
+    about groups.</li>
+  <li><b>Create groups from input objects</b> check-box permits to
+    automatically create groups corresponding to every initial mesh.
+
+\image html buildcompound_groups.png "Groups created from input meshes 'Box_large' and 'Box_small'"
+
+  <p></li>
+  <li>You can choose to additionally
+    \ref merging_nodes_page "Merge coincident nodes" 
+    \ref merging_elements_page "and elements" in the compound mesh, in
+    which case it is possible to define the \b Tolerance for this
+    operation.</li>
 </ul>
 
 \image html image160.gif "Example of a compound of two meshed cubes"
 
-<b>See Also</b> a sample 
+<b>See Also</b> a sample
 \ref tui_building_compound "TUI Example of building compounds."
 */
index 4d00c577f5fb45ee38fb290dd547b4b5167137c3..63b81ffc4b792ae8f5a9c8d6729a30a2ebe77f3b 100644 (file)
@@ -41,11 +41,9 @@ To apply this algorithm when you define your mesh, select <b>Body
 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> <b> Implement Edges </b> check-box activates incorporation of
   geometrical edges in the mesh.
   
@@ -64,9 +62,10 @@ This dialog allows to define
         System.</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
+        normalized at [0.0,1.0]. <em>f(t)</em> must be non-negative
+        at 0. <= \a t <= 1. The whole extent of geometry can be
+        divided into ranges with their own spacing formulas to apply;
+        \a t varies between 0.0 and 1.0 within each \b Range. \b Insert button
         divides a selected range into two. \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
index 416f9514cfdb44175f947b4271a10525a7dfa39e..7253782c1384736f084b50c72c9e8aab2c9c52de 100644 (file)
@@ -2,45 +2,45 @@
 
 \page changing_orientation_of_elements_page Changing orientation of elements
 
-\n Orientation of an element is changed by reverting the order of its nodes.
+\n Orientation of an element is changed by changing the order of its nodes.
 
 <em>To change orientation of elements:</em>
 <ol>
-<li>Display a mesh or a submesh in the 3D viewer.</li>
-<li>In the \b Modification menu select the \b Orientation item or click
-<em>Orientation</em> button in the toolbar.
+  <li>Select a mesh (and display it in the 3D Viewer if you are going to pick elements by mouse).</li>
+  <li>In the \b Modification menu select the \b Orientation item or click
+    <em>Orientation</em> button in the toolbar.
 
-<center>
+    <center>
 \image html image79.png
 <em>"Orientation" button</em>
-</center>
+    </center>
 
-The following dialog box will appear:
+    The following dialog box will appear:
 
-<center>
+    <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
-be highlighted. After that click the \b Add button and the ID of this
-element will be added to the list. To remove a selected element or
-elements from the list click the \b Remove button. The \b Sort button
-allows to sort the list of elements IDs. The <b>Set filter</b> button
-allows to apply a definite filter to selection of elements of your
-group.</li>
-<li><b>Apply to all</b> radio button allows to modify the orientation
-of all elements of the currently displayed mesh or submesh.</li>
-<li><b>Select from</b> set of fields allows to choose a submesh or an
-existing group whose elements will be automatically added to the
-list.</li>
-</ul>
-
-</li>
-<li>Click the \b Apply or <b>Apply and Close</b> button to confirm the operation.</li>
+    </center>
+    <ul>
+      <li>Select type of elements to reorient: \b Face or \b Volume.</li>
+      <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
+        be highlighted. After that click the \b Add button and the ID of this
+        element will be added to the list. To remove a selected element or
+        elements from the list click the \b Remove button. The \b Sort button
+        allows to sort the list of elements IDs. The <b>Set filter</b> button
+        allows to apply a definite \ref filtering_elements "filter" to the
+        selection of elements.</li>
+      <li><b>Apply to all</b> radio button allows to modify the orientation
+        of all elements of the selected mesh.</li>
+      <li><b>Select from</b> set of fields allows to choose a sub-mesh or an
+        existing group whose elements can be added to the list.</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_orientation "Change Orientation" operation. 
+<br><b>See Also</b> a sample TUI Script of a
+\ref tui_orientation "Change Orientation" operation.
 
 */
index 5d26cae6c0f05ce1aa1e6dcd4e2f9dc631137c0a..2ec8a49878fa121577843d32121c0b28324a3421 100644 (file)
@@ -2,14 +2,66 @@
 
 \page constructing_meshes_page Constructing meshes
 
-\n Construction of a mesh on some geometry consists of:
+To create a mesh on geometry, it is necessary to create a mesh object by choosing
+- a geometrical shape produced in the Geometry module (<em>main shape</em>);
+- <em>meshing parameters</em>, including 
+  - \ref basic_meshing_algos_page "meshing algorithms" and
+  - \ref about_hypo_page "hypotheses" specifying constraints to be
+    taken into account by the chosen meshing algorithms.
+
+Then you can launch mesh generation by invoking \ref compute_anchor "Compute" command.
+
+\note Sometimes \a hypotheses term is used to refer to both algorithms
+and hypotheses.
+
+Mesh generation on the geometry is performed in the bottom-up
+flow: nodes on vertices are created first, then edges are divided into
+segments using nodes on vertices; the node of segments are then
+used to mesh faces; then the nodes of faces are used to mesh
+solids. This automatically assures the conformity of the mesh.
+
+It is required to choose a meshing algorithm for every dimension of
+sub-shapes up to the highest dimension to be generated. Note
+that some algorithms generate elements of several dimensions, and
+others of only one. It is not necessary to define meshing
+parameters for all dimensions at once; you can start from 1D
+meshing parameters only, compute the 1D mesh, then define 2D meshing
+parameters and compute the 2D mesh (note that 1D mesh will not be
+re-computed).
+
+An algorithm of a certain dimension chosen at mesh creation is applied
+to discretize every sub-shape of this dimension. It is possible to
+specify a different algorithm or hypothesis to be applied to one or
+a group of sub-shapes by creating a \ref constructing_submeshes_page
+"sub-mesh". You can specify no algorithms at all at mesh object
+creation and specify the meshing parameters on sub-meshes only; then
+only the sub-shapes, for which an algorithm and a hypothesis (if any)
+have been defined will be discretized.
+
+\n Construction of a mesh on a geometry includes at least two 
+(\ref create_mesh_anchor "mesh creation" and
+\ref compute_anchor "computing") of the following steps:
 <ul>
-  <li> \ref create_mesh_anchor "Creating of a mesh object"</li>
-  <li> \ref evaluate_anchor "Evaluating mesh size" (optional)</li>
-  <li> \ref preview_anchor "Previewing the mesh" (optional)</li>
-  <li> \ref submesh_order_anchor "Changing sub-mesh priority" (optional)</li>
-  <li> \ref compute_anchor "Computing the mesh"</li>
-  <li> \ref edit_anchor "Editing the mesh" (optional)</li>
+  <li> \ref create_mesh_anchor "Creation of a mesh object", where you
+  can specify meshing parameters to apply to all sub-shapes of the
+  main shape.</li>
+  <li> \ref constructing_submeshes_page "Creation of sub-meshes",
+  (optional) where you can specify meshing parameters to apply to the
+  selected sub-shapes.</li>
+  <li> \ref evaluate_anchor "Evaluating mesh size" (optional) can be
+  used to know an approximate number of elements before their actual generation.</li>
+  <li> \ref preview_anchor "Previewing the mesh" (optional) can be
+  used to generate mesh of only lower dimension(s) in order to
+  visually estimate it before full mesh generation, which can be much
+  longer.</li>
+  <li> \ref submesh_order_anchor "Changing sub-mesh priority"
+  (optional) can be useful if there are concurrent sub-meshes
+  defined.</li>
+  <li> \ref compute_anchor "Computing the mesh" uses defined meshing
+  parameters to generate mesh elements.</li>
+  <li> \ref edit_anchor "Editing the mesh" (optional) can be used to
+  \ref modifying_meshes_page "modify" the mesh of a lower dimension before
+  \ref compute_anchor "computing" elements of an upper dimension.</li>
 </ul>
 
 \anchor create_mesh_anchor
@@ -35,7 +87,7 @@
       Hexahedral, Tetrahedral, Triangular </b> and \b Quadrilateral (there
     can be less items for the geometry of lower dimensions).
 
-    Selection of a mesh type hides all meshing algorithms that can not
+    Selection of a mesh type hides all meshing algorithms that cannot
     generate elements of this type.</li>
 
   <li>Apply \subpage basic_meshing_algos_page "meshing algorithms" and
 
     "Create mesh" dialog box contains several tab pages titled \b 3D,
     \b 2D, \b 1D and \b 0D. The title of each page reflects the
-    dimension of the CAD model (geometry) the algorithms listed on
+    dimension of the sub-shapes the algorithms listed on
     this page affect and the maximal dimension of elements the algorithms
     generate. For example, \b 3D page lists the algorithms that affect
-    3D geometrical objects (solids) and generate 3D mesh elements
+    3D sub-shapes (solids) and generate 3D mesh elements
     (tetrahedra, hexahedra etc.)
 
+    As soon as you have selected an algorithm, you can create a
+    hypothesis (or select an already created one). A set of accessible
+    hypotheses includes only the hypotheses that can be used by the
+    selected algorithm.
+
     \note
-    - Some page(s) can be disabled if the source geometrical
+    - Some page(s) can be disabled if the geometrical
     object does not include shapes (sub-shapes) of the corresponding
     dimension(s). For example, if the input object is a geometrical face,
     \b 3D page is disabled.
     - Some algorithms affect the geometry of several dimensions,
-    i.e. "1D-2D" or "1D-2D-3D". If such an algorithm is selected by the
-    user, the dialog box pages related to the corresponding lower level
-    dimensions are disabled.
-    - \b 0D page does not refer to the 0D elements, but to 0D
-    geometry (vertices). Mesh module does not provide algorithms that
+    i.e. 1D+2D or 1D+2D+3D. If such an algorithm is selected, the
+    dialog pages related to the corresponding lower dimensions are
+    disabled.
+    - \b 0D page refers to 0D geometry (vertices) rather than
+    to 0D elements. Mesh module does not provide algorithms that
     produce 0D elements. Currently \b 0D page provides only one
-    algorithm "Segments around vertex" that allows specyfying the required
+    algorithm "Segments around vertex" that allows specifying the required
     size of mesh edges about the selected vertex (or vertices).
 
     For example, you need to mesh a 3D object.
 
-    First, type the name of 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 the name of the object has not yet appeared in \b Geometry field).
+    First, you can change a default name of your mesh in the \b Name
+    box. Then check that the selected geometrical object indicated in
+    \b Geometry field, is what you wish to mesh; if not, select
+    the correct object in the Object Browser. Click "Select" button
+    near \b Geometry field if the name of the object has not yet
+    appeared in \b Geometry field.
     <center>
     \image html image120.png
     <em>"Select" button</em>
     </center>
 
     Now you can define 3D Algorithm and 3D Hypotheses, which will be
-    applied to the solids of your geometrical object. Click the <em>"Add
-      Hypothesis"</em>  button to add a hypothesis.
+    applied to discretize the solids of your geometrical object using
+    3D elements. Click the <em>"Add Hypothesis"</em> button to create
+    and add a hypothesis.
     <center>
     \image html image121.png
     <em>"Add Hypothesis" button</em>
     choice of hypotheses and lower dimension algorithms depends on
     the higher dimension algorithm.
 
-    If you wish you can select different algorithms and/or hypotheses
-    for meshing some parts of your CAD model by \ref constructing_submeshes_page.
+    If you wish you can select other algorithms and/or hypotheses
+    for meshing some sub-shapes of your CAD model by \ref constructing_submeshes_page.
 
     Some algorithms generate mesh of several dimensions, while others
     produce mesh of only one dimension. In the latter case there must
     which is a 2D object, you do not need to define a 3D Algorithm and
     Hypotheses.
 
-    In the <b>Object Browser</b> the structure of the new mesh will be
+    In the <b>Object Browser</b> the structure of the new mesh is
     displayed as follows:
-
-    <center>
     \image html image88.jpg
-    </center>
-
     It contains: 
     <ul>
       <li>a mesh name (<em>Mesh_mechanic</em>);
       <li>a reference to the geometrical object on the basis of
         which the mesh has been constructed (\a mechanic);</li> 
       <li><b>Applied hypotheses</b> folder containing the references
-        to the hypotheses applied at the construction of the mesh;</li>
+        to the hypotheses chosen 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> 
+        to the algorithms chosen at the construction of the mesh.</li> 
+      <li><b>SubMeshes on Face</b> folder containing the sub-meshes
+        defined on geometrical faces. There also can be folders for
+        sub-meshes on vertices, edges, wires, shells, solids and
+        compounds.</li>
+      <li><b>Groups of Faces</b> folder containing the groups of mesh
+        faces. There also can be folders for groups of nodes, edges,
+        volumes 0D elements and balls.</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
+    pre-defined sets of algorithms and hypotheses. In addition to the built-in
     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).
-
+    file does (sets of hypotheses are enclosed between \<hypotheses-set-group\>
+      tags). For example:
+~~~~~~{.xml}
+    <?xml version='1.0' encoding='us-ascii'?>
+    <!DOCTYPE meshers PUBLIC "" "desktop.dtd">
+    <meshers>
+    <hypotheses-set-group>
+        <hypotheses-set name="My favorite hypotheses"
+                        hypos="AutomaticLength"
+                        algos="CompositeSegment_1D, Quadrangle_2D, GHS3D_3D"/>
+    </hypotheses-set-group>
+    </meshers>
+~~~~~~
+    If the file contents are incorrect, there can be an error at
+    activation of Mesh module: <em>"fatal parsing error: error
+    triggered by consumer in line ..."</em>
+<br>
+<center>
       \image html hypo_sets.png
       List of sets of hypotheses. Tag <em>[custom]</em> is
       automatically added to the sets defined by the user.
-      
-      \note \a Automatic in the names of pre-defined sets of
-      hypotheses means only that initially \ref
-      automatic_length_anchor "Automatic Length" hypothesis was
-      included in these sets, and not that these sets are suitable for
-      meshing any geometry.
+</center>
+      \note 
+      - \a "Automatic" in the names of predefined sets of hypotheses
+      does not actually mean that they are suitable for meshing any
+      geometry.
+      - The list of sets of hypotheses can be shorter than in the
+        above image depending on the geometry dimension.
   </li>
 </ol>
 
@@ -187,7 +266,9 @@ information box:
 <h2>Previewing the mesh</h2>
 
 Before \ref compute_anchor "the mesh computation", it is also possible
-to see the mesh preview.
+to see the mesh preview. This operation allows to incrementally
+compute the mesh, dimension by dimension, and to discard an
+unsatisfactory mesh.
 
 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
@@ -222,31 +303,31 @@ 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.
 
-<em>To change submesh priority:</em>
+<em>To change sub-mesh 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
+Choose "Change sub-mesh priority" from the Mesh menu or a pop-up
+menu. The opened dialog shows a list of sub-meshes in the order of
 their priority. 
 
-There is an example of submesh order modifications taking a Mesh created on a Box
+There is an example of sub-mesh order modifications taking a 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:
+The first sub-mesh <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:
+The second sub-mesh <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:
+And the last sub-mesh <b>Submesh_3</b> created on <b>Face_3</b> is:
 <ul>
   <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>
@@ -254,7 +335,7 @@ And the last submesh object <b>Submesh_3</b> created on <b>Face_3</b> is:
 
 The sub-meshes become concurrent if they share sub-shapes that can be
 meshed with different algorithms (or different hypotheses). In the
-example, we have three submeshes with concurrent algorithms, because
+example, we have three sub-meshes with concurrent algorithms, because
 they have different hypotheses.
 
 The first mesh computation is made with:
@@ -284,15 +365,15 @@ As we can see, each mesh computation has a different number of result
 elements and a different mesh discretization 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
+Additionally, sub-mesh 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. 
+modifying the order of sub-meshes. 
 <center>
 \image html mesh_order_preview.png
-<em>"Preview with submesh priority list box"</em></center>
+<em>"Preview with sub-mesh priority list box"</em></center>
 
-If there are no concurrent submeshes under the Mesh object, the user
+If there are no concurrent sub-meshes under the Mesh object, the user
 will see the following information.
 <center>
 \image html mesh_order_no_concurrent.png
@@ -305,8 +386,8 @@ will see the following information.
 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.
+the <b>Object Browser</b>. From the \b Mesh menu or the context menu
+select \b Compute or click \a "Compute" button of the toolbar.
 
 <center>
 \image html image28.png
@@ -314,26 +395,36 @@ click "Compute" button of the toolbar.
 </center>
 
 After the mesh computation finishes, the Mesh Computation information
-box appears. In case of a success, the box shows
-information on number of entities of different types in the mesh.
+box appears. If you close this box and click "Compute" button again,
+without previously changing meshing parameters, the mesh will NOT be
+re-computed and the Mesh Computation information box will be shown
+with the same contents. (To fully re-compute the mesh, invoke 
+\ref clear_mesh_anchor "Clear Mesh Data" command before). 
+
+If the mesh computation has been a success, the box shows information
+on the number of entities of different types in the mesh.
 
 \image html meshcomputationsucceed.png
 
-If the mesh computation failed, the information about the cause of the
+\anchor meshing_failed_anchor
+If the mesh computation has failed, the information about the cause of the
 failure is provided in \b Errors table.
 
 \image html meshcomputationfail.png
 
-After you select the error, <b>Show Sub-shape</b> button allows
-visualizing in magenta the geometrical entity that causes the error.
+After you select an error in \b Errors table, <b>Show Sub-shape</b> button allows
+visualizing in magenta the geometrical entity meshing of which failed
+(Name of this entity or its ID and type is shown in \a Sub-shape column).
 
+<center>
 \image html failed_computation.png 
 <em>3D algorithm failed to compute mesh on a box shown using <b>Show
     Sub-shape</b> button</em>
+</center>
 
 <b>Publish Sub-shape</b> button publishes the sub-shape, whose meshing
-has failed, in GEOM component as a child of the mesh geometry, which
-allows analyzing the problem geometry and creating a submesh on it in
+has failed, in the Geometry component as a child of the main shape, which
+allows analyzing the problematic geometry and creating a sub-mesh on it in
 order to locally tune the hypotheses.
 
 If the failure is caused by an invalid input mesh and the algorithm has
@@ -347,9 +438,11 @@ the visualization of faces and volumes (if any).
 <b>Bad Mesh to Group</b> button creates groups of bad mesh entities
 to facilitate their analysis.
 
+<center>
 \image html show_bad_mesh.png
 <em>Edges bounding a hole in the surface are shown in magenta using <b>Show
     bad Mesh</b> button</em>
+</center>
 
 \note Mesh Computation Information box does not appear if you set
 "Mesh computation/Show a computation result notification" preference 
@@ -362,12 +455,12 @@ By default, the information box is always shown after mesh computation operation
 \anchor edit_anchor
 <h2>Editing the mesh</h2>
 
-It is possible to \ref modifying_meshes_page "edit the mesh" of
-lower dimension before generation of mesh of higher dimension.
+It is possible to \ref modifying_meshes_page "edit the mesh" of a 
+lower dimension before generation of the mesh of a higher dimension.
 
-For example you can generate 2D mesh, modify it using e.g. 
-\ref pattern_mapping_page, and then generate 3D mesh basing on the
-modified 2D mesh. The workflow is following:
+For example you can generate 2D mesh, modify it using e.g. 
+\ref pattern_mapping_page, and then generate 3D mesh basing on the
+modified 2D mesh. The workflow is as follows:
 - Define 1D and 2D meshing algorithms.
 - Compute the mesh. 2D mesh is generated.
 - Apply \ref pattern_mapping_page.
@@ -376,9 +469,9 @@ and hypotheses.
 - Compute the mesh. 3D mesh is generated.
 
 \note Nodes and elements added \ref adding_nodes_and_elements_page
-"manually" can't be used in this workflow because the manually created
-entities are not attached to any geometry and thus (usually) can't be
-found by a mesher paving some geometry.
+"manually" cannot be used in this workflow because the manually created
+entities are not attached to any geometry and thus (usually) cannot be
+found by the mesher paving a geometry.
 
 <b>See Also</b> a sample TUI Script demonstrates the possibility of 
 \ref tui_editing_while_meshing "Intermediate edition while meshing"
index 782b5662ee539d38821e49c8c690df822326a585..43f99e5c599e71976cd33d0a38dfb9377b32dd54 100644 (file)
@@ -2,13 +2,20 @@
 
 \page constructing_submeshes_page Constructing sub-meshes
 
-Sub-mesh is a mesh on a geometrical sub-object (sub-shape) used to assign
-different meshing algorithms and/or hypotheses than the algorithms and
-hypotheses assigned to the parent mesh on the parent geometrical
-object, that allows getting a local mesh refinement.
+By purpose, the sub-mesh is an object used to assign to a sub-shape
+different meshing parameters than those assigned to the main shape.
 
-A sub-shape to create a sub-mesh on should be retrieved from the shape
-of the parent mesh one of the following ways: <ul>
+Structurally, the sub-mesh is a mesh on a certain sub-shape, or a group of
+sub-shapes, possibly generated using different meshing algorithms
+and/or hypotheses than those used to generate the mesh on other
+sub-shapes.
+
+Creation of a sub-mesh allows to control individually meshing of a
+certain sub-shape, thus to get a locally coarser or finer mesh, to get
+elements of different types in the same mesh, etc.
+
+A sub-shape to create a sub-mesh on should be retrieved from the main shape
+in one of the following ways: <ul>
 <li> In Geometry module, via <em>New Entity > Explode</em> menu.</li>
 <li> In Geometry module, by creation of a group (<em>New Entity >
     Group > Create Group</em> menu).</li> 
@@ -16,33 +23,53 @@ of the parent mesh one of the following ways: <ul>
   \ref subshape_by_mesh_elem "selecting a mesh element" generated on a
   sub-shape of interest. This way is accessible if the mesh is
   already computed.</li> 
+<li> In Mesh module, by clicking <em>Publish Sub-shape</em> button in a
+      dialog showing \ref meshing_failed_anchor "meshing errors".</li> 
+</ul>
+
+Internally, definition of meshing parameters to apply for
+discretization of a certain sub-shape, for example an edge of a
+compound of solids, starts from searching an algorithm, 1D as for the
+edge. The following sub-shapes are sequentially checked for presence
+of a sub-mesh where 1D algorithm is assigned:
+<ul>
+<li> the \b edge itself</li>
+<li> <b>groups of edges</b> containing the edge, if any</li>
+<li> \b wires sharing the edge</li>
+<li> \b faces sharing the edge</li>
+<li> <b>groups of faces</b> sharing the edge, if any</li>
+<li> \b shells sharing the edge</li>
+<li> \b solids sharing the edge</li>
+<li> <b>groups of solids</b> sharing the edge, if any</li>
+<li> the <b>main shape</b></li>
 </ul>
+(This sequence of sub-shapes defines the priority of sub-meshes. Thus more
+local, i.e. assigned to sub-shape of lower dimension, algorithms and
+hypotheses have higher priority during the search of hypotheses to
+apply.)
+
+As soon as a 1D algorithm is found, the search stops and the same
+sequence of sub-shapes is checked to find the main and additional 1D
+hypotheses, which can be taken into account by the found 1D algorithm. 
 
-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 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 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". The
- default sub-meshes priority is such that multi-dimensional algorithms
- are processed first.
-<br>
+The multi-dimensional algorithms have a higher priority than
+uni-dimensional ones if they are assigned to sub-meshes of the
+same priority.
+
+If meshing parameters are defined on sub-meshes of the same priority,
+for example, different 1D hypotheses are assigned to two faces sharing
+an edge, the hypothesis assigned to a sub-shape with a lower ID will
+be used for meshing. You can \ref submesh_order_anchor "change" mutual
+priority of such concurrent sub-meshes. 
 
 \n Construction of a sub-mesh consists of:
 <ul>
-<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 
+<li>Selecting a mesh which will encapsulate the sub-mesh</li>
+<li>Selecting a sub-shape for meshing</li>
+<li>Applying one or several
 \ref about_hypo_page "hypotheses" and 
 \ref basic_meshing_algos_page "meshing algorithms" which will be used
-at computation of this sub-mesh</li>
+for discretization of this sub-shape.</li>
 </ul>
 
 <br><em>To construct a sub-mesh:</em>
@@ -61,13 +88,15 @@ The following dialog box will appear:
 \par
 \image html createmesh-inv2.png
 
-\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
-sub-mesh. You can select meshing algorithms and hypotheses in the same way as
-in \ref constructing_meshes_page "Create mesh" menu.
+sub-mesh. You can define meshing algorithms and hypotheses in the same way as
+in \ref constructing_meshes_page "Create mesh" dialog. 
+
+Later you can change the applied hypotheses or their parameters in 
+\ref editing_meshes_page "Edit mesh/sub-mesh" dialog. Mesh entities
+generated using changed hypotheses are automatically removed.
 
-\par
 \anchor subshape_by_mesh_elem
 If the parent mesh is already computed, then you can define the
 \b Geometry by picking mesh elements computed on a sub-shape of interest
@@ -78,42 +107,36 @@ already down, then click it to release and then click it again. The
 following pop-up menu allowing to choose a way of geometry definition will
 appear.
 
-\par
 \image html choose_geom_selection_way.png
 
-\par
 <b>Direct geometry selection</b> enables selecting the sub-shape in the Object
 Browser.
 <b>Find geometry by mesh element selection</b> activates the following dialog.
 
-\par
 \image html find_geom_by_mesh_elem.png
 
-\par
 In this dialog, <b> Element Type </b> defines a kind of element to pick in the
 Viewer.
 Instead of picking an element in the Viewer, you can type its
 ID in <b> Element ID</b> field. 
-<b> Geometry name </b> field allows defining a name of the sub-shape
+<b> Geometry name </b> field allows defining a name of the sub-shape
 with which the sub-shape will appear in the Object Browser (if not yet
 there).
 
-\par
 In the Object Browser the structure of the new sub-mesh will be
 displayed as follows:
 
 \image html image10.jpg
 
-\par
 It contains:
 <ul>
 <li>a sub-mesh name (\a SubMeshFace1)
 <li>a reference to the geometrical object on the basis of which the
   sub-mesh has been constructed (<em>Cylindrical Face_1</em>);</li>
-<li><b>Applied hypotheses</b> folder containing the references to the
-hypotheses selected at the construction of the sub-mesh;</li>
-<li><b>Applied algorithms</b> folder containing the references to the
-algorithms selected at the construction of the sub-mesh.</li>
+<li><em>Applied hypotheses</em> folder containing the references to the
+hypotheses assigned to the sub-mesh;</li>
+<li><em>Applied algorithms</em> folder containing the references to the
+algorithms assigned to the sub-mesh.</li>
 </ul>
 
 <br><b>See Also</b> a sample TUI Script of a 
index ee68098e968f65316ff5e6e92f85e37d94a4f58b..a253c05230094f9c65032646faa07204da743119 100644 (file)
@@ -14,10 +14,11 @@ quadratic meshes.
 <em>To produce a conversion:</em>
 <ol>
 <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.
+  Viewer.</li>
+<li>From the Modification menu or from the contextual menu in the
+  Object Browser choose <b> Convert to/from Quadratic Mesh</b> item,
+  or click <em>"Convert to/from quadratic"</em> button in the
+  toolbar.
 
 <center>
 \image html image154.png
@@ -33,16 +34,14 @@ The following dialog box will appear:
 
 <ul>
 <li>If it is necessary to convert a linear mesh to quadratic or a quadratic
-  mesh to linear. **Convert to bi-quadratic** option does the same as
-  **Convert to quadratic** except for that TRIA7, QUAD9 and HEXA27
-  elements are created instead of TRIA6, QUAD8, and HEXA20 elements
-  respectively. 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>
+  mesh to linear. **Convert to bi-quadratic** creates some types of quadratic
+  elements with additional central nodes: TRIA7, QUAD9 and HEXA27
+  elements instead of TRIA6, QUAD8, and HEXA20 elements
+  respectively.</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
+  geometry** (meshed shape). This option is relevant for conversion to
   quadratic provided that the mesh is based on a geometry (not imported
-  from file).</li> 
+  from file).</li>
 </ul>
 
 \image html image156.gif
@@ -52,7 +51,7 @@ The following dialog box will appear:
 <center>Quadratic mesh</center>
 
 </li>
-<li>Click the \b Apply or \b OK button.</li>
+<li>Click the \b Apply or <b>Apply and Close</b> button.</li>
 </ol>
 
 <br><b>See Also</b> a sample TUI Script of a \ref tui_quadratic "Convert to/from quadratic" operation.
index 15bf2d129e26169a60b29b3b58360e261f3f56da..404359ce7f5f6b910d08ac70c548627bb3d63b31 100644 (file)
@@ -7,8 +7,9 @@
 <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.
+From the contextual menu in the Object Browser of 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>
@@ -24,7 +25,7 @@ In the dialog:
 <li>specify the part of mesh to copy:
 
 <ul>
-<li><b>Select the whole mesh, submesh or group</b> by mouse activating
+<li><b>Select whole mesh, sub-mesh 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> 
@@ -41,7 +42,7 @@ selection_filter_library_page "Selection filter library" page.</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>
+  the source mesh to the newly created mesh.</li>
 </ul>
 </li>
 
old mode 100755 (executable)
new mode 100644 (file)
index a09272c..009866e
@@ -2,16 +2,21 @@
 
 \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>.
+This operation allows creating groups on geometry on all selected
+shapes. Only the main shape of the mesh and its sub-shapes can be selected.
+
+The type of each new group is defined automatically by the nature of
+the <b>Geometry</b>.
+The group names will be the same as the names of geometrical objects.
+
+To use this operation, select in the \b Mesh menu or in the contextual
+menu in the Object browser <b>Create Groups from Geometry</b> item.
 
 \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>.
+In this dialog \b Elements group contains a list of shapes, on which 
+groups of elements will be created; \b Nodes group contains a list of shapes, 
+on which groups of nodes will be created.
 
 
 */
index 5dda220d1e343f2bbbe8492bfe96d8eb8db0c256..da12c8337b6b5472b33fde063a5ca0b338cbc534 100644 (file)
@@ -2,11 +2,11 @@
 
 \page creating_groups_page Creating groups
 
-\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: 
+\n In MESH you can create a \ref grouping_elements_page "group" of
+elements of a certain type. The main way to create a group, is to
+select in the \b Mesh menu <b>Create Group</b> item (also available in
+the context menu of the mesh).<br>
+To create a group you should define the following: 
 <ul>
 <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
@@ -22,13 +22,12 @@ 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>
+<li><b>Color</b> - allows to assign to the group a certain color. The
+  chosen color is used to display the elements of the group.<br>
+  Activation of <em>Auto Color</em> item in mesh context menu
+  switches on a random choice of a color for a new group.</li>
 </ul>
-SALOME Platform distinguishes between the three Group types:
+Mesh module distinguishes between the three Group types:
 <b>Standalone Group</b>, <b>Group on Geometry</b> and <b>Group on Filter</b>.
 
 \anchor standalone_group <br><h2>"Standalone Group"</h2>
@@ -37,8 +36,8 @@ SALOME Platform distinguishes between the three Group types:
 the following ways:
 <ul>
 <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
+  mesh. For this, turn on the <b>Select All</b> check-box. In this mode
+  all controls, which allow selecting the entities, are
   disabled.</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
@@ -49,14 +48,15 @@ the following ways:
   selection of the elements for your group. See more about filters on
   the \ref selection_filter_library_page "Selection filter library"
   page.</li> 
-<li>By adding entities from either a sub-mesh 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 sub-mesh or
-  a group of the appropriate type.</li>
+<li>By adding entities from either a sub-mesh or another
+  group. For this, turn on the <b>Enable manual edition</b> check
+  box. <b>Select from</b> fields group allows to select a sub-mesh or
+  a group of the appropriate type and to \b Add their elements to the
+  group.</li>
 </ul>
 In the <b>manual edition</b> mode you can
 <ul>
-<li>click the \b Remove button to remove the selected list items from
+<li>click the \b Remove button to remove the selected items from
   the list.</li>
 <li>click the <b>Sort List</b> button to sort the list of IDs of 
   mesh elements.</li>
@@ -70,9 +70,9 @@ 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> 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>
+with IDs of faces belonging to the selected 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>
@@ -87,10 +87,6 @@ is changed, the new one is not updated accordingly.
 <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>
-
 <b>See Also</b> a sample TUI Script of a 
 \ref tui_create_standalone_group "Create a Standalone Group"
 operation.  
@@ -101,14 +97,24 @@ operation.
 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.
+contents are dynamically updated if the mesh is modified. The group on
+geometry can be created only if the mesh is based on geometry.
+
+To define a group, click the \a Selection button and choose
+- <em>Direct geometry selection</em> to select a shape in the Object
+  Browser or in the Viewer;
+- <em>Find geometry by mesh element selection</em> to activate a
+  dialog which retrieves a shape by the selected element generated on
+  this shape.
+
+Note that this choice is available only if the mesh elements are
+already generated.
 
 \image html a-creategroup.png
 
+After confirmation of the operation a new group of mesh elements will
+be created.
+
 \image html image132.gif
 <center>In this picture the cells which belong to a certain
   geometrical face are selected in green.</center>
@@ -123,11 +129,13 @@ operation.
 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.
+dynamically updated if the mesh is modified.
+
+To define a group, click the <b>Set filter</b> button and define
+criteria of the filter in the opened dialog. After the
+operation is confirmed, a new group of mesh elements will be created. See more about
+filters on the 
+\ref selection_filter_library_page "Selection filter library" page. 
 
 \image html creategroup_on_filter.png
 
index 222ea8379193963d24db33e81d9a60ca72c098f0..34f26a67dd20a5be6d238176dc7c18b48f537509 100644 (file)
@@ -6,7 +6,7 @@ This operation allows cutting one or several quadrangle elements into two or fou
 
 <em>To cut quadrangles:</em>
 
-1) Display a mesh, a 2D sub-mesh or a group of faces in the 3D viewer.
+1) Select a mesh (and display it in the 3D Viewer if you are going to pick elements by mouse).
 
 2) In the \b Modification menu select the <b>Cutting of quadrangles</b> item or
 click <em>"Cutting of quadrangles"</em> button in the toolbar.
@@ -25,8 +25,9 @@ keyboard button to select several quadrangles):
   - Click \b Add button and the ID of this quadrangle will be added to the list. 
   - To remove a selected element or elements from the list click \b Remove button. 
   - <b>Sort list</b> button allows sorting the list of IDs. 
-  - \b Filter button allows applying a definite filter to the selection of quadrangles.
-- <b>Apply to all</b> check box allows cutting all quadrangles of the selected mesh, sub-mesh or group.
+  - \b Filter button allows applying a definite \ref filtering_elements "filter" 
+    to the selection of quadrangles.
+- <b>Apply to all</b> check box allows cutting all quadrangles of the selected mesh.
 - \b Preview provides a preview of cutting in the viewer. It is disabled for <b>Cut into 4 triangles</b> as this cutting way implies no ambiguity.
 - \b Criterion defines the way of cutting:
   - <b>Cut into 4 triangles</b> allows cutting a quadrangle into four triangles by inserting a new node at the center of the quadrangle. The other options allow cutting a quadrangle into two triangles by connecting the nodes of a diagonal.
@@ -36,7 +37,7 @@ keyboard button to select several quadrangles):
     - <b>Aspect Ratio</b> cuts by the diagonal splitting the quadrangle into triangles with \ref aspect_ratio_page "Aspect Ratio" closer to 1
     - <b>Minimum Angle</b> cuts by the diagonal splitting the quadrangle into triangles with \ref minimum_angle_page "Minimum Angle" closer to 60 degrees.
     - <b>Skew</b> cuts by the diagonal splitting the quadrangle into triangles with \ref skew_page "Skew" closer to 0.0 degrees.
-- <b>Select from</b> allows choosing a sub-mesh or an existing group, whose quadrangle elements will be automatically added to the main list.
+- <b>Select from</b> allows choosing a sub-mesh or an existing group, whose quadrangle elements then can be added to the main list.
 
 3) Click the \b Apply or <b>Apply and Close</b> button to confirm the operation.
 
index beb9d8e40aee62ff42d2f2c41fad79f4d6c03676..4b978245c713edd71b1144ff24826b5f594aeee0 100644 (file)
@@ -1,8 +1,12 @@
 /*!
 
-\page  use_existing_page Use Edges/Faces to be Created Manually"
+\page  use_existing_page Use Edges/Faces to be Created Manually
 
-The algorithms <b>Use Edges to be Created Manually</b> and <b>Use Faces to be Created Manually</b> allow  creating a 1D or a 2D mesh in a python script (using <em>AddNode, AddEdge</em> and <em>AddFace</em> commands) and then using such sub-meshes in the construction of a 2D or a 3D mesh. 
+The algorithms <b>Use Edges to be Created Manually</b> and 
+<b>Use Faces to be Created Manually</b> allow  creating a 1D or a 2D mesh
+in a python script (using <em>AddNode, AddEdge</em>
+and <em>AddFace</em> commands) and then using such sub-meshes in the
+construction of a 2D or a 3D mesh. 
 
 For example, you want to use standard algorithms to generate 1D and 3D
 meshes and to create 2D mesh by your python code. For this, you
index 86addcf5d8d0257d2d3abad3ad69bc2966900174..521b552823f35d4b98213eb9636006ac32d985a6 100644 (file)
@@ -2,18 +2,21 @@
 
 \page deleting_groups_page Deleting groups with content
 
-\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>
-menu. Then click <b>Apply and Close</b> button to remove the selected groups and close the
-menu or \b Apply button to remove them and proceed with the selection.
+To delete groups and their content, in the menu 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.
+
+The selected groups will be listed in <b>Delete groups with contents</b> menu. 
+Then click <b>Apply and Close</b> button to remove the selected groups
+and close the menu or \b Apply button to remove them and proceed with
+the selection.
 
 \image html deletegroups.png
-\n Please, note that this operation <b>removes groups with their
-elements</b>. To delete a group and leave its elements intact, right-click
+
+\n Please, note that this operation removes groups <b>with their
+  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>.
+menu or select the group and choose <b>Edit -> Delete</b> in the main menu.
 
 */
index 8642ebfdb85acaa1953ecad44ce955ff5e01dc0b..c97663de2fd735485ad1442ef29e972a6c1c23d4 100644 (file)
@@ -1,6 +1,6 @@
 /*!
 
-\page diagonal_inversion_of_elements_page Diagonal inversion of elements
+\page diagonal_inversion_of_elements_page Diagonal inversion of two triangles
 
 \n In MESH you can inverse the diagonal (edge) of a pseudo-quadrangle
 formed by two neighboring triangles with one common edge.
@@ -18,7 +18,8 @@ The following dialog box shall appear:
 \image html diagonalinversion.png
  
 </li>
-<li>Enter the ID of the required edge in the \b Edge field or select
+<li>Enter IDs of nodes forming the required edge in the \b Edge field
+(the node IDs must be separated by dashes) or select
 this edge in the 3D viewer.</li>
 <li>Click the \b Apply or <b>Apply and Close</b> button.</li>
 </ol>
@@ -30,4 +31,4 @@ this edge in the 3D viewer.</li>
 <br><b>See Also</b> a sample TUI Script of a 
 \ref tui_diagonal_inversion "Diagonal Inversion of Elements" operation.  
 
-*/
\ No newline at end of file
+*/
index ccd0043efbfd24267119c90e04552337b64f8239..13b11c38e337f855afdba2e5c6a0ad155526e2a6 100644 (file)
@@ -7,15 +7,17 @@ edges or combine them.
 
 \image html image56.jpg Only Faces
 
-\image html image58.gif Only Edges
+\image html image58.png Only Edges
+
+\image html image59.png Edges + Faces
 
 If the mesh contains a lot of elements, select <b>Choose...</b> item, 
 
 \image html display_entity_choose_item.png Item to call 'Display Entity' dialog box
 
-and <b>Display Entity</b> dialog box will provide a way to display only some entities at first display instead of displaying all entities long time.
+and <b>Display Entity</b> dialog box will provide a way to display only some entities at the first display instead of displaying all entities, which can take a long time.
 
 \image html display_entity_dlg.png 'Display Entity' dialog allows to select entities before displaying
 
-\note This menu item is available from popup menu in both Object browser and 3D viewer.
+\note This menu item is available from the context menu in both Object browser and 3D viewer.
 */
\ No newline at end of file
index dcdc6f491833d20c7816db4c08607ab095d53770..955d0cffeb6f6e2298dd16cb1d515d9de0c3a21c 100644 (file)
@@ -143,8 +143,8 @@ Parameters to be defined in this mode:
     The created flat volumes (or faces) are stored in groups. These groups are named
     according to the position of the group in the list of groups: group
     "j_n_p" is a group of flat elements that are built between the group \#n
-    and the group \#p in the group list. All the flat elements are gathered
-    into the group named "joints3D" (correspondingly "joints2D"). The flat element of the multiple
+    and the group \#p in the group list. All flat elements are gathered
+    into the group named "joints3D" (correspondingly "joints2D"). The flat elements of multiple
     junctions between the simple junction are stored in a group named
     "jointsMultiples".</li>
   <li> If <b>On all boundaries</b> option is activated, the volumes (or faces),
index 18b8ef654b1394300db694eeeb1a3c056040a53b..a880b1cfbc67184c4c62e1b8d03a20ee2d824273 100644 (file)
@@ -25,11 +25,12 @@ a <em>group on filter</em>. For more information see
 modification of the group.</li>
 </ol>
 
+<br>
 \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>
+a standalone group and modify its contents:</em>
 <ol>
-<li>Select your group on geometry (or on filter) in the
+<li>Select your group on geometry or on filter in the
 Object Browser and in the \b Mesh menu click the <b>Edit Group as
 Standalone</b> item.</li>
 
index 4cc70553fe34336561b80b37fd85f2a9704e67e3..a4602e6c48089e2a4b0963fb070cfa670d2f2adc 100644 (file)
@@ -16,10 +16,13 @@ You can also change values for the current hypothesis by clicking the
 \image html image122.png
 <center><em>"Edit Hypothesis" button</em></center>
 
+Mesh entities generated before using changed hypotheses are automatically removed.
+
 See how the mesh constructed on a geometrical object
-changes if we apply different algorithms to it.
+changes if we apply different meshing parameters to it.
 
 \image html edit_mesh1.png "Example of a mesh with Max. Element area 2D hypothesis roughly corresponding to 1D hypotheses on edges"
+<br>
 
 \image html edit_mesh_change_value_hyp.png "And now the Max Element area is greatly reduced"
 
index a28af48d4673c0db26d087a53363270c2fdc13b1..5a603b2291732e042761dad674ff92a07cbde40e 100644 (file)
@@ -3,8 +3,15 @@
 \page extrusion_page Extrusion
 
 \n Extrusion is used to build mesh elements of plus one
-dimension than the input ones. Any node, segment or 2D element can be
-extruded. Each type of elements has a corresponding type of extruded elements:
+dimension than the input ones. Boundary elements around generated
+mesh of plus one dimension are additionally created. All created
+elements can be automatically grouped. Extrusion can be used to create
+a \ref extrusion_struct "structured mesh from scratch".
+
+\image html extrusion_box.png "If you extrude several quadrangles, you get exactly the same mesh as if you meshed a geometrical box (except for that the initial quadrangles can be incorrectly oriented): quadrangles and segments are created on the boundary of the generated mesh"
+
+<p>Any node, segment or 2D element can be extruded. Each type of
+elements is extruded into a corresponding type of result elements:
 <table>
 <tr><td><b>Extruded element</b></td><td><b> Result element </b></td></tr>
 <tr><td>Node              </td><td> Segment </td></tr>
@@ -15,6 +22,14 @@ extruded. Each type of elements has a corresponding type of extruded elements:
 <tr><td>Hexagonal polygon </td><td> Hexagonal prism </td></tr>
 </table>
 
+When 2D elements are extruded, in addition to 3D elements segments are
+created on the ribs of the resulting 3D mesh. Free edges of input 2D elements
+generate logically horizontal rib segments. Logically vertical rib
+segments are generated from the nodes belonging to a sole input 2D element
+(the figure below illustrates this rule).
+
+\image html extru_rib_segs.png "Two triangles extruded: no vertical rib segments generated from nodes #2 and #3 as they are shared by both triangles"
+
 <em>To use extrusion:</em>
 <ol>
 <li>From the \b Modification menu choose the \b Extrusion item or click
@@ -25,61 +40,121 @@ extruded. Each type of elements has a corresponding type of extruded elements:
 <em>"Extrusion" button</em>
 </center>
 
-The following dialog common for line and planar elements will appear:
+The following dialog will appear:
 
 \image html extrusionalongaline1.png
 
-\image html extrusionalongaline2.png
-
 </li>
 
 <li>In this dialog:
 <ul>
-  <li>Select the type of elements which will be extruded (nodes, 1D or
-  2D elements).</li>
-  <li>Specify the IDs of the elements which will be extruded by one
-    following means:
+  <li>Use \a Selection button to specify what you are going to
+    select at a given moment, \b Nodes, \b Edges or \b Faces.
+    \image html image120.png
+    <center><em>"Selection" button</em></center>
+  </li>
+  <li>Specify \b Nodes, \b Edges and \b Faces, which will be extruded, by one
+    of following means:
     <ul>
-      <li><b>Select the whole mesh, submesh or group</b> activating this
-        checkbox.</li>
+      <li><b>Select the whole mesh, sub-mesh or group</b> activating the
+        corresponding check-box.</li>
       <li>Choose mesh elements with the mouse in the 3D Viewer. It is
         possible to select a whole area with a mouse frame.</li> 
-      <li>Input the element IDs directly in <b>ID Elements</b>
-        field. The selected elements will be highlighted in the viewer.</li> 
+      <li>Input the element IDs directly in <b>Node IDs</b>, <b>Edge
+        IDs</b> and <b>Face IDs</b> fields. The selected elements will
+        be highlighted in the viewer, if the mesh is shown there.</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 filtering_elements "Selection filters" 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>
-  </ul>
-  <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>
+  <li>If the <b>Extrusion to Distance</b> radio button is selected
+    - specify the translation vector by which the elements will be extruded.
+  </li>
+  <p><br></p>
+
+\image html extrusionalongaline2.png  
+
+ <li>If the <b>Extrusion Along Vector</b> radio button is selected
+    <ul>
+      <li>specify the coordinates of the \b Vector along which the elements
+        will be extruded, either directly or by selecting the mesh face (the
+        normal to the face will define the vector),</li>
+      <li>specify the \b Distance of extrusion along the vector (it can
+        be negative).</li>
+    </ul>
+  </li>
+  <p><br></p>
+
+\image html extrusionalongaline3.png  
+  
+  <li>If the <b>Extrusion By Normal</b> radio button is selected,
+    every node of the selected faces is extruded along the \a average
+    of the \a normal vectors to the faces sharing the node. (Nodes and
+    edges cannot be extruded in this mode.)
+    <ul>
+      <li>Specify the \b Distance of extrusion (it can be negative),</li>
+      <li>Use <b>Along average normal</b> check-box to specify along
+        which vector the distance is measured.
+        <ul>
+          <li>If it is \a activated the distance is measured along the
+            average normal mentioned above. </li>
+          <li>If it is \a deactivated every node is extruded along the
+            average normal till its intersection with a virtual plane obtained
+            by translation of the face sharing the node along its own normal
+            by the \b Distance.</li>
+        </ul>
+        The picture below shows a cross-section of a 2D mesh extruded
+        with <b>Along average normal</b> activated (to the left) and
+        deactivated (to the right). 
+
+        \image html extrusionbynormal_alongavgnorm.png "'Along average normal' activated (to the left) and deactivated (to the right)"
+        <p></li>
+
+      <li><b>Use only input elements</b> check-box specifies what
+        elements will be used to compute the average normal.<ul>
+          <li> If it is \a activated only selected faces, among faces
+            sharing the node, are used to compute the average normal at
+            the node. </li>
+          <li>Else all faces sharing the node are used.</li></ul>
+
+        The picture below shows a cross-section of a 2D mesh the upper
+        plane of which is extruded with <b>Use only input elements</b>
+        activated (to the left) and deactivated (to the right). 
+
+        \image html extrusionbynormal_useonly.png "'Use only input elements' activated (to the left) and deactivated (to the right)"
+        <p></li>
+  </li>
   </ul>
-  <li>Specify the number of steps.</li>
+
+  <li>Specify the <b>Number of steps</b>.</li>
   <li>If you activate <b>Generate Groups</b> check-box, the <em>result elements</em>
-    created from <em>extruded elements</em> contained in groups will be
+    created from <em>selected elements</em> contained in groups will be
     included into new groups named by pattern "<old group
-    name>_extruded" and "<old group name>_top". For example if an
-    extruded quadrangle is included in \a Group_1 group then result
-    hexahedra will be included in \a Group_1_extruded group and a
-    quadrangle created at the "top" of extruded mesh will
-    be included in \a Group_1_top group. <br>This check-box is active
-    only if there are some groups in the mesh.</li>
+    name>_extruded" and "<old group name>_top". For example if a
+    selected quadrangle is included in \a g_Faces group (see figures
+    below) then result hexahedra will be included in \a
+    g_Faces_extruded group and a quadrangle created at the "top" of
+    extruded mesh will be included in \a g_Faces_top group. <br> 
+\image html extrusion_groups.png
+\image html extrusion_groups_res.png
+    <p> This check-box is active only if there are some groups in the mesh.
+  </li>
 </ul>
 
 <li>Click \b Apply or <b> Apply and Close</b>  button to confirm the operation.</li>
 </ol>
+<p>
+
+\anchor extrusion_struct
+<h2>Example: creation of a structured mesh from scratch</h2>
 
-\image html image77.jpg "The mesh with an edge selected for extrusion"
+\image html image75.jpg "A node is extruded into a line of segments"
+<br>
+\image html image76.jpg "The line of segments is extruded into a quadrangle mesh"
+<br>
+\image html image77.jpg "The quadrangle mesh is revolved into a hexahedral mesh"
 
-\image html image76.jpg "The mesh with extruded edge" 
 
 <br><b>See Also</b> a sample TUI Script of an 
 \ref tui_extrusion "Extrusion" operation. 
index 4de60e53559b3269856e5922bd9d19fa83575d5d..03717c77fb60f1ed6d72d70c02a03bc73f8f3b6f 100644 (file)
@@ -3,8 +3,9 @@
 \page extrusion_along_path_page Extrusion along Path
 
 \n In principle, <b>Extrusion along 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 1D mesh or 1D sub-mesh. 
+as \ref extrusion_page "Extrusion", the main difference is that we
+define not a vector, but a path of extrusion which must be an 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
@@ -66,8 +67,8 @@ six coincident nodes and two coincident faces in the resulting
 mesh.</center>
 
 \image html circle_angles_after.png
-<center>The same, but using angles {45, -45, 45, -45, 45, -45, 45,
--45}</center>
+<center>The same, but using angles {45, -45, 45, -45, 45, -45, 45, -45}
+</center>
 
 <br><em>To use Extrusion along Path:</em>
 <ol>
@@ -77,75 +78,93 @@ 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 common for line and planar elements will appear:
+The following dialog will appear:
 
 \image html extrusion_along_path_dlg.png
 </li>
 
 <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><b>Select the whole mesh, sub-mesh or group</b> activating the corresponding check-box; 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 \b Path along which the elements will be extruded.<br>
-  Path definition consists of several elements:
-  <ul>
-    <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>Activate <b>Generate Groups</b> check-box if it is necessary to  copy the groups of
-  elements of the source mesh to the newly created one. </li>
+    <li>Use \a Selection button to specify what you are going to
+    select at a given moment, \b Nodes, \b Edges or \b Faces.
+\image html image120.png
+<center><em>"Selection" button</em></center>
+    </li>
+    <li>Specify \b Nodes, \b Edges and \b Faces, which will be extruded, by one
+      of following means:
+      <ul>
+        <li><b>Select the whole mesh, sub-mesh or group</b> activating this
+          check-box.</li>
+        <li>Choose mesh elements with the mouse in the 3D Viewer. It is
+          possible to select a whole area with a mouse frame.</li>
+        <li>Input the element IDs directly in <b>Node IDs</b>, <b>Edge
+            IDs</b> and <b>Face IDs</b> fields. The selected elements will
+          be highlighted in the viewer, if the mesh is shown there.</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 filtering_elements "Selection filters" page.</li>
+      </ul>
+    </li>
+    <li>Define the \b Path along which the elements will be extruded.<br>
+      Path definition consists of several elements:
+      <ul>
+        <li><b>Mesh or sub-mesh</b> - 1D mesh or sub-mesh, along which
+        proceeds the extrusion.</li>
+        <li><b>Start node</b> - the start node of the Path. It is used
+        to define the direction of extrusion. </li>
+      </ul>
+    </li>
+  <li>If you activate <b>Generate Groups</b> check-box, the <em>result elements</em>
+    created from <em>selected elements</em> contained in groups will be
+    included into new groups named by pattern "<old group
+    name>_extruded" and "<old group name>_top". For example if a
+    selected quadrangle is included in \a g_Faces group (see figures
+    below) then result hexahedra will be included in \a
+    g_Faces_extruded group and a quadrangle created at the "top" of
+    extruded mesh will be included in \a g_Faces_top group. <br> 
+\image html extrusion_groups.png
+\image html extrusion_groups_res.png
+    <p> This check-box is active only if there are some groups in the mesh.
+  </li>
 </ul>
 </li>
 
 <li>There are two optional parameters, which can be very useful:
 <ul>
 <li>If the path of extrusion is curvilinear, at each iteration the
-extruded elements are rotated to keep its initial angularity to the
-curve. By default, the <b>Base Point</b> around which the elements are rotated is
-the mass center of the elements, however, you can specify any point as
-the <b>Base Point</b> and the elements will be rotated with respect to this
-point.<br>
-  Note that only the displacement of the <b>Base Point</b> exactly equals to the 
-  path, and all other extruded elements simply keep their position relatively to the <b>Base Point</b> at each iteration.
-</li>
-<li>The elements can also be rotated around the path to get the resulting
-mesh in a helical fashion. You can set the values of angles at the
-right, add them to the list of angles at the left by pressing the <em>"Add"</em>
-button and remove them from the list by pressing the <em>"Remove"</em> button. 
-
+  extruded elements are rotated to keep its initial angularity to the
+  curve. By default, the <b>Base Point</b> around which the elements
+  are rotated is the mass center of the elements, however, you can
+  specify any point as the <b>Base Point</b> and the elements will be
+  rotated with respect to this point.<br>
+  Note that only the displacement of the <b>Base Point</b> exactly
+  equals to the path, and all other extruded elements simply keep
+  their position relatively to the <b>Base Point</b> at each
+  iteration.</li>
+<li>The elements can also be rotated around the path to get the
+  resulting mesh in a helical fashion. You can set the values of
+  angles at the right, add them to the list of angles at the left by
+  pressing the <em>"Add"</em> button and remove them from the list by
+  pressing the <em>"Remove"</em> button.
 \image html add.png
 <center><em>"Add" button</em></center>
-
 \image html remove.png
 <center><em>"Remove" button</em></center>
 
-<b>Linear variation of the angles</b> option allows defining the angle of gradual rotation for the whole path. 
-At each step the elements will be rotated by <code>angle / nb. of steps</code>. 
-
+<b>Linear variation of the angles</b> option allows defining the angle
+of gradual rotation for the whole path. At each step the elements will
+be rotated by <code>angle / nb. of steps</code>.
 </li>
 </ul>
 </li>
 
 
-<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
-duplicated nodes and faces, because no sewing is done.
+<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
+  duplicated nodes and faces, because no sewing is done.
 </li>
 </ol>
 
index 824fbd9e04a5bbb0c0dbeb8dbc2b9c2402c1a39a..3a8497c3047274f167b85acfabbff0cd567c4044 100644 (file)
@@ -2,14 +2,16 @@
 
 \page free_borders_page Free borders
 
-\n This mesh quality control highlights borders of faces consisting of
-edges belonging to one face only.
+\n This mesh quality control highlights 1D elements (segments)
+belonging to one element (face or volume) only.
 
 \image html free_borders1.png
 
-In this picture the free borders are displayed in white.
+In this picture the free borders are displayed in red. (Faces are
+explicitly shown via <em>Display Entity</em> menu as all elements but
+segments are hidden upon this control activation).
 
 <br><b>See Also</b> a sample TUI Script of a 
 \ref tui_free_borders "Free Borders quality control" operation.  
 
-*/
\ No newline at end of file
+*/
index 2d51733fca1afe8ab55c9fda25563e9e42361588..2e9d4a6ecfce814aff2c25ace9e0a5c2e76df89d 100644 (file)
@@ -2,8 +2,8 @@
 
 \page free_edges_page Free edges
 
-\n This mesh quality control highlights borders of  elements of mesh
-consisting of edges belonging to one element of mesh only.
+\n This mesh quality control highlights borders of faces
+(links between nodes, not mesh segments) belonging to one face only.
 
 \image html free_edges.png
 <center>In this picture some elements of mesh have been deleted and
@@ -12,4 +12,4 @@ the "holes" are outlined in red.</center>
 <br><b>See Also</b> a sample TUI Script of a 
 \ref tui_free_edges "Free Edges quality control" operation.  
 
-*/
\ No newline at end of file
+*/
index a6a1b91ff9feab668713c98889e4fa6b88d1edc7..7d31f73504d7dedf4e880d7d14a69081b36bf163 100755 (executable)
@@ -1,22 +1,39 @@
 /*!
 
-\page group_of_underlying_elements_page Create Group of Underlying Elements
+\page group_of_underlying_elements_page Group Based on Nodes of Other Groups
 
 
-To create groups of entities from existing groups of superior dimensions, in the \b Mesh menu select <b>Group of underlying entities</b>.<br>
+To create a standalone group of entities basing on nodes of existing
+reference groups, in the \b Mesh menu select <b>Group of underlying entities</b>.
 
 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:
+In this dialog box specify <ul>
+  <li> the resulting <b>Group name</b>, </li>
+  <li> the <b>Elements Type</b> of entities of the resulting group,</li>
+  <li> the criterion of inclusion of a mesh entity to the result group,
+    which is <b>Number of common nodes</b> of the entity and the
+    reference groups: <ul>
+      <li>\b All - include if all nodes are common;</li>
+      <li>\b Main - include if all corner nodes are common (meaningful for
+        a quadratic mesh) </li>
+      <li><b>At least one</b> - include if one or more nodes are common</li>
+      <li>\b Majority - include if half or more nodes are common</li></ul>
+  </li>
+  <li> select reference groups,</li>
+  <li> If <b>Include underlying entities only</b> option is activated
+  an entity can be included if it is based on nodes of
+  one element of a reference group.</li>
+</ul>
+
+In the figure below, there are two reference Volume groups:
 
 \image html dimgroup_src.png
-<center>Source groups</center>
+<center>Reference groups</center>
 
-In this case the following results for Faces, Edges and Nodes are obtained: 
+In this case the following results for Faces, Edges and Nodes are obtained:
 
 \image html dimgroup_2d.png
 <center>Faces</center>
@@ -27,8 +44,8 @@ In this case the following results for Faces, Edges and Nodes are obtained:
 \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"
+<b>See Also</b> a sample TUI Script of a
+\ref tui_create_dim_group "Creating groups basing on nodes of other groups"
 operation.
 
 */
index c6905cdcec047d189723aef78a29d1fed7494dbb..9548913da3b29ca9e8f5cf1a044b0c0bf8b67c6a 100644 (file)
@@ -2,45 +2,81 @@
 
 \page grouping_elements_page Grouping elements
 
-In Mesh module it is possible to create groups of mesh elements:
+In Mesh module it is possible to create groups of mesh entities:
 nodes, edges, faces, volumes, 0D elements or balls. 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.
+elements of only one type. Groups, unlike sub-meshes, are exported
+along with mesh entities into the files of following formats: MED, UNV,
+and CGNS. The group has a color attribute which is used for
+visualization only and is not exported.
+
+There are three types of groups different by their internal
+organization:<ol>
+<li><b>Standalone group</b> is a static set of mesh entities. Its
+  contents can be explicitly controlled by the user. Upon removal of
+  the entities included into the group, the group becomes empty and
+  its content can be restored only manually. Hence it is
+  reasonable to create standalone groups when the mesh generation is
+  finished and mesh quality is verified.
+  \warning Creation and edition of large standalone groups in
+  \ref creating_groups_page "Create group" dialog using manual edition
+  is problematic due to poor performance of the dialog.</li>
+  
+<li><b>Group on geometry</b> is associated to a sub-shape or a group of
+  sub-shapes of the main shape and includes mesh entities generated on
+  these geometrical entities. The association to a geometry is
+  established at group construction and cannot be changed. The group
+  contents are always updated automatically, hence the
+  group can be created even before mesh elements generation.</li>
+<li><b>Group on filter</b> encapsulates a filter, which is used to
+  select mesh entities composing the group from the whole
+  mesh. Criteria of the filter can be changed at any time. The
+  group contents are always updated automatically, hence
+  the group can be created even before mesh elements generation.</li>
+</ol>
+The group on geometry and group on filter can be converted to
+a standalone group.
+
+\image html groups_in_OB.png "Groups of different types look differently in the Object Browser"
+
+The following ways of group creation are possible:
+
+- \subpage creating_groups_page "Create group" dialog allows creation of
+  a group of any type:
+  \ref standalone_group "Standalone group",
+  \ref group_on_geom "Group on geometry" and
+  \ref group_on_filter "Group on filter" using dedicated tabs.
+- \subpage create_groups_from_geometry_page "Create Groups from Geometry"
+  dialog allows creation of several groups on geometry at once.
+- Standalone groups of all nodes and elements of the chosen sub-mesh
+  (type of elements depends on dimension of sub-mesh geometry) can
+  be created using <b>Mesh -> Construct Group</b> menu item (available
+  from the context menu as well).
+- Standalone groups of any element type can be created basing on nodes
+  of other groups - using \subpage group_of_underlying_elements_page
+  "Group based on nodes of other groups" dialog.
+- Standalone groups can be created by applying 
+  \subpage using_operations_on_groups_page "Boolean operations" to
+  other groups.
+- Creation of standalone groups is an option of many 
+  \ref modifying_meshes_page "mesh modification" operations.
 
 The created groups can be later:
 
 - \subpage editing_groups_page "Edited"
-- \subpage using_operations_on_groups_page "Subjected to Boolean operations"
-- \subpage deleting_groups_page "Deleted"
+- \subpage deleting_groups_page "Deleted", either as an object or
+  together with contained elements.
+- The group on geometry and group on filter can be 
+  \ref convert_to_standalone "converted into the standalone" group.
+- \ref importing_exporting_meshes_page "Exported" into a file as a
+  whole mesh.
 
-In the Object Browser, if groups or sub-meshes container item has more
-than one child sub-object, it is possible to sort the children in
-ascending order. For this, select the parent object in the Object
-Browser and choose <b>Sort children</b> context menu item. 
+In the Object Browser, if an item contains more than one child group,
+it is possible to sort the groups by name in ascending order
+using <b>Sort children</b> context menu item. 
 
-\image html smesh_sort.png "Sorting of sub-objects"
+\image html smesh_sort_groups.png "Sorting groups"
 
-An important tool, providing filters for creation of \b Standalone
-groups and groups <b>On Filter</b> is \ref selection_filter_library_page.
+An important tool, providing filters for creation of standalone
+groups and groups on filter is \ref selection_filter_library_page.
 
 */
index 516981cd95a856e85de3458a0a3981a0571f9f28..b8951f00a71824ad48b399acd5af4a3c9a9a2051 100644 (file)
@@ -4,8 +4,8 @@
 
 \n In MESH there is a functionality allowing import/export
 of meshes from/to \b MED, \b UNV (I-DEAS 10), \b DAT (simple ascii format), \b STL,
-\b GMF (internal format of DISTENE products, namely BLSurf, GHS3D and
-Hexotic algorithms) and \b CGNS format files. You can also export a
+\b GMF (internal format of DISTENE products, namely MG-CADSurf, MG-Tetra and
+MG-Hexa algorithms) and \b CGNS format files. You can also export a
 group as a whole mesh.
 
 
index d7a4751379887f8e85a26c96a0e3df5068182a1c..9ecb7c5f0886ac597c3170cd42dda4be700b74e2 100644 (file)
@@ -4,27 +4,43 @@
 
 \image html a-viewgeneral.png
 
-\n \b MESH module of SALOME is destined for:
+\n \b Mesh module of SALOME is destined for:
 <ul>
-<li>\subpage about_meshes_page "meshing geometrical models"
-previously created or imported by the Geometry component; </li>
-<li>\ref importing_exporting_meshes_page "import and export of meshes in various formats";</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>filtering sub-sets of mesh entities (nodes elements) using
-\subpage filters_page "Filters" functionality;</li>
+<li>\subpage about_meshes_page "creating meshes" in different ways:
+ - by meshing geometrical models previously created or imported by the
+   Geometry component; 
+ - bottom-up, using \ref modifying_meshes_page "mesh edition"
+   operations, especially \ref extrusion_page "extrusion" and \ref
+   revolution_page "revolution";
+ - by generation of the 3D mesh from the 2D mesh (the latter can be
+  either \ref importing_exporting_meshes_page "imported" or manually
+  created); 
+ </li>
+<li>\ref importing_exporting_meshes_page "importing and exporting meshes" 
+  in various formats;</li>
 <li>\subpage modifying_meshes_page "modifying meshes" with a vast
-array of dedicated operations;</li> 
-<li>various \subpage measurements_page "measurements" of the mesh objects.
+  array of dedicated operations;</li> 
+<li>\subpage grouping_elements_page "creating groups" of mesh
+  elements;</li>
+<li>filtering mesh entities (nodes or elements) using
+  \subpage filters_page "Filters" functionality for \ref
+  grouping_elements_page "creating groups" and applying \ref
+  modifying_meshes_page "mesh modifications";</li>
+<li>\subpage viewing_meshes_overview_page "viewing meshes" in
+  the VTK viewer and \ref mesh_infos_page "getting info" on mesh
+  and its sub-objects;</li>
+<li>applying to meshes \subpage quality_page "Quality Controls", 
+  allowing to highlight important elements;</li>
+<li>taking various \subpage measurements_page "measurements" of the
+  mesh objects.</li>
 </ul>
 
-It is possible to easily set parameters via the variables predefined in
-\subpage using_notebook_mesh_page "Salome notebook".
+It is possible to use the variables predefined in
+\subpage using_notebook_mesh_page "Salome notebook" to set parameters
+of operations.
 
-Mesh module preferences are described in the \subpage mesh_preferences_page section of SALOME Mesh Help.
+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".
index 4ed5b69e6a408857ce3e01af34ae6adb0c99f644..b3599ae29f4426612687f0138bb597f01b30ae26 100644 (file)
@@ -3,8 +3,7 @@
 \page length_2d_page Length 2D
 
 \n This quality control criterion consists of calculation of length of
-the edges combining the meshing elements (triangles and quadrangles)
-of your mesh.
+the links between corner nodes of mesh faces.
 
 <em>To apply the Length 2D quality criterion to your mesh:</em>
 <ol>
@@ -16,7 +15,8 @@ of your mesh.
 \image html image34.png
 <center><em>"Length 2D" button</em></center>
 
-Your mesh will be displayed in the viewer with its elements colored according to the applied mesh quality control criterion:
+Your mesh will be displayed in the viewer with links colored according
+to the applied mesh quality control criterion:
 
 \image html length2d.png
 </li>
@@ -25,4 +25,4 @@ Your mesh will be displayed in the viewer with its elements colored according to
 <br><b>See Also</b> a sample TUI Script of a 
 \ref tui_length_2d "Length 2D quality control" operation.  
 
-*/
\ No newline at end of file
+*/
index a53257eefd4a6c997f9efe564a74ab493227ffb9..3dfec30d59f7f1e9ca637d48d5ef842c797743a1 100644 (file)
@@ -3,7 +3,10 @@
 \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.
+elements of a higher dimension, for example, to create 2D elements
+around a block of 3D elements as in the following figure.
+
+\image html 2d_from_3d_example.png "Missing 2D elements were generated"
 
 <em>To generate border elements:</em>
 <ol>
@@ -25,8 +28,8 @@ the type of operation you would like to perform.</li>
 \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>
+<li><b>2D from 3D</b> creates missing mesh faces on free facets of volume elements</li>
+<li><b>1D from 2D</b> creates missing 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.
@@ -38,7 +41,7 @@ In this dialog:
   <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>
+    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
index bb65232d392ba7a78a6a0c28af05435bf713f799..6236ad02bb55d12e90363728726b0adc45494523 100644 (file)
@@ -2,63 +2,62 @@
 
 \page merging_elements_page Merging Elements
 
-\n This functionality allows to merge coincident elements of a mesh
-selectable in the dialog box.
+\n This functionality allows to merge coincident elements of a
+mesh. Two elements are considered coincident if they are based on the
+same set of nodes.
 
-\image html mergeelems_ico.png "Merge elements button"
+\image html mergeelems_ico.png "Merge elements menu button"
 
-<ol>
-<li>Choose in the main menu \b Modification -> \b Transformation -> <b>Merge elements</b> item. The following dialog box
-shall appear:</li>
+To merge elements choose in the main menu \b Modification -> \b Transformation
+-> <b>Merge elements</b> item. The following dialog box shall
+appear:
 
 \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>
+In this dialog:
 <ul>
-<li>In the \b Automatic Mode the elements created on the same nodes will be merged.</li>
-</ul>
-</li>
+  <li>\b Name is the name of the mesh object whose elements will be
+    merged.</li> 
+  <li>\b Automatic or \b Manual Mode allows choosing how the elements
+    are processed. In the \b Automatic Mode all elements created on
+    the same nodes will be merged. In \b Manual mode you can adjust
+    groups of coincident elements detected by the program.
 
-<li>If the \b Manual Mode is selected, additional controls are
-available:
+    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 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>
-<li><b>Show double elements IDs</b> checkbox shows/hides identifiers of
-elements in the 3D viewer.</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 Detect button generates the list of coincident elements found
+    in the selected object.</li>
+  <li><b>Coincident elements</b> is a list of groups of elements for
+    merging. After the operation all elements of each group will
+    be united into one element. The first element of a group is kept and
+    the others are removed.
+  <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> check-box selects all groups.</li>
+  <li><b>Show double elements IDs</b> check-box shows/hides identifiers of
+    elements of the selected groups in the 3D viewer.</li>
+  <li><b>Edit selected group of coincident elements</b> list allows
+    editing the selected group:
+    <br><br>
+    \image html add.png
+    <center>adds to the group the elements selected in the viewer.</center>
+    <br>
+    \image html remove.png
+    <center>removes the selected elements from the group.</center>
+    <br>
+    \image html sort.png
+    <center>moves the selected element to the first position in the
+      group in order to keep it in the mesh.</center>
+    <br>
+  </li>
+</ul>
+  <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 3efec052141621b51abdbe0738acbfc5f92cf19f..8aff9aa0944e5c6ba8ebdad16e85d2d47d4a22c9 100644 (file)
@@ -6,76 +6,104 @@ 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"
+\image html mergenodes_ico.png "Merge nodes menu button"
 
 <em>To merge nodes of your mesh:</em>
 <ol>
-<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:</li>
+<li>Choose \b Modification -> \b Transformation -> <b>Merge nodes</b>
+  menu item. The following dialog box 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 Automatic or \b Manual mode allows choosing how the nodes are
+  processed. In \b Manual mode you can adjust groups of coincident nodes
+  detected by the program and/or select any nodes to be merged.</li>
 <li>\b Tolerance is a maximum distance between nodes sufficient for
 merging.</li>
-<li><b>Exclude Groups</b> group box allows to ignore the nodes which
-belong to the specified mesh groups.
+<li>Activation of <b>No merge of corner and medium nodes of quadratic
+    cells</b> check-box prevents merging medium nodes of quadratic
+    elements with corner nodes. This check-box is enabled provided
+    that the selected mesh includes quadratic elements.</li>
+<li><b>Exclude groups from detection</b> group allows to ignore the
+  nodes which belong to the specified mesh groups. This control is
+  active provided that the mesh includes groups.</li>
+<li><b>Nodes to keep during the merge</b> group allows to specify
+  nodes to keep in the mesh. (By default a node being the first in a
+  group of coincident nodes is kept.) It is possible to either select
+  nodes in the Viewer or select groups of any element type whose nodes
+  will be kept.
+  <ul>
+    <li>\a Selection button activates selection of nodes to keep.</li>
+    <li><b>Nodes</b> button activates selection of nodes in the
+      Viewer.</li>
+    <li><b>Groups and sub-meshes</b> button activates selection of
+      groups and sub-meshes.</li>
+    <li>\b Add button adds selected nodes or groups to the list.</li>
+    <li> Nodes or groups selected in the list can be removed using \b
+      Remove button.</li>
+  </ul>
+</li>
 </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>
+<li>In the \b Automatic Mode all nodes within the indicated tolerance
+will be merged. The nodes which belong to the groups specified in
+<b>Exclude groups from detection</b> will NOT be taken into account.</li>
 </ul>
 </li><br>
-<li>If the \b Manual Mode is selected, additional controls are available:
+<li> The \b Manual mode gives you full control of what the operation will do.
+In this mode additional controls are available:
 <ul>
-<li>\b Detect button generates the list of coincident nodes for the given
-\b Tolerance.</li>
-<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.
+  <li>\b Detect button generates the list of coincident nodes for the given
+    \b Tolerance.</li>
+  <li><b>Coincident nodes</b> is a list of groups of nodes for
+    merging. Upon \b Apply all nodes of each group will
+    be united into one node. The first node of a group is kept and
+    the others are removed. By default the first node has a lowest ID
+    within the group.
 <ul>
 <li>\b Remove button deletes the selected group from the list.</li>
 <li>\b Add button adds to the list a group of nodes selected in the
-viewer with pressed "Shift" key.</li>
-<li><b>Select all</b> checkbox selects all groups.</li>
-<li><b>Show double nodes IDs</b> checkbox shows/hides identifiers of
-nodes in the 3D viewer.</li>
+viewer.</li>
+<li><b>Select all</b> check-box selects all groups.</li>
+<li><b>Show double nodes IDs</b> check-box shows/hides identifiers of
+nodes of selected groups in the 3D viewer.</li>
 </ul>
 
 <br>
 \image html mergenodes.png
 <br>
 </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 node selected in the viewer.</center>
-<br>
-\image html remove.png
-<center>removes from the group the selected node.</center>
-<br>
-\image html sort.png
-<center>moves the selected node to the first position in the
-group. This means that all other nodes will be merged into this
-one.</center><br>
-</li>
+  <li><b>Edit selected group of coincident nodes</b> list allows
+  editing the selected group:
+    <br><br>
+    \image html add.png
+    <center>adds to the group the nodes selected in the viewer.</center>
+    <br>
+    \image html remove.png
+    <center>removes from the group the selected nodes.</center>
+    <br>
+    \image html sort.png
+    <center>moves the selected node to the first position in the
+      group in order to keep it in the mesh.</center><br>
+  </li>
 </ul>
 </li>
 <li>To confirm your choice click \b Apply or <b>Apply and Close</b> button.</li>
 </ol>
 
-\image html merging_nodes1.png "The initial obgect" 
-
-\image html merging_nodes2.png "The object has been merged with a very big tolerance"
+\image html merging_nodes1.png 
+<center> The initial object. Nodes 25, 26 and 5 are added to <b>Nodes
+    to keep during the merge</b> group.
+</center>
+<br>
+\image html merging_nodes2.png
+<center> The object has been merged
+</center>
 
 <br><b>See Also</b> a sample TUI Script of a 
 \ref tui_merging_nodes "Merge Nodes" operation.  
index 8ead995f07ffe38d497b3246efa6c686d6860696..929deb8f3f34e98d1b8eb885ba7c8235fefecfb8 100644 (file)
@@ -14,14 +14,16 @@ in the toolbar.
 <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 advanced_mesh_infos_anchor "Base Info"</b> - to show
+  base and quantitative 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.
+  detailed information about the selected mesh nodes or elements.
+- <b>\ref mesh_addition_info_anchor "Additional Info"</b> - to show
+  additional information available for the selected mesh, sub-mesh or
+  group object. 
 - <b>\ref mesh_quality_info_anchor "Quality Info"</b> - to show
-overall quality information about the selected mesh, sub-mesh or group object.
+  overall quality information about the selected mesh, sub-mesh or group
+  object. 
 
 \anchor advanced_mesh_infos_anchor
 <h2>Base Information</h2>
@@ -43,7 +45,8 @@ information about the selected mesh node(s) or element(s), namely:
 - For a node:
   - Node ID;
   - Coordinates (X, Y, Z);
-  - Connectivity information (connected elements);
+  - Connectivity information (connected elements); double click in
+    this line reveals information about these elements;
   - Position on a shape (for meshes built on a geometry);
   - Groups information (names of groups the node belongs to).
 
@@ -55,7 +58,8 @@ information about the selected mesh node(s) or element(s), namely:
   - Element ID;
   - Type (triangle, quadrangle, etc.);
   - Gravity center (X, Y, Z coordinates);
-  - Connectivity information (connected nodes);
+  - Connectivity information (connected nodes); double click in
+    a line of a node reveals the information about this node;
   - Quality controls (area, aspect ration, volume, etc.);
   - Position on a shape (for meshes built on a geometry);
   - Groups information (names of groups the element belongs to).
@@ -63,7 +67,7 @@ information about the selected mesh node(s) or element(s), namely:
 <center>\image html eleminfo2.png 
 <em>"Element Info" page, element information</em></center>
 
-The use can either input the ID of a node or element he wants to
+The user can either input the ID of a node or element he wants to
 analyze directly in the dialog box or select the node(s) or element(s) in
 the 3D viewer.
 
@@ -152,6 +156,8 @@ button. Also, values are automatically computed if the number of
 nodes / elements does not exceed the "Automatic controls compute limit" set 
 via the "Mesh information" preferences (zero value means that there is no limit).
 
+\note The plot functionality is available only if the GUI module is built with Plot 2D Viewer (option SALOME_USE_PLOT2DVIEWER is ON when building GUI module).
+
 The button \b "Dump" allows printing the information displayed in the
 dialog box to a .txt file.
 
index e0374fd4c41e9ffba551484034ba199c5e86ea28..26efbe272d13a378a0161f22292bb56a58419bf6 100644 (file)
@@ -2,8 +2,8 @@
 
 \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.
+In the Mesh module you can set mesh preferences, which can be used right now 
+or in later sessions with this module according to the preferences.
 
 <h2>General Preferences</h2>
 
@@ -39,21 +39,22 @@ later sessions with this module.
     mesh nodes, at which they are considered coincident by <b>Double nodes</b>
     quality control.
 
-- <b>Display mode</b> - allows to set Wireframe, Shading, Nodes or Shrink
+- <b>Display mode</b>
+  - <b>Default display mode</b> - allows to set Wireframe, Shading, Nodes or Shrink
   presentation mode as default.
 
 - <b>Representation of the 2D quadratic elements</b>
-  - <b>Representation of the 2D quadratic elements</b> combobox - allows
-    to select lines or arcs for representation of quadratic elements.
+  - <b>Default mode of the 2D quadratic elements</b> combo-box - allows
+    to select lines or arcs for representation of quadratic elements as default.
   - <b>Maximum Angle</b> - maximum deviation angle used by the
     application to build arcs.
 
 - <b>Mesh export</b>
-  - If you toggle <b>Automatically create groups for MED export</b> checkbox,
+  - If you toggle <b>Automatically create groups for MED export</b> check-box,
     this operation will be carried out automatically.
 
 - <b>Mesh computation</b>
-  - <b>Show a computation result notification</b> combobox allows to
+  - <b>Show a computation result notification</b> combo-box allows to
     select the notification mode about a mesh computation result.
     There are 3 possible modes:
     - <b>Never</b> - do not show the result dialog at all;
@@ -130,13 +131,17 @@ later sessions with this module.
 
 \image html pref22.png
 
-- <b>Nodes</b>
+- <b>Nodes</b> allows to define default parameters for nodes, which will be applied 
+  for a newly created mesh only. Existing meshes can be customized using 
+  \ref colors_size_page "Properties dialog box" available from the context menu of a mesh.
   - <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.
   - <b>Type of marker</b> - allows to define the shape of nodes.
   - <b>Scale of marker</b> - allows to define the size of nodes.
 
-- <b>Elements</b>
+- <b>Elements</b> allows to define default parameters for different elements, which will be applied 
+  for a newly created mesh only. Existing meshes can be customized using 
+  \ref colors_size_page "Properties dialog box" available from the context menu of a mesh.
   - <b>Surface color</b>  - allows to select the surface color of 2D elements
     (seen in Shading mode). Click on the colored line to access to the
     <b>Select Color</b> dialog box.
@@ -149,8 +154,8 @@ later sessions with this module.
   - <b>Reversed volume color</b> - allows to select the surface color
     of reversed 3D elements. Use the slider to select the color generated basing on
     the <b>Volume color</b> by changing its brightness and saturation.
-  - <b>0D elements</b> - allows to choose color of 0D mesh elements.
-  - <b>Balls</b> - allows to choose color of discrete mesh elements (balls).
+  - <b>0D element color</b> - allows to choose color of 0D mesh elements.
+  - <b>Ball color</b> - allows to choose color of discrete mesh elements (balls).
   - <b>Outline color</b> - allows to select the color of element
     borders.
   - <b>Wireframe color</b> - allows to select the color of borders of
@@ -167,21 +172,24 @@ later sessions with this module.
   - <b>Shrink coef.</b> - allows to define relative space of elements
     compared to gaps between them in shrink mode.
 
-- <b>Groups</b> allows to define groups default properties:
+- <b>Groups</b>
   - <b>Names color</b> - specifies color of group names to be used in
     3D viewer.
-  - <b>Default color</b> - specifies default group color.
+  - <b>Default color</b> - specifies the default group color, which is used 
+  to create a new mesh group (see \ref creating_groups_page "Create Group dialog box").
 
 - <b>Numbering</b> allows to define properties of numbering functionality:
   - <b>Nodes</b> - specifies text properties of nodes numbering
     (font family, size, attributes, color).
   - <b>Elements</b> - same for elements.
 
-- <b>Orientation of Faces</b> - allows to define the behavior of
-  <b>Orientation of faces</b> functionality:
-  - \b Color - allows to define the color of orientation vertors;
+- <b>Orientation of Faces</b> - allows to define default properties of orientation vectors.
+  These preferences will be applied to the newly created meshes only; properties of existing meshes
+  can be customized using \ref colors_size_page "Properties dialog box"
+  available from the context menu of a mesh.
+  - \b Color - allows to define the color of orientation vectors;
   - \b Scale - allows to define the size of orientation vectors;
-  - <b>3D Vector</b> checkbox allows to choose between 2D planar
+  - <b>3D Vector</b> check-box allows to choose between 2D planar
     and 3D vectors.
 
 <br><h2>Selection Preferences</h2>
@@ -191,7 +199,7 @@ later sessions with this module.
 - <b>Selection</b> - performed with mouse-indexing (preselection)
   and left-clicking on an object, whose appearance changes as defined in
   the <b>Preferences</b>.
-  - <b>Object Color</b> -  allows to select the color of mesh (edges and
+  - <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.
   - <b>Element color</b> - allows to select the color of surface of selected
@@ -200,7 +208,7 @@ later sessions with this module.
 
 - <b>Preselection</b> - performed with mouse-indexing on an object,
   whose appearance changes as defined in the <b>Preferences</b>.
-  - <b>Highlight Color</b> -  allows to select the color of mesh (edges and
+  - <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.
 
@@ -211,6 +219,11 @@ later sessions with this module.
 
 \image html pref24.png
 
+\note The following settings are default and will be applied for 
+a newly created mesh only. Existing meshes 
+can be customized using local \ref scalar_bar_dlg "Scalar Bar Properties dialog box" 
+available from the context menu of a mesh.
+
 - <b>Font</b> - in this menu you can set type, face and color for
   the font of <b>Title</b> and <b>Labels</b>.
 
index a86e6986ba832fefac8c8a2a1e2cee28c11422b7..1684404ab2b52a5a170726e1c0709d9f67d6f13f 100644 (file)
@@ -3,8 +3,8 @@
 \page mesh_through_point_page Moving nodes
 
 \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.
+- by movement of the node closest to the point or 
+- by movement of a selected node to the point.
 
 <em>To displace a node:</em>
 <ol>
@@ -17,19 +17,20 @@ click <em>"Move Node"</em> button in the toolbar.
 The following dialog will appear:
 
 \image html meshtopass1.png "Manual node selection"
+<br>
 
 \image html meshtopass2.png "Automatic node selection"
+<br>
 
 </li>
 <li>Specify the way of node selection: manually (the first radio
   button) or automatically (the second radio button).</li>
-<li>If the manual method is selected, select the necessary node (X, Y,
-  Z fields show the original coordinates of the node to move) or type
+<li>If the manual method is selected, select a node to move (X, Y,
+  Z fields show the original coordinates of the node) or type
   the node ID.</li>
-<li>Enter the coordinates of the destination point.</li>
-<li>Click <b>Update Destination</b> button to set the coordinates
-  of the destination point equal to the coordinates of the node to
-  move.</li>
+<li>Enter the coordinates of the destination point. You can
+  click <b>Update Destination</b> button to set the coordinates of the
+  destination point equal to the coordinates of the node to move.</li>
 <li>Activate \b Preview check-box to show the result of move in the
   viewer.</li>
 <li>Click the \b Apply or <b>Apply and Close</b> button to confirm the
old mode 100755 (executable)
new mode 100644 (file)
index f09ab21..3490916
@@ -2,57 +2,66 @@
 
 \page modifying_meshes_page Modifying meshes
 
-Salome provides an extremely vast specter of mesh modification and
+Salome provides a vast specter of mesh modification and
 transformation operations, giving the possibility to:
 
 <ul>
 <li>\subpage adding_nodes_and_elements_page "Add" mesh elements from
-nodes to polyhedrons at an arbitrary place in the mesh.</li>
+  nodes to polyhedrons at an arbitrary place in the mesh.</li>
 <li>\subpage adding_quadratic_elements_page "Add quadratic" mesh
-elements (used in quadratic meshes) from quadratic nodes to quadratic polyhedrons at an arbitrary place in the mesh.</li>
+  elements from quadratic segments to quadratic hexahedrons at an
+  arbitrary place in the mesh.</li>
 <li>\subpage removing_nodes_and_elements_page "Remove" any existing
-mesh elements.</li>
-<li>\subpage translation_page "Translate" in the indicated direction the mesh or some of
-its elements.</li>
+  mesh elements and nodes.</li>
+<li>\subpage translation_page "Translate" in the indicated direction
+  the mesh or some of its elements.</li>
 <li>\subpage rotation_page "Rotate" by the indicated axis and angle
-the mesh or some of its elements.</li>
-<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 or/and Elements". Duplication of nodes can be useful to emulate a crack in the model.</li>
+  the mesh or some of its elements.</li>
+<li>\subpage scale_page "Scale" the mesh or some of its elements.</li>
+<li>\subpage symmetry_page "Mirror" the mesh through a point, a vector
+  or a plane of symmetry.</li>
+<li>\subpage double_nodes_page "Duplicate nodes or/and Elements". 
+  Duplication of nodes can be useful 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 Nodes", considered coincident
-within the indicated tolerance.</li>
-<li>\subpage merging_elements_page "Merge Elements", considered coincident
-within the indicated tolerance.</li>
-<li>\subpage mesh_through_point_page "Move Nodes" to an arbitrary location
-with consequent transformation of all adjacent elements and edges.</li>
-<li>\subpage diagonal_inversion_of_elements_page "Invert an edge" between neighboring triangles.</li>
+  border to side or side elements.</li>
+<li>\subpage merging_nodes_page "Merge Nodes", coincident within the
+  indicated tolerance.</li>
+<li>\subpage merging_elements_page "Merge Elements" based on the same
+  nodes.</li>
+<li>\subpage mesh_through_point_page "Move Nodes" to an arbitrary
+  location with consequent transformation of all adjacent
+  elements.</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".</li>
-<li>\subpage cutting_quadrangles_page "Cut a quadrangle" into two triangles.</li>
-<li>\subpage split_to_tetra_page "Split" volumic elements into tetrahedra or prisms.</li>
+  of the selected elements.</li>
+<li>\subpage reorient_faces_page "Orient faces" by several means.</li>
+<li>\subpage cutting_quadrangles_page "Cut a quadrangle" into two
+  triangles.</li>
+<li>\subpage split_to_tetra_page "Split" volumic elements into
+  tetrahedra or prisms.</li>
+<li>\subpage split_biquad_to_linear_page "Split bi-quadratic" elements
+  into linear ones without creation of additional nodes.</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>
+  them by adjusting the locations of nodes.</li>
+<li>Create an \subpage extrusion_page "extrusion" along a vector or by
+  normal to a discretized surface.</li>
 <li>Create an \subpage extrusion_along_path_page "extrusion along a path".</li>
-<li>Create an edge or a surface by \subpage revolution_page "revolution"
-of the selected node or edge.</li>
+<li>Create elements by \subpage revolution_page "revolution" of the
+  selected nodes and elements.</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 convert_to_from_quadratic_mesh_page "Convert linear 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>
 
-It is possible to \ref edit_anchor "modify the mesh" of lower
-dimension before generation of mesh of higher dimension.
+\note It is possible to \ref edit_anchor "modify the mesh" of a lower
+dimension before generation of the mesh of a higher dimension.
 
 <p><br></p>
 
index 969b9fc5e066a39b75acea62020432974a51864c..b42795e5d3eb2c6709c72f41f657a38a900a26a7 100644 (file)
@@ -14,17 +14,19 @@ The smp file contains 4 sections:
 
 -# 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 coordinates for a 3D pattern.
-Note, that node coordinates of a 3D pattern can be defined only by relative values in range [0;1].
+  node coordinates for a 2D pattern or 3 node coordinates 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.
+  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 is
+  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).
+  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 liner 2d elements are allowed) and 4, 5, 6 or 8
+  indices for a 3D pattern (only linear 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.
@@ -107,21 +109,24 @@ 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>
+  created manually or generated automatically from an existing mesh or
+  sub-mesh.</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>
+  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>
 </ul>
+
 Alternatively, it is possible to select <b>Refine selected mesh elements</b> 
 check-box and apply the pattern to <ul>
-<li> <b>Mesh Face</b> instead of a geometric Face</li>
-<li> and select \b Node instead of vertex.</li>
+  <li> <b>Mesh Face</b> instead of a geometric Face</li>
+  <li> and select \b Node instead of vertex.</li>
 </ul>
+
 Additionally it is possible to: <ul>
 <li> <b>Reverse the order of key-points</b>. By default, the vertices of
-     a face are ordered counterclockwise.</li>
+  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>
@@ -133,17 +138,18 @@ Additionally it is possible to: <ul>
 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>
+  created manually or generated automatically from an existing mesh or
+  sub-mesh.</li>
 <li> A 3D block (Solid) object.</li>
 <li> Two vertices that specify the order of nodes in the resulting
   mesh.</li>
 </ul>
+
 Alternatively, it is possible to select <b>Refine selected mesh elements</b> 
-checkbox and apply the pattern to
+check-box and apply the pattern to
 <ul>
-<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> 
+  <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> 
 </ul>
 Additionally it is possible to:
 <ul>
@@ -152,7 +158,7 @@ Additionally it is possible to:
 </ul>
 
 <br>
-<h3> Automatic Generation </h3>
+<h3> Automatic Pattern Generation</h3>
 
 To generate a pattern automatically from an existing mesh or sub-mesh,
 click \b New button.
@@ -164,8 +170,8 @@ The following dialog box will appear:
 In this dialog you should specify:
 
 <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
+<li> <b>Mesh or Sub-mesh</b>, which is a meshed geometrical face (for a
+2D pattern) or a meshed solid block (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 
@@ -204,17 +210,17 @@ The mapping algorithm for a 2D case is as follows:
   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
+- The coordinates 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
+  possible to find, where the points at the intersection of iso-lines
   and boundaries are mapped. Then it is possible to find
-  the direction of mapped isolinesection and, filally, the poitions of
+  the direction of mapped iso-line section and, finally, the positions 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. 
 position of the node is found as an average of the positions on mapped
 iso-lines. 
 \image html image97.gif
 
 The 3D algorithm is similar.
diff --git a/doc/salome/gui/SMESH/input/quad_from_ma_algo.doc b/doc/salome/gui/SMESH/input/quad_from_ma_algo.doc
new file mode 100644 (file)
index 0000000..e3df9e4
--- /dev/null
@@ -0,0 +1,35 @@
+/*!
+
+\page quad_from_ma_algo_page Medial Axis Projection Quadrangle meshing algorithm
+
+Medial Axis Projection algorithm can be used for meshing faces with
+sinuous borders and a channel-like shape, for which it can be
+difficult to define 1D hypotheses such that to obtain a good shape of
+resulting quadrangles. The algorithm can be also applied to faces with ring
+topology, which can be viewed as a closed 'channel'. In the latter
+case radial discretization of a ring can be specified by
+using <em>Number of Layers</em> or <em>Distribution of Layers</em>
+hypothesis.
+
+\image html quad_from_ma_mesh.png "A mesh of a river model to the left and of a ring-face to the right"
+
+The algorithm provides proper shape of quadrangles by constructing Medial
+Axis between sinuous borders of the face and using it to
+discretize the borders. (Shape of quadrangles can be not perfect at
+locations where opposite sides of a 'channel' are far from being parallel.)
+
+\image html quad_from_ma_medial_axis.png "Medial Axis between two blue sinuous borders"
+
+The Medial Axis is used in two ways:
+<ol>
+<li>If there is a sub-mesh on a sinuous border, then the nodes of
+  this border are mapped to the opposite border via the Medial
+  Axis.</li>
+<li> If there are no sub-meshes on sinuous borders, then the part of
+  the Medial Axis that can be mapped to both borders is discretized
+  using a 1D hypothesis assigned to the face or its ancestor shapes,
+  and the division points are mapped from the Medial Axis to both
+  borders to find positions of nodes.</li>
+</ol>
+
+*/
diff --git a/doc/salome/gui/SMESH/input/quad_ijk_algo.doc b/doc/salome/gui/SMESH/input/quad_ijk_algo.doc
new file mode 100644 (file)
index 0000000..1ba49dd
--- /dev/null
@@ -0,0 +1,49 @@
+/*!
+
+\page quad_ijk_algo_page Quadrangle (Mapping) meshing algorithm
+
+<b>Quadrangle (Mapping)</b> meshing algorithm is intended for creating
+all-quadrangle and quad-dominant meshes on faces without holes and
+bound by at least three edges.
+
+The algorithm can create mesh on any face but its quality and
+validity depend on two factors:
+- face shape (number of edges and boundary concavity);
+- discretization of edges.
+
+\image html quad_mesh_invalid.png "Invalid mesh on quadrilateral concave faces"
+
+The algorithm uses <em>Transfinite Interpolation</em> technique in the 
+parametric space of a face to locate nodes inside the face.
+
+The algorithm treats any face as quadrangle. If a face is bound by
+more than four edges, four most sharp vertices are considered as
+corners of the quadrangle and all edges between these vertices are
+treated as quadrangle sides. In the case of three edges, the vertex
+specified by the user is considered as a degenerated side of the
+quadrangle. 
+
+\image html quad_meshes.png "Algorithm generates a structured mesh on complex faces provided that edges are properly discretized"
+
+To get an all-quadrangle mesh you have to carefully define 1D
+hypotheses on edges of a face. To get a \b structured mesh you have to provide
+equal number of segments on opposite sides of the quadrangle. If this
+condition is not respected, the algorithm by default (without a 
+hypothesis) creates a \b quad-dominant mesh with triangles located near the
+side with the maximal number of segments. However, you can get an
+\b all-quadrangle mesh in this case by using 
+\ref hypo_quad_params_anchor "Quadrangle Parameters"
+hypothesis to specify how to make transition mesh between opposite
+sides with different number of segments, provided that certain
+conditions are respected. In any case the total number of segments must be
+even. To use \a Reduced transition method, there must be an equal number
+of segments on one pair of opposite sides.
+
+The following hypotheses help to create quadrangle meshes. 
+- \ref propagation_anchor "Propagation" additional 1D hypotheses
+  help to get an equal number of segments on the opposite sides of a
+  quadrilateral face.
+- \ref a1d_algos_anchor "Composite Side Discretization" algorithm is useful
+  to discretize several C1 continuous edges as one quadrangle side.
+
+*/
index 63f2f3bb2b69bd9e924316adbc92af99ae453d07..fd506d2b76e01ba038c55e6fca22e337604b64c0 100644 (file)
@@ -130,7 +130,7 @@ Object Browser and select Clear Mesh Data in the pop-up menu.</li>
   <li> if the mesh is computed on a geometry, then "Clear Mesh Data" removes
     all elements and nodes.</li>
   <li> if the mesh is not based on a geometry (imported, compound, created from
-    scratch etc), then "Clear Mesh Data" removes only the elements and
+    scratch etc.), then "Clear Mesh Data" removes only the elements and
     nodes computed by algorithms. If no such elements or nodes have been created, can remove nothing.</li></ul>
 
 <br><b>See Also</b> a sample TUI Script of a 
diff --git a/doc/salome/gui/SMESH/input/renumbering_nodes_and_elements.doc b/doc/salome/gui/SMESH/input/renumbering_nodes_and_elements.doc
deleted file mode 100644 (file)
index 0c0f34d..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*!
-
-\page renumbering_nodes_and_elements_page Renumbering nodes and elements
-
-\n In MESH you can renumber the nodes and elements of your mesh.
-
-<ul>
-<li>\ref renumbering_nodes_anchor "Nodes"</li>
-<li>\ref renumbering_elements_anchor "Elements"</li>
-</ul>
-
-<br>
-\anchor renumbering_nodes_anchor
-<h2>Renumbering nodes</h2>
-
-<em>To renumber the nodes of your mesh:</em>
-<ol>
-<li>In the \b Modification menu select \b Renumbering submenu and
-choose the \b Nodes item or click <em>"Renumbering nodes"</em> button
-in the toolbar.
-
-\image html image63.png
-<center><em>"Renumbering nodes" button</em></center>
-
-The following dialog box will appear:
-
-\image html renumbernodes.png
-</li>
-
-<li>Fill the \b Mesh field by selecting your mesh in the Object
-Browser or in the 3D viewer.</li>
-<li>Click the \b Apply or <b>Apply and Close</b> button to perform the operation.</li>
-</ol>
-
-<br>
-\anchor renumbering_elements_anchor
-<h2>Renumbering elements</h2>
-
-<em>To renumber the elements of your mesh:</em>
-<ol>
-<li>In the \b Modification menu select \b Renumbering submenu and
-choose the \b Elements item or click <em>"Renumbering elements"</em>
-button in the toolbar.
-
-\image html image64.png
-<center><em>"Renumbering elements" button</em></center>
-
-The following dialog box will appear:
-
-\image html renumberelements.png
-</li>
-
-<li>Fill the \b Mesh field by selecting your mesh in the Object
-Browser or in the 3D viewer.</li>
-<li>Click the \b Apply or <b>Apply and Close</b> button to perform the operation.</li>
-</ol>
-
-<br><b>See Also</b> a sample TUI Script of a 
-\ref tui_renumbering_nodes_and_elements "Renumbering Nodes and Elements" operation.  
-
-*/
\ No newline at end of file
index 519da7ef11e5a7160fd1effb8cb59f26bf2cfc0a..96072cf4392471d858d77d177900d9ef75f6c979 100644 (file)
@@ -1,23 +1,26 @@
 /*!
 
-\page reorient_faces_page Reorient faces
+\page reorient_faces_page Orient faces
 
-\n This operation allows changing orientation of faces two ways.
-<ol>
-<li> To reorient a set of neighboring faces by defining the desired
-  orientation by a vector. <br> Since the 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
-  either <ul>
-    <li> found by proximity to a given point or </li> 
-    <li> specified explicitly. </li> 
-</ul> </li>
-<li> To reorient faces with relation to adjacent volumes. </li>
-</ol>
+\n This operation allows fixing the orientation of a set of faces in
+the following ways:
+<ul>
+<li>The required orientation of a set of neighboring faces can be defined
+  by a vector giving the direction of a normal to a certain face. <br>
+  Since the direction of face normals in the set can be even opposite,
+  it is necessary to specify a \a control face, the normal to which
+  will be compared with the vector. This face can be either:
+  <ul>
+    <li>found by proximity to a given point, or</li> 
+    <li>specified explicitly.</li> 
+  </ul>
+</li>
+<li>Alternatively, the faces can be oriented relatively to the adjacent volumes.</li>
+</ul>
 
-Orientation of a face is changed by reverting the order of its nodes.
+The orientation of a face is changed by reverting the order of its nodes.
 
-<em>To change orientation of faces:</em>
+<em>To set orientation of faces:</em>
 <ol>
 <li>In the \b Modification menu select <b>Reorient faces</b>
   item or click <em>Reorient faces</em> button in the toolbar.
@@ -26,43 +29,63 @@ Orientation of a face is changed by reverting the order of its nodes.
 \image html reorient_faces_face.png
 <em>"Reorient faces" button</em>
 </center>
+</li>
 
-The following dialog box will appear:
-
-<center>
-\image html reorient_2d_point.png "First mode: to reorient adjacent faces according to a vector. The control face is found by point."
-<br>
-\image html reorient_2d_face.png "Second mode: to reorient adjacent faces according to a vector. The control face is explicitly given."
-<br>
-\image html reorient_2d_volume.png "Third mode: to reorient faces with relation to adjacent volumes."
-</center>
+<li>In the "Reorient faces" dialog box
 
-<li>In this dialog
 <ul>
-<li>Specify either of the tree operation modes.</li>
 <li>Select the \b Object (mesh, sub-mesh or group)
   containing faces to reorient, in the Object Browser or in the 3D
   Viewer.</li>
-<li>To reorient according to vector: <ul>
+
+<li>To reorient by direction of the face normal:
+    <ul>
     <li>Specify the coordinates of the \b Point by which the control face
-      will be found or the control \b Face itself. You can easy specify the \b
-      Point by either picking a node in the 3D Viewer or selecting a vertex
-      in the Object Browser. It is possible to pick the \b Face by mouse in
-      the 3D Viewer or enter its ID.</li>
+      will be found. You can specify the \b Point by picking a
+      node in the 3D Viewer or selecting a vertex in the Object
+      Browser.</li>
     <li>Set up the \b Direction vector to be compared with the normal of the
-      control face. If you pick a node in the 3D Viewer then the \b Direction
-      vector will go from the coordinate system origin to the selected node.
-      If you pick two nodes (holding Shift button) then the \b Direction vector
-      will go from the first to the second node.</li> </ul> </li>
-<li>To reorient according to volumes: <ul>
+      control face. There are following options: <ul>
+        <li>adjust vector components directly;</li>
+        <li>select a vertex in the Object Browser or a node in the 3D
+          Viewer; their coordinates will define vector components;</li>
+        <li> pick two nodes (holding Shift button), the \b Direction vector
+          will go from the first to the second node.</li>
+      </ul>
+    </ul>
+
+<br>
+<center>
+\image html reorient_2d_point.png "The orientation of adjacent faces is chosen according to a vector. The control face is found by point."
+</center>
+
+</li>
+
+<li>In the second mode it is possible to pick the \b Face by mouse in the 3D Viewer or directly input the \b Face ID in the corresponding field.
+
+<center>
+\image html reorient_2d_face.png "The orientation of adjacent faces is chosen according to a vector. The control face is explicitly given."
+</center>
+
+</li>
+
+<li>In the third mode, the faces can be reoriented according to volumes:
+    <ul>
     <li>Select an object (mesh, sub-mesh or group) containing
       reference \b Volumes, in the Object Browser or in the 3D
       Viewer.</li>
     <li>Specify whether face normals should point outside or inside
       the reference volumes using <b>Face normal outside volume</b>
-      check-box.</li></ul> </li>
-</ul>
+      check-box.</li>
+    </ul>
+
+<br>
+<center>
+\image html reorient_2d_volume.png "The orientation of faces is chosen relatively to adjacent volumes."
+</center>
+
 </li>
+</ul>
 
 <li>Click the \b Apply or <b>Apply and Close</b> button to confirm the operation.</li>
 </ol>
index 1d13bb23a321e63919dae5b3200cd08ae3c283b2..4b1d8124057b511f576c9db87c447ae61c0d29d7 100644 (file)
 
 \page revolution_page Revolution
 
-\n Revolution is a type of surface meshing by generation from
-discretized lines. It is used to build mesh elements of plus one
-dimension than the swept ones. Each swept 1D element produces one or
-more quadrangles (or triangles if one node of a rotated element lays
-on the revolution axis).
+\n Revolution is used to build mesh elements of plus one
+dimension than the input ones.  Boundary elements around generated
+mesh of plus one dimension are additionally created. All created
+elements can be automatically grouped. Revolution can be used to create
+a \ref extrusion_struct "structured mesh from scratch". 
+See \ref extrusion_page page for general information on Revolution,
+which can be viewed as extrusion along a circular path.
 
 <em>To apply revolution:</em>
 <ol>
-<li>From the \b Modification menu choose the \b Revolution item or click
-<em>"Revolution"</em> button in the toolbar.
+  <li>From the \b Modification menu choose the \b Revolution item or click
+    <em>"Revolution"</em> button in the toolbar.
 
 \image html image92.png
 <center><em>"Revolution" button</em></center>
 
-The following dialog common for line and planar elements will appear:
+The following dialog will appear:
 
 \image html revolution1.png
 
-</li>
-
-<li>
-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:
-
-
-<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>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 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>
-
-\image html revolutionsn2.png "Example of Revolution with Angle by Step"
-
-<li> Total Angle - the elements are extruded by the specified angle only once and the number of steps defines the number of iterations 
-(i.e.for Angle=30 and Number of Steps=2, the elements will be extruded by 30/2=15 degrees twice for a total of 30). </li>
-
-\image html revolutionsn1.png "Example of Revolution with Total Angle"
-
-</ul>
-</li>
-
-<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 \b Apply or <b> Apply and Close</b> button to confirm the
-operation.</li>
+  </li>
+
+  <li>In this dialog:
+    <ul>
+    <li>Use \a Selection button to specify what you are going to
+    select at a given moment, \b Nodes, \b Edges or \b Faces.
+\image html image120.png
+<center><em>"Selection" button</em></center>
+    </li>
+    <li>Specify \b Nodes, \b Edges and \b Faces, which will be revolved, by one
+      of following means:
+      <ul>
+        <li><b>Select the whole mesh, sub-mesh or group</b> activating this
+          check-box.</li>
+        <li>Choose mesh elements with the mouse in the 3D Viewer. It is
+          possible to select a whole area with a mouse frame.</li>
+        <li>Input the element IDs directly in <b>Node IDs</b>, <b>Edge
+            IDs</b> and <b>Face IDs</b> fields. The selected elements will
+          be highlighted in the viewer, if the mesh is shown there.</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 filtering_elements "Selection filters" page.</li>
+      </ul>
+    </li>
+    <li>Specify the \b Axis of revolution:
+      <ul>
+        <li>Specify the coordinates of the start \b Point of the
+          axis of revolution; either directly or by picking a node
+          in the Viewer (selection of nodes is activated as you click
+          the \a Selection button).</li>
+        <li>Specify the \b Vector of the axis in either of three ways:
+          <ul>
+            <li>directly adjust vector components;</li>
+            <li>click \a Selection button, choose <em>From Origin to
+                selected Point</em> in the opened menu and pick a node
+                in the Viewer; </li>
+            <li>click \a Selection button, chose <em>Normal to
+                selected Face</em> in the opened menu and pick a mesh
+                face in the Viewer.</li> 
+      </ul></ul>
+    </li>
+    <li>Specify the \b Angle of revolution and the <b>Number of
+        steps </b> of revolution,
+      <ul> 
+        <li> <b>Angle by Step</b> - the elements are revolved by the
+          specified angle at each step (i.e. for Angle=30 and Number of
+          Steps=3, the elements will be extruded by 30 degrees twice for a
+          total of 30*3=90)
+\image html revolutionsn2.png "Example of Revolution with Angle by Step. Angle=30 and Number of Steps=3"
+        </li>
+        <li> <b>Total Angle</b> - the elements are revolved by the
+          specified angle only once and the number of steps defines the
+          number of iterations (i.e. for Angle=30 and Number of Steps=3,
+          the elements will be revolved by 30/3=10 degrees twice for a
+          total of 30).
+\image html revolutionsn1.png "Example of Revolution with Total Angle. Angle=30 and Number of Steps=3"
+        </li>
+      </ul>
+    </li>
+    <li>Specify the \b Tolerance, which is used to detect nodes lying
+      on the axis of revolution.
+    </li>
+    <li>Activate  <b>Preview</b> check-box to see the result mesh in
+      the viewer.
+    </li>
+    <li>If you activate <b>Generate Groups</b> check-box, the <em>result elements</em>
+      created from <em>selected elements</em> contained in groups will be
+      included into new groups named by pattern "<old group
+      name>_rotated" and "<old group name>_top". For example if a
+      selected quadrangle is included in \a g_Faces group (see figures
+      below) then result hexahedra will be included in \a
+      g_Faces_rotated group and a quadrangle created at the "top" of
+      revolved mesh will be included in \a g_Faces_top group. <br> 
+\image html extrusion_groups.png
+\image html extrusion_groups_res.png
+    <p> This check-box is active only if there are some groups in the mesh.
+    </li>
+    </ul>
+  </li>
+
+  <li>Click \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 
+<br><b>See Also</b> a sample TUI Script of a
 \ref tui_revolution "Revolution" operation.
 
 */
index f6250d2e509b0ddb13a1044d0eff9f82d0d8d972..ecd2e8aa9f91a13de0121db7a528cf1c8989fc3c 100644 (file)
@@ -3,15 +3,20 @@
 \page segments_around_vertex_algo_page Segments around Vertex
 
 \n <b>Segments around Vertex</b> algorithm is considered to be a 0D meshing
-algorithm, but, of course, it doesn't mesh nodes. It allows to define
-the local size of the elements in the neighborhood of a certain
-node. If we choose an object of higher dimension, it applies to all
-its tops, i.e. corners of a box.  The 0D algorithm combines with the
-algorithms of higher dimensions, but it is not necessarily required
-for their successful implementation.
+algorithm, but, of course, it doesn't mesh vertices. It allows to define
+the local size of the segments in the neighborhood of a certain
+vertex. If we assign this algorithm to a geometrical object of higher
+dimension, it applies to all its vertices.
 
-This algorithm allows only one hypothesis.
+Length of segments near vertex is defined by <b> Length Near
+  Vertex </b> hypothesis.
+This hypothesis is used by \ref a1d_algos_anchor "Wire Discretization" or
+\ref a1d_algos_anchor "Composite Side Discretization" algorithms as
+follows: a geometrical edge is discretized according to a 1D
+  hypotheses and then nodes near vertices are modified to assure the
+  segment length required by <b> Length Near Vertex </b> hypothesis.
 
 \image html lengthnearvertex.png
 
-*/
\ No newline at end of file
+
+*/
index 02d39a54150e9478484b6603d28bf0d41478a621..7189ccc437a066e9038cedaa523cbeecccdbf3a3 100644 (file)
@@ -2,9 +2,11 @@
 
 \page selection_filter_library_page Selection filter library
 
-\n Selection filter library is a powerful tool enabling to create
-filters to be used on meshes. You can access to it from the Main Menu
-via <b>Tools / Selection filter library</b>.
+\n Selection filter library allows creating and storing in files
+the filters that can be later reused for operations on meshes. You can
+access it from the Main Menu via <b>Tools / Selection filter library</b>.
+It is also possible to save any filter by invoking the filter library
+from \a Filter dialog launched from any mesh operation.
 
 \image html selectionfilterlibrary.png
 
@@ -18,36 +20,37 @@ filter. By default it is prefixed with the corresponding entity type.
 
 \anchor filtering_elements
 
-When we use filters during group creation or another operation (by 
-clicking <b>Set Filters</b> button in the corresponding dialog), the
-menu for setting filters looks a bit differently (see the image below).
+When we use filters during group creation or another operation (by 
+clicking <b>Set Filter</b> button in the corresponding dialog), the
+dialog for setting filters looks as shown below.
 
-Each filter can be applicable to \b Nodes, \b Edges, \b Faces or \b
-Volumes. You can combine many criteria in one filter, but they all
-must be of the same <b>Entity type</b>.
-\n The \b Add button creates a new criterion at the end of the list of
+\image html a-filteronfaces.png
+
+The \b Add button creates a new criterion at the end of the list of
 criteria. The \b Insert button creates a new criterion before the
 selected criterion. The \b Remove button deletes the selected
-criterion. The \b Clear button deletes all criteria.
+criterion. The \b Clear button deletes all criteria.\n
+If there is a choice of <b>Entity type</b> in the dialog, only
+criteria of currently selected type are used to create or change a
+filter, and criteria of hidden types (if were specified) are ignored.
 \n Each <b>Entity type</b> has its specific list of criteria, however all
-filters have common syntax. For each criterion you should specify the
-<b>Threshold Value</b> and whether we search for the elements that should be
-\b More, \b Less or \b Equal to this \b Value. You can also reverse the
-sense of a criterion using \b Unary operator Not and you should
-specify logical relations between criteria using \b Binary operators
-Or and And.
-\n Some criteria should have the additional parameter of \b Tolerance.
-<br> 
-Switching on <b>Insert filter in viewer</b> checkbox limits
+filters have common syntax. The <b>Threshold Value</b> should be specified 
+for most criteria. For numerical criteria it is necessary to indicate if 
+the found elements should be \b More, \b Less or \b Equal to this
+\b Value. You can also reverse the sense of a criterion using \b Unary
+operator \a Not and you should specify logical relations between
+criteria using \b Binary operators \a Or and \a And.
+\n Some criteria have the additional parameter of \b Tolerance.<br> 
+Switching on <b>Insert filter in viewer</b> check-box limits
 selection of elements in the Viewer to the 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
+Dialog</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 deselected. If <b>Current
-Group</b> is chosen, the filter will be applied to the list of
+Dialog</b> is chosen, the filter will be applied to the list of
 elements in the current dialog and the elements rejected
 by the filter will be removed from the list.
 <br>
@@ -60,15 +63,12 @@ in the Library.
 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.
 
-\image html a-filteronfaces.png
-
 Some criteria are applicable to all <b>Entity types</b>:
 <ul><li>
-<b>Belong to Geom</b> selects entities whose all nodes
-lie on the shape defined by <b>Threshold Value</b>.
-If the threshold shape is a sub-shape of the main shape of the mesh
-the algorithm works faster, if this is any other
-shape the algorithm works slower.
+<b>Belong to Geom</b> selects entities whose all nodes lie on the
+shape defined by <b>Threshold Value</b>. If the threshold shape is a
+sub-shape of the main shape of the mesh the algorithm works faster, if
+this is any other shape the algorithm works slower.
 </li><li>
 <b>Lying on Geom</b> selects entities whose at least one node
 lies on the shape defined by the <b>Threshold Value</b>.
@@ -76,6 +76,9 @@ If the threshold shape is a sub-shape of the main shape of the mesh the
 algorithm works faster, if this is any other
 shape, the algorithm works slower.
 </li><li>
+<b>Belong to Mesh Group</b> selects entities included into the mesh group
+defined by the <b>Threshold Value</b>.
+</li><li>
 <b>Range of IDs</b> allows selection of entities with the specified
 IDs. 
 <b>Threshold Value</b> can be, for example: "1,2,3,50-60,63,67,70-78"
@@ -94,14 +97,17 @@ other parts. <b>Threshold Value</b> locating any element of the domain can be ei
 </li>
 </ul>
 
-Some criteria are applicable to all <b>Entity types</b>, except for
-<b>Nodes</b>
+Some criteria are applicable to all <b>Entity types</b> of dimension
+more than zero, i.e. to \b Edges, \b Faces and \b Volumes:
 <ul><li>
 <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 the element entity type defined by the <b>Threshold Value</b>.
+types depends on the current entity type.
+</li><li>
+<b>Entity type</b> allows selection of elements by their type defined
+as a combination of geometry type and the number of nodes.
 </li>
 </ul>
 
@@ -132,7 +138,7 @@ See also \ref tui_double_nodes_control "Double Nodes quality control".
 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
+one element (face or volume) 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.
@@ -176,8 +182,8 @@ The following criteria allow selecting mesh <b>Faces</b>:
 \ref area_page "Area quality control"), which is more, less or equal (within a given
 <b>Tolerance</b>) to the predefined <b>Threshold Value</b>.
 </li><li>
-<b>Free edges</b> selects 2D mesh elements consisting of edges belonging to 
-one element of mesh only. See also a
+<b>Free edges</b> selects 2D mesh elements having at least one 
+edge, which is not shared with other faces. See also a
 \ref free_edges_page "Free Edges quality control".
 </li><li>
 <b>Free faces</b> selects 2D mesh elements, which belong to less than two volumes.
index c3afbf1e07fe43515666cba75520fda59eac46a9..cfb6206dd34d66b6226df0465d9a8bf423ba6f5c 100644 (file)
@@ -2,7 +2,7 @@
 
 \page sewing_meshes_page Sewing meshes
 
-\n In SMESH you can sew elements of  different meshes. The current
+\n In SMESH you can sew elements of a mesh. The current
 functionality allows you to sew:
 <ul>
 <li>\ref free_borders_anchor "Free borders"</li>
@@ -13,26 +13,89 @@ functionality allows you to sew:
 
 \image html sewing.png "Sewing button"
 
-<em>To sew elements of different meshes:</em>
+<em>To sew elements of a mesh:</em>
 <ol>
 <li>From the \b Modification menu choose the \b Transformation item
 and from its sub-menu select the \b Sewing item.</li>
 <li>Check in the dialog box one of the radio buttons corresponding to
 the type of sewing 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 of sewing.</li>
+<li>Click the \b Apply or <b>Apply and Close</b> button to perform the
+  operation of sewing.</li>
 </ol>
 
+
 <br>
 \anchor free_borders_anchor
 <h2>Sew free borders</h2>
 
-This functionality allows you to unite two free borders of a 2D mesh.
+This functionality allows you to unite free borders of a 2D mesh.
+
+There are two working modes: \a Automatic and \a Manual. In the \b
+Automatic mode, the program finds free borders coincident within the
+specified tolerance and sews them. Optionally it is possible to
+visually check and correct if necessary the found free borders before
+sewing. <br>
+In the \b Manual mode you are to define borders to sew by picking
+three nodes of each of two borders.
 
 \image html sewing1.png
+<center>Default mode is \a Automatic</center>
+
+To use \b Automatic sewing:
+<ul>
+<li>Specify the mesh you want to sew by selecting it or any its part
+  (group or sub-mesh) in the Object Browser or in the VTK Viewer.</li>
+<li>Specify the \b Tolerance, within which free borders are considered
+  coincident. At the default zero \b Tolerance, the tolerance used by
+  the search algorithm is defined as one tenth of an average size of
+  elements adjacent to compared free borders.</li>
+<li>To visually check the coincident free borders found by the
+  algorithm, switch off <b>Auto Sewing</b> check-box. The controls
+  to adjust groups of coincident free borders will become available in
+  the dialog.</li>
+
+\image html sewing_auto.png
+<center>Controls to adjust groups of coincident free borders</center>
+
+<li>\b Detect button launches the algorithm of search of coincident
+  free borders.</li>
+<li>The found groups of <b>Coincident Free Borders</b> are shown in the
+  list, one group per line. Each group has its own color, which is used
+  to display the group borders in the VTK Viewer. A free border
+  within a group is designated by the IDs of its first, second and
+  last nodes within parenthesis. All borders present in the list will
+  be sewn upon \b Apply. </li>
+<li>\b Remove button removes the selected groups from the list.</li>
+<li><b>Select All</b> check-box selects all groups in the list.</li>
+<li>When a group is selected, its borders appear in <b>Edit Selected
+    Group</b> list that allows you to change this group.</li>
+<li>
+\image html sort.png
+<em>Set First</em> button moves the selected border to the
+  first position in the group, as a result other borders will be moved
+  to this border during sewing.
+</li><li>
+\image html remove.png
+<em>Remove Border</em> button removes the selected borders from the
+  group. It is active if there are more than two borders in the group.
+</li>
+<li>Selection of a border in the list allows changing its first and
+  last nodes whose IDs appear in two fields below the list. \a Arrow
+  buttons near each field move the corresponding end node by the
+  number of nodes defined by \b Step field.</li>
+<li>
+\image html swap.png
+<em>Swap</em> button swaps the first and last nodes of a
+  selected border.
+</li>
+</ul>
+
+For sewing free borders manually you should switch the \b Mode to \b
+Manual and define three points on each border: the first, the second and the
+last node:
 
-For sewing free borders you should define three points on each border:
-first, second and the last node:
+\image html sewing_manual.png
 <ul>
 <li>the first node specifies beginning of the border;</li>
 <li>the second node specifies the part of the border which should be
@@ -50,6 +113,16 @@ corresponding end nodes of two borders will be merged. Intermediate
 nodes of two borders will be either merged or inserted into faces of
 the opposite border.
 
+In practice the borders to sew often coincide and in this case it is
+difficult to specify the first and the last nodes of a border since
+they coincide with the first and the last nodes of the other
+border. To cope with this,
+\ref merging_nodes_page "merge" coincident nodes into one
+beforehand. Two figures below illustrate this approach.
+\image html sew_using_merge.png "Merge coincident nodes, which are difficult to distinguish"
+<br>
+\image html sew_after_merge.png "After merging nodes it is easy to specify border nodes"
+
 The sewing algorithm is as follows:
 <ol>
 <li>The parameter (U) of each node within a border is computed. So
@@ -158,4 +231,4 @@ nodes in 3D viewer or define them by its id.
 <b>See Also</b> a sample TUI Script of a 
 \ref tui_sew_side_elements "Sew Side Elements" operation.  
 
-*/
\ No newline at end of file
+*/
index 68db07e1c8881bf299de0fc1192b7dd4043c1255..2846b0884c24f0048d90854b6e6c2ae6e8e2289f 100644 (file)
@@ -4,11 +4,6 @@
 
 \n In SALOME 7.2, the Python interface for %Mesh has been slightly modified to offer new functionality:
 
-<ul>
-  <li>\subpage tui_execution_distribution_page</li>
-  <li>\subpage tui_auto_completion_documentation_page</li>
-</ul>
-
 \n Scripts generated for SALOME 6 and older versions must be adapted to work in SALOME 7.2 with full functionality.
 \n The compatibility mode allows old scripts to work in almost all cases, but with a warning.
 
index dc15270a8e460109cfb6310c3f97df9fc8ad15b5..801b1c9d8a4b24de5cb98973d2be67928ad10c44 100644 (file)
@@ -2,8 +2,12 @@
 
 \page smoothing_page Smoothing
 
-\n Smoothing is used to adjust the locations of element corners
-(nodes) to reduce distortions in these elements.
+\n Smoothing is used to improve quality of 2D mesh by adjusting the
+locations of element corners (nodes). 
+
+\note Depending on the chosen method and mesh geometry
+the smoothing can actually decrease the quality of elements and even
+make some elements inverted.
 
 <em>To apply smoothing to the elements of your mesh:</em>
 <ol>
@@ -23,23 +27,25 @@ The following dialog will appear:
 <ul>
 <li>specify the IDs of the elements which will be smoothed:
 <ul>
-<li><b>Select the whole mesh, submesh or group</b> activating this
-checkbox; or</li>
+<li><b>Select the whole mesh, sub-mesh or group</b> activating this
+  check-box; 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>
+  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 filters</b> button allows to apply a filter
+  to the selection of elements. See more about filters in the 
+  \ref filtering_elements "Selection filter library" page.</li>
 </ul>
 </li>
 
-<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>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 (a set of element), the nodes on
+  boundary of the element set 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
@@ -48,27 +54,26 @@ edge.
 <li>\b Centroidal smoothing pulls a node toward the
 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 fastest method. Centroidal smoothing usually
-produces  a mesh with more uniform element sizes. Both methods
-produce good results with "free" meshes.</li>
+Laplacian method will produce the mesh with the least element
+edge length. It is also the fastest method. Centroidal smoothing
+produces a mesh with more uniform element sizes.</li>
 </ul>
 
 \image html image83.gif
 
 </li>
-<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>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>   
+<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>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> check-box if it is necessary 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 that is suitable for <b>planar meshes only</b>. </li>
 </ul>
 </li>
 <li>Click \b Apply or <b> Apply and Close</b> button to confirm the operation.</li>
diff --git a/doc/salome/gui/SMESH/input/split_biquad_to_linear.doc b/doc/salome/gui/SMESH/input/split_biquad_to_linear.doc
new file mode 100644 (file)
index 0000000..ea4ac72
--- /dev/null
@@ -0,0 +1,37 @@
+/*!
+
+\page split_biquad_to_linear_page Split bi-quadratic into linear
+
+\n This functionality allows to split bi-quadratic elements into
+linear ones without creation of additional nodes.
+
+So that
+- bi-quadratic triangle will be split into 3 linear quadrangles;
+- bi-quadratic quadrangle will be split into 4 linear quadrangles;
+- tri-quadratic hexahedron will be split into 8 linear hexahedra;
+- quadratic segments adjacent to the split bi-quadratic element will
+  be split into 2 liner segments.
+
+\image html split_biquad_to_linear_mesh.png "Mesh before and after splitting"
+
+<em>To split bi-quadratic elements into linear:</em>
+<ol>
+<li>From the \b Modification menu choose the <b>Split bi-quadratic into linear</b> item or
+click <em>"Split bi-quadratic into linear"</em> button in the toolbar.
+
+\image html split_biquad_to_linear_icon.png
+<center><em>"Split bi-quadratic into linear" button</em></center>
+
+The following dialog box shall appear:
+
+\image html split_biquad_to_linear_dlg.png
+</li>
+<li>Select a mesh, groups or sub-meshes in the Object Browser or in the
+  Viewer.</li>
+<li>Click the \b Apply or <b>Apply and Close</b> button.</li>
+</ol>
+
+<br><b>See Also</b> a sample TUI Script of a \ref tui_split_biquad "Split bi-quadratic into linear" operation.
+
+*/
index fb5c4e1651bd0be0cb9f5bdba72a4f76b35e69db..b6ee36e935a981d21f70a30335ca87c53bc62f16 100644 (file)
@@ -7,7 +7,7 @@ tetrahedra or hexahedra into prisms. 2D mesh is modified accordingly.
 
 <em>To split volumes:</em>
 <ol>
-<li>Display a mesh, a sub-mesh or a group in the 3D viewer.</li>
+<li>Select a mesh, a sub-mesh or a group.</li>
 <li>In the \b Modification menu select the <b>Split Volumes</b> item or
 click <em>"Split Volumes"</em> button in the toolbar.
 
index 924e4eeb0e2e8d79c9a3880b00f55aaf4404fad7..4641ffe31d908fb20724b104043adb18eedca748 100644 (file)
@@ -5,7 +5,7 @@
 \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>
+<em>To create a symmetrical copy:</em>
 
 <ol>
 <li>From the \b Modification menu choose \b Transformation -> \b Symmetry item  or click
@@ -16,67 +16,72 @@ your mesh or some of its elements.
 One of the following dialogs will appear:
 
 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 symmetry1.png "a point" <br>
+\image html symmetry2.png "an axis" <br>
 \image html symmetry3.png "a plane (defined by a point and a normal to the plane)"
 
 </li>
 
 <li>In the dialog:
 <ul>
-<li>specify the IDs of the elements for the symmetry operation:
+<li>specify 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>
+<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 
+  \ref filtering_elements "filter" to the selection of elements.</li> 
 </ul>
 </li>
 
 <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>
+  of the point, either directly or by picking a mesh node;</li>
 <li>if the mesh is mirrored through an axis: 
 <ul>
-<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>
+<li>specify the coordinates of the start \b Point of the axis, either
+  directly or by picking a mesh node;</li>
+<li>specify the components of axis \b Vector, either directly or by
+  picking a mesh node, in which case \b Vector is defined as a shift
+  between the \b Point and the node;</li>
 </ul>
 </li>
 
 <li>if the mesh is mirrored through a plane:
 <ul>
-<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>
+<li>specify the cooordinates of the \b Point lying on the plane,
+  either directly or by picking a mesh node;</li>
+<li>specify the components of plane \b Normal, either directly or by
+  picking a mesh node, in which case \b Normal is defined as a shift
+  between the \b Point and the node.</li>
 </ul>
 </li>
 
 <li>specify the conditions of symmetry operation:
 <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>
+<li>activate <b>Move elements</b> radio button to change the location of
+  the selected elements within the current mesh;</li>
+<li>activate <b>Copy elements</b> radio button to duplicate the
+  selected elements at the new location within the current mesh;</li>
+<li>activate <b>Create as new mesh</b> radio button to create a new
+  element in a new mesh; the new mesh appears in the Object Browser
+  with the default name \a MeshName_mirrored (it is possible to change
+  this name in the adjacent box);</li>
+<li>activate <b> Copy groups </b> check-box to put new mesh entities
+  into new groups if source entities belong to some groups. New
+  groups are named by pattern "<old group name>_mirrored".</li>
 </ul>
 </li>
 </ul>
-<li>activate <b>Preview</b> checkbox to show the result of transformation in the viewer </li>
+<li>activate <b>Preview</b> check-box 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>
+  operation.</li>
 </ul>
 
 </ol>
index 143c34628a8b14fc8cb713ef200542ba03d5d966..da3ed83f65984bc275a3878fc26b5fe795c1966a 100644 (file)
@@ -3,11 +3,10 @@
 \page taper_page Taper
 
 \n \b Taper mesh quality criterion represents the ratio of the areas
-of two triangles separated by a diagonal. So it can be calculated only
-for elements consisting of 4 nodes.
+of two triangles separated by a diagonal within a quadrilateral face.
 
-  <b><center>JA=0.25 * (A1 + A2 + A3 + A4)
-  <br> TAPER= MAX(|A1/JA - 1|, |A2/JA - 1|, |A3/JA - 1|, |A4/JA - 1|)</center></b>
+  <b><center>JA = 0.25 * (A1 + A2 + A3 + A4)
+  <br> TAPER = MAX(|A1/JA - 1|, |A2/JA - 1|, |A3/JA - 1|, |A4/JA - 1|)</center></b>
 
 <br><em>To apply the Taper quality criterion to your mesh:</em>
 
index 856c7fe9b139b26324be915a903b60e922587738..cfe65fff5a46161b183718d1e5f361686354ad61 100755 (executable)
@@ -2,16 +2,18 @@
 
 \page tui_filters_page Filters usage
 
+\tableofcontents
+
 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.
+Several filtering criteria can be combined together by using logical
+operators \a AND and \a OR. In addition, a filtering criterion can
+be reverted using logical operator \a NOT.
 
-Mesh filters use the functionality of mesh quality controls to filter
+Mesh filters can 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,
@@ -300,6 +302,16 @@ Filter over-constrained volumes:
 
 \sa \ref tui_over_constrained_faces
 
+\section filter_belong_to_group Belong to Mesh Group
+
+Filter mesh entities (nodes or elements) included in a mesh group
+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_BelongToMeshGroup
+- threshold is mesh group object
+
+\tui_script{filters_belong2group.py}
+
 \section filter_belong_to_geom Belong to Geom
 
 Filter mesh entities (nodes or elements) which all nodes lie on the
@@ -404,9 +416,9 @@ entity type.
 
 \tui_script{filters_ex35.py}
 
-\section combining_filters How to combine filters with Criterion structures?
+\section combining_filters How to combine several criteria into a filter?
 
-Filters can be combined by making use of "criteria".
+Several criteria can be combined into a filter.
 
 Example :
 
index 7ceb5ebf7d3df335804156e73c12817bd4f1c6a0..107306547185e0be615e26d69d03f438370a357c 100644 (file)
 <h2>Convert mesh to/from quadratic</h2>
 \tui_script{modifying_meshes_ex26.py}
 
+<br>
+\anchor tui_split_biquad
+<h2>Split bi-quadratic into linear</h2>
+\tui_script{split_biquad.py}
+
 */
index 55843b2229c724b1f63d25df7e4051a98579f9e1..b9704a41ab49f80f3a7f717bdc69d3b0799ee6fa 100644 (file)
@@ -2,14 +2,15 @@
 
 \page uniting_set_of_triangles_page Uniting a set of triangles
 
-\n In contrast to the previous operation this one allows to unite at
-once many triangles if they have adjacent edges.
+\n It is possible to unite many neighboring triangles into
+quadrangles by deletion of the common edge.
 
 <em>To union several triangles:</em>
 <ol>
-<li>Display a mesh or a sub-mesh in the 3D viewer.</li>
+<li>Select a mesh (and display it in the 3D Viewer if you are going to
+  pick elements by mouse).</li>
 <li>In the \b Modification menu select the <b>Union of triangles</b>
-item or click <em>"Union of triangles"</em> button in the toolbar.
+  item or click <em>"Union of triangles"</em> button in the tool-bar.
 
 \image html image80.png
 <center><em>"Union of triangles" button</em></center>
@@ -20,20 +21,20 @@ The following dialog box will appear:
 
 <ul>
 <li><b>The main list</b> shall contain the triangles which will be
-united. You can click on an triangle in the 3D viewer and it will be
-highlighted. After that click the \b Add button and the ID of this
-triangle will be added to the list. To remove a selected element or
-elements from the list click the \b Remove button. The \b Sort button allows
-to sort the list of IDs. The <b>Set filter</b> button allows to apply a
-definite filter to selection of triangles.</li>
-<li><b>Apply to all</b> radio button allows to modify connectivity and
-type of all triangles of the currently displayed mesh or sub-mesh.</li>
+  united. You can click on a triangle in the 3D viewer and it will be
+  highlighted. After that click the \b Add button and the ID of this
+  triangle will be added to the list. To remove a selected element or
+  elements from the list click the \b Remove button. The \b Sort button allows
+  to sort the list of IDs. The <b>Filter</b> button allows to apply a
+  definite \ref filtering_elements "filter" to selection of triangles.</li>
+<li><b>Apply to all</b> radio button allows to apply the operation to
+  all triangles of the selected mesh.</li>
 <li><b>Preview</b> provides a preview in the viewer.</li>
 <li>\b Criterion menu allows to choose a quality criterion,
- which will be optimized to select triangles to unite.</li>
 which will be optimized to select triangles to unite.</li>
 <li><b>Select from</b> set of fields allows to choose a sub-mesh or an
-existing group whose triangle elements will be automatically added to
-the list.</li>
+  existing group whose triangle elements then can be added to the
+  list.</li>
 </ul>
 
 </li>
index 95b9fced63850c0a020faf8e85f3748ffdb481f7..f965a015f091f159b38c13a91de104f5e2a8f399 100644 (file)
@@ -2,14 +2,14 @@
 
 \page uniting_two_triangles_page Uniting two triangles
 
-\n In MESH you can union two neighboring triangles (cells) by deletion
+\n In MESH you can union two neighboring triangles by deletion
 of the common edge.
 
 <em>To unite two triangles:</em>
 <ol>
 <li>From the \b Modification menu choose the <b>Union of two
 triangles</b> item or click <em>"Union of two triangles"</em> button
-in the toolbar.
+in the tool-bar.
 
 \image html image71.png
 <center><em>"Union of two triangles" button</em></center>
@@ -19,8 +19,9 @@ The following dialog box shall appear:
 \image html unionoftwotriangles.png
 
 </li>
-<li>Enter the ID of the required edge in the \b Edge  field or select
-this edge in the 3D viewer.</li>
+<li>Enter IDs of nodes forming the required edge in the \b Edge field
+  (a couple of node IDs separated by a dash) or select this edge in
+  the 3D viewer.</li>
 <li>Click the \b Apply or <b>Apply and Close</b> button.</li>
 </ol>
 
@@ -31,4 +32,4 @@ this edge in the 3D viewer.</li>
 <br><b>See Also</b> a sample TUI Script of a 
 \ref tui_uniting_two_triangles "Uniting Two Triangles" operation.  
 
-*/
\ No newline at end of file
+*/
index 916061733dffc81dc5e9abc293b8301c1a4e72c2..a380581ab13b4d096b57d68302dd1e59237b0437 100644 (file)
@@ -1,6 +1,6 @@
 /*!
 
-\page using_operations_on_groups_page Using operations on groups
+\page using_operations_on_groups_page Boolean operations on groups
 
 \n In MESH you can perform some Boolean operations on groups, which
 belong to one and the same mesh.
@@ -120,4 +120,4 @@ group.</li>
 <b>See Also</b> a sample TUI Script of a 
 \ref tui_cut_of_groups "Cut of Groups" operation.  
 
-*/
\ No newline at end of file
+*/
index 248685579d9520764670d9577cd559f271de8e09..2472c24fa5f02da5f6cee7a15102c728aaf548fc 100644 (file)
@@ -26,8 +26,11 @@ information about 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
+<li><b>Auto Color</b> - switch on / off auto-assigning colors for the
+  groups. If switched on, a default color of a new group in 
+  \ref creating_groups_page "Create Group" dialog is chosen
+  randomly. </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>
 <li>\subpage display_mode_page "Display Mode" - allows to select between
index 2972fc5e3a6d2ce43375a6f49b6313de67ab8dcc..affd43d8422006bcb1acafde91836112e5cf7b98 100755 (executable)
@@ -4,7 +4,7 @@
   <ul>
     $navpath
     <li class="footer">
-      Copyright &copy; 2007-2014  CEA/DEN, EDF R&amp;D, OPEN CASCADE<br>
+      Copyright &copy; 2007-2015  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>
     </li>
   </ul>
index 065c8b8430fe81530b7837de6bb6426345daccca..6112e402428c423cbc16f0f0f3759b479cb6f278 100755 (executable)
@@ -1,4 +1,4 @@
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -26,7 +26,10 @@ SALOME_CONFIGURE_FILE(static/header.html.in static/header.html)
 ADD_CUSTOM_TARGET(dev_docs ${DOXYGEN_EXECUTABLE})
 
 INSTALL(CODE "FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/SMESH)")
-INSTALL(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/SMESH DESTINATION ${SALOME_INSTALL_DOC}/tui)
+INSTALL(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/SMESH 
+        DESTINATION ${SALOME_INSTALL_DOC}/tui
+        PATTERN "*.md5" EXCLUDE
+        PATTERN "*.map" EXCLUDE)
 INSTALL(FILES images/head.png DESTINATION ${SALOME_INSTALL_DOC}/tui/SMESH) 
 
 SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES SMESH)
index 41f8b4513eca011487e5d739dc07ac98b3d4d2ff..3b002f9902195f0df2a5f799404ed66efe19c21c 100755 (executable)
@@ -1,4 +1,4 @@
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 2972fc5e3a6d2ce43375a6f49b6313de67ab8dcc..affd43d8422006bcb1acafde91836112e5cf7b98 100755 (executable)
@@ -4,7 +4,7 @@
   <ul>
     $navpath
     <li class="footer">
-      Copyright &copy; 2007-2014  CEA/DEN, EDF R&amp;D, OPEN CASCADE<br>
+      Copyright &copy; 2007-2015  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>
     </li>
   </ul>
index f938e0444c40b28d1f5a5f1ea30773a77a4e0cae..92bfcc47edccd35dde49a43b332b0e2ee322d699 100755 (executable)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2012-2015  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
index 72d1b1a2d2817cd9e7cd4bc128332ffe3a182ff2..62e4ed488cf31b0d340b24ee3a0cee14ccabeaa0 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -857,11 +857,26 @@ module StdMeshers
     void GetCopySourceMesh(out boolean toCopyMesh,out boolean toCopyGroups);
   };
 
+  /*!
+   * Method of computing translation of a node at Viscous Layers construction
+   */
+  enum VLExtrusionMethod { 
+    // node is translated along normal to a surface with possible further smoothing
+    SURF_OFFSET_SMOOTH,
+    // node is translated along the average normal of surrounding faces till
+    // intersection with a neighbor face translated along its own normal 
+    // by the layers thickness
+    FACE_OFFSET,
+    // node is translated along the average normal of surrounding faces
+    // by the layers thickness
+    NODE_OFFSET
+  };
+
   /*!
    * 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)
+   * NETGEN 3D, Hexahedron(i,j,k), MG_Tetra
    */
   interface StdMeshers_ViscousLayers : SMESH::SMESH_Hypothesis
   {
@@ -892,10 +907,13 @@ module StdMeshers
     short GetNumberLayers();
 
     /*!
-     * Set factor (>1.0) of growth of layer thickness towards inside of mesh
+     * Set factor (>=1.0) of growth of layer thickness towards inside of mesh
      */
     void SetStretchFactor(in double factor) raises (SALOME::SALOME_Exception);
     double GetStretchFactor();
+
+    void SetMethod( in VLExtrusionMethod how );
+    VLExtrusionMethod GetMethod();
   };
 
   /*!
@@ -933,7 +951,7 @@ module StdMeshers
     short GetNumberLayers();
 
     /*!
-     * Set factor (>1.0) of growth of layer thickness towards inside of mesh
+     * Set factor (>=1.0) of growth of layer thickness towards inside of mesh
      */
     void SetStretchFactor(in double factor) raises (SALOME::SALOME_Exception);
     double GetStretchFactor();
@@ -1072,6 +1090,20 @@ module StdMeshers
   {
   };
 
+  /*!
+   * StdMeshers_QuadFromMedialAxis_1D2D: interface of "Quadrangle (Medial Axis Projection)" algorithm
+   */
+  interface StdMeshers_QuadFromMedialAxis_1D2D : SMESH::SMESH_2D_Algo
+  {
+  };
+
+  /*!
+   * StdMeshers_PolygonPerFace_2D: interface of "Polygon Per Face" 2D algorithm
+   */
+  interface StdMeshers_PolygonPerFace_2D : SMESH::SMESH_2D_Algo
+  {
+  };
+
   /*!
    * StdMeshers_Hexa_3D: interface of "Hexahedron (i,j,k)" algorithm
    */
index 5da26e1d18754b24d54e588bb776ab74b3b6f02f..738aa325e45af6bed4ba03ffcad84441d737a2e2 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -61,6 +61,7 @@ module SMESH
     FT_MultiConnection2D,
     FT_Length,
     FT_Length2D,
+    FT_BelongToMeshGroup,
     FT_BelongToGeom,
     FT_BelongToPlane,
     FT_BelongToCylinder,
@@ -228,6 +229,17 @@ module SMESH
    */
   interface EqualVolumes: Predicate {};
 
+  /*!
+  * Logical functor (predicate) "Belong To Mesh Group".
+  * Verify whether a mesh element is included into a mesh group
+  */
+  interface BelongToMeshGroup: Predicate
+  {
+    void SetGroup( in SMESH::SMESH_GroupBase theGroup );
+    void SetGroupID( in string theID ); // IOR or StoreName
+    SMESH::SMESH_GroupBase GetGroup();
+  };
+
   /*!
    * Logical functor (predicate) "Belong To Geometry".
    * Verify whether mesh element or node belong to pointed Geom Object
@@ -559,59 +571,60 @@ module SMESH
     /*!
     *  Create numerical functors
     */
-    MinimumAngle      CreateMinimumAngle();
-    AspectRatio       CreateAspectRatio();
-    AspectRatio3D     CreateAspectRatio3D();
-    Warping           CreateWarping();
-    Taper             CreateTaper();
-    Skew              CreateSkew();
-    Area              CreateArea();
-    Volume3D          CreateVolume3D();
+    MinimumAngle       CreateMinimumAngle();
+    AspectRatio        CreateAspectRatio();
+    AspectRatio3D      CreateAspectRatio3D();
+    Warping            CreateWarping();
+    Taper              CreateTaper();
+    Skew               CreateSkew();
+    Area               CreateArea();
+    Volume3D           CreateVolume3D();
     MaxElementLength2D CreateMaxElementLength2D();
     MaxElementLength3D CreateMaxElementLength3D();
-    Length            CreateLength();
-    Length2D          CreateLength2D();
-    MultiConnection   CreateMultiConnection();
-    MultiConnection2D CreateMultiConnection2D();
-    BallDiameter      CreateBallDiameter();
+    Length             CreateLength();
+    Length2D           CreateLength2D();
+    MultiConnection    CreateMultiConnection();
+    MultiConnection2D  CreateMultiConnection2D();
+    BallDiameter       CreateBallDiameter();
     /*!
-    *  Create logical functors ( predicates )
-    */
-    BelongToGeom      CreateBelongToGeom();
-    BelongToPlane     CreateBelongToPlane();
-    BelongToCylinder  CreateBelongToCylinder();
+     *  Create logical functors ( predicates )
+     */
+    BelongToMeshGroup  CreateBelongToMeshGroup();
+    BelongToGeom       CreateBelongToGeom();
+    BelongToPlane      CreateBelongToPlane();
+    BelongToCylinder   CreateBelongToCylinder();
     BelongToGenSurface CreateBelongToGenSurface();
 
-    LyingOnGeom       CreateLyingOnGeom();
+    LyingOnGeom        CreateLyingOnGeom();
 
-    FreeBorders       CreateFreeBorders();
-    FreeEdges         CreateFreeEdges();
-    FreeNodes         CreateFreeNodes();
-    FreeFaces         CreateFreeFaces();
+    FreeBorders        CreateFreeBorders();
+    FreeEdges          CreateFreeEdges();
+    FreeNodes          CreateFreeNodes();
+    FreeFaces          CreateFreeFaces();
 
-    EqualNodes        CreateEqualNodes();
-    EqualEdges        CreateEqualEdges();
-    EqualFaces        CreateEqualFaces();
-    EqualVolumes      CreateEqualVolumes();
+    EqualNodes         CreateEqualNodes();
+    EqualEdges         CreateEqualEdges();
+    EqualFaces         CreateEqualFaces();
+    EqualVolumes       CreateEqualVolumes();
 
-    RangeOfIds        CreateRangeOfIds();
+    RangeOfIds         CreateRangeOfIds();
 
-    BadOrientedVolume CreateBadOrientedVolume();
-    BareBorderVolume  CreateBareBorderVolume();
-    BareBorderFace    CreateBareBorderFace();
+    BadOrientedVolume  CreateBadOrientedVolume();
+    BareBorderVolume   CreateBareBorderVolume();
+    BareBorderFace     CreateBareBorderFace();
     OverConstrainedVolume CreateOverConstrainedVolume();
     OverConstrainedFace   CreateOverConstrainedFace();
-    LinearOrQuadratic CreateLinearOrQuadratic();
+    LinearOrQuadratic  CreateLinearOrQuadratic();
 
-    GroupColor        CreateGroupColor();
-    ElemGeomType      CreateElemGeomType();
-    ElemEntityType    CreateElemEntityType();
-    CoplanarFaces     CreateCoplanarFaces();
-    ConnectedElements CreateConnectedElements();
+    GroupColor         CreateGroupColor();
+    ElemGeomType       CreateElemGeomType();
+    ElemEntityType     CreateElemEntityType();
+    CoplanarFaces      CreateCoplanarFaces();
+    ConnectedElements  CreateConnectedElements();
 
     /*!
-    *  Create comparators ( predicates )
-    */
+     *  Create comparators ( predicates )
+     */
     LessThan          CreateLessThan();
     MoreThan          CreateMoreThan();
     EqualTo           CreateEqualTo();
index cb625d0b9da1fce14b190787a89b2e940f1404d0..ec43ae7146def2c40e68c18b07bde5386984ce71 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -276,16 +276,16 @@ module SMESH
       raises ( SALOME::SALOME_Exception );
 
     /*!
-     * Concatenate the given meshes into one mesh.
+     * Concatenate the given meshes or groups 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)
+    SMESH_Mesh Concatenate(in ListOfIDSources theMeshesArray,
+                           in boolean         theUniteIdenticalGroups,
+                           in boolean         theMergeNodesAndElements,
+                           in double          theMergeTolerance)
       raises ( SALOME::SALOME_Exception );
 
     /*!
@@ -296,10 +296,10 @@ module SMESH
      * theMergeNodesAndElements flag is true.
      * Create the groups of all elements from initial meshes.
      */
-    SMESH_Mesh ConcatenateWithGroups(in mesh_array theMeshesArray,
-                                     in boolean    theUniteIdenticalGroups,
-                                     in boolean    theMergeNodesAndElements,
-                                     in double     theMergeTolerance)
+    SMESH_Mesh ConcatenateWithGroups(in ListOfIDSources theMeshesArray,
+                                     in boolean         theUniteIdenticalGroups,
+                                     in boolean         theMergeNodesAndElements,
+                                     in double          theMergeTolerance)
       raises ( SALOME::SALOME_Exception );
 
     /*!
@@ -439,6 +439,79 @@ module SMESH
                           in string             theLibName,
                           in GEOM::GEOM_Object  theShapeObject,
                           in boolean            toCheckAll );
+
+
+    /*!
+     * Return indices of elements, which are located inside the sphere
+     *  \param theSource - mesh, sub-mesh or group
+     *  \param theElemType - mesh element type
+     *  \param theX - x cooridate of the center of the sphere
+     *  \param theY - y cooridate of the center of the sphere
+     *  \param theZ - y cooridate of the center of the sphere
+     *  \param theR - radius of the sphere
+     */
+    long_array GetInsideSphere( in SMESH_IDSource theSource,
+                               in ElementType    theElemType,
+                               in double theX, 
+                               in double theY, 
+                               in double theZ,
+                               in double theR );    
+
+    /*!
+     * Return indices of elements, which are located inside the box
+     *  \param theSource - mesh, sub-mesh or group
+     *  \param theElemType - mesh element type
+     *  \param theX1 - x cooridate of the first opposite point
+     *  \param theY1 - y cooridate of the first opposite point
+     *  \param theZ1 - y cooridate of the first opposite point
+     *  \param theX2 - x cooridate of the second opposite point
+     *  \param theY2 - y cooridate of the second opposite point
+     *  \param theZ2 - y cooridate of the second opposite point
+     */
+    long_array GetInsideBox( in SMESH_IDSource theSource,
+                            in ElementType    theElemType,
+                            in double theX1, 
+                            in double theY1, 
+                            in double theZ1,
+                            in double theX2,
+                            in double theY2,
+                            in double theZ2);    
+    /*!
+     * Return indices of elements, which are located inside the box
+     *  \param theSource - mesh, sub-mesh or group
+     *  \param theElemType - mesh element type
+     *  \param theX - x cooridate of the cented of the bottom face
+     *  \param theY - y cooridate of the cented of the bottom face
+     *  \param theZ - y cooridate of the cented of the bottom face
+     *  \param theDX - x cooridate of the cented of the base vector
+     *  \param theDY - y cooridate of the cented of the base vector
+     *  \param theDZ - z cooridate of the cented of the base vector
+     *  \param theH - height of the cylinder
+     *  \param theR - radius of the cylinder
+     */
+    long_array GetInsideCylinder( in SMESH_IDSource theSource,
+                                 in ElementType    theElemType,
+                                 in double theX, 
+                                 in double theY, 
+                                 in double theZ,
+                                 in double theDX,
+                                 in double theDY,
+                                 in double theDZ,
+                                 in double theH,
+                                 in double theR );    
+    /*!
+     * Return indices of elements, which are located inside the geometry
+     *  \param theSource - mesh, sub-mesh or group
+     *  \param theElemType - mesh element type
+     *  \param theGeom - geometrical object
+     *  \param theTolerance - tolerance for selection.
+     */
+    long_array GetInside( in SMESH_IDSource theSource,
+                         in ElementType    theElemType,
+                         in GEOM::GEOM_Object theGeom,
+                         in double theTolerance );    
+
+
   };
 
 };
index 399d701d9a40f61736ef49729932fabfd2c5b810..4941f14df5c8ec12a8c87d6fc708b27437313c0c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -121,7 +121,13 @@ module SMESH
      * (corresponds to the "hue" parameter of the color - must be in range [0, 360])
      */
     long GetColorNumber();
-  }; 
+
+    /*!
+     * Returns \c true if \c this group depends on the \a other via
+     * FT_BelongToMeshGroup predicate or vice versa
+     */
+    boolean IsInDependency( in SMESH_GroupBase other );
+  };
 
   /*!
    * SMESH_Group: interface of a standalone group object
@@ -170,7 +176,7 @@ module SMESH
    */
   interface SMESH_GroupOnFilter : SMESH_GroupBase
   {
-    void   SetFilter( in Filter theFilter); 
+    void   SetFilter( in Filter theFilter) raises (SALOME::SALOME_Exception)
     Filter GetFilter();
   };
 
index 65f944111e65e7e27146035c3357b9af859cc59d..ab6e7dd43c1fc2f40803cfa5d0fe7d1a6eb06eff 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -87,6 +87,13 @@ module SMESH
      * Verify whether hypothesis supports given entity type 
      */
     boolean IsDimSupported( in Dimension type );
+
+    /*!
+     * Return true if a hypothesis has parameters.
+     *
+     * This method is intended for GUI to know if "Edit" menu item sould be available
+     */
+    boolean HasParameters();
   };
 
   typedef sequence<string> ListOfHypothesisName;
index 0315022f292f85cd8b9aca475ec1e0ccd7e1aad3..2da555d91869f1c3d83304a01b089b96e084d16f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 593272ab041154ef960366d3ce0ec1811e91858a..9ede0252fd5aec967268aa8430741bc3d24c4ec7 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -66,6 +66,7 @@ module SMESH
       ADD_QUADEDGE,
       ADD_QUADTRIANGLE,
       ADD_QUADQUADRANGLE,
+      ADD_QUADPOLYGON,
       ADD_QUADTETRAHEDRON,
       ADD_QUADPYRAMID,
       ADD_QUADPENTAHEDRON,
@@ -89,18 +90,18 @@ module SMESH
 
   struct PointStruct { double x;
                        double y;
-                       double z; } ;
+                       double z; };
 
   typedef sequence<PointStruct> nodes_array;
 
-  struct DirStruct   { PointStruct PS ; } ;          // analog to OCCT gp_Vec
+  struct DirStruct   { PointStruct PS; };          // analog to OCCT gp_Vec
 
   struct AxisStruct  { double x;
                        double y;
                        double z;
                        double vx;
                        double vy;
-                       double vz; } ;
+                       double vz; };
   /*!
    * Node location on a shape
    */
@@ -132,7 +133,7 @@ module SMESH
     BALL,
     NB_ELEMENT_TYPES
   };
-  typedef sequence<ElementType> array_of_ElementType ;
+  typedef sequence<ElementType> array_of_ElementType;
 
   /*!
    * Enumeration for element geometry type, like SMDSAbs_GeometryType in SMDSAbs_ElementType.hxx
@@ -150,7 +151,8 @@ module SMESH
     Geom_PENTA,
     Geom_HEXAGONAL_PRISM,
     Geom_POLYHEDRA,
-    Geom_BALL
+    Geom_BALL,
+    Geom_LAST
   };
   
   /*!
@@ -252,6 +254,14 @@ module SMESH
     long   major, minor, release; //!< MED file version
   };
 
+  /*!
+   * Enumeration for CreateDimGroup()
+   */
+  enum NB_COMMON_NODES_ENUM
+  {
+    ALL_NODES, MAIN, AT_LEAST_ONE, MAJORITY
+  };
+
   /*!
    * Auxilary flags for advanced extrusion.
    * BOUNDARY: create or not boundary for result of extrusion
@@ -313,6 +323,11 @@ module SMESH
      * happen if mesh data is not yet fully loaded from the file of study.
      */
     boolean IsMeshInfoCorrect();
+
+    /*!
+     * Returns mesh unstructed grid information.
+     */
+    SALOMEDS::TMPFile GetVtkUgStream();
   };
 
   interface SMESH_Group;
@@ -492,14 +507,21 @@ module SMESH
       raises (SALOME::SALOME_Exception);
       
     /*!
-     *  Create groups of entities from existing groups of superior dimensions 
-     *  New group is created. System 
-     *  1) extracts all nodes from each group,
-     *  2) combines all elements of specified dimension laying on these nodes.
+     *  Create a group of entities basing on nodes of other groups.
+     *  \param [in] aListOfGroups - list of either groups, sub-meshes or filters.
+     *  \param [in] anElemType - a type of elements to include to the new group.
+     *  \param [in] name - a name of the new group.
+     *  \param [in] nbCommonNodes - criterion of inclusion of an element to the new group.
+     *  \param [in] underlyingOnly - if \c True, an element is included to the 
+     *         new group provided that it is based on nodes of an element of
+     *         \a aListOfGroups
+     *  \return SMESH_Group - the created group
      */
-    SMESH_Group CreateDimGroup( in ListOfGroups aListOfGroups,
-                                in ElementType  anElemType,
-                                in string       name )
+    SMESH_Group CreateDimGroup( in ListOfIDSources      aListOfGroups,
+                                in ElementType          anElemType,
+                                in string               name,
+                                in NB_COMMON_NODES_ENUM nbCommonNodes,
+                                in boolean              underlyingOnly )
       raises (SALOME::SALOME_Exception);
 
     /*!
@@ -757,6 +779,9 @@ module SMESH
     long NbPolygons()
       raises (SALOME::SALOME_Exception);
 
+    long NbPolygonsOfOrder(in ElementOrder order)
+      raises (SALOME::SALOME_Exception);
+
     long NbVolumes()
       raises (SALOME::SALOME_Exception);
 
@@ -1019,7 +1044,7 @@ module SMESH
       raises (SALOME::SALOME_Exception);
     
     /*!
-     * Return type of submesh element
+     * Returns type of mesh element (same as SMESH_Mesh::GetElementType() )
      */
     ElementType GetElementType( in long id, in boolean iselem )
       raises (SALOME::SALOME_Exception);
index 293c8c8de10205af43ea45e8139b45cca64cb022..8c63fdbdab7dc8a9eb4e57da139fe1d08ef25781 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 
 module SMESH
 {
+  interface NumericalFunctor;
+
   enum Bnd_Dimension { BND_2DFROM3D, BND_1DFROM3D, BND_1DFROM2D };
 
+
+  struct FreeBorder
+  {
+    SMESH::long_array nodeIDs; // all nodes defining a free border
+    // 1st and last node is same in a closed border
+  };
+  struct FreeBorderPart
+  {
+    short border; // border index within a sequence<FreeBorder>
+    long  node1;  // node index within the border-th FreeBorder
+    long  node2;
+    long  nodeLast;
+  };
+  typedef sequence<FreeBorder>       ListOfFreeBorders;
+  typedef sequence<FreeBorderPart>   FreeBordersGroup;
+  typedef sequence<FreeBordersGroup> ListOfFreeBorderGroups;
+
+  struct CoincidentFreeBorders
+  {
+    ListOfFreeBorders      borders;          // nodes of all free borders
+    ListOfFreeBorderGroups coincidentGroups; // groups of coincident parts of borders
+  };
+
+
   /*!
    * This interface makes modifications on the Mesh - removing elements and nodes etc.
    */
-  interface NumericalFunctor;
-
   interface SMESH_MeshEditor
   {
+   /*!
+    * Returns a mesh subject to edition
+    */
+    SMESH_Mesh GetMesh();
+
    /*!
     * Return data of mesh edition preview which is computed provided
-    * that the editor was obtained trough SMESH_Mesh::GetMeshEditPreviewer()
+    * that the editor was obtained through SMESH_Mesh::GetMeshEditPreviewer()
     */
     MeshPreviewStruct GetPreviewData() raises (SALOME::SALOME_Exception);
 
    /*!
     * If during last operation of MeshEditor some nodes were
-    * created this method returns list of their IDs, if new nodes
+    * created, this method returns list of their IDs, if new nodes
     * not created - returns empty list
     */
     long_array GetLastCreatedNodes() raises (SALOME::SALOME_Exception);
 
    /*!
     * If during last operation of MeshEditor some elements were
-    * created this method returns list of their IDs, if new elements
+    * created, this method returns list of their IDs, if new elements
     * not created - returns empty list
     */
     long_array GetLastCreatedElems() raises (SALOME::SALOME_Exception);
@@ -138,6 +167,13 @@ module SMESH
 
     long AddPolygonalFace(in long_array IdsOfNodes) raises (SALOME::SALOME_Exception);
 
+    /*!
+     * Create a quadratic polygonal face
+     *  \param IdsOfNodes - nodes of the polygon; corner nodes follow first
+     *  \return long - ID of a new polygon
+     */
+    long AddQuadPolygonalFace(in long_array IdsOfNodes) raises (SALOME::SALOME_Exception);
+
     /*!
      *  Create volume, either linear and quadratic (this is determed
      *  by number of given nodes).
@@ -348,13 +384,25 @@ module SMESH
      *         to \a facetToSplitNormal location are split, else \a facetToSplitNormal
      *         is used to find the facet to split in all domains present in \a elems.
      */
-    void SplitHexahedraIntoPrisms(in SMESH_IDSource     elems, 
+    void SplitHexahedraIntoPrisms(in SMESH_IDSource     elems,
                                   in SMESH::PointStruct startHexPoint,
                                   in SMESH::DirStruct   facetToSplitNormal,
                                   in short              methodFlags,
                                   in boolean            allDomains)
       raises (SALOME::SALOME_Exception);
 
+    /*!
+     * \brief Split bi-quadratic elements into linear ones without creation of additional nodes.
+     *   - bi-quadratic triangle will be split into 3 linear quadrangles;
+     *   - bi-quadratic quadrangle will be split into 4 linear quadrangles;
+     *   - tri-quadratic hexahedron will be split into 8 linear hexahedra;
+     *   Quadratic elements of lower dimension  adjacent to the split bi-quadratic element
+     *   will be split in order to keep the mesh conformal.
+     *  \param elems - elements to split
+     */
+    void SplitBiQuadraticIntoLinear(in ListOfIDSources elems)
+      raises (SALOME::SALOME_Exception);
+
 
     enum Smooth_Method { LAPLACIAN_SMOOTH, CENTROIDAL_SMOOTH };
 
@@ -393,7 +441,7 @@ module SMESH
     void    ConvertFromQuadraticObject(in SMESH_IDSource theObject)
       raises (SALOME::SALOME_Exception);
 
-    void ConvertToBiQuadratic(in boolean        theForce3d, 
+    void ConvertToBiQuadratic(in boolean        theForce3d,
                               in SMESH_IDSource theObject)
       raises (SALOME::SALOME_Exception);
 
@@ -402,190 +450,73 @@ module SMESH
     void RenumberElements() raises (SALOME::SALOME_Exception);
 
     /*!
-     * \brief Genarate dim+1 elements by rotation of given elements around axis
-     * \param IDsOfElements - elements to ratate
-     * \param Axix - rotation axis
-     * \param AngleInRadians - rotation angle
-     * \param NbOfSteps - number of elements to generate from one element
-     */
-    void RotationSweep(in long_array       IDsOfElements,
-                       in AxisStruct       Axix,
-                       in double           AngleInRadians,
-                       in long             NbOfSteps,
-                       in double           Tolerance) 
-      raises (SALOME::SALOME_Exception);
-    /*!
-     * \brief Same as previous but additionally create groups of elements
-     *  generated from elements belonging to preexisting groups
-     */
-    ListOfGroups RotationSweepMakeGroups(in long_array       IDsOfElements,
-                                         in AxisStruct       Axix,
-                                         in double           AngleInRadians,
-                                         in long             NbOfSteps,
-                                         in double           Tolerance) 
-      raises (SALOME::SALOME_Exception);
-    /*!
-     * \brief Genarate dim+1 elements by rotation of the object around axis
-     * \param theObject - object containing elements to ratate
-     * \param Axix - rotation axis
-     * \param AngleInRadians - rotation angle
-     * \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) 
-      raises (SALOME::SALOME_Exception);
-    /*!
-     * \brief Same as previous but additionally create groups of elements
-     *  generated from elements belonging to preexisting groups
-     */
-    ListOfGroups RotationSweepObjectMakeGroups(in SMESH_IDSource  theObject,
-                                               in AxisStruct      Axix,
-                                               in double          AngleInRadians,
-                                               in long            NbOfSteps,
-                                               in double          Tolerance) 
-      raises (SALOME::SALOME_Exception);
-    /*!
-     * \brief Genarate dim+1 elements by rotation of the object around axis
-     * \param theObject - object containing elements to ratate
-     * \param Axix - rotation axis
-     * \param AngleInRadians - rotation angle
-     * \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) 
-      raises (SALOME::SALOME_Exception);
-    /*!
-     * \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) 
-      raises (SALOME::SALOME_Exception);
-    /*!
-     * \brief Genarate dim+1 elements by rotation of the object around axis
-     * \param theObject - object containing elements to ratate
-     * \param Axix - rotation axis
-     * \param AngleInRadians - rotation angle
-     * \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) 
-      raises (SALOME::SALOME_Exception);
-    /*!
-     * \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) 
-      raises (SALOME::SALOME_Exception);
-    /*!
-     * \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 ExtrusionSweep(in long_array      IDsOfElements,
-                        in DirStruct       StepVector,
-                        in long            NbOfSteps) 
-      raises (SALOME::SALOME_Exception);
-    /*!
-     * \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) 
-      raises (SALOME::SALOME_Exception);
-    /*!
-     * \brief Same as previous but additionally create groups of elements
-     *  generated from elements belonging to preexisting groups
-     */
-    ListOfGroups ExtrusionSweepMakeGroups(in long_array      IDsOfElements,
-                                          in DirStruct       StepVector,
-                                          in long            NbOfSteps) 
-      raises (SALOME::SALOME_Exception);
-   /*!
-     * \brief Same as previous but elements are nodes
-     */
-    ListOfGroups ExtrusionSweepMakeGroups0D(in long_array      IDsOfElements,
-                                          in DirStruct       StepVector,
-                                          in long            NbOfSteps) 
-      raises (SALOME::SALOME_Exception);
-   /*!
-    * 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
-    *   EXTRUSION_FLAG_SEW is set
-    */
-    void AdvancedExtrusion(in long_array      IDsOfElements,
-                           in DirStruct       StepVector,
-                           in long            NbOfSteps,
-                           in long            ExtrFlags,
-                           in double          SewTolerance) 
-      raises (SALOME::SALOME_Exception);
-    /*!
-     * \brief Same as previous but additionally create groups of elements
-     *  generated from elements belonging to preexisting groups
-     */
-    ListOfGroups AdvancedExtrusionMakeGroups(in long_array      IDsOfElements,
-                                             in DirStruct       StepVector,
-                                             in long            NbOfSteps,
-                                             in long            ExtrFlags,
-                                             in double          SewTolerance) 
-      raises (SALOME::SALOME_Exception);
-
-    void ExtrusionSweepObject(in SMESH_IDSource  theObject,
-                              in DirStruct       StepVector,
-                              in long            NbOfSteps) 
-      raises (SALOME::SALOME_Exception);
-    ListOfGroups ExtrusionSweepObjectMakeGroups(in SMESH_IDSource  theObject,
-                                                in DirStruct       StepVector,
-                                                in long            NbOfSteps) 
-      raises (SALOME::SALOME_Exception);
-
-    void ExtrusionSweepObject0D(in SMESH_IDSource theObject,
-                                in DirStruct      StepVector,
-                                in long           NbOfSteps) 
-      raises (SALOME::SALOME_Exception);
-    ListOfGroups ExtrusionSweepObject0DMakeGroups(in SMESH_IDSource theObject,
-                                                  in DirStruct      StepVector,
-                                                  in long           NbOfSteps) 
-      raises (SALOME::SALOME_Exception);
-
-    void ExtrusionSweepObject1D(in SMESH_IDSource theObject,
-                                in DirStruct      StepVector,
-                                in long           NbOfSteps) 
-      raises (SALOME::SALOME_Exception);
-    ListOfGroups ExtrusionSweepObject1DMakeGroups(in SMESH_IDSource theObject,
-                                                  in DirStruct      StepVector,
-                                                  in long           NbOfSteps) 
-      raises (SALOME::SALOME_Exception);
-
-    void ExtrusionSweepObject2D(in SMESH_IDSource theObject,
-                                in DirStruct      StepVector,
-                                in long           NbOfSteps) 
-      raises (SALOME::SALOME_Exception);
-    ListOfGroups ExtrusionSweepObject2DMakeGroups(in SMESH_IDSource theObject,
-                                                  in DirStruct      StepVector,
-                                                  in long           NbOfSteps) 
+     * \brief Generate dim+1 elements by rotation of the object around axis
+     *  \param Nodes - nodes to revolve: a list including groups, sub-meshes or a mesh
+     *  \param Edges - edges to revolve: a list including groups, sub-meshes or a mesh
+     *  \param Faces - faces to revolve: a list including groups, sub-meshes or a mesh
+     *  \param Axis - rotation axis
+     *  \param AngleInRadians - rotation angle
+     *  \param NbOfSteps - number of elements to generate from one element
+     *  \param ToMakeGroups - if true, new elements will be included into new groups
+     *         corresponding to groups the input elements included in.
+     *  \return ListOfGroups - new groups craeted if \a ToMakeGroups is true
+     */
+    ListOfGroups RotationSweepObjects(in ListOfIDSources Nodes,
+                                      in ListOfIDSources Edges,
+                                      in ListOfIDSources Faces,
+                                      in AxisStruct      Axis,
+                                      in double          AngleInRadians,
+                                      in long            NbOfSteps,
+                                      in double          Tolerance,
+                                      in boolean         ToMakeGroups)
+      raises (SALOME::SALOME_Exception);
+
+    /*!
+     * \brief Generate dim+1 elements by extrusion of elements along vector
+     *  \param nodes - nodes to extrude: a list including groups, sub-meshes or a mesh
+     *  \param edges - edges to extrude: a list including groups, sub-meshes or a mesh
+     *  \param faces - faces to extrude: a list including groups, sub-meshes or a mesh
+     *  \param stepVector - vector giving direction and distance of an extrusion step
+     *  \param nbOfSteps - number of elements to generate from one element
+     *  \param toMakeGroups - if true, new elements will be included into new groups
+     *         corresponding to groups the input elements included in.
+     *  \return ListOfGroups - new groups craeted if \a toMakeGroups is true
+     */
+    ListOfGroups ExtrusionSweepObjects(in ListOfIDSources nodes,
+                                       in ListOfIDSources edges,
+                                       in ListOfIDSources faces,
+                                       in DirStruct       stepVector,
+                                       in long            nbOfSteps,
+                                       in boolean         toMakeGroups)
+      raises (SALOME::SALOME_Exception);
+
+    /*! Generates new elements by extrusion along the normal to a discretized surface or wire
+     */
+    ListOfGroups ExtrusionByNormal(in ListOfIDSources theObjects,
+                                   in double          stepSize,
+                                   in long            nbOfSteps,
+                                   in boolean         byAverageNormal,
+                                   in boolean         useInputElemsOnly,
+                                   in boolean         makeGroups,
+                                   in short           dim)
+      raises (SALOME::SALOME_Exception);
+
+    /*!
+     * 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
+     *         EXTRUSION_FLAG_SEW is set
+     *  \param ToMakeGroups - if true, new elements will be included into new groups
+     *         corresponding to groups the input elements included in.
+     *  \return ListOfGroups - new groups craeted if \a ToMakeGroups is true
+     */
+    ListOfGroups AdvancedExtrusion(in long_array IDsOfElements,
+                                   in DirStruct  StepVector,
+                                   in long       NbOfSteps,
+                                   in long       ExtrFlags,
+                                   in double     SewTolerance,
+                                   in boolean    ToMakeGroups)
       raises (SALOME::SALOME_Exception);
 
     enum Extrusion_Error {
@@ -596,112 +527,21 @@ module SMESH
       EXTR_BAD_STARTING_NODE,
       EXTR_BAD_ANGLES_NUMBER,
       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) 
-      raises (SALOME::SALOME_Exception);
-
-    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) 
-      raises (SALOME::SALOME_Exception);
-
-    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) 
-      raises (SALOME::SALOME_Exception);
-    ListOfGroups ExtrusionAlongPathMakeGroups(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,
-                                              out Extrusion_Error  Error) 
-      raises (SALOME::SALOME_Exception);
-
-    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) 
-      raises (SALOME::SALOME_Exception);
-    ListOfGroups ExtrusionAlongPathObjectMakeGroups(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) 
-      raises (SALOME::SALOME_Exception);
-
-    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) 
-      raises (SALOME::SALOME_Exception);
-    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) 
-      raises (SALOME::SALOME_Exception);
-
-    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) 
-      raises (SALOME::SALOME_Exception);
-    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) 
+    };
+
+    ListOfGroups ExtrusionAlongPathObjects(in ListOfIDSources Nodes,
+                                           in ListOfIDSources Edges,
+                                           in ListOfIDSources Faces,
+                                           in SMESH_IDSource    Path,
+                                           in GEOM::GEOM_Object PathShape,
+                                           in long              NodeStart,
+                                           in boolean           HasAngles,
+                                           in double_array      Angles,
+                                           in boolean           LinearVariation,
+                                           in boolean           HasRefPoint,
+                                           in PointStruct       RefPoint,
+                                           in boolean           MakeGroups,
+                                           out Extrusion_Error  Error)
       raises (SALOME::SALOME_Exception);
 
    /*!
@@ -805,41 +645,45 @@ module SMESH
                                in AxisStruct Axis,
                                in double     AngleInRadians,
                                in boolean    CopyGroups,
-                               in string     MeshName) 
+                               in string     MeshName)
       raises (SALOME::SALOME_Exception);
 
     void RotateObject (in SMESH_IDSource theObject,
                        in AxisStruct     Axis,
                        in double         AngleInRadians,
-                       in boolean        Copy) 
+                       in boolean        Copy)
       raises (SALOME::SALOME_Exception);
     ListOfGroups RotateObjectMakeGroups (in SMESH_IDSource theObject,
                                          in AxisStruct     Axis,
-                                         in double         AngleInRadians) 
+                                         in double         AngleInRadians)
       raises (SALOME::SALOME_Exception);
     SMESH_Mesh RotateObjectMakeMesh (in SMESH_IDSource theObject,
                                      in AxisStruct     Axis,
                                      in double         AngleInRadians,
                                      in boolean        CopyGroups,
-                                     in string         MeshName) 
+                                     in string         MeshName)
       raises (SALOME::SALOME_Exception);
 
     void FindCoincidentNodes (in  double              Tolerance,
-                              out array_of_long_array GroupsOfNodes) 
+                              out array_of_long_array GroupsOfNodes,
+                              in  boolean             SeparateCornersAndMedium)
       raises (SALOME::SALOME_Exception);
 
     void FindCoincidentNodesOnPart (in  SMESH_IDSource      SubMeshOrGroup,
                                     in  double              Tolerance,
-                                    out array_of_long_array GroupsOfNodes) 
+                                    out array_of_long_array GroupsOfNodes,
+                                    in  boolean             SeparateCornersAndMedium)
       raises (SALOME::SALOME_Exception);
 
     void FindCoincidentNodesOnPartBut (in  SMESH_IDSource      SubMeshOrGroup,
                                        in  double              Tolerance,
                                        out array_of_long_array GroupsOfNodes,
-                                       in  ListOfIDSources     ExceptSubMeshOrGroups) 
+                                       in  ListOfIDSources     ExceptSubMeshOrGroups,
+                                       in  boolean             SeparateCornersAndMedium)
       raises (SALOME::SALOME_Exception);
 
-    void MergeNodes (in array_of_long_array GroupsOfNodes) 
+    void MergeNodes (in array_of_long_array    GroupsOfNodes,
+                     in SMESH::ListOfIDSources NodesToKeep)
       raises (SALOME::SALOME_Exception);
 
     /*!
@@ -903,6 +747,21 @@ module SMESH
     short GetPointState(in double x, in double y, in double z) 
       raises (SALOME::SALOME_Exception);
 
+    /*!
+     * Returns groups of FreeBorder's coincident within the given tolerance.
+     * If the tolerance <= 0.0 then one tenth of an average size of elements adjacent
+     * to free borders being compared is used.
+     */
+    CoincidentFreeBorders FindCoincidentFreeBorders(in double tolerance);
+
+    /*!
+     * Sew FreeBorder's of each group
+     */
+    short SewCoincidentFreeBorders (in CoincidentFreeBorders freeBorders,
+                                    in boolean               createPolygons,
+                                    in boolean               createPolyedrs)
+      raises (SALOME::SALOME_Exception);
+
     enum Sew_Error {
       SEW_OK,
       SEW_BORDER1_NOT_FOUND,
index 3a5e7900a346ffe9eb904ed5f053112e85dc2a5c..8799f273993d3739fc8a2fdafca4f16cc89351e4 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 46ca05a363db0190b76118b7b0aa9a8ce634ae4c..66f426f0090dfbb9bbba5dd6183af7992de57bfd 100755 (executable)
@@ -1,4 +1,4 @@
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -38,6 +38,8 @@ SET(SMESH_RESOURCES_FILES
   mesh_choose_all.png
   mesh_clear.png
   mesh_compute.png
+  mesh_evaluate.png
+  mesh_order.png
   mesh_diagonal.png
   mesh_edit.png
   mesh_hexa.png
@@ -96,6 +98,7 @@ SET(SMESH_RESOURCES_FILES
   mesh_tetra.png
   mesh_tree_algo_hexa.png
   mesh_tree_algo_mefisto.png
+  mesh_tree_algo_polygon.png
   mesh_tree_algo.png
   mesh_tree_algo_0D.png
   mesh_tree_algo_quad.png
@@ -168,6 +171,7 @@ SET(SMESH_RESOURCES_FILES
   mesh_quad_edge.png
   mesh_quad_triangle.png
   mesh_quad_quadrangle.png
+  mesh_quad_polygon.png
   mesh_quad_tetrahedron.png
   mesh_quad_pyramid.png
   mesh_quad_pentahedron.png
@@ -199,6 +203,7 @@ SET(SMESH_RESOURCES_FILES
   scale.png
   scale_along_axes.png
   split_into_tetra.png
+  split_biquad.png
   mesh_duplicate_nodes.png
   mesh_duplicate_nodes_with_elem.png
   mesh_duplicate_elem_only.png
@@ -215,6 +220,9 @@ SET(SMESH_RESOURCES_FILES
   mesh_measure_length.png
   mesh_measure_area.png
   mesh_measure_volume.png
+  mesh_extmeth_node_offset.png
+  mesh_extmeth_surf_offset_smooth.png
+  mesh_extmeth_face_offset.png
 )
 
 INSTALL(FILES ${SMESH_RESOURCES_FILES} DESTINATION ${SALOME_SMESH_INSTALL_RES_DATA})
index cf89dd5c2d80e9c1a843851ab5c122e847e341c3..429d960099539830b39c202a9a158a4e517456d2 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version='1.0' encoding='us-ascii' ?>
 <!--
-  Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+  Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 
   Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
   CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
  
 <!-- XML component catalog -->
 <begin-catalog>
-
-<!-- Path prefix information -->
-
-<path-prefix-list>
-</path-prefix-list>
-
-<type-list>
-  <objref name="SMESH_Mesh" id="IDL:SMESH/SMESH_Mesh:1.0"/>
-  <objref name="SMESH_Hypothesis" id="IDL:SMESH/SMESH_Hypothesis:1.0"/>
-</type-list>
-
-<!-- Component list -->
-<component-list>
-       <component>
-               <!-- Component identification -->
-               <component-name>SMESH</component-name>
-               <component-username>Mesh</component-username>
-               <component-type>MESH</component-type>
-               <component-author>NRI</component-author>
-               <component-version>@SALOMESMESH_VERSION@</component-version>
-               <component-comment>Mesh component</component-comment>
-               <component-multistudy>1</component-multistudy>
-               <component-icone>ModuleMesh.png</component-icone>
-               <component-impltype>1</component-impltype>
-
-            <component-interface-list>
-                <component-interface-name>SMESH</component-interface-name>
-                <component-interface-comment></component-interface-comment>
-                <component-service-list>
-                    <component-service>
-                        <service-name>CreateHypothesis</service-name>
-                        <service-author></service-author>
-                        <service-version></service-version>
-                        <service-comment></service-comment>
-                        <service-by-default>1</service-by-default>
-                        <inParameter-list>
-                            <inParameter>
-                                <inParameter-type>string</inParameter-type>
-                                <inParameter-name>anHyp</inParameter-name>
-                                <inParameter-comment></inParameter-comment>
-                            </inParameter>
-                            <inParameter>
-                                <inParameter-type>long</inParameter-type>
-                                <inParameter-name>studyId</inParameter-name>
-                                <inParameter-comment></inParameter-comment>
-                            </inParameter>
-                        </inParameter-list>
-                        <outParameter-list>
-                           <outParameter>
-                                <outParameter-type>SMESH_Hypothesis</outParameter-type>
-                                <outParameter-name>aHyp</outParameter-name>
-                                <outParameter-comment></outParameter-comment>
-                           </outParameter>
-                       </outParameter-list>
-                    </component-service>
-                    <component-service>
-                        <service-name>Init</service-name>
-                        <service-author></service-author>
-                        <service-version></service-version>
-                        <service-comment></service-comment>
-                        <service-by-default>1</service-by-default>
-                        <inParameter-list>
-                            <inParameter>
-                                <inParameter-type>GEOM_Gen</inParameter-type>
-                                <inParameter-name>geomEngine</inParameter-name>
-                                <inParameter-comment></inParameter-comment>
-                            </inParameter>
-                            <inParameter>
-                                <inParameter-type>long</inParameter-type>
-                                <inParameter-name>studyId</inParameter-name>
-                                <inParameter-comment></inParameter-comment>
-                            </inParameter>
-                            <inParameter>
-                                <inParameter-type>GEOM_Shape</inParameter-type>
-                                <inParameter-name>aShape</inParameter-name>
-                                <inParameter-comment></inParameter-comment>
-                            </inParameter>
-                        </inParameter-list>
-                        <outParameter-list>
-                           <outParameter>
-                               <outParameter-type>SMESH_Mesh</outParameter-type>
-                               <outParameter-name>aMesh</outParameter-name>
-                               <outParameter-comment></outParameter-comment>
-                           </outParameter>
-                       </outParameter-list>
-                    </component-service>
-                    <component-service>
-                        <service-name>Compute</service-name>
-                        <service-author></service-author>
-                        <service-version></service-version>
-                        <service-comment></service-comment>
-                        <service-by-default>1</service-by-default>
-                        <inParameter-list>
-                            <inParameter>
-                                <inParameter-type>SMESH_Mesh</inParameter-type>
-                                <inParameter-name>aMesh</inParameter-name>
-                                <inParameter-comment></inParameter-comment>
-                            </inParameter>
-                            <inParameter>
-                                <inParameter-type>GEOM_Shape</inParameter-type>
-                                <inParameter-name>aSubShape</inParameter-name>
-                                <inParameter-comment></inParameter-comment>
-                            </inParameter>
-                        </inParameter-list>
-                        <outParameter-list>
-                            <outParameter>
-                                <outParameter-type>boolean</outParameter-type>
-                                <outParameter-name>res</outParameter-name>
-                                <outParameter-comment>Result</outParameter-comment>
-                            </outParameter>
-                       </outParameter-list>
-                    </component-service>
-                    <component-service>
-                        <service-name>IsReadyToCompute</service-name>
-                        <service-author></service-author>
-                        <service-version></service-version>
-                        <service-comment></service-comment>
-                        <service-by-default>1</service-by-default>
-                        <inParameter-list>
-                            <inParameter>
-                                <inParameter-type>SMESH_Mesh</inParameter-type>
-                                <inParameter-name>aMesh</inParameter-name>
-                                <inParameter-comment></inParameter-comment>
-                            </inParameter>
-                            <inParameter>
-                                <inParameter-type>GEOM_Shape</inParameter-type>
-                                <inParameter-name>aSubShape</inParameter-name>
-                                <inParameter-comment></inParameter-comment>
-                            </inParameter>
-                        </inParameter-list>
-                        <outParameter-list>
-                                <outParameter-type>boolean</outParameter-type>
-                                <outParameter-name>res</outParameter-name>
-                                <outParameter-comment>Result</outParameter-comment>
-                       </outParameter-list>
-                    </component-service>
-                </component-service-list>
-                <component-interface-name>SMESH_Mesh</component-interface-name>
-                <component-interface-comment></component-interface-comment>
-                <component-service-list>
-                    <component-service>
-                        <service-name>AddHypothesis</service-name>
-                        <service-author></service-author>
-                        <service-version></service-version>
-                        <service-comment></service-comment>
-                        <service-by-default>1</service-by-default>
-                        <inParameter-list>
-                            <inParameter>
-                                <inParameter-type>GEOM_Shape</inParameter-type>
-                                <inParameter-name>aSubShape</inParameter-name>
-                                <inParameter-comment></inParameter-comment>
-                            </inParameter>
-                            <inParameter>
-                                <inParameter-type>SMESH_Hypothesis</inParameter-type>
-                                <inParameter-name>aHyp</inParameter-name>
-                                <inParameter-comment></inParameter-comment>
-                            </inParameter>
-                        </inParameter-list>
-                        <outParameter-list>
-                            <outParameter>
-                                <outParameter-type>boolean</outParameter-type>
-                                <outParameter-name>res</outParameter-name>
-                                <outParameter-comment>Result</outParameter-comment>
-                            </outParameter>
-                       </outParameter-list>
-                    </component-service>
-                </component-service-list>
-            </component-interface-list>
-       <constraint>hostname = localhost</constraint>
-       </component>
+  
+  <!-- Path prefix information -->
+  <path-prefix-list>
+  </path-prefix-list>
+  
+  <!-- SMESH data types  -->
+  <type-list>
+    <objref name="SMESH/SMESH_Mesh" id="IDL:SMESH/SMESH_Mesh:1.0"/>
+    <objref name="SMESH/SMESH_Hypothesis" id="IDL:SMESH/SMESH_Hypothesis:1.0"/>
+  </type-list>
+  
+  <!-- Component list -->
+  <component-list>
+    <component>
+      <!-- Component: SMESH -->
+      <!-- Component identification -->
+      <component-name>SMESH</component-name>
+      <component-username>Mesh</component-username>
+      <component-type>MESH</component-type>
+      <component-author>SALOME team</component-author>
+      <component-version>@SALOMESMESH_VERSION@</component-version>
+      <component-comment>Mesh component</component-comment>
+      <component-multistudy>1</component-multistudy>
+      <component-icone>ModuleMesh.png</component-icone>
+      <component-impltype>1</component-impltype>
+      <constraint></constraint>
+      
+      <!-- component interface list -->
+      <component-interface-list>
+       <component-interface-name>SMESH</component-interface-name>
+       <component-interface-comment></component-interface-comment>
+       <component-service-list>
+          <component-service>
+            <service-name>CreateHypothesis</service-name>
+            <service-author>SALOME team</service-author>
+            <service-version>@SALOMESMESH_VERSION@</service-version>
+            <service-comment></service-comment>
+            <service-by-default>0</service-by-default>
+            <inParameter-list>
+              <inParameter>
+               <inParameter-type>string</inParameter-type>
+               <inParameter-name>anHyp</inParameter-name>
+               <inParameter-comment></inParameter-comment>
+              </inParameter>
+              <inParameter>
+               <inParameter-type>long</inParameter-type>
+               <inParameter-name>studyId</inParameter-name>
+               <inParameter-comment></inParameter-comment>
+              </inParameter>
+            </inParameter-list>
+            <outParameter-list>
+             <outParameter>
+               <outParameter-type>SMESH/SMESH_Hypothesis</outParameter-type>
+              <outParameter-name>aHyp</outParameter-name>
+              <outParameter-comment></outParameter-comment>
+           </outParameter>
+         </outParameter-list>
+        </component-service>
+        <component-service>
+          <service-name>Init</service-name>
+          <service-author>SALOME team</service-author>
+          <service-version>@SALOMESMESH_VERSION@</service-version>
+          <service-comment></service-comment>
+          <service-by-default>0</service-by-default>
+          <inParameter-list>
+            <inParameter>
+              <inParameter-type>GEOM/GEOM_Gen</inParameter-type>
+              <inParameter-name>geomEngine</inParameter-name>
+              <inParameter-comment></inParameter-comment>
+            </inParameter>
+            <inParameter>
+              <inParameter-type>long</inParameter-type>
+              <inParameter-name>studyId</inParameter-name>
+              <inParameter-comment></inParameter-comment>
+            </inParameter>
+            <inParameter>
+              <inParameter-type>GEOM/GEOM_Object</inParameter-type>
+              <inParameter-name>aShape</inParameter-name>
+              <inParameter-comment></inParameter-comment>
+            </inParameter>
+          </inParameter-list>
+          <outParameter-list>
+           <outParameter>
+             <outParameter-type>SMESH/SMESH_Mesh</outParameter-type>
+             <outParameter-name>aMesh</outParameter-name>
+             <outParameter-comment></outParameter-comment>
+           </outParameter>
+         </outParameter-list>
+        </component-service>
+        <component-service>
+          <service-name>Compute</service-name>
+          <service-author>SALOME team</service-author>
+          <service-version>@SALOMESMESH_VERSION@</service-version>
+          <service-comment></service-comment>
+          <service-by-default>0</service-by-default>
+          <inParameter-list>
+            <inParameter>
+              <inParameter-type>SMESH/SMESH_Mesh</inParameter-type>
+              <inParameter-name>aMesh</inParameter-name>
+              <inParameter-comment></inParameter-comment>
+            </inParameter>
+            <inParameter>
+              <inParameter-type>GEOM/GEOM_Object</inParameter-type>
+              <inParameter-name>aSubShape</inParameter-name>
+              <inParameter-comment></inParameter-comment>
+            </inParameter>
+          </inParameter-list>
+          <outParameter-list>
+            <outParameter>
+              <outParameter-type>boolean</outParameter-type>
+              <outParameter-name>res</outParameter-name>
+              <outParameter-comment>Result</outParameter-comment>
+            </outParameter>
+         </outParameter-list>
+        </component-service>
+        <component-service>
+          <service-name>IsReadyToCompute</service-name>
+          <service-author>SALOME team</service-author>
+          <service-version>@SALOMESMESH_VERSION@</service-version>
+          <service-comment></service-comment>
+          <service-by-default>0</service-by-default>
+          <inParameter-list>
+            <inParameter>
+              <inParameter-type>SMESH/SMESH_Mesh</inParameter-type>
+              <inParameter-name>aMesh</inParameter-name>
+              <inParameter-comment></inParameter-comment>
+            </inParameter>
+            <inParameter>
+              <inParameter-type>GEOM/GEOM_Object</inParameter-type>
+              <inParameter-name>aSubShape</inParameter-name>
+              <inParameter-comment></inParameter-comment>
+            </inParameter>
+          </inParameter-list>
+          <outParameter-list>
+            <outParameter-type>boolean</outParameter-type>
+            <outParameter-name>res</outParameter-name>
+            <outParameter-comment>Result</outParameter-comment>
+         </outParameter-list>
+        </component-service>
+      </component-service-list>
+      <component-interface-name>SMESH/SMESH_Mesh</component-interface-name>
+      <component-interface-comment></component-interface-comment>
+      <component-service-list>
+        <component-service>
+          <service-name>AddHypothesis</service-name>
+          <service-author>SALOME team</service-author>
+          <service-version>@SALOMESMESH_VERSION@</service-version>
+          <service-comment></service-comment>
+          <service-by-default>0</service-by-default>
+          <inParameter-list>
+            <inParameter>
+              <inParameter-type>GEOM/GEOM_Object</inParameter-type>
+              <inParameter-name>aSubShape</inParameter-name>
+              <inParameter-comment></inParameter-comment>
+            </inParameter>
+            <inParameter>
+              <inParameter-type>SMESH/SMESH_Hypothesis</inParameter-type>
+              <inParameter-name>aHyp</inParameter-name>
+              <inParameter-comment></inParameter-comment>
+            </inParameter>
+          </inParameter-list>
+          <outParameter-list>
+            <outParameter>
+              <outParameter-type>boolean</outParameter-type>
+              <outParameter-name>res</outParameter-name>
+              <outParameter-comment>Result</outParameter-comment>
+            </outParameter>
+         </outParameter-list>
+        </component-service>
+      </component-service-list>
+    </component-interface-list>
+  </component>
 </component-list>
 </begin-catalog>
index c49059d3a984ab6728550c093a4d3406a033cc03..94c0d894eec572bfe7c4286e0aafed27c7733c4d 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-  Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+  Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 
   Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
   CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -44,6 +44,7 @@
     <parameter name="type_of_marker"               value="1"  />
     <parameter name="marker_scale"                 value="9"  />
     <parameter name="elem0d_size"                  value="5" />
+    <parameter name="ball_elem_diameter"           value="1" />
     <parameter name="ball_elem_size"               value="10" />
     <parameter name="ball_elem_scale"              value="1" />
     <parameter name="element_width"                value="1" />
index 239ff2cb4919b3e4cdce58a31602899989bb665e..c537c5adc9b1115e3ef318d155244315c2a11783 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version='1.0' encoding='us-ascii'?>
 <!DOCTYPE meshers PUBLIC "" "desktop.dtd">
 <!--
-  Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+  Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 
   Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
   CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
       </python-wrap>
     </algorithm>
 
+    <algorithm type     ="QuadFromMedialAxis_1D2D"
+               label-id ="Quadrangle (Medial Axis Projection)"
+               icon-id  ="mesh_algo_quad.png"
+               hypos    ="NumberOfLayers2D, LayerDistribution2D"
+               opt-hypos="ViscousLayers2D"
+               input    ="EDGE"
+               output   ="QUAD"
+               dim      ="2">
+      <python-wrap>
+        <algo>QuadFromMedialAxis_1D2D=Quadrangle(algo=smeshBuilder.QUAD_MA_PROJ)</algo>
+        <hypo>ViscousLayers2D=ViscousLayers2D(SetTotalThickness(),SetNumberLayers(),SetStretchFactor(),SetIgnoreEdges())</hypo>
+        <hypo>NumberOfLayers2D=NumberOfLayers(SetNumberOfLayers())</hypo>
+      </python-wrap>
+    </algorithm>
+
+    <algorithm type     ="PolygonPerFace_2D"
+               label-id ="Polygon per Face"
+               icon-id  ="mesh_algo_polygon.png"
+               opt-hypos="ViscousLayers2D"
+               input    ="EDGE"
+               output   ="POLYGON,QUAD,TRIA"
+               dim      ="2">
+      <python-wrap>
+        <algo>PolygonPerFace_2D=Polygon()</algo>
+        <hypo>ViscousLayers2D=ViscousLayers2D(SetTotalThickness(),SetNumberLayers(),SetStretchFactor(),SetIgnoreEdges())</hypo>
+      </python-wrap>
+    </algorithm>
+
     <algorithm type     ="Hexa_3D"
                label-id ="Hexahedron (i,j,k)"
                icon-id  ="mesh_algo_hexa.png"
                dim      ="3">
       <python-wrap>
         <algo>Hexa_3D=Hexahedron(algo=smeshBuilder.Hexa)</algo>
-        <hypo>ViscousLayers=ViscousLayers(SetTotalThickness(),SetNumberLayers(),SetStretchFactor(),SetIgnoreFaces())</hypo>
+        <hypo>ViscousLayers=ViscousLayers(SetTotalThickness(),SetNumberLayers(),SetStretchFactor(),SetFaces(1),SetFaces(2),SetMethod())</hypo>
       </python-wrap>
     </algorithm>
 
diff --git a/resources/mesh_evaluate.png b/resources/mesh_evaluate.png
new file mode 100644 (file)
index 0000000..eddace2
Binary files /dev/null and b/resources/mesh_evaluate.png differ
diff --git a/resources/mesh_extmeth_face_offset.png b/resources/mesh_extmeth_face_offset.png
new file mode 100644 (file)
index 0000000..918b507
Binary files /dev/null and b/resources/mesh_extmeth_face_offset.png differ
diff --git a/resources/mesh_extmeth_node_offset.png b/resources/mesh_extmeth_node_offset.png
new file mode 100644 (file)
index 0000000..6ce27c3
Binary files /dev/null and b/resources/mesh_extmeth_node_offset.png differ
diff --git a/resources/mesh_extmeth_surf_offset_smooth.png b/resources/mesh_extmeth_surf_offset_smooth.png
new file mode 100644 (file)
index 0000000..8a8ecc3
Binary files /dev/null and b/resources/mesh_extmeth_surf_offset_smooth.png differ
diff --git a/resources/mesh_order.png b/resources/mesh_order.png
new file mode 100644 (file)
index 0000000..d8cea67
Binary files /dev/null and b/resources/mesh_order.png differ
diff --git a/resources/mesh_quad_polygon.png b/resources/mesh_quad_polygon.png
new file mode 100644 (file)
index 0000000..e9dfa35
Binary files /dev/null and b/resources/mesh_quad_polygon.png differ
diff --git a/resources/mesh_tree_algo_polygon.png b/resources/mesh_tree_algo_polygon.png
new file mode 100644 (file)
index 0000000..3770515
Binary files /dev/null and b/resources/mesh_tree_algo_polygon.png differ
diff --git a/resources/split_biquad.png b/resources/split_biquad.png
new file mode 100644 (file)
index 0000000..0b9b7a0
Binary files /dev/null and b/resources/split_biquad.png differ
index 257de2054d160fb9b4b140c6e6fbe95106b20276..a9973c685105f84f8f36d600c581064f11e56e5b 100755 (executable)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2012-2015  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
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 
-# Copyright (C) 2012-2013  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
-#
-
 ##
 # Common packages
 ##
index c415bbb0af668b747b0b57a0061283e2c4043260..be31cb1048e20f959633c1dc9b5339ebd5d43d34 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2012-2015  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
index 6311da713a53cdff7413d67c76f886b75066d35a..3f612a24fc823cc2b4750d44f01095709f07ba70 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 #include "SMDS_QuadraticFaceOfNodes.hxx"
 #include "SMDS_VolumeTool.hxx"
 #include "SMESHDS_GroupBase.hxx"
+#include "SMESHDS_GroupOnFilter.hxx"
 #include "SMESHDS_Mesh.hxx"
-#include "SMESH_OctreeNode.hxx"
 #include "SMESH_MeshAlgos.hxx"
+#include "SMESH_OctreeNode.hxx"
 
 #include <Basics_Utils.hxx>
 
@@ -43,6 +44,7 @@
 #include <Geom_CylindricalSurface.hxx>
 #include <Geom_Plane.hxx>
 #include <Geom_Surface.hxx>
+#include <NCollection_Map.hxx>
 #include <Precision.hxx>
 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
 #include <TColStd_MapOfInteger.hxx>
@@ -135,8 +137,8 @@ namespace {
     int aResult0 = 0, aResult1 = 0;
      // last node, it is a medium one in a quadratic edge
     const SMDS_MeshNode* aLastNode = anEdge->GetNode( anEdge->NbNodes() - 1 );
-    const SMDS_MeshNode* aNode0 = anEdge->GetNode( 0 );
-    const SMDS_MeshNode* aNode1 = anEdge->GetNode( 1 );
+    const SMDS_MeshNode*    aNode0 = anEdge->GetNode( 0 );
+    const SMDS_MeshNode*    aNode1 = anEdge->GetNode( 1 );
     if ( aNode1 == aLastNode ) aNode1 = 0;
 
     SMDS_ElemIteratorPtr anElemIter = aLastNode->GetInverseElementIterator();
@@ -158,29 +160,6 @@ namespace {
     }
     int aResult = std::max ( aResult0, aResult1 );
 
-//     TColStd_MapOfInteger aMap;
-
-//     SMDS_ElemIteratorPtr anIter = anEdge->nodesIterator();
-//     if ( anIter != 0 ) {
-//       while( anIter->more() ) {
-//      const SMDS_MeshNode* aNode = (SMDS_MeshNode*)anIter->next();
-//      if ( aNode == 0 )
-//        return 0;
-//      SMDS_ElemIteratorPtr anElemIter = aNode->GetInverseElementIterator();
-//      while( anElemIter->more() ) {
-//        const SMDS_MeshElement* anElem = anElemIter->next();
-//        if ( anElem != 0 && anElem->GetType() != SMDSAbs_Edge ) {
-//          int anId = anElem->GetID();
-
-//          if ( anIter->more() )              // i.e. first node
-//            aMap.Add( anId );
-//          else if ( aMap.Contains( anId ) )
-//            aResult++;
-//        }
-//      }
-//       }
-//     }
-
     return aResult;
   }
 
@@ -232,7 +211,7 @@ void NumericalFunctor::SetMesh( const SMDS_Mesh* theMesh )
   myMesh = theMesh;
 }
 
-bool NumericalFunctor::GetPoints(const int theId,
+bool NumericalFunctor::GetPoints(const int       theId,
                                  TSequenceOfXYZ& theRes ) const
 {
   theRes.clear();
@@ -256,6 +235,7 @@ bool NumericalFunctor::GetPoints(const SMDS_MeshElement* anElem,
     return false;
 
   theRes.reserve( anElem->NbNodes() );
+  theRes.setElement( anElem );
 
   // Get nodes of the element
   SMDS_ElemIteratorPtr anIter;
@@ -272,7 +252,6 @@ bool NumericalFunctor::GetPoints(const SMDS_MeshElement* anElem,
       break;
     default:
       anIter = anElem->nodesIterator();
-      //return false;
     }
   }
   else {
@@ -280,9 +259,13 @@ bool NumericalFunctor::GetPoints(const SMDS_MeshElement* anElem,
   }
 
   if ( anIter ) {
+    double xyz[3];
     while( anIter->more() ) {
       if ( const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>( anIter->next() ))
-        theRes.push_back( gp_XYZ( aNode->X(), aNode->Y(), aNode->Z() ) );
+      {
+        aNode->GetXYZ( xyz );
+        theRes.push_back( gp_XYZ( xyz[0], xyz[1], xyz[2] ));
+      }
     }
   }
 
@@ -347,7 +330,7 @@ void NumericalFunctor::GetHistogram(int                  nbIntervals,
   std::multiset< double > values;
   if ( elements.empty() )
   {
-    SMDS_ElemIteratorPtr elemIt = myMesh->elementsIterator(GetType());
+    SMDS_ElemIteratorPtr elemIt = myMesh->elementsIterator( GetType() );
     while ( elemIt->more() )
       values.insert( GetValue( elemIt->next()->GetID() ));
   }
@@ -480,6 +463,27 @@ double MaxElementLength2D::GetValue( const TSequenceOfXYZ& P )
     double D2 = getDistance(P( 3 ),P( 7 ));
     aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(D1,D2));
   }
+  // Diagonals are undefined for concave polygons
+  // else if ( P.getElementEntity() == SMDSEntity_Quad_Polygon && P.size() > 2 ) // quad polygon
+  // {
+  //   // sides
+  //   aVal = getDistance( P( 1 ), P( P.size() )) + getDistance( P( P.size() ), P( P.size()-1 ));
+  //   for ( size_t i = 1; i < P.size()-1; i += 2 )
+  //   {
+  //     double L = getDistance( P( i ), P( i+1 )) + getDistance( P( i+1 ), P( i+2 ));
+  //     aVal = Max( aVal, L );
+  //   }
+  //   // diagonals
+  //   for ( int i = P.size()-5; i > 0; i -= 2 )
+  //     for ( int j = i + 4; j < P.size() + i - 2; i += 2 )
+  //     {
+  //       double D = getDistance( P( i ), P( j ));
+  //       aVal = Max( aVal, D );
+  //     }
+  // }
+  // { // polygons
+    
+  // }
 
   if( myPrecision >= 0 )
   {
@@ -518,148 +522,164 @@ double MaxElementLength3D::GetValue( long theElementId )
   if( GetPoints( theElementId, P ) ) {
     double aVal = 0;
     const SMDS_MeshElement* aElem = myMesh->FindElement( theElementId );
-    SMDSAbs_ElementType aType = aElem->GetType();
+    SMDSAbs_EntityType      aType = aElem->GetEntityType();
     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 );
-            }
+    switch ( aType ) {
+    case SMDSEntity_Tetra: { // 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;
+    }
+    case SMDSEntity_Pyramid: { // 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;
+    }
+    case SMDSEntity_Penta: { // 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;
+    }
+    case SMDSEntity_Hexa: { // 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;
+    }
+    case SMDSEntity_Hexagonal_Prism: { // 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;
+    }
+    case SMDSEntity_Quad_Tetra: { // 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;
+    }
+    case SMDSEntity_Quad_Pyramid: { // 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;
+    }
+    case SMDSEntity_Quad_Penta: { // 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;
+    }
+    case SMDSEntity_Quad_Hexa:
+    case SMDSEntity_TriQuad_Hexa: { // 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;
+    }
+    case SMDSEntity_Quad_Polyhedra:
+    case SMDSEntity_Polyhedra: { // 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 );
           }
         }
       }
+      break;
     }
+    case SMDSEntity_Node:
+    case SMDSEntity_0D:
+    case SMDSEntity_Edge:
+    case SMDSEntity_Quad_Edge:
+    case SMDSEntity_Triangle:
+    case SMDSEntity_Quad_Triangle:
+    case SMDSEntity_BiQuad_Triangle:
+    case SMDSEntity_Quadrangle:
+    case SMDSEntity_Quad_Quadrangle:
+    case SMDSEntity_BiQuad_Quadrangle:
+    case SMDSEntity_Polygon:
+    case SMDSEntity_Quad_Polygon:
+    case SMDSEntity_Ball:
+    case SMDSEntity_Last: return 0;
+    } // switch ( aType )
 
     if( myPrecision >= 0 )
     {
@@ -698,8 +718,9 @@ double MinimumAngle::GetValue( const TSequenceOfXYZ& P )
   aMin = getAngle(P( P.size() ), P( 1 ), P( 2 ));
   aMin = Min(aMin,getAngle(P( P.size()-1 ), P( P.size() ), P( 1 )));
 
-  for (int i=2; i<P.size();i++){
-      double A0 = getAngle( P( i-1 ), P( i ), P( i+1 ) );
+  for ( size_t i = 2; i < P.size(); i++ )
+  {
+    double A0 = getAngle( P( i-1 ), P( i ), P( i+1 ) );
     aMin = Min(aMin,A0);
   }
 
@@ -1356,10 +1377,10 @@ double Taper::GetValue( const TSequenceOfXYZ& P )
     return 0.;
 
   // Compute taper
-  double J1 = getArea( P( 4 ), P( 1 ), P( 2 ) ) / 2.;
-  double J2 = getArea( P( 3 ), P( 1 ), P( 2 ) ) / 2.;
-  double J3 = getArea( P( 2 ), P( 3 ), P( 4 ) ) / 2.;
-  double J4 = getArea( P( 3 ), P( 4 ), P( 1 ) ) / 2.;
+  double J1 = getArea( P( 4 ), P( 1 ), P( 2 ) );
+  double J2 = getArea( P( 3 ), P( 1 ), P( 2 ) );
+  double J3 = getArea( P( 2 ), P( 3 ), P( 4 ) );
+  double J4 = getArea( P( 3 ), P( 4 ), P( 1 ) );
 
   double JA = 0.25 * ( J1 + J2 + J3 + J4 );
   if ( JA <= theEps )
@@ -1380,7 +1401,7 @@ double Taper::GetValue( const TSequenceOfXYZ& P )
 double Taper::GetBadRate( double Value, int /*nbNodes*/ ) const
 {
   // the taper is in the range [0.0,1.0]
-  // 0.0  = good (no taper)
+  // 0.0 = good (no taper)
   // 1.0 = bad  (les cotes opposes sont allignes)
   return Value;
 }
@@ -1466,13 +1487,16 @@ SMDSAbs_ElementType Skew::GetType() const
 double Area::GetValue( const TSequenceOfXYZ& P )
 {
   double val = 0.0;
-  if ( P.size() > 2 ) {
+  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++) {
+
+    for (size_t i=4; i<=P.size(); i++)
+    {
       gp_Vec aVec1( P(i-1) - P(1) );
-      gp_Vec aVec2( P(i) - P(1) );
+      gp_Vec aVec2( P(i  ) - P(1) );
       gp_Vec tmp = aVec1 ^ aVec2;
       SumVec.Add(tmp);
     }
@@ -1522,81 +1546,78 @@ SMDSAbs_ElementType Length::GetType() const
 //================================================================================
 /*
   Class       : Length2D
-  Description : Functor for calculating length of edge
+  Description : Functor for calculating minimal length of edge
 */
 //================================================================================
 
-double Length2D::GetValue( long theElementId)
+double Length2D::GetValue( long theElementId )
 {
   TSequenceOfXYZ P;
 
-  //cout<<"Length2D::GetValue"<<endl;
-  if (GetPoints(theElementId,P)){
-    //for(int jj=1; jj<=P.size(); jj++)
-    //  cout<<"jj="<<jj<<" P("<<P(jj).X()<<","<<P(jj).Y()<<","<<P(jj).Z()<<")"<<endl;
-
-    double  aVal;// = GetValue( P );
-    const SMDS_MeshElement* aElem = myMesh->FindElement( theElementId );
-    SMDSAbs_ElementType aType = aElem->GetType();
-
+  if ( GetPoints( theElementId, P ))
+  {
+    double aVal = 0;
     int len = P.size();
+    SMDSAbs_EntityType aType = P.getElementEntity();
 
-    switch (aType){
-    case SMDSAbs_All:
-    case SMDSAbs_Node:
-    case SMDSAbs_Edge:
-      if (len == 2){
+    switch (aType) {
+    case SMDSEntity_Edge:
+      if (len == 2)
         aVal = getDistance( P( 1 ), P( 2 ) );
-        break;
-      }
-      else if (len == 3){ // quadratic edge
+      break;
+    case SMDSEntity_Quad_Edge:
+      if (len == 3) // quadratic edge
         aVal = getDistance(P( 1 ),P( 3 )) + getDistance(P( 3 ),P( 2 ));
-        break;
-      }
-    case SMDSAbs_Face:
+      break;
+    case SMDSEntity_Triangle:
       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;
+        aVal = Min(L1,Min(L2,L3));
       }
-      else if (len == 4){ // quadrangles
+      break;
+    case SMDSEntity_Quadrangle:
+      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;
+        aVal = Min(Min(L1,L2),Min(L3,L4));
       }
-      if (len == 6){ // quadratic triangles
+      break;
+    case SMDSEntity_Quad_Triangle:
+    case SMDSEntity_BiQuad_Triangle:
+      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));
-        //cout<<"L1="<<L1<<" L2="<<L2<<"L3="<<L3<<" aVal="<<aVal<<endl;
-        break;
+        aVal = Min(L1,Min(L2,L3));
       }
-      else if (len == 8){ // quadratic quadrangles
+      break;
+    case SMDSEntity_Quad_Quadrangle:
+    case SMDSEntity_BiQuad_Quadrangle:
+      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;
+        aVal = Min(Min(L1,L2),Min(L3,L4));
       }
-    case SMDSAbs_Volume:
-      if (len == 4){ // tetraidrs
+      break;
+    case SMDSEntity_Tetra:
+      if (len == 4){ // tetrahedra
         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;
+        aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6));
       }
-      else if (len == 5){ // piramids
+      break;
+    case SMDSEntity_Pyramid:
+      if (len == 5){ // piramids
         double L1 = getDistance(P( 1 ),P( 2 ));
         double L2 = getDistance(P( 2 ),P( 3 ));
         double L3 = getDistance(P( 3 ),P( 4 ));
@@ -1606,11 +1627,12 @@ double Length2D::GetValue( long theElementId)
         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;
+        aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6));
+        aVal = Min(aVal,Min(L7,L8));
       }
-      else if (len == 6){ // pentaidres
+      break;
+    case SMDSEntity_Penta:
+      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 ));
@@ -1621,11 +1643,12 @@ double Length2D::GetValue( long theElementId)
         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;
+        aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6));
+        aVal = Min(aVal,Min(Min(L7,L8),L9));
       }
-      else if (len == 8){ // hexaider
+      break;
+    case SMDSEntity_Hexa:
+      if (len == 8){ // hexahedron
         double L1 = getDistance(P( 1 ),P( 2 ));
         double L2 = getDistance(P( 2 ),P( 3 ));
         double L3 = getDistance(P( 3 ),P( 4 ));
@@ -1639,13 +1662,12 @@ double Length2D::GetValue( long theElementId)
         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;
-
+        aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6));
+        aVal = Min(aVal,Min(Min(L7,L8),Min(L9,L10)));
+        aVal = Min(aVal,Min(L11,L12));
       }
-
+      break;
+    case SMDSEntity_Quad_Tetra:
       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 ));
@@ -1653,10 +1675,11 @@ double Length2D::GetValue( long theElementId)
         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;
+        aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6));
       }
-      else if (len == 13){ // quadratic piramids
+      break;
+    case SMDSEntity_Quad_Pyramid:
+      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( 4 ));
@@ -1665,11 +1688,12 @@ double Length2D::GetValue( long theElementId)
         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;
+        aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6));
+        aVal = Min(aVal,Min(L7,L8));
       }
-      else if (len == 15){ // quadratic pentaidres
+      break;
+    case SMDSEntity_Quad_Penta:
+      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 ));
@@ -1679,11 +1703,13 @@ double Length2D::GetValue( long theElementId)
         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;
+        aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6));
+        aVal = Min(aVal,Min(Min(L7,L8),L9));
       }
-      else if (len == 20){ // quadratic hexaider
+      break;
+    case SMDSEntity_Quad_Hexa:
+    case SMDSEntity_TriQuad_Hexa:
+      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 ));
@@ -1696,17 +1722,61 @@ double Length2D::GetValue( long theElementId)
         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;
-
+        aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6));
+        aVal = Min(aVal,Min(Min(L7,L8),Min(L9,L10)));
+        aVal = Min(aVal,Min(L11,L12));
       }
-
-    default: aVal=-1;
+      break;
+    case SMDSEntity_Polygon:
+      if ( len > 1 ) {
+        aVal = getDistance( P(1), P( P.size() ));
+        for ( size_t i = 1; i < P.size(); ++i )
+          aVal = Min( aVal, getDistance( P( i ), P( i+1 )));
+      }
+      break;
+    case SMDSEntity_Quad_Polygon:
+      if ( len > 2 ) {
+        aVal = getDistance( P(1), P( P.size() )) + getDistance( P(P.size()), P( P.size()-1 ));
+        for ( size_t i = 1; i < P.size()-1; i += 2 )
+          aVal = Min( aVal, getDistance( P( i ), P( i+1 )) + getDistance( P( i+1 ), P( i+2 )));
+      }
+      break;
+    case SMDSEntity_Hexagonal_Prism:
+      if (len == 12) { // hexagonal prism
+        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( 5 ));
+        double L5 = getDistance(P( 5 ),P( 6 ));
+        double L6 = getDistance(P( 6 ),P( 1 ));
+
+        double L7 = getDistance(P( 7 ), P( 8 ));
+        double L8 = getDistance(P( 8 ), P( 9 ));
+        double L9 = getDistance(P( 9 ), P( 10 ));
+        double L10= getDistance(P( 10 ),P( 11 ));
+        double L11= getDistance(P( 11 ),P( 12 ));
+        double L12= getDistance(P( 12 ),P( 7 ));
+
+        double L13 = getDistance(P( 1 ),P( 7 ));
+        double L14 = getDistance(P( 2 ),P( 8 ));
+        double L15 = getDistance(P( 3 ),P( 9 ));
+        double L16 = getDistance(P( 4 ),P( 10 ));
+        double L17 = getDistance(P( 5 ),P( 11 ));
+        double L18 = getDistance(P( 6 ),P( 12 ));
+        aVal = Min(Min(Min(L1,L2),Min(L3,L4)),Min(L5,L6));
+        aVal = Min(aVal, Min(Min(Min(L7,L8),Min(L9,L10)),Min(L11,L12)));
+        aVal = Min(aVal, Min(Min(Min(L13,L14),Min(L15,L16)),Min(L17,L18)));
+      }
+      break;
+    case SMDSEntity_Polyhedra:
+    {
+    }
+    break;
+    default:
+      return 0;
     }
 
-    if (aVal <0){
+    if (aVal < 0 ) {
       return 0.;
     }
 
@@ -1724,7 +1794,7 @@ double Length2D::GetValue( long theElementId)
 
 double Length2D::GetBadRate( double Value, int /*nbNodes*/ ) const
 {
-  // meaningless as it is not quality control functor
+  // meaningless as it is not quality control functor
   return Value;
 }
 
@@ -1742,14 +1812,16 @@ Length2D::Value::Value(double theLength,long thePntId1, long thePntId2):
   }
 }
 
-bool Length2D::Value::operator<(const Length2D::Value& x) const{
+bool Length2D::Value::operator<(const Length2D::Value& x) const
+{
   if(myPntId[0] < x.myPntId[0]) return true;
   if(myPntId[0] == x.myPntId[0])
     if(myPntId[1] < x.myPntId[1]) return true;
   return false;
 }
 
-void Length2D::GetValues(TValues& theValues){
+void Length2D::GetValues(TValues& theValues)
+{
   TValues aValues;
   SMDS_FaceIteratorPtr anIter = myMesh->facesIterator();
   for(; anIter->more(); ){
@@ -1946,14 +2018,16 @@ MultiConnection2D::Value::Value(long thePntId1, long thePntId2)
   }
 }
 
-bool MultiConnection2D::Value::operator<(const MultiConnection2D::Value& x) const{
+bool MultiConnection2D::Value::operator<(const MultiConnection2D::Value& x) const
+{
   if(myPntId[0] < x.myPntId[0]) return true;
   if(myPntId[0] == x.myPntId[0])
     if(myPntId[1] < x.myPntId[1]) return true;
   return false;
 }
 
-void MultiConnection2D::GetValues(MValues& theValues){
+void MultiConnection2D::GetValues(MValues& theValues)
+{
   if ( !myMesh ) return;
   SMDS_FaceIteratorPtr anIter = myMesh->facesIterator();
   for(; anIter->more(); ){
@@ -2373,26 +2447,15 @@ bool FreeEdges::IsSatisfy( long theId )
   if ( aFace == 0 || aFace->GetType() != SMDSAbs_Face || aFace->NbNodes() < 3 )
     return false;
 
-  SMDS_ElemIteratorPtr anIter;
-  if ( aFace->IsQuadratic() ) {
-    anIter = dynamic_cast<const SMDS_VtkFace*>
-      (aFace)->interlacedNodesElemIterator();
-  }
-  else {
-    anIter = aFace->nodesIterator();
-  }
+  SMDS_NodeIteratorPtr anIter = aFace->interlacedNodesIterator();
   if ( !anIter )
     return false;
 
   int i = 0, nbNodes = aFace->NbNodes();
   std::vector <const SMDS_MeshNode*> aNodes( nbNodes+1 );
   while( anIter->more() )
-  {
-    const SMDS_MeshNode* aNode = (SMDS_MeshNode*)anIter->next();
-    if ( aNode == 0 )
+    if ( ! ( aNodes[ i++ ] = anIter->next() ))
       return false;
-    aNodes[ i++ ] = aNode;
-  }
   aNodes[ nbNodes ] = aNodes[ 0 ];
 
   for ( i = 0; i < nbNodes; i++ )
@@ -2525,7 +2588,7 @@ bool FreeFaces::IsSatisfy( long theId )
 
   int nbNode = aFace->NbNodes();
 
-  // collect volumes check that number of volumss with count equal nbNode not less than 2
+  // collect volumes to check that number of volumes with count equal nbNode not less than 2
   typedef map< SMDS_MeshElement*, int > TMapOfVolume; // map of volume counters
   typedef map< SMDS_MeshElement*, int >::iterator TItrMapOfVolume; // iterator
   TMapOfVolume mapOfVol;
@@ -2605,7 +2668,7 @@ GroupColor::GroupColor()
 
 bool GroupColor::IsSatisfy( long theId )
 {
-  return (myIDs.find( theId ) != myIDs.end());
+  return myIDs.count( theId );
 }
 
 void GroupColor::SetType( SMDSAbs_ElementType theType )
@@ -2623,16 +2686,15 @@ static bool isEqual( const Quantity_Color& theColor1,
 {
   // tolerance to compare colors
   const double tol = 5*1e-3;
-  return ( fabs( theColor1.Red() - theColor2.Red() ) < tol &&
+  return ( fabs( theColor1.Red()   - theColor2.Red() )   < tol &&
            fabs( theColor1.Green() - theColor2.Green() ) < tol &&
-           fabs( theColor1.Blue() - theColor2.Blue() ) < tol );
+           fabs( theColor1.Blue()  - theColor2.Blue() )  < tol );
 }
 
-
 void GroupColor::SetMesh( const SMDS_Mesh* theMesh )
 {
   myIDs.clear();
-  
+
   const SMESHDS_Mesh* aMesh = dynamic_cast<const SMESHDS_Mesh*>(theMesh);
   if ( !aMesh )
     return;
@@ -2640,20 +2702,24 @@ void GroupColor::SetMesh( const SMDS_Mesh* theMesh )
   int nbGrp = aMesh->GetNbGroups();
   if ( !nbGrp )
     return;
-  
+
   // iterates on groups and find necessary elements ids
   const std::set<SMESHDS_GroupBase*>& aGroups = aMesh->GetGroups();
   set<SMESHDS_GroupBase*>::const_iterator GrIt = aGroups.begin();
-  for (; GrIt != aGroups.end(); GrIt++) {
+  for (; GrIt != aGroups.end(); GrIt++)
+  {
     SMESHDS_GroupBase* aGrp = (*GrIt);
     if ( !aGrp )
       continue;
     // check type and color of group
-    if ( !isEqual( myColor, aGrp->GetColor() ) )
-      continue;
-    if ( myType != SMDSAbs_All && myType != (SMDSAbs_ElementType)aGrp->GetType() )
+    if ( !isEqual( myColor, aGrp->GetColor() ))
       continue;
 
+    // IPAL52867 (prevent infinite recursion via GroupOnFilter)
+    if ( SMESHDS_GroupOnFilter * gof = dynamic_cast< SMESHDS_GroupOnFilter* >( aGrp ))
+      if ( gof->GetPredicate().get() == this )
+        continue;
+
     SMDSAbs_ElementType aGrpElType = (SMDSAbs_ElementType)aGrp->GetType();
     if ( myType == aGrpElType || (myType == SMDSAbs_All && aGrpElType != SMDSAbs_Node) ) {
       // add elements IDS into control
@@ -2945,6 +3011,17 @@ bool ConnectedElements::IsSatisfy( long theElementId )
  */
 //================================================================================
 
+namespace
+{
+  inline bool isLessAngle( const gp_Vec& v1, const gp_Vec& v2, const double cos )
+  {
+    double dot = v1 * v2; // cos * |v1| * |v2|
+    double l1  = v1.SquareMagnitude();
+    double l2  = v2.SquareMagnitude();
+    return (( dot * cos >= 0 ) && 
+            ( dot * dot ) / l1 / l2 >= ( cos * cos ));
+  }
+}
 CoplanarFaces::CoplanarFaces()
   : myFaceID(0), myToler(0)
 {
@@ -2956,7 +3033,7 @@ void CoplanarFaces::SetMesh( const SMDS_Mesh* theMesh )
   {
     // Build a set of coplanar face ids
 
-    myCoplanarIDs.clear();
+    myCoplanarIDs.Clear();
 
     if ( !myMeshModifTracer.GetMesh() || !myFaceID || !myToler )
       return;
@@ -2970,8 +3047,8 @@ void CoplanarFaces::SetMesh( const SMDS_Mesh* theMesh )
     if (!normOK)
       return;
 
-    const double radianTol = myToler * M_PI / 180.;
-    std::set< SMESH_TLink > checkedLinks;
+    const double cosTol = Cos( myToler * M_PI / 180. );
+    NCollection_Map< SMESH_TLink, SMESH_TLink > checkedLinks;
 
     std::list< pair< const SMDS_MeshElement*, gp_Vec > > faceQueue;
     faceQueue.push_back( make_pair( face, myNorm ));
@@ -2985,7 +3062,7 @@ void CoplanarFaces::SetMesh( const SMDS_Mesh* theMesh )
       {
         const SMDS_MeshNode*  n1 = face->GetNode( i );
         const SMDS_MeshNode*  n2 = face->GetNode(( i+1 )%nbN);
-        if ( !checkedLinks.insert( SMESH_TLink( n1, n2 )).second )
+        if ( !checkedLinks.Add( SMESH_TLink( n1, n2 )))
           continue;
         SMDS_ElemIteratorPtr fIt = n1->GetInverseElementIterator(SMDSAbs_Face);
         while ( fIt->more() )
@@ -2994,9 +3071,9 @@ void CoplanarFaces::SetMesh( const SMDS_Mesh* theMesh )
           if ( f->GetNodeIndex( n2 ) > -1 )
           {
             gp_Vec norm = getNormale( static_cast<const SMDS_MeshFace*>(f), &normOK );
-            if (!normOK || myNorm.Angle( norm ) <= radianTol)
+            if (!normOK || isLessAngle( myNorm, norm, cosTol))
             {
-              myCoplanarIDs.insert( f->GetID() );
+              myCoplanarIDs.Add( f->GetID() );
               faceQueue.push_back( make_pair( f, norm ));
             }
           }
@@ -3007,7 +3084,7 @@ void CoplanarFaces::SetMesh( const SMDS_Mesh* theMesh )
 }
 bool CoplanarFaces::IsSatisfy( long theElementId )
 {
-  return myCoplanarIDs.count( theElementId );
+  return myCoplanarIDs.Contains( theElementId );
 }
 
 /*
@@ -3618,7 +3695,7 @@ bool ManifoldPart::process()
       myMapIds.Add( aFaceId );
     }
 
-    if ( fi == ( myAllFacePtr.size() - 1 ) )
+    if ( fi == int( myAllFacePtr.size() - 1 ))
       fi = 0;
   } // end run on vector of faces
   return !myMapIds.IsEmpty();
@@ -3820,9 +3897,59 @@ void ManifoldPart::getFacesByLink( const ManifoldPart::Link& theLink,
   }
 }
 
+/*
+  Class       : BelongToMeshGroup
+  Description : Verify whether a mesh element is included into a mesh group
+*/
+BelongToMeshGroup::BelongToMeshGroup(): myGroup( 0 )
+{
+}
+
+void BelongToMeshGroup::SetGroup( SMESHDS_GroupBase* g )
+{
+  myGroup = g;
+}
+
+void BelongToMeshGroup::SetStoreName( const std::string& sn )
+{
+  myStoreName = sn;
+}
+
+void BelongToMeshGroup::SetMesh( const SMDS_Mesh* theMesh )
+{
+  if ( myGroup && myGroup->GetMesh() != theMesh )
+  {
+    myGroup = 0;
+  }
+  if ( !myGroup && !myStoreName.empty() )
+  {
+    if ( const SMESHDS_Mesh* aMesh = dynamic_cast<const SMESHDS_Mesh*>(theMesh))
+    {
+      const std::set<SMESHDS_GroupBase*>& grps = aMesh->GetGroups();
+      std::set<SMESHDS_GroupBase*>::const_iterator g = grps.begin();
+      for ( ; g != grps.end() && !myGroup; ++g )
+        if ( *g && myStoreName == (*g)->GetStoreName() )
+          myGroup = *g;
+    }
+  }
+  if ( myGroup )
+  {
+    myGroup->IsEmpty(); // make GroupOnFilter update its predicate
+  }
+}
+
+bool BelongToMeshGroup::IsSatisfy( long theElementId )
+{
+  return myGroup ? myGroup->Contains( theElementId ) : false;
+}
+
+SMDSAbs_ElementType BelongToMeshGroup::GetType() const
+{
+  return myGroup ? myGroup->GetType() : SMDSAbs_All;
+}
 
 /*
-   ElementsOnSurface
+  ElementsOnSurface
 */
 
 ElementsOnSurface::ElementsOnSurface()
@@ -3999,7 +4126,41 @@ void ElementsOnShape::SetAllNodes (bool theAllNodes)
 
 void ElementsOnShape::SetMesh (const SMDS_Mesh* theMesh)
 {
-  myMesh = theMesh;
+  myMeshModifTracer.SetMesh( theMesh );
+  if ( myMeshModifTracer.IsMeshModified())
+  {
+    size_t nbNodes = theMesh ? theMesh->NbNodes() : 0;
+    if ( myNodeIsChecked.size() == nbNodes )
+    {
+      std::fill( myNodeIsChecked.begin(), myNodeIsChecked.end(), false );
+    }
+    else
+    {
+      SMESHUtils::FreeVector( myNodeIsChecked );
+      SMESHUtils::FreeVector( myNodeIsOut );
+      myNodeIsChecked.resize( nbNodes, false );
+      myNodeIsOut.resize( nbNodes );
+    }
+  }
+}
+
+bool ElementsOnShape::getNodeIsOut( const SMDS_MeshNode* n, bool& isOut )
+{
+  if ( n->GetID() >= (int) myNodeIsChecked.size() ||
+       !myNodeIsChecked[ n->GetID() ])
+    return false;
+
+  isOut = myNodeIsOut[ n->GetID() ];
+  return true;
+}
+
+void ElementsOnShape::setNodeIsOut( const SMDS_MeshNode* n, bool  isOut )
+{
+  if ( n->GetID() < (int) myNodeIsChecked.size() )
+  {
+    myNodeIsChecked[ n->GetID() ] = true;
+    myNodeIsOut    [ n->GetID() ] = isOut;
+  }
 }
 
 void ElementsOnShape::SetShape (const TopoDS_Shape&       theShape,
@@ -4008,7 +4169,7 @@ void ElementsOnShape::SetShape (const TopoDS_Shape&       theShape,
   myType  = theType;
   myShape = theShape;
   if ( myShape.IsNull() ) return;
-  
+
   TopTools_IndexedMapOfShape shapesMap;
   TopAbs_ShapeEnum shapeTypes[4] = { TopAbs_SOLID, TopAbs_FACE, TopAbs_EDGE, TopAbs_VERTEX };
   TopExp_Explorer sub;
@@ -4026,6 +4187,16 @@ void ElementsOnShape::SetShape (const TopoDS_Shape&       theShape,
   myClassifiers.resize( shapesMap.Extent() );
   for ( int i = 0; i < shapesMap.Extent(); ++i )
     myClassifiers[ i ] = new TClassifier( shapesMap( i+1 ), myToler );
+
+  if ( theType == SMDSAbs_Node )
+  {
+    SMESHUtils::FreeVector( myNodeIsChecked );
+    SMESHUtils::FreeVector( myNodeIsOut );
+  }
+  else
+  {
+    std::fill( myNodeIsChecked.begin(), myNodeIsChecked.end(), false );
+  }
 }
 
 void ElementsOnShape::clearClassifiers()
@@ -4037,38 +4208,45 @@ void ElementsOnShape::clearClassifiers()
 
 bool ElementsOnShape::IsSatisfy (long elemId)
 {
+  const SMDS_Mesh*        mesh = myMeshModifTracer.GetMesh();
   const SMDS_MeshElement* elem =
-    ( myType == SMDSAbs_Node ? myMesh->FindNode( elemId ) : myMesh->FindElement( elemId ));
+    ( myType == SMDSAbs_Node ? mesh->FindNode( elemId ) : mesh->FindElement( elemId ));
   if ( !elem || myClassifiers.empty() )
     return false;
 
-  for ( size_t i = 0; i < myClassifiers.size(); ++i )
+  bool isSatisfy = myAllNodesFlag, isNodeOut;
+
+  gp_XYZ centerXYZ (0, 0, 0);
+
+  SMDS_ElemIteratorPtr aNodeItr = elem->nodesIterator();
+  while (aNodeItr->more() && (isSatisfy == myAllNodesFlag))
   {
-    SMDS_ElemIteratorPtr aNodeItr = elem->nodesIterator();
-    bool isSatisfy = myAllNodesFlag;
-    
-    gp_XYZ centerXYZ (0, 0, 0);
+    SMESH_TNodeXYZ aPnt( aNodeItr->next() );
+    centerXYZ += aPnt;
 
-    while (aNodeItr->more() && (isSatisfy == myAllNodesFlag))
+    isNodeOut = true;
+    if ( !getNodeIsOut( aPnt._node, isNodeOut ))
     {
-      SMESH_TNodeXYZ aPnt ( aNodeItr->next() );
-      centerXYZ += aPnt;
-      isSatisfy = ! myClassifiers[i]->IsOut( aPnt );
+      for ( size_t i = 0; i < myClassifiers.size() && isNodeOut; ++i )
+        isNodeOut = myClassifiers[i]->IsOut( aPnt );
+
+      setNodeIsOut( aPnt._node, isNodeOut );
     }
+    isSatisfy = !isNodeOut;
+  }
 
-    // Check the center point for volumes MantisBug 0020168
-    if (isSatisfy &&
-        myAllNodesFlag &&
-        myClassifiers[i]->ShapeType() == TopAbs_SOLID)
-    {
-      centerXYZ /= elem->NbNodes();
+  // Check the center point for volumes MantisBug 0020168
+  if (isSatisfy &&
+      myAllNodesFlag &&
+      myClassifiers[0]->ShapeType() == TopAbs_SOLID)
+  {
+    centerXYZ /= elem->NbNodes();
+    isSatisfy = false;
+    for ( size_t i = 0; i < myClassifiers.size() && !isSatisfy; ++i )
       isSatisfy = ! myClassifiers[i]->IsOut( centerXYZ );
-    }
-    if ( isSatisfy )
-      return true;
   }
 
-  return false;
+  return isSatisfy;
 }
 
 TopAbs_ShapeEnum ElementsOnShape::TClassifier::ShapeType() const
@@ -4308,6 +4486,7 @@ bool BelongToGeom::IsSatisfy (long theId)
       case SMDS_TOP_FACE   : return ( IsContains( myMeshDS,myShape,aNode,TopAbs_FACE ));
       case SMDS_TOP_3DSPACE: return ( IsContains( myMeshDS,myShape,aNode,TopAbs_SOLID ) ||
                                       IsContains( myMeshDS,myShape,aNode,TopAbs_SHELL ));
+      default:;
       }
     }
   }
@@ -4333,6 +4512,7 @@ bool BelongToGeom::IsSatisfy (long theId)
         case SMDSAbs_Face  : return ( IsContains( myMeshDS,myShape,anElem,TopAbs_FACE ));
         case SMDSAbs_Volume: return ( IsContains( myMeshDS,myShape,anElem,TopAbs_SOLID )||
                                       IsContains( myMeshDS,myShape,anElem,TopAbs_SHELL ));
+        default:;
         }
       }
     }
@@ -4409,12 +4589,22 @@ void LyingOnGeom::init()
     myIsSubshape = false;
   }
   else {
-    TopTools_IndexedMapOfShape aMap;
-    TopExp::MapShapes(aMainShape, aMap);
-    myIsSubshape = IsSubShape(aMap, myShape);
+    myIsSubshape = myMeshDS->IsGroupOfSubShapes( myShape );
   }
 
-  if (!myIsSubshape)
+  if (myIsSubshape)
+  {
+    TopTools_IndexedMapOfShape shapes;
+    TopExp::MapShapes( myShape, shapes );
+    mySubShapesIDs.Clear();
+    for ( int i = 1; i <= shapes.Extent(); ++i )
+    {
+      int subID = myMeshDS->ShapeToIndex( shapes( i ));
+      if ( subID > 0 )
+        mySubShapesIDs.Add( subID );
+    }
+  }
+  else
   {
     myElementsOnShapePtr.reset(new ElementsOnShape());
     myElementsOnShapePtr->SetTolerance(myTolerance);
@@ -4434,43 +4624,22 @@ bool LyingOnGeom::IsSatisfy( long theId )
     return myElementsOnShapePtr->IsSatisfy(theId);
   }
 
-  // Case of submesh
-  if( myType == SMDSAbs_Node )
-  {
-    if( const SMDS_MeshNode* aNode = myMeshDS->FindNode( theId ) )
-    {
-      const SMDS_PositionPtr& aPosition = aNode->GetPosition();
-      SMDS_TypeOfPosition aTypeOfPosition = aPosition->GetTypeOfPosition();
-      switch( aTypeOfPosition )
-      {
-      case SMDS_TOP_VERTEX : return IsContains( myMeshDS,myShape,aNode,TopAbs_VERTEX );
-      case SMDS_TOP_EDGE   : return IsContains( myMeshDS,myShape,aNode,TopAbs_EDGE );
-      case SMDS_TOP_FACE   : return IsContains( myMeshDS,myShape,aNode,TopAbs_FACE );
-      case SMDS_TOP_3DSPACE: return IsContains( myMeshDS,myShape,aNode,TopAbs_SHELL );
-      }
-    }
-  }
-  else
+  // Case of sub-mesh
+
+  const SMDS_MeshElement* elem =
+    ( myType == SMDSAbs_Node ) ? myMeshDS->FindNode( theId ) : myMeshDS->FindElement( theId );
+
+  if ( mySubShapesIDs.Contains( elem->getshapeId() ))
+    return true;
+
+  if ( elem->GetType() != SMDSAbs_Node )
   {
-    if( const SMDS_MeshElement* anElem = myMeshDS->FindElement( theId ) )
+    SMDS_ElemIteratorPtr nodeItr = elem->nodesIterator();
+    while ( nodeItr->more() )
     {
-      if( myType == SMDSAbs_All )
-      {
-        return Contains( myMeshDS,myShape,anElem,TopAbs_EDGE ) ||
-               Contains( myMeshDS,myShape,anElem,TopAbs_FACE ) ||
-               Contains( myMeshDS,myShape,anElem,TopAbs_SHELL )||
-               Contains( myMeshDS,myShape,anElem,TopAbs_SOLID );
-      }
-      else if( myType == anElem->GetType() )
-      {
-        switch( myType )
-        {
-        case SMDSAbs_Edge  : return Contains( myMeshDS,myShape,anElem,TopAbs_EDGE );
-        case SMDSAbs_Face  : return Contains( myMeshDS,myShape,anElem,TopAbs_FACE );
-        case SMDSAbs_Volume: return Contains( myMeshDS,myShape,anElem,TopAbs_SHELL )||
-                                    Contains( myMeshDS,myShape,anElem,TopAbs_SOLID );
-        }
-      }
+      const SMDS_MeshElement* aNode = nodeItr->next();
+      if ( mySubShapesIDs.Contains( aNode->getshapeId() ))
+        return true;
     }
   }
 
@@ -4516,51 +4685,47 @@ bool LyingOnGeom::Contains( const SMESHDS_Mesh*     theMeshDS,
                             TopAbs_ShapeEnum        theFindShapeEnum,
                             TopAbs_ShapeEnum        theAvoidShapeEnum )
 {
-  if (IsContains(theMeshDS, theShape, theElem, theFindShapeEnum, theAvoidShapeEnum))
-    return true;
-
-  TopTools_IndexedMapOfShape aSubShapes;
-  TopExp::MapShapes( theShape, aSubShapes );
-
-  for (int i = 1; i <= aSubShapes.Extent(); i++)
-  {
-    const TopoDS_Shape& aShape = aSubShapes.FindKey(i);
-
-    if( SMESHDS_SubMesh* aSubMesh = theMeshDS->MeshElements( aShape ) ){
-      if( aSubMesh->Contains( theElem ) )
-        return true;
-
-      SMDS_NodeIteratorPtr aNodeIt = aSubMesh->GetNodes();
-      while ( aNodeIt->more() )
-      {
-        const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(aNodeIt->next());
-        SMDS_ElemIteratorPtr anElemIt = aNode->GetInverseElementIterator();
-        while ( anElemIt->more() )
-        {
-          const SMDS_MeshElement* anElement = static_cast<const SMDS_MeshElement*>(anElemIt->next());
-          if (anElement == theElem)
-            return true;
-        }
-      }
-    }
-  }
+  // if (IsContains(theMeshDS, theShape, theElem, theFindShapeEnum, theAvoidShapeEnum))
+  //   return true;
+
+  // TopTools_MapOfShape aSubShapes;
+  // TopExp_Explorer exp( theShape, theFindShapeEnum, theAvoidShapeEnum );
+  // for ( ; exp.More(); exp.Next() )
+  // {
+  //   const TopoDS_Shape& aShape = exp.Current();
+  //   if ( !aSubShapes.Add( aShape )) continue;
+
+  //   if ( SMESHDS_SubMesh* aSubMesh = theMeshDS->MeshElements( aShape ))
+  //   {
+  //     if ( aSubMesh->Contains( theElem ))
+  //       return true;
+
+  //     SMDS_ElemIteratorPtr nodeItr = theElem->nodesIterator();
+  //     while ( nodeItr->more() )
+  //     {
+  //       const SMDS_MeshElement* aNode = nodeItr->next();
+  //       if ( aSubMesh->Contains( aNode ))
+  //         return true;
+  //     }
+  //   }
+  // }
   return false;
 }
 
-TSequenceOfXYZ::TSequenceOfXYZ()
+TSequenceOfXYZ::TSequenceOfXYZ(): myElem(0)
 {}
 
-TSequenceOfXYZ::TSequenceOfXYZ(size_type n) : myArray(n)
+TSequenceOfXYZ::TSequenceOfXYZ(size_type n) : myArray(n), myElem(0)
 {}
 
-TSequenceOfXYZ::TSequenceOfXYZ(size_type n, const gp_XYZ& t) : myArray(n,t)
+TSequenceOfXYZ::TSequenceOfXYZ(size_type n, const gp_XYZ& t) : myArray(n,t), myElem(0)
 {}
 
-TSequenceOfXYZ::TSequenceOfXYZ(const TSequenceOfXYZ& theSequenceOfXYZ) : myArray(theSequenceOfXYZ.myArray)
+TSequenceOfXYZ::TSequenceOfXYZ(const TSequenceOfXYZ& theSequenceOfXYZ) : myArray(theSequenceOfXYZ.myArray), myElem(theSequenceOfXYZ.myElem)
 {}
 
 template <class InputIterator>
-TSequenceOfXYZ::TSequenceOfXYZ(InputIterator theBegin, InputIterator theEnd): myArray(theBegin,theEnd)
+TSequenceOfXYZ::TSequenceOfXYZ(InputIterator theBegin, InputIterator theEnd): myArray(theBegin,theEnd), myElem(0)
 {}
 
 TSequenceOfXYZ::~TSequenceOfXYZ()
@@ -4569,6 +4734,7 @@ TSequenceOfXYZ::~TSequenceOfXYZ()
 TSequenceOfXYZ& TSequenceOfXYZ::operator=(const TSequenceOfXYZ& theSequenceOfXYZ)
 {
   myArray = theSequenceOfXYZ.myArray;
+  myElem  = theSequenceOfXYZ.myElem;
   return *this;
 }
 
@@ -4602,6 +4768,11 @@ TSequenceOfXYZ::size_type TSequenceOfXYZ::size() const
   return myArray.size();
 }
 
+SMDSAbs_EntityType TSequenceOfXYZ::getElementEntity() const
+{
+  return myElem ? myElem->GetEntityType() : SMDSEntity_Last;
+}
+
 TMeshModifTracer::TMeshModifTracer():
   myMeshModifTime(0), myMesh(0)
 {
index 36b86c9de5bfc21a731a2b0bf0ec241859676d8c..c7398b0ef4d0364f7d49480b2e8e5aa3924a85f7 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -37,7 +37,6 @@
 #include <TColStd_SequenceOfInteger.hxx>
 #include <TCollection_AsciiString.hxx>
 #include <TopAbs.hxx>
-#include <TopTools_MapOfShape.hxx>
 #include <TopoDS_Face.hxx>
 #include <gp_XYZ.hxx>
 
@@ -54,6 +53,7 @@ class SMDS_Mesh;
 
 class SMESHDS_Mesh;
 class SMESHDS_SubMesh;
+class SMESHDS_GroupBase;
 
 class gp_Pnt;
 
@@ -67,7 +67,7 @@ namespace SMESH{
     public:
       TSequenceOfXYZ();
 
-      TSequenceOfXYZ(size_type n);
+      explicit TSequenceOfXYZ(size_type n);
 
       TSequenceOfXYZ(size_type n, const gp_XYZ& t);
 
@@ -92,8 +92,16 @@ namespace SMESH{
 
       size_type size() const;
 
+
+      void setElement(const SMDS_MeshElement* e) { myElem = e; }
+
+      const SMDS_MeshElement* getElement() const { return myElem; }
+
+      SMDSAbs_EntityType getElementEntity() const;
+
     private:
-      std::vector<gp_XYZ> myArray;
+      std::vector<gp_XYZ>     myArray;
+      const SMDS_MeshElement* myElem;
     };
 
     /*!
@@ -763,8 +771,8 @@ namespace SMESH{
                               TMapOfLink&            theNonManifold,
                               SMDS_MeshFace*         theNextFace ) const;
 
-     void     getFacesByLink( const Link& theLink,
-                              TVectorOfFacePtr& theFaces ) const;
+      void     getFacesByLink( const Link& theLink,
+                               TVectorOfFacePtr& theFaces ) const;
 
     private:
       const SMDS_Mesh*      myMesh;
@@ -779,6 +787,27 @@ namespace SMESH{
     };
     typedef boost::shared_ptr<ManifoldPart> ManifoldPartPtr;
 
+    /*
+      Class       : BelongToMeshGroup
+      Description : Verify whether a mesh element is included into a mesh group
+    */
+    class SMESHCONTROLS_EXPORT BelongToMeshGroup : public virtual Predicate
+    {
+    public:
+      BelongToMeshGroup();
+      virtual void SetMesh( const SMDS_Mesh* theMesh );
+      virtual bool IsSatisfy( long theElementId );
+      virtual SMDSAbs_ElementType GetType() const;
+
+      void SetGroup( SMESHDS_GroupBase* g );
+      void SetStoreName( const std::string& sn );
+      const SMESHDS_GroupBase* GetGroup() const { return myGroup; }
+
+    private:
+      SMESHDS_GroupBase* myGroup;
+      std::string        myStoreName;
+    };
+    typedef boost::shared_ptr<BelongToMeshGroup> BelongToMeshGroupPtr;
 
     /*
       Class       : ElementsOnSurface
@@ -809,7 +838,6 @@ namespace SMESH{
       TMeshModifTracer      myMeshModifTracer;
       TColStd_MapOfInteger  myIds;
       SMDSAbs_ElementType   myType;
-      //Handle(Geom_Surface)  mySurf;
       TopoDS_Face           mySurf;
       double                myToler;
       bool                  myUseBoundaries;
@@ -867,14 +895,18 @@ namespace SMESH{
         double                      myTol;
       };
       void clearClassifiers();
+      bool getNodeIsOut( const SMDS_MeshNode* n, bool& isOut );
+      void setNodeIsOut( const SMDS_MeshNode* n, bool  isOut );
 
       std::vector< TClassifier* > myClassifiers;
-      const SMDS_Mesh*            myMesh;
       SMDSAbs_ElementType         myType;
       TopoDS_Shape                myShape;
       double                      myToler;
       bool                        myAllNodesFlag;
 
+      TMeshModifTracer            myMeshModifTracer;
+      std::vector<bool>           myNodeIsChecked;
+      std::vector<bool>           myNodeIsOut;
     };
 
     typedef boost::shared_ptr<ElementsOnShape> ElementsOnShapePtr;
@@ -949,6 +981,7 @@ namespace SMESH{
       virtual void                    init();
 
       TopoDS_Shape                    myShape;
+      TColStd_MapOfInteger            mySubShapesIDs;
       const SMESHDS_Mesh*             myMeshDS;
       SMDSAbs_ElementType             myType;
       bool                            myIsSubshape;
@@ -1055,7 +1088,7 @@ namespace SMESH{
       TMeshModifTracer     myMeshModifTracer;
       long                 myFaceID;
       double               myToler;
-      std::set< long >     myCoplanarIDs;
+      TColStd_MapOfInteger myCoplanarIDs;
     };
     typedef boost::shared_ptr<CoplanarFaces> CoplanarFacesPtr;
 
index 8eccaefcdd7094355a079cf7150ea99cd8ee968c..e334ab798f75938352b0df84b33c1b8ac17eba8b 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2012-2015  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
index 5f11f4ce69e1ca837b1775026d9c5c8e33bd20a3..d97bcd0c32ee56a616b05b3ce1ae3e19e472a46c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 9c11777074d80530702f879963be403e4229f60d..dc7cac68abff550658374671ff4b8a4435f03fed 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index c98d796c0b99f1bebb628a2b098b6e7fe3cd43cd..03971550da7ce8e5bb4ad5a3917400358875ff76 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 53a495de817a7669c67a72fac54299d708565ede..cada40f96763dcd096d5a35f988cb4cdcc93670b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index bef32a825027864fde72c8502eef92f0e1df70dc..e321b598017a03a5c3c4c56c21b616a9c3fe1535 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 40fa34ac4a5a46921ebe1116c47433181884a2de..09034571429690e9bd688344b29d8be647bcfda1 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 4000199df2578aee61b9f78f10d0c46c2d7a5a37..841e8cb593cde772971459328a4369a7df838a5e 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 24da12ab9b510757f8c7bc332012b033e5967a67..05a03baa9ede956a0b6593b5b1f4cfc63eb02d46 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index e74eb65844dd5653aac4ee56d33540de35951289..22406eae725e0ff85cb866f9a421ad594ef7969d 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2012-2015  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
index 4d3d1e4459aa993f2ca8549cb2162c1ccbaf969a..4393e471c2f72361e7ecc3880a5f251fcb8e2d4c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -234,7 +234,7 @@ namespace
         dist2 = ( nn1[1] - nn2[1] ).Modulus();
         tol   = 1e-5 * ( nn1[0] - nn1[1] ).Modulus();
       }
-      return ( dist1 < tol & dist2 < tol );
+      return ( dist1 < tol && dist2 < tol );
     }
     return false;
   }
@@ -451,7 +451,7 @@ namespace
     if ( !_nodeReplacementMap.empty() )
     {
       map< int, int >::const_iterator it, end = _nodeReplacementMap.end();
-      for ( size_t i = 0; i < nbIds; ++i )
+      for ( int i = 0; i < nbIds; ++i )
         if (( it = _nodeReplacementMap.find( ids[i] + idShift)) != end )
           ids[i] = it->second;
         else
@@ -459,7 +459,7 @@ namespace
     }
     else if ( idShift )
     {
-      for ( size_t i = 0; i < nbIds; ++i )
+      for ( int i = 0; i < nbIds; ++i )
         ids[i] += idShift;
     }
   }
@@ -1022,7 +1022,7 @@ Driver_Mesh::Status DriverCGNS_Read::Perform()
           if ( zone.IsStructured() )
           {
             int axis = 0; // axis perpendiculaire to which boundary elements are oriented
-            if ( ids.size() >= meshDim * 2 )
+            if ( (int) ids.size() >= meshDim * 2 )
             {
               for ( ; axis < meshDim; ++axis )
                 if ( ids[axis] - ids[axis+meshDim] == 0 )
@@ -1127,7 +1127,7 @@ Driver_Mesh::Status DriverCGNS_Read::Perform()
 
             if ( psType == CGNS_ENUMV( PointRange ) && ids.size() == 2 )
             {
-              for ( size_t i = ids[0]; i <= ids[1]; ++i )
+              for ( cgsize_t i = ids[0]; i <= ids[1]; ++i )
                 if ( const SMDS_MeshElement* e = myMesh->FindElement( i ))
                   groupDS.Add( e );
             }
index 3d1962872aaa785b8e805d56a00237aedb4ea9da..6ae4b812a91f7c0b9f49d6756b9b2dfb2db891fc 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -35,7 +35,7 @@
 
 /*!
  * \brief Driver reading a mesh from the CGNS file. The mesh to read is selected by 
- *  an index (counted form 0) set via SetMeshId()
+ *  an index (counted from 0) set via SetMeshId()
  */
 class MESHDriverCGNS_EXPORT DriverCGNS_Read : public Driver_SMESHDS_Mesh
 {
index 1afa5423954d2fe1978d9b1e3dca416480e8dd1f..f83fe915e283cb75693c039c6f63f3717a4f8488 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -147,6 +147,7 @@ namespace
       }
       {
         cgTypes[SMDSEntity_Polygon]         = CGNS_ENUMV( NGON_n );
+        cgTypes[SMDSEntity_Quad_Polygon]    = CGNS_ENUMV( NGON_n );
         cgTypes[SMDSEntity_Polyhedra]       = CGNS_ENUMV( NFACE_n );
         cgTypes[SMDSEntity_Hexagonal_Prism] = CGNS_ENUMV( NFACE_n );
       }
@@ -370,6 +371,21 @@ Driver_Mesh::Status DriverCGNS_Write::Perform()
       }
       while ( elem && elem->GetEntityType() == elemType );
 
+    else if ( elemType == SMDSEntity_Quad_Polygon ) // QUADRATIC POLYGONS
+      do // write as linear NGON_n
+      {
+        elemData.push_back( elem->NbNodes() );
+        interlace = & SMDS_MeshCell::interlacedSmdsOrder( SMDSEntity_Quad_Polygon,
+                                                          elem->NbNodes() )[0];
+        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_Polyhedra ||
               elemType == SMDSEntity_Hexagonal_Prism) // POLYHEDRA
     {
index 9457285522217ecebeed065c7ecdf76d4cae2195..1f6d0f36601854880b9535e7883f3badbbbe60e1 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 59381dfd7d5766080523ec42edb92074400e13e2..2c24fb5c384f0f952d0f8f7872922207d42ee3f1 100755 (executable)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index cf87186d8a3b4f221190f7d62506446b443f3b62..cf024279cc437a36b1b7ebdceef03e60a7b167fc 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2012-2015  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
index cf85859910db8b9789d616bb26b61d2154de8de3..7c1616a2a31ee15db67d7f7d5b07ed7438528706 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -53,7 +53,7 @@ Driver_Mesh::Status DriverDAT_R_SMDS_Mesh::Perform()
    ****************************************************************************/
   char *file2Read = (char *)myFile.c_str();
   FILE* aFileId = fopen(file2Read, "r");
-  if (aFileId < 0) {
+  if ( !aFileId ) {
     fprintf(stderr, ">> ERREUR : ouverture du fichier %s \n", file2Read);
     return DRS_FAIL;
   }
index 4b877073bf73532bab8c8a6d9d0a2defadd3b0f1..b95ddabcb0f319718ec7ca5b6da00ef1d02313de 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 400daa548c30b9d97c3a350ed6303aac1dd5ae9a..63de896b38e3d67a147e1ab3d47ab46679d0a4e1 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -38,11 +38,10 @@ Driver_Mesh::Status DriverDAT_W_SMDS_Mesh::Perform()
   Status aResult = DRS_OK;
 
   int nbNodes, nbCells;
-  //int i;
-  
+
   char *file2Read = (char *)myFile.c_str();
   FILE* aFileId = fopen(file2Read, "w+");
-  if (aFileId < 0) {
+  if ( !aFileId ) {
     fprintf(stderr, ">> ERREUR : ouverture du fichier %s \n", file2Read);
     return DRS_FAIL;
   }
@@ -50,12 +49,12 @@ Driver_Mesh::Status DriverDAT_W_SMDS_Mesh::Perform()
   /****************************************************************************
    *                       NOMBRES D'OBJETS                                    *
    ****************************************************************************/
-  
+
   /* Combien de noeuds ? */
   nbNodes = myMesh->NbNodes();
-  
+
   /* Combien de mailles, faces ou aretes ? */
-  int /*nb_of_nodes,*/ nb_of_edges, nb_of_faces, nb_of_volumes;
+  int nb_of_edges, nb_of_faces, nb_of_volumes;
   nb_of_edges = myMesh->NbEdges();
   nb_of_faces = myMesh->NbFaces();
   nb_of_volumes = myMesh->NbVolumes();
@@ -63,18 +62,18 @@ Driver_Mesh::Status DriverDAT_W_SMDS_Mesh::Perform()
   SCRUTE(nb_of_edges);
   SCRUTE(nb_of_faces);
   SCRUTE(nb_of_volumes);
-  
-  fprintf(stdout, "%d %d\n", nbNodes, nbCells);
+
+  //fprintf(stdout, "%d %d\n", nbNodes, nbCells);
   fprintf(aFileId, "%d %d\n", nbNodes, nbCells);
-  
+
   /****************************************************************************
    *                       ECRITURE DES NOEUDS                                 *
    ****************************************************************************/
-  
+
   SMDS_NodeIteratorPtr itNodes=myMesh->nodesIterator();
   while(itNodes->more()){               
     const SMDS_MeshNode * node = itNodes->next();
-    fprintf(aFileId, "%d %e %e %e\n", node->GetID(), node->X(), node->Y(), node->Z());
+    fprintf(aFileId, "%d %.14e %.14e %.14e\n", node->GetID(), node->X(), node->Y(), node->Z());
   }
         
   /****************************************************************************
index 39f9acd666e2f350773f9e779455a0f89b463bb4..e3725df03907c996e443f5f70bf5f7132fee4804 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index b22e5078d666b193cd73eb3bbb726384a71f6866..a0efc29173b8a59864fb663471349264039783be 100755 (executable)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 3c1bf7ada92ec1f52a85111ee4dbf3c7bd1e2ffa..dae9073ee6d9d5c1e66f6da049eb19525be797d2 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2012-2015  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
index 0337dd255eed8092518439cb546a0997712b181e..3c40bd0542128f85fddf81f8fe82b63463cda2a1 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 8393e14e250efd1c1a116aacd52fde6db2e04ac0..d15c24b71e281c9a39d43da0286e143ae779941b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 6fdeaab0f2a54018a5196c7eee5a48d6f3a86508..5dee87177794b9ddb04723c4f49215d18a2d6ff4 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -407,7 +407,7 @@ Driver_Mesh::Status DriverGMF_Read::Perform()
   {
     // get ids of existing groups
     std::set< int > groupIDs;
-    const std::set<SMESHDS_GroupBase*>& groups = myMesh->GetGroups();
+    const std::set<SMESHDS_GroupBase*>&          groups = myMesh->GetGroups();
     std::set<SMESHDS_GroupBase*>::const_iterator grIter = groups.begin();
     for ( ; grIter != groups.end(); ++grIter )
       groupIDs.insert( (*grIter)->GetID() );
index 5064840ef32bf1908057146950d6ff326a902bab..db8d5a142f813e7100d1a011c32247d8d73ae68a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index ddf3b7600a12690b86a217d8c9fd631cffb39b65..963f1bc17383a1e81b5f64ee77eddefe5ea4ac44 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -121,7 +121,7 @@ Driver_Mesh::Status DriverGMF_Write::Perform()
 {
   Kernel_Utils::Localizer loc;
 
-  const int dim = 3, version = sizeof(long) == 4 ? 2 : 3;
+  const int dim = 3, version = sizeof(double) < 8 ? 1 : 2;
 
   int meshID = GmfOpenMesh( myFile.c_str(), GmfWrite, version, dim );
   if ( !meshID )
@@ -296,19 +296,19 @@ Driver_Mesh::Status DriverGMF_Write::Perform()
       SMDSAbs_EntityType smdsEntity;
       std::string entity = groupName.substr( pos + strlen("_required_"));
       if      ( entity == "Vertices" ) {
-        gmfKwd   = GmfRequiredVertices;
+        gmfKwd     = GmfRequiredVertices;
         smdsEntity = SMDSEntity_Node;
       }
       else if ( entity == "Edges" ) {
-        gmfKwd   = GmfRequiredEdges;
+        gmfKwd     = GmfRequiredEdges;
         smdsEntity = SMDSEntity_Edge;
       }
       else if ( entity == "Triangles" ) {
-        gmfKwd   = GmfRequiredTriangles;
+        gmfKwd     = GmfRequiredTriangles;
         smdsEntity = SMDSEntity_Triangle;
       }
       else if ( entity == "Quadrilaterals" ) {
-        gmfKwd   = GmfRequiredQuadrilaterals;
+        gmfKwd     = GmfRequiredQuadrilaterals;
         smdsEntity = SMDSEntity_Quadrangle;
       }
       else {
@@ -330,11 +330,11 @@ Driver_Mesh::Status DriverGMF_Write::Perform()
 
       // choose a TElem2IDMap
       TElem2IDMap* elem2IDMap = 0;
-      if ( smdsEntity == SMDSEntity_Quadrangle && nbOkElems != myMesh->NbFaces() )
+      if ( smdsEntity == SMDSEntity_Quadrangle    && nbOkElems != myMesh->NbFaces() )
         elem2IDMap = & quad2IDMap;
       else if ( smdsEntity == SMDSEntity_Triangle && nbOkElems != myMesh->NbFaces() )
         elem2IDMap = & tria2IDMap;
-      else if ( smdsEntity == SMDSEntity_Edge && nbOkElems != myMesh->NbEdges() )
+      else if ( smdsEntity == SMDSEntity_Edge     && nbOkElems != myMesh->NbEdges() )
         elem2IDMap = & edge2IDMap;
 
       // write the group
index 2b844d352765a280cc67be1417f556bb2753cef1..ae4a645806a3d438d659430ca37ee3bd83206157 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 0fb168ad52880917ec078a38e640769392346634..1b04c4acbe7676de58178f70d18165c922dbb093 100755 (executable)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 28d1b8a022f2ea05fbb21e82b2acf96ad3f8f7c9..6ddf6f27e88d8bee991c4e3eb15c94f513cbb18c 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2012-2015  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
index 299b610837ef0c0a1c4bc66fdf7ac26f505a079a..9b47216d239d2b300140cb121b8ecc82c9765b29 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 2f9aceb467012d1a9705c823fb6ab2c2ceb102b1..d682304fe699f98ffc30fabd6cbc359d9cafc5d4 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 5a1c4d66cdd2397988e763a47e9d0880c71cef41..c83534cf9b01e60bde87c3e02df50c738f25e524 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 4a11f8c997e25e3395a3dbecf1cc7e6eb678a808..74c3e6da8b73f060b0de531b9d2a06d2c29093aa 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 //  Module : SMESH
 
 #include "DriverMED_R_SMESHDS_Mesh.h"
-#include "SMESHDS_Mesh.hxx"
-#include "utilities.h"
 
 #include "DriverMED_Family.h"
-
 #include "SMESHDS_Group.hxx"
+#include "SMESHDS_Mesh.hxx"
+#include "SMESH_Comment.hxx"
 
-#include "MED_Factory.hxx"
 #include "MED_CoordUtils.hxx"
+#include "MED_Factory.hxx"
 #include "MED_Utilities.hxx"
 
 #include <NCollection_Map.hxx>
 
-#include <stdlib.h>
+#include "utilities.h"
+
+//#include <stdlib.h>
 
 #ifdef _DEBUG_
 static int MYDEBUG = 1;
@@ -62,579 +63,837 @@ namespace DriverMED
                        const TID2FamilyMap&  myFamilies);
   /*!
    * \brief Ensure aFamily has a required ID
-    * \param aFamily - a family to check
-    * \param anID - an ID aFamily should have
-    * \param myFamilies - a map of the family ID to the Family
-    * \retval bool  - true if successful
+   * \param aFamily - a family to check
+   * \param anID - an ID aFamily should have
+   * \param myFamilies - a map of the family ID to the Family
+   * \retval bool  - true if successful
    */
   bool checkFamilyID(DriverMED_FamilyPtr & aFamily,
                      int                   anID,
                      const TID2FamilyMap&  myFamilies);
-}
 
-void
-DriverMED_R_SMESHDS_Mesh
-::SetMeshName(string theMeshName)
-{
-  myMeshName = theMeshName;
+
+  const SMDS_MeshNode* FindNode(const SMDS_Mesh* theMesh, TInt theId)
+  {
+    const SMDS_MeshNode* aNode = theMesh->FindNode(theId);
+    if(aNode) return aNode;
+    EXCEPTION(runtime_error,"SMDS_Mesh::FindNode - cannot find a SMDS_MeshNode for ID = "<<theId);
+  }
+
 }
 
-static const SMDS_MeshNode* 
-FindNode(const SMDS_Mesh* theMesh, TInt theId)
+//================================================================================
+/*!
+ * \brief Stores a mesh name
+ */
+//================================================================================
+
+void DriverMED_R_SMESHDS_Mesh::SetMeshName(string theMeshName)
 {
-  const SMDS_MeshNode* aNode = theMesh->FindNode(theId);
-  if(aNode) return aNode;
-  EXCEPTION(runtime_error,"SMDS_Mesh::FindNode - cannot find a SMDS_MeshNode for ID = "<<theId);
+  myMeshName = theMeshName;
 }
 
+//================================================================================
+/*!
+ * \brief Reads a med file
+ */
+//================================================================================
 
-Driver_Mesh::Status 
-DriverMED_R_SMESHDS_Mesh
-::Perform()
+Driver_Mesh::Status DriverMED_R_SMESHDS_Mesh::Perform()
 {
+  using namespace DriverMED;
+
   Status aResult = DRS_FAIL;
   bool isDescConn = false; // Mantis issue 0020483
 #ifndef _DEXCEPT_
-  try{
+  try {
 #endif
     myFamilies.clear();
     if(MYDEBUG) MESSAGE("Perform - myFile : "<<myFile);
     PWrapper aMed = CrWrapper(myFile,true);
 
     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);
+    TInt aNbMeshes = aMed->GetNbMeshes();
+    for (int iMesh = 0; iMesh < aNbMeshes; iMesh++)
+    {
+      // Reading the MED mesh
+      //---------------------
+      PMeshInfo aMeshInfo = aMed->GetPMeshInfo(iMesh+1);
 
-        string aMeshName;
-        if (myMeshId != -1) {
-          ostringstream aMeshNameStr;
-          aMeshNameStr<<myMeshId;
-          aMeshName = aMeshNameStr.str();
-        } else {
-          aMeshName = myMeshName;
-        }
-        if(MYDEBUG) MESSAGE("Perform - aMeshName : "<<aMeshName<<"; "<<aMeshInfo->GetName());
-        if(aMeshName != aMeshInfo->GetName()) continue;
-        aResult = DRS_OK;
-
-        // Reading MED families to the temporary structure
-        //------------------------------------------------
-        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 << " :");
-            
-            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;
-            for (TInt iGr = 0; iGr < aNbGrp; iGr++) {
-              string aGroupName = aFamilyInfo->GetGroupName(iGr);
-              if(isAttrOk){
-                TInt anAttrVal = aFamilyInfo->GetAttrVal(iGr);
-                aFamily->SetGroupAttributVal(anAttrVal);
-              }
-              
-              if(MYDEBUG) MESSAGE(aGroupName);
-              aFamily->AddGroupName(aGroupName);
-              
+      string aMeshName;
+      if (myMeshId != -1) aMeshName = SMESH_Comment( myMeshId );
+      else                aMeshName = myMeshName;
+
+      if(MYDEBUG) MESSAGE("Perform - aMeshName : "<<aMeshName<<"; "<<aMeshInfo->GetName());
+      if ( aMeshName != aMeshInfo->GetName() ) continue;
+      aResult = DRS_OK;
+
+      // Reading MED families to the temporary structure
+      //------------------------------------------------
+      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 << " :");
+
+          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;
+          for (TInt iGr = 0; iGr < aNbGrp; iGr++)
+          {
+            string aGroupName = aFamilyInfo->GetGroupName(iGr);
+            if ( isAttrOk ) {
+              TInt anAttrVal = aFamilyInfo->GetAttrVal(iGr);
+              aFamily->SetGroupAttributVal(anAttrVal);
             }
-            aFamily->SetId( aFamId );
-            myFamilies[aFamId] = aFamily;
+            if(MYDEBUG) MESSAGE(aGroupName);
+            aFamily->AddGroupName(aGroupName);
           }
+          aFamily->SetId( aFamId );
+          myFamilies[aFamId] = aFamily;
         }
+      }
 
-        if (aMeshInfo->GetType() == MED::eSTRUCTURE){
-          /*bool aRes = */DriverMED::buildMeshGrille(aMed,aMeshInfo,myMesh,myFamilies);
-          continue;
-        }
+      if (aMeshInfo->GetType() == MED::eSTRUCTURE)
+      {
+        /*bool aRes = */DriverMED::buildMeshGrille(aMed,aMeshInfo,myMesh,myFamilies);
+        continue;
+      }
 
-        // Reading MED nodes to the corresponding SMDS structure
-        //------------------------------------------------------
-        PNodeInfo aNodeInfo = aMed->GetPNodeInfo(aMeshInfo);
-        if (!aNodeInfo) {
-          aResult = DRS_FAIL;
-          continue;
+      // Reading MED nodes to the corresponding SMDS structure
+      //------------------------------------------------------
+      PNodeInfo aNodeInfo = aMed->GetPNodeInfo(aMeshInfo);
+      if (!aNodeInfo) {
+        aResult = DRS_FAIL;
+        continue;
+      }
+      aMeshInfo->myDim=aMeshInfo->mySpaceDim;// ignore meshdim in MEDFile because it can be false
+      PCoordHelper aCoordHelper = GetCoordHelper(aNodeInfo);
+
+      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);
+        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
+            (aCoords[0],aCoords[1],aCoords[2],aNodeInfo->GetElemNum(iElem));
+        }
+        else {
+          aNode = myMesh->AddNodeWithID
+            (aCoords[0],aCoords[1],aCoords[2], iElem+1);
         }
-        aMeshInfo->myDim=aMeshInfo->mySpaceDim;// ignore meshdim in MEDFile because it can be false
-        PCoordHelper aCoordHelper = GetCoordHelper(aNodeInfo);
-
-        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);
-          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
-              (aCoords[0],aCoords[1],aCoords[2],aNodeInfo->GetElemNum(iElem));
-          } else {
-            aNode = myMesh->AddNodeWithID
-              (aCoords[0],aCoords[1],aCoords[2], iElem+1);
-          }
 
-          // Save reference to this node from its family
-          TInt aFamNum = aNodeInfo->GetFamNum(iElem);
-          if ( DriverMED::checkFamilyID ( aFamily, aFamNum, myFamilies ))
-          {
-            aFamily->AddElement(aNode);
-            aFamily->SetType(SMDSAbs_Node);
-          }
+        // Save reference to this node from its family
+        TInt aFamNum = aNodeInfo->GetFamNum(iElem);
+        if ( DriverMED::checkFamilyID ( aFamily, aFamNum, myFamilies ))
+        {
+          aFamily->AddElement(aNode);
+          aFamily->SetType(SMDSAbs_Node);
         }
+      }
 
-        // Are there any MED cells in descending connectivity
-        // Mantis issue 0020483
-        //---------------------------------------------------
-        NCollection_Map<EEntiteMaillage> aDescendingEntitiesMap;
-        if (!isDescConn) {
-          MED::TEntityInfo aEntityInfoDesc = aMed->GetEntityInfo(aMeshInfo, eDESC);
-          MED::TEntityInfo::iterator anEntityIterDesc = aEntityInfoDesc.begin();
-          //for (; anEntityIterDesc != aEntityInfoDesc.end() && !isDescConn; anEntityIterDesc++) {
-          for (; anEntityIterDesc != aEntityInfoDesc.end(); anEntityIterDesc++) {
-            const EEntiteMaillage& anEntity = anEntityIterDesc->first;
-            aDescendingEntitiesMap.Add(anEntity);
-            //if (anEntity != eNOEUD) isDescConn = true;
-          }
+      // Are there any MED cells in descending connectivity
+      // Mantis issue 0020483
+      //---------------------------------------------------
+      NCollection_Map<EEntiteMaillage> aDescendingEntitiesMap;
+      if (!isDescConn) {
+        MED::TEntityInfo aEntityInfoDesc = aMed->GetEntityInfo(aMeshInfo, eDESC);
+        MED::TEntityInfo::iterator anEntityIterDesc = aEntityInfoDesc.begin();
+        //for (; anEntityIterDesc != aEntityInfoDesc.end() && !isDescConn; anEntityIterDesc++) {
+        for (; anEntityIterDesc != aEntityInfoDesc.end(); anEntityIterDesc++) {
+          const EEntiteMaillage& anEntity = anEntityIterDesc->first;
+          aDescendingEntitiesMap.Add(anEntity);
+          //if (anEntity != eNOEUD) isDescConn = true;
         }
+      }
 
-        // 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, eNOD);
-        MED::TEntityInfo::iterator anEntityIter = aEntityInfo.begin();
-        for (; anEntityIter != aEntityInfo.end(); anEntityIter++) {
-          const EEntiteMaillage& anEntity = anEntityIter->first;
-          aDescendingEntitiesMap.Remove(anEntity); // Mantis issue 0020483
-          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();
+      // 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, eNOD);
+      MED::TEntityInfo::iterator anEntityIter = aEntityInfo.begin();
+
+      for (; anEntityIter != aEntityInfo.end(); anEntityIter++)
+      {
+        const EEntiteMaillage& anEntity = anEntityIter->first;
+        aDescendingEntitiesMap.Remove(anEntity); // Mantis issue 0020483
+        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;
 
-              EBooleen anIsElemNum = takeNumbers ? aBallInfo->IsElemNum() : eFAUX;
-              if ( anIsElemNum && aBallInfo->myElemNum->empty() )
-                anIsElemNum = eFAUX;
+          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;
+            // 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( (*aBallInfo->myConn)[ iBall ]-1 );
-                  anIsNodeNum = myMesh->FindNode( aNodeIds[iBall] ) ? eVRAI : eFAUX;
-                }
+            if(anIsNodeNum) {
+              aNodeIds.resize( aNbBalls );
+              for(TInt iBall = 0; iBall < aNbBalls && anIsNodeNum; iBall++)
+              {
+                aNodeIds[iBall] = aNodeInfo->GetElemNum( (*aBallInfo->myConn)[ iBall ]-1 );
+                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++)
+            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 ( DriverMED::checkFamilyID ( aFamily, aFamNum, myFamilies ))
               {
-                anElement = 0;
+                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:
+          case ePOLYGON2:
+          {
+            PPolygoneInfo aPolygoneInfo = aMed->GetPPolygoneInfo(aMeshInfo,anEntity,aGeom);
+            EBooleen anIsElemNum = takeNumbers ? aPolygoneInfo->IsElemNum() : eFAUX;
+
+            typedef SMDS_MeshFace* (SMESHDS_Mesh::* FAddPolyWithID)
+              (const std::vector<int> & nodes_ids, const int ID);
+            typedef SMDS_MeshFace* (SMESHDS_Mesh::* FAddPolygon)
+              (const std::vector<const SMDS_MeshNode*> & nodes);
+
+            FAddPolyWithID addPolyWithID = & SMESHDS_Mesh::AddPolygonalFaceWithID;
+            FAddPolygon       addPolygon = & SMESHDS_Mesh::AddPolygonalFace;
+            if ( aGeom == ePOLYGON2 ) {
+              addPolyWithID = & SMESHDS_Mesh::AddQuadPolygonalFaceWithID;
+              addPolygon    = & SMESHDS_Mesh::AddQuadPolygonalFace;
+            }
+            TNodeIds aNodeIds;
+            vector<const SMDS_MeshNode*> aNodes;
+            const TInt aNbElem = aPolygoneInfo->GetNbElem();
+            for ( TInt iElem = 0; iElem < aNbElem; iElem++ )
+            {
+              MED::TCConnSlice aConnSlice = aPolygoneInfo->GetConnSlice(iElem);
+              TInt aNbConn = aPolygoneInfo->GetNbConn(iElem);
+              aNodeIds.resize( 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];
+#else
+              for(TInt iConn = 0; iConn < aNbConn; iConn++)
+                aNodeIds[iConn] = aConnSlice[iConn];
+#endif
+              bool isRenum = false;
+              SMDS_MeshElement* anElement = NULL;
+              TInt aFamNum = aPolygoneInfo->GetFamNum(iElem);
+#ifndef _DEXCEPT_
+              try {
+#endif
                 if ( anIsElemNum ) {
-                  if (!(anElement = myMesh->AddBallWithID( aNodeIds[iBall],
-                                                           aBallInfo->myDiameters[iBall],
-                                                           aBallInfo->GetElemNum(iBall))))
-                    anIsElemNum = eFAUX;
+                  TInt anElemId = aPolygoneInfo->GetElemNum( iElem );
+                  anElement = (myMesh->*addPolyWithID)( aNodeIds, anElemId );
+                }
+                if ( !anElement ) {
+                  aNodes.resize( aNbConn );
+                  for ( TInt iConn = 0; iConn < aNbConn; iConn++ )
+                    aNodes[iConn] = FindNode( myMesh, aNodeIds[iConn] );
+                  anElement = (myMesh->*addPolygon)( aNodes );
+                  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 ( !anElement )
-                  myMesh->AddBall( myMesh->FindNode( aNodeIds[iBall]),
-                                   aBallInfo->myDiameters[iBall] );
-
-                // Save reference to this element from its family
-                TInt aFamNum = aBallInfo->GetFamNum(iBall);
                 if ( DriverMED::checkFamilyID ( aFamily, aFamNum, myFamilies ))
                 {
+                  // Save reference to this element from its family
                   aFamily->AddElement(anElement);
-                  aFamily->SetType( SMDSAbs_Ball );
+                  aFamily->SetType(anElement->GetType());
                 }
               }
+            }
+            break;
+          }
+          case ePOLYEDRE: {
+            PPolyedreInfo aPolyedreInfo = aMed->GetPPolyedreInfo(aMeshInfo,anEntity,aGeom);
+            EBooleen anIsElemNum = takeNumbers ? aPolyedreInfo->IsElemNum() : eFAUX;
 
-              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 = 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();
+                aQuantities[iFace] = aNbConn;
 #ifdef _EDF_NODE_IDS_
                 if(anIsNodeNum)
                   for(TInt iConn = 0; iConn < aNbConn; iConn++)
-                    aNodeIds[iConn] = aNodeInfo->GetElemNum(aConnSlice[iConn] - 1);
+                  {
+                    aNodeIds[iNode] = aNodeInfo->GetElemNum(aConnSlice[iConn] - 1);
+                    iNode++;
+                  }
                 else
                   for(TInt iConn = 0; iConn < aNbConn; iConn++)
-                    aNodeIds[iConn] = aConnSlice[iConn];
+                  {
+                    aNodeIds[iNode++] = aConnSlice[iConn];
+                  }
 #else
                 for(TInt iConn = 0; iConn < aNbConn; iConn++)
-                  aNodeIds[iConn] = aConnSlice[iConn];
-#endif
-                bool isRenum = false;
-                SMDS_MeshElement* anElement = NULL;
-                TInt aFamNum = aPolygoneInfo->GetFamNum(iElem);
+                {
+                  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 = aPolygoneInfo->GetElemNum(iElem);
-                    anElement = myMesh->AddPolygonalFaceWithID(aNodeIds,anElemId);
-                  }
-                  if(!anElement){
-                    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;
-                  }
-#ifndef _DEXCEPT_
-                }catch(const std::exception& exc){
-                  aResult = DRS_FAIL;
-                }catch (...){
-                  aResult = DRS_FAIL;
+                if(anIsElemNum){
+                  TInt anElemId = aPolyedreInfo->GetElemNum(iElem);
+                  anElement = myMesh->AddPolyhedralVolumeWithID(aNodeIds,aQuantities,anElemId);
                 }
-#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 ( DriverMED::checkFamilyID ( aFamily, aFamNum, myFamilies ))
-                  {
-                    // Save reference to this element from its family
-                    aFamily->AddElement(anElement);
-                    aFamily->SetType(anElement->GetType());
-                  }
+                  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;
               }
-              break;
-            }
-            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();
-                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();
-                  aQuantities[iFace] = aNbConn;
-#ifdef _EDF_NODE_IDS_
-                  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          
+              if(!anElement){
+                aResult = DRS_WARN_SKIP_ELEM;
+              }else{
+                if(isRenum){
+                  anIsElemNum = eFAUX;
+                  takeNumbers = false;
+                  if (aResult < DRS_WARN_RENUMBER)
+                    aResult = DRS_WARN_RENUMBER;
                 }
-
-                bool isRenum = false;
-                SMDS_MeshElement* anElement = NULL;
-                TInt aFamNum = aPolyedreInfo->GetFamNum(iElem);
-                
-#ifndef _DEXCEPT_
-                try{
-#endif
-                  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 ( DriverMED::checkFamilyID ( aFamily, aFamNum, myFamilies )) {
-                    // Save reference to this element from its family
-                    aFamily->AddElement(anElement);
-                    aFamily->SetType(anElement->GetType());
-                  }
+                if ( DriverMED::checkFamilyID ( aFamily, aFamNum, myFamilies )) {
+                  // Save reference to this element from its family
+                  aFamily->AddElement(anElement);
+                  aFamily->SetType(anElement->GetType());
                 }
               }
-              break;
             }
-            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 eTRIA7:   aNbNodes = 7;  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++){
-                bool anIsValidConnect = false;
-                TCConnSlice aConnSlice = aCellInfo->GetConnSlice(iElem);
+            break;
+          }
+          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 eTRIA7:   aNbNodes = 7;  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++ )
+            {
+              bool anIsValidConnect = false;
+              TCConnSlice aConnSlice = aCellInfo->GetConnSlice(iElem);
 #ifndef _DEXCEPT_
-                try{
+              try{
 #endif
 #ifdef _EDF_NODE_IDS_
-                  if(anIsNodeNum)
-                    for(int iNode = 0; iNode < aNbNodes; iNode++)
-                      aNodeIds[iNode] = aNodeInfo->GetElemNum(aConnSlice[iNode] - 1);
-                  else
-                    for(int iNode = 0; iNode < aNbNodes; iNode++)
-                      aNodeIds[iNode] = aConnSlice[iNode];
-#else
+                if(anIsNodeNum)
+                  for(int iNode = 0; iNode < aNbNodes; iNode++)
+                    aNodeIds[iNode] = aNodeInfo->GetElemNum(aConnSlice[iNode] - 1);
+                else
                   for(int iNode = 0; iNode < aNbNodes; iNode++)
                     aNodeIds[iNode] = aConnSlice[iNode];
+#else
+                for(int iNode = 0; iNode < aNbNodes; iNode++)
+                  aNodeIds[iNode] = aConnSlice[iNode];
 #endif
-                  anIsValidConnect = true;
+                anIsValidConnect = true;
 #ifndef _DEXCEPT_
-                }catch(const std::exception& exc){
-                  INFOS("Following exception was caught:\n\t"<<exc.what());
-                  aResult = DRS_FAIL;
-                }catch(...){
-                  INFOS("Unknown exception was caught !!!");
-                  aResult = DRS_FAIL;
-                }
+              }catch(const std::exception& exc){
+                INFOS("Following exception was caught:\n\t"<<exc.what());
+                aResult = DRS_FAIL;
+              }catch(...){
+                INFOS("Unknown exception was caught !!!");
+                aResult = DRS_FAIL;
+              }
 #endif          
-                if(!anIsValidConnect)
-                  continue;
+              if(!anIsValidConnect)
+                continue;
 
-                bool isRenum = false;
-                const SMDS_MeshElement* anElement = NULL;
-                TInt aFamNum = aCellInfo->GetFamNum(iElem);
+              bool isRenum = false;
+              const SMDS_MeshElement* anElement = NULL;
+              TInt aFamNum = aCellInfo->GetFamNum(iElem);
 #ifndef _DEXCEPT_
-                try{
+              try{
 #endif
-                  //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],
-                                                        aNodeIds[1],
+                //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],
+                                                      aNodeIds[1],
+                                                      aCellInfo->GetElemNum(iElem));
+                  if (!anElement) {
+                    anElement = myMesh->AddEdge(FindNode(myMesh,aNodeIds[0]),
+                                                FindNode(myMesh,aNodeIds[1]));
+                    isRenum = anIsElemNum;
+                  }
+                  break;
+                case eSEG3:
+                  if(anIsElemNum)
+                    anElement = myMesh->AddEdgeWithID(aNodeIds[0],
+                                                      aNodeIds[1],
+                                                      aNodeIds[2],
+                                                      aCellInfo->GetElemNum(iElem));
+                  if (!anElement) {
+                    anElement = myMesh->AddEdge(FindNode(myMesh,aNodeIds[0]),
+                                                FindNode(myMesh,aNodeIds[1]),
+                                                FindNode(myMesh,aNodeIds[2]));
+                    isRenum = anIsElemNum;
+                  }
+                  break;
+                case eTRIA3:
+                  aNbNodes = 3;
+                  if(anIsElemNum)
+                    anElement = myMesh->AddFaceWithID(aNodeIds[0],
+                                                      aNodeIds[1],
+                                                      aNodeIds[2],
+                                                      aCellInfo->GetElemNum(iElem));
+                  if (!anElement) {
+                    anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]),
+                                                FindNode(myMesh,aNodeIds[1]),
+                                                FindNode(myMesh,aNodeIds[2]));
+                    isRenum = anIsElemNum;
+                  }
+                  break;
+                case eTRIA6:
+                  aNbNodes = 6;
+                  if(anIsElemNum)
+                    anElement = myMesh->AddFaceWithID(aNodeIds[0], aNodeIds[1],
+                                                      aNodeIds[2], aNodeIds[3],
+                                                      aNodeIds[4], aNodeIds[5],
+                                                      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]));
+                    isRenum = anIsElemNum;
+                  }
+                  break;
+                case eTRIA7:
+                  aNbNodes = 7;
+                  if(anIsElemNum)
+                    anElement = myMesh->AddFaceWithID(aNodeIds[0], aNodeIds[1],
+                                                      aNodeIds[2], aNodeIds[3],
+                                                      aNodeIds[4], aNodeIds[5], aNodeIds[6],
+                                                      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]));
+                    isRenum = anIsElemNum;
+                  }
+                  break;
+                case eQUAD4:
+                  aNbNodes = 4;
+                  if(anIsElemNum)
+                    anElement = myMesh->AddFaceWithID(aNodeIds[0], aNodeIds[1],
+                                                      aNodeIds[2], aNodeIds[3],
+                                                      aCellInfo->GetElemNum(iElem));
+                  if (!anElement) {
+                    anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]),
+                                                FindNode(myMesh,aNodeIds[1]),
+                                                FindNode(myMesh,aNodeIds[2]),
+                                                FindNode(myMesh,aNodeIds[3]));
+                    isRenum = anIsElemNum;
+                  }
+                  break;
+                case eQUAD8:
+                  aNbNodes = 8;
+                  if(anIsElemNum)
+                    anElement = myMesh->AddFaceWithID(aNodeIds[0], aNodeIds[1],
+                                                      aNodeIds[2], aNodeIds[3],
+                                                      aNodeIds[4], aNodeIds[5],
+                                                      aNodeIds[6], aNodeIds[7],
+                                                      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]));
+                    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)
+                    anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
+                                                        aNodeIds[2], aNodeIds[3],
                                                         aCellInfo->GetElemNum(iElem));
-                    if (!anElement) {
-                      anElement = myMesh->AddEdge(FindNode(myMesh,aNodeIds[0]),
-                                                  FindNode(myMesh,aNodeIds[1]));
-                      isRenum = anIsElemNum;
-                    }
-                    break;
-                  case eSEG3:
-                    if(anIsElemNum)
-                      anElement = myMesh->AddEdgeWithID(aNodeIds[0],
-                                                        aNodeIds[1],
-                                                        aNodeIds[2],
+                  if (!anElement) {
+                    anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
+                                                  FindNode(myMesh,aNodeIds[1]),
+                                                  FindNode(myMesh,aNodeIds[2]),
+                                                  FindNode(myMesh,aNodeIds[3]));
+                    isRenum = anIsElemNum;
+                  }
+                  break;
+                case eTETRA10:
+                  aNbNodes = 10;
+                  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],
                                                         aCellInfo->GetElemNum(iElem));
-                    if (!anElement) {
-                      anElement = myMesh->AddEdge(FindNode(myMesh,aNodeIds[0]),
+                  if (!anElement) {
+                    anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
                                                   FindNode(myMesh,aNodeIds[1]),
-                                                  FindNode(myMesh,aNodeIds[2]));
-                      isRenum = anIsElemNum;
-                    }
-                    break;
-                  case eTRIA3:
-                    aNbNodes = 3;
-                    if(anIsElemNum)
-                      anElement = myMesh->AddFaceWithID(aNodeIds[0],
-                                                        aNodeIds[1],
-                                                        aNodeIds[2],
+                                                  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]));
+                    isRenum = anIsElemNum;
+                  }
+                  break;
+                case ePYRA5:
+                  aNbNodes = 5;
+                  if(anIsElemNum)
+                    anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
+                                                        aNodeIds[2], aNodeIds[3],
+                                                        aNodeIds[4],
                                                         aCellInfo->GetElemNum(iElem));
-                    if (!anElement) {
-                      anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]),
+                  if (!anElement) {
+                    anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
                                                   FindNode(myMesh,aNodeIds[1]),
-                                                  FindNode(myMesh,aNodeIds[2]));
-                      isRenum = anIsElemNum;
-                    }
-                    break;
-                  case eTRIA6:
-                    aNbNodes = 6;
-                    if(anIsElemNum)
-                      anElement = myMesh->AddFaceWithID(aNodeIds[0], aNodeIds[1],
+                                                  FindNode(myMesh,aNodeIds[2]),
+                                                  FindNode(myMesh,aNodeIds[3]),
+                                                  FindNode(myMesh,aNodeIds[4]));
+                    isRenum = anIsElemNum;
+                  }
+                  break;
+                case ePYRA13:
+                  aNbNodes = 13;
+                  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],
+                                                        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]));
+                    isRenum = anIsElemNum;
+                  }
+                  break;
+                case ePENTA6:
+                  aNbNodes = 6;
+                  if(anIsElemNum)
+                    anElement = myMesh->AddVolumeWithID(aNodeIds[0],
+                                                        aNodeIds[1],
+                                                        aNodeIds[2],
+                                                        aNodeIds[3],
+                                                        aNodeIds[4],
+                                                        aNodeIds[5],
                                                         aCellInfo->GetElemNum(iElem));
-                    if (!anElement) {
-                      anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]),
+                  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]));
-                      isRenum = anIsElemNum;
-                    }
-                    break;
-                  case eTRIA7:
-                    aNbNodes = 7;
-                    if(anIsElemNum)
-                      anElement = myMesh->AddFaceWithID(aNodeIds[0], aNodeIds[1],
+                    isRenum = anIsElemNum;
+                  }
+                  break;
+                case ePENTA15:
+                  aNbNodes = 15;
+                  if(anIsElemNum)
+                    anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
                                                         aNodeIds[2], aNodeIds[3],
-                                                        aNodeIds[4], aNodeIds[5], aNodeIds[6],
+                                                        aNodeIds[4], aNodeIds[5],
+                                                        aNodeIds[6], aNodeIds[7],
+                                                        aNodeIds[8], aNodeIds[9],
+                                                        aNodeIds[10], aNodeIds[11],
+                                                        aNodeIds[12], aNodeIds[13],
+                                                        aNodeIds[14],
                                                         aCellInfo->GetElemNum(iElem));
-                    if (!anElement) {
-                      anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]),
+                  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]));
-                      isRenum = anIsElemNum;
-                    }
-                    break;
-                  case eQUAD4:
-                    aNbNodes = 4;
-                    if(anIsElemNum)
-                      anElement = myMesh->AddFaceWithID(aNodeIds[0], aNodeIds[1],
-                                                        aNodeIds[2], aNodeIds[3],
+                                                  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]));
+                    isRenum = anIsElemNum;
+                  }
+                  break;
+                case eHEXA8:
+                  aNbNodes = 8;
+                  if(anIsElemNum)
+                    anElement = myMesh->AddVolumeWithID(aNodeIds[0],
+                                                        aNodeIds[1],
+                                                        aNodeIds[2],
+                                                        aNodeIds[3],
+                                                        aNodeIds[4],
+                                                        aNodeIds[5],
+                                                        aNodeIds[6],
+                                                        aNodeIds[7],
                                                         aCellInfo->GetElemNum(iElem));
-                    if (!anElement) {
-                      anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]),
+                  if (!anElement) {
+                    anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
                                                   FindNode(myMesh,aNodeIds[1]),
                                                   FindNode(myMesh,aNodeIds[2]),
-                                                  FindNode(myMesh,aNodeIds[3]));
-                      isRenum = anIsElemNum;
-                    }
-                    break;
-                  case eQUAD8:
-                    aNbNodes = 8;
-                    if(anIsElemNum)
-                      anElement = myMesh->AddFaceWithID(aNodeIds[0], aNodeIds[1],
+                                                  FindNode(myMesh,aNodeIds[3]),
+                                                  FindNode(myMesh,aNodeIds[4]),
+                                                  FindNode(myMesh,aNodeIds[5]),
+                                                  FindNode(myMesh,aNodeIds[6]),
+                                                  FindNode(myMesh,aNodeIds[7]));
+                    isRenum = anIsElemNum;
+                  }
+                  break;
+
+                case eHEXA20:
+                  aNbNodes = 20;
+                  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],
                                                         aCellInfo->GetElemNum(iElem));
-                    if (!anElement) {
-                      anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]),
+                  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]));
-                      isRenum = anIsElemNum;
-                    }
-                    break;
-                  case eQUAD9:
-                    aNbNodes = 9;
-                    if(anIsElemNum)
-                      anElement = myMesh->AddFaceWithID(aNodeIds[0], aNodeIds[1],
+                                                  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]));
+                    isRenum = anIsElemNum;
+                  }
+                  break;
+
+                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[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->AddFace(FindNode(myMesh,aNodeIds[0]),
+                  if (!anElement) {
+                    anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
                                                   FindNode(myMesh,aNodeIds[1]),
                                                   FindNode(myMesh,aNodeIds[2]),
                                                   FindNode(myMesh,aNodeIds[3]),
@@ -642,322 +901,102 @@ DriverMED_R_SMESHDS_Mesh
                                                   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)
-                      anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
-                                                          aNodeIds[2], aNodeIds[3],
-                                                          aCellInfo->GetElemNum(iElem));
-                    if (!anElement) {
-                      anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
-                                                    FindNode(myMesh,aNodeIds[1]),
-                                                    FindNode(myMesh,aNodeIds[2]),
-                                                    FindNode(myMesh,aNodeIds[3]));
-                      isRenum = anIsElemNum;
-                    }
-                    break;
-                  case eTETRA10:
-                    aNbNodes = 10;
-                    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],
-                                                          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]));
-                      isRenum = anIsElemNum;
-                    }
-                    break;
-                  case ePYRA5:
-                    aNbNodes = 5;
-                    if(anIsElemNum)
-                      anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
-                                                          aNodeIds[2], aNodeIds[3],
-                                                          aNodeIds[4],
-                                                          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]));
-                      isRenum = anIsElemNum;
-                    }
-                    break;
-                  case ePYRA13:
-                    aNbNodes = 13;
-                    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],
-                                                          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]));
-                      isRenum = anIsElemNum;
-                    }
-                    break;
-                  case ePENTA6:
-                    aNbNodes = 6;
-                    if(anIsElemNum)
-                      anElement = myMesh->AddVolumeWithID(aNodeIds[0],
-                                                          aNodeIds[1],
-                                                          aNodeIds[2],
-                                                          aNodeIds[3],
-                                                          aNodeIds[4],
-                                                          aNodeIds[5],
-                                                          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]));
-                      isRenum = anIsElemNum;
-                    }
-                    break;
-                  case ePENTA15:
-                    aNbNodes = 15;
-                    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],
-                                                          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[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]),
-                                                    FindNode(myMesh,aNodeIds[12]),
-                                                    FindNode(myMesh,aNodeIds[13]),
-                                                    FindNode(myMesh,aNodeIds[14]));
-                      isRenum = anIsElemNum;
-                    }
-                    break;
-                  case eHEXA8:
-                    aNbNodes = 8;
-                    if(anIsElemNum)
-                      anElement = myMesh->AddVolumeWithID(aNodeIds[0],
-                                                          aNodeIds[1],
-                                                          aNodeIds[2],
-                                                          aNodeIds[3],
-                                                          aNodeIds[4],
-                                                          aNodeIds[5],
-                                                          aNodeIds[6],
-                                                          aNodeIds[7],
-                                                          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]));
-                      isRenum = anIsElemNum;
-                    }
-                    break;
-
-                  case eHEXA20:
-                    aNbNodes = 20;
-                    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],
-                                                          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]));
-                      isRenum = anIsElemNum;
-                    }
-                    break;
-
-                  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)
+                                                  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;
+
+                default:;
+
+                } // switch(aGeom)
 
 #ifndef _DEXCEPT_
-                }catch(const std::exception& exc){
-                  INFOS("The following exception was caught:\n\t"<<exc.what());
-                  aResult = DRS_FAIL;
-                }catch(...){
-                  INFOS("Unknown exception was caught !!!");
-                  aResult = DRS_FAIL;
-                }
-#endif          
-                if (!anElement) {
-                  aResult = DRS_WARN_SKIP_ELEM;
+              } catch(const std::exception& exc) {
+                INFOS("The following exception was caught:\n\t"<<exc.what());
+                aResult = DRS_FAIL;
+              } catch(...) {
+                INFOS("Unknown exception was caught !!!");
+                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;
                 }
-                else {
-                  if (isRenum) {
-                    anIsElemNum = eFAUX;
-                    takeNumbers = false;
-                    if (aResult < DRS_WARN_RENUMBER)
-                      aResult = DRS_WARN_RENUMBER;
-                  }
-                  if ( DriverMED::checkFamilyID ( aFamily, aFamNum, myFamilies )) {
-                    // Save reference to this element from its family
-                    myFamilies[aFamNum]->AddElement(anElement);
-                    myFamilies[aFamNum]->SetType(anElement->GetType());
-                  }
+                if ( DriverMED::checkFamilyID ( aFamily, aFamNum, myFamilies )) {
+                  // Save reference to this element from its family
+                  myFamilies[aFamNum]->AddElement(anElement);
+                  myFamilies[aFamNum]->SetType(anElement->GetType());
                 }
               }
-            }}
-          }
-        }
-        if (aDescendingEntitiesMap.Extent()) isDescConn = true; // Mantis issue 0020483
-      } // for(int iMesh = 0; iMesh < aNbMeshes; iMesh++)
-    } // if aNbMeshes
+            } // loop on aNbElems
+          }} // switch(aGeom)
+        } // loop on aGeom2Size
+      } // loop on aEntityInfo
+
+      if (aDescendingEntitiesMap.Extent()) isDescConn = true; // Mantis issue 0020483
+
+    } // for(int iMesh = 0; iMesh < aNbMeshes; iMesh++)
 #ifndef _DEXCEPT_
-  }catch(const std::exception& exc){
+  }
+  catch(const std::exception& exc)
+  {
     INFOS("The following exception was caught:\n\t"<<exc.what());
     aResult = DRS_FAIL;
-  }catch(...){
+  }
+  catch(...)
+  {
     INFOS("Unknown exception was caught !!!");
     aResult = DRS_FAIL;
   }
index 6b33445861bedefa167e04865ff3187e69f2be12..12b395105d74f08d000f647a93bd2eab171aa53f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 938927572aaaa9e08f599a3a3f559776580e5986..e40aac434f02d8d06962d5c802c21928845e12c8 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -168,7 +168,7 @@ bool DriverMED_W_Field::Set(SMESHDS_Mesh *      mesh,
 
 void DriverMED_W_Field::SetCompName(const int iComp, const char* name)
 {
-  if ( _compNames.size() <= iComp )
+  if ( (int)_compNames.size() <= iComp )
     _compNames.resize( iComp + 1 );
   _compNames[ iComp ] = name;
 }
@@ -327,7 +327,7 @@ Driver_Mesh::Status DriverMED_W_Field::Perform()
   MED::PIntTimeStampValue   timeStampIntVal = timeStampVal;
 
   // set values
-  int iVal = 0, i, nbE;
+  int iVal = 0;
   MED::TFloat* ptrDbl = 0;
   MED::TInt*   ptrInt = 0;
   for ( size_t iG = 1; iG < _nbElemsByGeom.size(); ++iG )
@@ -354,6 +354,8 @@ Driver_Mesh::Status DriverMED_W_Field::Perform()
 
   _dblValues.clear();
   _intValues.clear();
+
+  return DRS_OK;
 }
 
 namespace DriverMED // Implemetation of fuctions declared in DriverMED.hxx
index 074912341cf48375991c1f62a87d17d5dea4062a..454d677e0cd13d18592acf9b9f0d5483f57bf85f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index aec74adc9d00b70e7c3a62ffdc8ceae7ed079313..cee3e1b09f1c43971dcb4bb3d52128c11cce9b4a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -56,7 +56,8 @@ DriverMED_W_SMESHDS_Mesh::DriverMED_W_SMESHDS_Mesh():
   myDoGroupOfVolumes (false),
   myDoGroupOf0DElems(false),
   myDoGroupOfBalls(false),
-  myAutoDimension(true)
+  myAutoDimension(true),
+  myAddODOnVertices(false)
 {}
 
 void DriverMED_W_SMESHDS_Mesh::SetFile(const std::string& theFileName, 
@@ -524,7 +525,7 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
     const SMDS_MeshInfo& nbElemInfo = myMesh->GetMeshInfo();
 
     // poly elements are not supported by med-2.1
-    bool polyTypesSupported = myMed->CrPolygoneInfo(aMeshInfo,eMAILLE,ePOLYGONE,0,0);
+    bool polyTypesSupported = ( myMed->CrPolygoneInfo(aMeshInfo,eMAILLE,ePOLYGONE,0,0).get() != 0 );
     TInt nbPolygonNodes = 0, nbPolyhedronNodes = 0, nbPolyhedronFaces = 0;
 
     // nodes on VERTEXes where 0D elements are absent
@@ -605,12 +606,21 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
     if ( polyTypesSupported ) {
       aTElemTypeDatas.push_back( TElemTypeData(anEntity,
                                                ePOLYGONE,
-                                               nbElemInfo.NbPolygons(),
+                                               nbElemInfo.NbPolygons( ORDER_LINEAR ),
                                                SMDSAbs_Face));
       // we need one more loop on poly elements to count nb of their nodes
       aTElemTypeDatas.push_back( TElemTypeData(anEntity,
                                                ePOLYGONE,
-                                               nbElemInfo.NbPolygons(),
+                                               nbElemInfo.NbPolygons( ORDER_LINEAR ),
+                                               SMDSAbs_Face));
+      aTElemTypeDatas.push_back( TElemTypeData(anEntity,
+                                               ePOLYGON2,
+                                               nbElemInfo.NbPolygons( ORDER_QUADRATIC ),
+                                               SMDSAbs_Face));
+      // we need one more loop on QUAD poly elements to count nb of their nodes
+      aTElemTypeDatas.push_back( TElemTypeData(anEntity,
+                                               ePOLYGON2,
+                                               nbElemInfo.NbPolygons( ORDER_QUADRATIC ),
                                                SMDSAbs_Face));
     }
 #ifdef _ELEMENTS_BY_DIM_
@@ -706,9 +716,14 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
 
       // Treat POLYGONs
       // ---------------
-      if ( aElemTypeData->_geomType == ePOLYGONE )
+      if ( aElemTypeData->_geomType == ePOLYGONE ||
+           aElemTypeData->_geomType == ePOLYGON2 )
       {
-        elemIterator = myMesh->elementGeomIterator( SMDSGeom_POLYGON );
+        if ( aElemTypeData->_geomType == ePOLYGONE )
+          elemIterator = myMesh->elementEntityIterator( SMDSEntity_Polygon );
+        else
+          elemIterator = myMesh->elementEntityIterator( SMDSEntity_Quad_Polygon );
+
         if ( nbPolygonNodes == 0 ) {
           // Count nb of nodes
           while ( elemIterator->more() ) {
@@ -758,9 +773,10 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
               break;
           }
           myMed->SetPolygoneInfo(aPolygoneInfo);
-        }
 
-      } 
+          nbPolygonNodes = 0; // to treat next polygon type
+        }
+      }
 
       // Treat POLYEDREs
       // ----------------
index 4342d5dd233ec277b428b225654deff769e507d2..4bef76a646f48daad3b16333a8e5ef1221941ac4 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index c2d1efc300bb38ec349c95887975ee0ad24d623b..d0e7d628a80b68c0247572cc12dec2dd2cabdb59 100755 (executable)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index fa0a8139d86b8434572339ef019ea2892c7257f8..74e7232be138bd4b856ae293b5cecb54b0d4096e 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2012-2015  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
index 53374c647c6ffea6f0963d284bf839153fb36939..4a02cb29f8d1446d8a45ce33c6bbaf4387b04f3d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 75df49c52d5dbdfbfd59cdd86753f7fc31332d41..214f1404f2266834f421e86206d3e7363a217689 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 2ac7ca5daee2945c5b70ba03bcc1544f87f37c4e..6f9d02a3070e2d4970d99e8f4452b00ac22843b5 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 #include "SMDS_Mesh.hxx"
 #include "SMDS_MeshElement.hxx"
 #include "SMDS_MeshNode.hxx"
+#include "SMDS_PolygonalFaceOfNodes.hxx"
 #include "SMDS_SetIterator.hxx"
 #include "SMDS_VolumeTool.hxx"
 #include "SMESH_File.hxx"
 #include "SMESH_TypeDefs.hxx"
 
-//#include "utilities.h"
+#include <Standard_ErrorHandler.hxx>
+#include <Standard_Failure.hxx>
+#include <gp_Ax2.hxx>
 
 #include <limits>
 
@@ -74,6 +77,7 @@ Driver_Mesh::Status DriverSTL_W_SMDS_Mesh::Perform()
 
   return aResult;
 }
+
 //================================================================================
 /*!
  * \brief Destructor deletes temporary faces
@@ -82,8 +86,8 @@ Driver_Mesh::Status DriverSTL_W_SMDS_Mesh::Perform()
 
 DriverSTL_W_SMDS_Mesh::~DriverSTL_W_SMDS_Mesh()
 {
-  for ( unsigned i = 0; i < myVolumeTrias.size(); ++i )
-    delete myVolumeTrias[i];
+  for ( unsigned i = 0; i < myVolumeFacets.size(); ++i )
+    delete myVolumeFacets[i];
 }
 
 //================================================================================
@@ -94,6 +98,8 @@ DriverSTL_W_SMDS_Mesh::~DriverSTL_W_SMDS_Mesh()
 
 void DriverSTL_W_SMDS_Mesh::findVolumeTriangles()
 {
+  myNbVolumeTrias = 0;
+
   SMDS_VolumeTool theVolume;
   SMDS_VolumeIteratorPtr vIt = myMesh->volumesIterator();
   std::vector< const SMDS_MeshNode*> nodes;
@@ -106,19 +112,20 @@ void DriverSTL_W_SMDS_Mesh::findVolumeTriangles()
         const SMDS_MeshNode** n = theVolume.GetFaceNodes(iF);
         int                 nbN = theVolume.NbFaceNodes(iF);
         nodes.assign( n, n+nbN );
-        if ( !myMesh->FindElement( nodes, SMDSAbs_Face, /*Nomedium=*/false))
+        if ( !myMesh->FindElement( nodes, SMDSAbs_Face, /*noMedium=*/false))
         {
-          if ( nbN == 9 && !theVolume.IsPoly() ) // facet is SMDSEntity_BiQuad_Quadrangle
+          if (( nbN == 9 || nbN == 7 ) &&
+              ( !theVolume.IsPoly() )) // facet is bi-quaratic
           {
             int nbTria = nbN - 1;
             for ( int iT = 0; iT < nbTria; ++iT )
-              myVolumeTrias.push_back( new SMDS_FaceOfNodes( n[8], n[0+iT], n[1+iT] ));
+              myVolumeFacets.push_back( new SMDS_FaceOfNodes( n[8], n[0+iT], n[1+iT] ));
+            myNbVolumeTrias += nbTria;
           }
           else
           {
-            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] ));
+            myVolumeFacets.push_back( new SMDS_PolygonalFaceOfNodes( nodes ));
+            myNbVolumeTrias += nbN - 2;
           }
         }
       }
@@ -134,8 +141,8 @@ void DriverSTL_W_SMDS_Mesh::findVolumeTriangles()
 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()));
+  SMDS_ElemIteratorPtr tmpTriaIter( new SMDS_ElementVectorIterator( myVolumeFacets.begin(),
+                                                                    myVolumeFacets.end()));
   typedef std::vector< SMDS_ElemIteratorPtr > TElemIterVector;
   TElemIterVector iters(2);
   iters[0] = facesIter;
@@ -201,6 +208,177 @@ static gp_XYZ getNormale( const SMDS_MeshNode* n1,
   return n;
 }
 
+namespace
+{
+  /*!
+   * \brief Vertex of a polygon. Together with 2 neighbor Vertices represents a triangle
+   */
+  struct PolyVertex
+  {
+    SMESH_TNodeXYZ _nxyz;
+    gp_XY          _xy;
+    PolyVertex*    _prev;
+    PolyVertex*    _next;
+
+    void SetNodeAndNext( const SMDS_MeshNode* n, PolyVertex& v )
+    {
+      _nxyz.Set( n );
+      _next = &v;
+      v._prev = this;
+    }
+    PolyVertex* Delete()
+    {
+      _prev->_next = _next;
+      _next->_prev = _prev;
+      return _next;
+    }
+    void GetTriaNodes( const SMDS_MeshNode** nodes) const
+    {
+      nodes[0] = _prev->_nxyz._node;
+      nodes[1] =  this->_nxyz._node;
+      nodes[2] = _next->_nxyz._node;
+    }
+
+    inline static double Area( const PolyVertex* v0, const PolyVertex* v1, const PolyVertex* v2 )
+    {
+      gp_XY vPrev = v0->_xy - v1->_xy;
+      gp_XY vNext = v2->_xy - v1->_xy;
+      return vNext ^ vPrev;
+    }
+    double TriaArea() const { return Area( _prev, this, _next ); }
+
+    bool IsInsideTria( const PolyVertex* v )
+    {
+      gp_XY p = _prev->_xy - v->_xy;
+      gp_XY t =  this->_xy - v->_xy;
+      gp_XY n = _next->_xy - v->_xy;
+      const double tol = -1e-12;
+      return (( p ^ t ) >= tol &&
+              ( t ^ n ) >= tol &&
+              ( n ^ p ) >= tol );
+      // return ( Area( _prev, this, v ) > 0 &&
+      //          Area( this, _next, v ) > 0 &&
+      //          Area( _next, _prev, v ) > 0 );
+    }
+  };
+
+  //================================================================================
+  /*!
+   * \brief Triangulate a polygon. Assure correct orientation for concave polygons
+   */
+  //================================================================================
+
+  bool triangulate( std::vector< const SMDS_MeshNode*>& nodes, const size_t nbNodes )
+  {
+    // connect nodes into a ring
+    std::vector< PolyVertex > pv( nbNodes );
+    for ( size_t i = 1; i < nbNodes; ++i )
+      pv[i-1].SetNodeAndNext( nodes[i-1], pv[i] );
+    pv[ nbNodes-1 ].SetNodeAndNext( nodes[ nbNodes-1 ], pv[0] );
+
+    // get a polygon normal
+    gp_XYZ normal(0,0,0), p0,v01,v02;
+    p0  = pv[0]._nxyz;
+    v01 = pv[1]._nxyz - p0;
+    for ( size_t i = 2; i < nbNodes; ++i )
+    {
+      v02 = pv[i]._nxyz - p0;
+      normal += v01 ^ v02;
+      v01 = v02;
+    }
+    // project nodes to the found plane
+    gp_Ax2 axes;
+    try {
+      axes = gp_Ax2( p0, normal, v01 );
+    }
+    catch ( Standard_Failure ) {
+      return false;
+    }
+    for ( size_t i = 0; i < nbNodes; ++i )
+    {
+      gp_XYZ p = pv[i]._nxyz - p0;
+      pv[i]._xy.SetX( axes.XDirection().XYZ() * p );
+      pv[i]._xy.SetY( axes.YDirection().XYZ() * p );
+    }
+
+    // in a loop, find triangles with positive area and having no vertices inside
+    int iN = 0, nbTria = nbNodes - 2;
+    nodes.reserve( nbTria * 3 );
+    const double minArea = 1e-6;
+    PolyVertex* v = &pv[0], *vi;
+    int nbVertices = nbNodes, nbBadTria = 0, isGoodTria;
+    while ( nbBadTria < nbVertices )
+    {
+      if (( isGoodTria = v->TriaArea() > minArea ))
+      {
+        for ( vi = v->_next->_next;
+              vi != v->_prev;
+              vi = vi->_next )
+        {
+          if ( v->IsInsideTria( vi ))
+            break;
+        }
+        isGoodTria = ( vi == v->_prev );
+      }
+      if ( isGoodTria )
+      {
+        v->GetTriaNodes( &nodes[ iN ] );
+        iN += 3;
+        v = v->Delete();
+        if ( --nbVertices == 3 )
+        {
+          // last triangle remains
+          v->GetTriaNodes( &nodes[ iN ] );
+          return true;
+        }
+        nbBadTria = 0;
+      }
+      else
+      {
+        v = v->_next;
+        ++nbBadTria;
+      }
+    }
+
+    // the polygon is invalid; add triangles with positive area
+    nbBadTria = 0;
+    while ( nbBadTria < nbVertices )
+    {
+      isGoodTria = v->TriaArea() > minArea;
+      if ( isGoodTria )
+      {
+        v->GetTriaNodes( &nodes[ iN ] );
+        iN += 3;
+        v = v->Delete();
+        if ( --nbVertices == 3 )
+        {
+          // last triangle remains
+          v->GetTriaNodes( &nodes[ iN ] );
+          return true;
+        }
+        nbBadTria = 0;
+      }
+      else
+      {
+        v = v->_next;
+        ++nbBadTria;
+      }
+    }
+
+    // add all the rest triangles
+    while ( nbVertices >= 3 )
+    {
+      v->GetTriaNodes( &nodes[ iN ] );
+      iN += 3;
+      v = v->Delete();
+      --nbVertices;
+    }
+
+    return true;
+
+  } // triangulate()
+} // namespace
+
 //================================================================================
 /*!
  * \brief Return nb triangles in a decomposed mesh face
@@ -235,12 +413,13 @@ static int getNbTriangles( const SMDS_MeshElement* face)
  */
 //================================================================================
 
-static int getTriangles( const SMDS_MeshElement* face,
-                         const SMDS_MeshNode**   nodes)
+static int getTriangles( const SMDS_MeshElement*             face,
+                         std::vector< const SMDS_MeshNode*>& nodes)
 {
   // WARNING: decomposing into triangles must be coherent with getNbTriangles()
-  int nbTria, i = 0;
+  int nbTria, i = 0, nbNodes = face->NbNodes();
   SMDS_NodeIteratorPtr nIt = face->interlacedNodesIterator();
+  nodes.resize( nbNodes * 3 );
   nodes[ i++ ] = nIt->next();
   nodes[ i++ ] = nIt->next();
 
@@ -251,30 +430,42 @@ static int getTriangles( const SMDS_MeshElement* face,
   case SMDSEntity_BiQuad_Quadrangle:
     nbTria = ( type == SMDSEntity_BiQuad_Triangle ) ? 6 : 8;
     nodes[ i++ ] = face->GetNode( nbTria );
-    while ( i < 3*(nbTria-1) )
+    for ( i = 3; i < 3*(nbTria-1); i += 3 )
     {
-      nodes[ i++ ] = nodes[ i-2 ];
-      nodes[ i++ ] = nIt->next();
-      nodes[ i++ ] = nodes[ 2 ];
+      nodes[ i+0 ] = nodes[ i-2 ];
+      nodes[ i+1 ] = nIt->next();
+      nodes[ i+2 ] = nodes[ 2 ];
     }
-    nodes[ i++ ] = nodes[ i-2 ];
-    nodes[ i++ ] = nodes[ 0 ];
-    nodes[ i++ ] = nodes[ 2 ];
+    nodes[ i+0 ] = nodes[ i-2 ];
+    nodes[ i+1 ] = nodes[ 0 ];
+    nodes[ i+2 ] = nodes[ 2 ];
+    break;
+  case SMDSEntity_Triangle:
+    nbTria = 1;
+    nodes[ i++ ] = nIt->next();
     break;
   default:
-    // case SMDSEntity_Triangle:
     // case SMDSEntity_Quad_Triangle:
     // case SMDSEntity_Quadrangle:
     // case SMDSEntity_Quad_Quadrangle:
     // case SMDSEntity_Polygon:
     // case SMDSEntity_Quad_Polygon:
-    nbTria = face->NbNodes() - 2;
-    nodes[ i++ ] = nIt->next();
-    while ( i < 3*nbTria )
-    {
-      nodes[ i++ ] = nodes[ 0 ];
-      nodes[ i++ ] = nodes[ i-2 ];
+    nbTria = nbNodes - 2;
+    while ( nIt->more() )
       nodes[ i++ ] = nIt->next();
+
+    if ( !triangulate( nodes, nbNodes ))
+    {
+      nIt = face->interlacedNodesIterator();
+      nodes[ 0 ] = nIt->next();
+      nodes[ 1 ] = nIt->next();
+      nodes[ 2 ] = nIt->next();
+      for ( i = 3; i < 3*nbTria; i += 3 )
+      {
+        nodes[ i+0 ] = nodes[ 0 ];
+        nodes[ i+1 ] = nodes[ i-1 ];
+        nodes[ i+2 ] = nIt->next();
+      }
     }
     break;
   }
@@ -298,14 +489,14 @@ Driver_Mesh::Status DriverSTL_W_SMDS_Mesh::writeAscii() const
   aFile.writeRaw( buf.c_str(), buf.size() );
 
   char sval[128];
-  const SMDS_MeshNode* triaNodes[2048];
+  std::vector< const SMDS_MeshNode* > triaNodes;
 
   SMDS_ElemIteratorPtr itFaces = getFaces();
   while ( itFaces->more() )
   {
     const SMDS_MeshElement* aFace = itFaces->next();
     int nbTria = getTriangles( aFace, triaNodes );
-    
+
     for ( int iT = 0, iN = 0; iT < nbTria; ++iT )
     {
       gp_XYZ normale = getNormale( triaNodes[iN],
@@ -315,7 +506,7 @@ Driver_Mesh::Status DriverSTL_W_SMDS_Mesh::writeAscii() const
                " facet normal % 12e % 12e % 12e\n"
                "   outer loop\n" ,
                normale.X(), normale.Y(), normale.Z());
-      aFile.writeRaw ( sval, 70 );
+      aFile.writeRaw ( sval, 70 + strlen( sval + 70 )); // at least 70 but can be more (WIN)
 
       for ( int jN = 0; jN < 3; ++jN, ++iN )
       {
@@ -323,11 +514,11 @@ Driver_Mesh::Status DriverSTL_W_SMDS_Mesh::writeAscii() const
         sprintf (sval,
                  "     vertex % 12e % 12e % 12e\n",
                  node.X(), node.Y(), node.Z() );
-        aFile.writeRaw ( sval, 54 );
+        aFile.writeRaw ( sval, 54 + strlen( sval + 54 ));
       }
       aFile.writeRaw ("   endloop\n"
                       " endfacet\n", 21 );
-    } 
+    }
   }
   aFile.writeRaw ("endsolid\n" , 9 );
 
@@ -354,7 +545,7 @@ Driver_Mesh::Status DriverSTL_W_SMDS_Mesh::writeBinary() const
   aFile.openForWriting();
 
   // we first count the number of triangles
-  int nbTri = myVolumeTrias.size();
+  int nbTri = myNbVolumeTrias;
   {
     SMDS_FaceIteratorPtr itFaces = myMesh->facesIterator();
     while ( itFaces->more() ) {
@@ -372,7 +563,7 @@ Driver_Mesh::Status DriverSTL_W_SMDS_Mesh::writeBinary() const
 
   int dum=0;
 
-  const SMDS_MeshNode* triaNodes[2048];
+  std::vector< const SMDS_MeshNode* > triaNodes;
 
   SMDS_ElemIteratorPtr itFaces = getFaces();
   while ( itFaces->more() )
index 4d03b3fed66af5c55b21568d1c11fed63e765d3d..472610f0be47e3d3711edb23b5263d3efd8ff6c6 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -57,7 +57,8 @@ class MESHDRIVERSTL_EXPORT DriverSTL_W_SMDS_Mesh: public Driver_SMDS_Mesh
  private:
   // PRIVATE FIELDS
   bool myIsAscii;
-  std::vector<const SMDS_MeshElement*> myVolumeTrias; // tmp triangles
+  int                                  myNbVolumeTrias;
+  std::vector<const SMDS_MeshElement*> myVolumeFacets; // tmp faces
 };
 
 #endif
index 13385f7015fa2961b150362351fb63644cb062b6..b3f533b20bf9c5a2170588b93c5a9f8677739702 100755 (executable)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 794c9f56ef397a412e04a9d9d561aa5e48023969..a2fb2d035270eb0694627c2c5191c621cd7667e2 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2012-2015  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
index 317b2182afc376fd0fa3af57c0620ff598e9f845..95d6a2ff1cb4d6bd6c7e05bedb8e6682c5d167fe 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index de22ba86fe9e3dd6cb64073292f52d2ae85d0ea8..a50ee47f69bed895d59587187185aa1b7f977e0a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 13ca2e262682e268d87af41e14851c22106debed..5aa64330ac6867cb50f93cdce16f4dec323aaecd 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -183,7 +183,7 @@ Driver_Mesh::Status DriverUNV_W_SMDS_Mesh::Perform()
             aRec.fe_descriptor_id = anId;
             aRec.node_labels.reserve(aNbNodes);
             SMDS_NodeIteratorPtr aNodesIter = anElem->nodesIteratorToUNV();
-            while ( aNodesIter->more() && aRec.node_labels.size() < aNbNodes )
+            while ( aNodesIter->more() && (int)aRec.node_labels.size() < aNbNodes )
             {
               const SMDS_MeshElement* aNode = aNodesIter->next();
               aRec.node_labels.push_back(aNode->GetID());
index 858f667feafde0f7af39b86195713be30a2c5e65..d09d2d4058d27c901065de9e542c68945a1405c7 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 801fdb9f4ee9f9233851496adb24590c156ce017..9f9ef953635aca4d8e43e851c0e2dddf786aeeab 100755 (executable)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 47e44554f9a2ba4442ef99f7cab726ba01cf610c..87c15bcdf625c5e7c39d46c6a284ed1831e14ac8 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 38a617f71ec2c8318d24c8c8540df9d13f4fad27..2dab980215fa401487bcc60df0be6b33d2ada528 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 182e9d7e8d723ccfb1a97344ee10707c29c4f4ab..89a80abd643052f258f4e53b77f6c4b677e9f4f2 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index c6b4736ffddd31c6174d93bec359cbe5a0e0b809..2b518a9aa15940111b7e0d15709d15119c1d07e3 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index f4df5bac28a736c0a429909ed609dee48ece8f51..c7160adf627edd58cf7bd44f9bc43a024e88d065 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 87659e6680f6c672fda60b50da58acdcd7b1ec08..1ef8a38e091d1a56d142440da2cc2cced130909c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 527614f131dfe31485c7e739fa52a64ed717b9c6..695431a3115dfb0aa783e3bf3d36036d50af1369 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index f5ece4a2d8714590e17d18f3f39fbd78c231cfbb..5e155c7806525e73ff7e9511449aa4e015427712 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 459b0e6a09cd76f54ced6f8de948fdab78b40242..24f224c1fcd866a8914ff97462388245aee031ae 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 60b198941c89d21be263917181de4380290c81cd..60dd28afe2568b9434a6376afec075e78d57dee3 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 9a1c6267dc54fd87e1fc1dd6a522c7c0628ef060..546e98d3ffaebbf93902e0a3c92ca914b158d3c6 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index af5643d0331e15bac00b40a3e8e50a7133d136cb..28ebcd17fede540c129cdd7c4dc8de50050f5e8a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -56,24 +56,27 @@ namespace UNV{
   {
     assert (in_file.good());
     assert (!ds_name.empty());
-    
+
     std::string olds, news;
-    
+
     in_file.seekg(0);
-    while(true){
+    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() ){     
+      while( ((olds != "-1") || (news == "-1")))
+      {
         olds = news;
         in_file >> news;
-      }
-      if(in_file.eof())
-      {
-        in_file.clear();
-        return false;
+
+        if ( in_file.eof() || in_file.fail() )
+        {
+          in_file.clear();
+          return false;
+        }
       }
       if (news == ds_name)
         return true;
@@ -90,17 +93,17 @@ namespace UNV{
    */
   inline double D_to_e(std::string& number)
   {
-    /* find "D" in string, start looking at 
+    /* find "D" in string, start looking at
      * 6th element, to improve speed.
      * We dont expect a "D" earlier
      */
-    const int position = number.find("D",6);
-    if(position != std::string::npos){
-      number.replace(position, 1, "e"); 
-    }
+    const size_t position = number.find("D",6);
+    if ( position != std::string::npos )
+      number.replace(position, 1, "e");
+
     return atof (number.c_str());
   }
-  
+
   /**
    * @returns \p false when file is incorrect, \p true otherwise.
    * Check file with name \p theFileName for correct terminate
index 38cdc56c896a58b33a1644b2e0ecee7225a406dd..3e842cf60bc239150fbcf9ad23fb9c1145960e53 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2012-2015  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
index 62795f8787c3cd1f2dae28834b5f6138b2b0ca2b..effa5cd1d9f4b2e98b3b53cbc1009782781d5305 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index c752feaf9fb249d1d7df47df3939e41d91c95329..4c2dcc8c0b0ab8b4f1f831090abeef968187d164 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 0c118238582224947e71b14be0711072144857c0..ff12d3821040724b39a49731e2ee292586cefc46 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -71,7 +71,7 @@ namespace MED{
                 eQUAD4=204, eTRIA6=206, eTRIA7=207, eQUAD8=208, eQUAD9=209,eTETRA4=304,
                 ePYRA5=305, ePENTA6=306, eHEXA8=308, eOCTA12=312, eTETRA10=310, 
                 ePYRA13=313, ePENTA15=315, eHEXA20=320, eHEXA27=327,
-                ePOLYGONE=400, ePOLYEDRE=500, eNONE=0, 
+                ePOLYGONE=400, ePOLYGON2=420, ePOLYEDRE=500, eNONE=0, 
                 eBALL=1101 /*no such a type in med.h, it's just a trick*/,
                 eAllGeoType=-1 } EGeometrieElement;
 
index f28175b60e1fc7185bb796521abea77c68350199..203a0565b50d57e6129e9df5695c3b521ea0dfbc 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 5a091ce03d2f80d9ea7e567b377b8b04bbad2413..01c8446b022010368a0ff3b760f3e355b2baffdc 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index db27e4e22d7d9119702389b22e97996fd7de46b4..9025f7b32e414c9110fb398ee2e469dfa4b08dd3 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index 817690c12db0a9226e4e189b92eff11a6a01f820..b5ef03d798c7adc45339a9a498455016cbdd9ef4 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index 6381e15436d6a7452d820a5306dd76efaed5c9ac..a89c45aefc3795e434756337bee91b9531389300 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index b97383ddc54c0e4a99c23e9a04aa4afcb964ad62..d2bafc497cb330387e78f680d5bc0c4b73bebee8 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 0c52a2062a0843557867e42439426221bb8c95ef..7477805f16e67dd393715d0bf67bf7ab00381564 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index b8d0e853a8cbaaf7a3e37f4635b692fef8af594a..9eb9241460b75613755fa70928847a82c607c66a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index a138b340397c04e5e0d6fcb8dfed10948b0ab4b3..2a105fa4457ec37f52080f4ba9a86c52932d3f38 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 5a2cdb0564a350bc8038e81b9664c48cbb244c76..0f1d1a21a84b6d7842eaa700b48b1976a3545c17 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 0f00d598a7acd241f58f02a1d460ad63dcb801f4..9b8fba09a1981caebd8834cd4754bc3385cc7e8b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index af3e56fc6210e6b96385dacb1a9a9e27a6bca6ca..637a403933f7f05b7080e539b148b9f34c531938 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 917c61a53c5ebeec3514b4754906ea16a57fba8a..d04b0576241e1208954718f71dad4b8ea3a119c9 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -79,6 +79,7 @@ bool InitEntity2GeomSet()
   aGeomFACESet.insert(eQUAD8);
   aGeomFACESet.insert(eQUAD9);
   aGeomFACESet.insert(ePOLYGONE);
+  aGeomFACESet.insert(ePOLYGON2);
 
   TGeomSet& aGeomMAILLESet = Entity2GeomSet[eMAILLE];
   aGeomMAILLESet.insert(ePOINT1);
index dc438956057ed6d1cd735f46f9d0e2917bd9c6e3..250a05c7cde3f6c34b1189cfa4e490e14b5d7705 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index e0b6abb3a6c5caa421f086d5c9880670d282eac2..38fd1bd6d5d7719d1a4ce71e40ca8cbf87369a7a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 92fef242ba1c3141b5f1c96318cc8e78002aa54d..a25b1b4974f77a39c33ef4e9fd122e2379e4e6d1 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index d64d2b853c430dbdf323f6bc5efa97b4ee41af90..2a14dd844c351d8ce8e6c9a9db37243fa861b674 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 2b0d7d451268b3e10327e3009f5210941d38c973..11dfc2d31e7ed2734367fb08602d9aff0b7d5a23 100755 (executable)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 1320cea8cb9abeaf9890bf7032fb047431058a19..15d0610b69075cafbcaa7d1118ab2995ed302733 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2012-2015  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
index 9661c6e4fcd9d56393c523b7f7d6b623fab6c65a..a6ca900620137c3d3fe9f7e7bc3953dc7350a83a 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2012-2015  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
index 06ebdd00fe22e0cd5c385c2cec8a79cf25ce5a14..3bb54574e402c2106f117aae1986d71e1b00bb22 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -27,9 +27,9 @@
 #include <stdio.h>
 #include <sstream>
 
+#include <med.h>
 extern "C"
 {
-#include <med.h>
 #ifndef WIN32
   #include <unistd.h>
 #endif
index f83ab21b91261662f2c75f4b99dc8508e68636b0..930d17a0da7ca50f5c7f07abf81e969c7cacf22d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index ecfa5dad3bdbce0e5956daa2946d41a2436a7ace..6f305f61efadc04c16b0d53422be7718c9d5f735 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 5f5414156888648c258f65686b9e7250168f6cea..8bd7d0e7a9c54ef5aeca12f1c619a950df68a3dc 100755 (executable)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index cbfc090f9429d354eb9cb762ba54c9a7d491fc8f..25afc1cd2bc5587917fefa0602f88df4f90901e6 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 5594d6aaedb0c790b20f051ce84719eddeeef406..472f784b889b9d28f84b6b58a0d1bdae2f94b372 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2012-2015  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
index 1b097b9b19c4a5967ebcc762c0fff55e2bcd284f..549f1944aa5164e4474040d507b0466a7777222a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 #include "MED_Algorithm.hxx"
 #include "MED_Utilities.hxx"
 
-extern "C"
-{
 #include <med.h>
 #include <med_err.h>
-}
 
 #ifdef _DEBUG_
 static int MYDEBUG = 0;
@@ -166,11 +163,26 @@ namespace MED
 
 
     //---------------------------------------------------------------
-    TVWrapper::TVWrapper(const std::string& theFileName): 
+    TVWrapper::TVWrapper(const std::string& theFileName):
       myFile(new TFile(theFileName))
-    {}
-    
-    
+    {
+      TErr aRet;
+      myFile->Open( eLECTURE_ECRITURE, &aRet );
+      // if(aRet < 0)
+      //   myFile->Close();
+      //   myFile->Open( eLECTURE_AJOUT, &aRet );
+      // }
+      if(aRet < 0) {
+        myFile->Close();
+        myFile->Open( eLECTURE, &aRet );
+      }
+      if(aRet < 0) {
+        myFile->Close();
+        myFile->Open( eCREATION, &aRet );
+      }
+    }
+
+
     //----------------------------------------------------------------------------
     TInt
     TVWrapper
@@ -948,22 +960,19 @@ namespace MED
 
       MED::TMeshInfo& aMeshInfo = *theInfo.myMeshInfo;
 
-      TValueHolder<TString, char> aMeshName(aMeshInfo.myName);
-      TValueHolder<TElemNum, med_int> anIndex(theInfo.myIndex);
-      TInt aNbElem = (TInt)theInfo.myElemNum->size();
-      TValueHolder<TElemNum, med_int> aConn(theInfo.myConn);
-      TValueHolder<EEntiteMaillage, med_entity_type> anEntity(theInfo.myEntity);
+      TValueHolder<TString, char                       > aMeshName(aMeshInfo.myName);
+      TValueHolder<TElemNum, med_int                   > anIndex  (theInfo.myIndex);
+      TValueHolder<TElemNum, med_int                   > aConn    (theInfo.myConn);
+      TValueHolder<EEntiteMaillage, med_entity_type    > anEntity (theInfo.myEntity);
+      TValueHolder<EGeometrieElement, med_geometry_type> aGeom    (theInfo.myGeom);
       TValueHolder<EConnectivite, med_connectivity_mode> aConnMode(theInfo.myConnMode);
+      TInt aNbElem = (TInt)theInfo.myElemNum->size();
 
       TErr aRet;
-      aRet = MEDmeshPolygonRd(myFile->Id(),
-                              &aMeshName,
-                              MED_NO_DT,
-                              MED_NO_IT,
-                              anEntity,
-                              aConnMode,
-                              &anIndex,
-                              &aConn);
+      aRet = MEDmeshPolygon2Rd(myFile->Id(), &aMeshName,
+                               MED_NO_DT, MED_NO_IT,
+                               anEntity, aGeom,
+                               aConnMode, &anIndex, &aConn);
 
       if(theErr) 
         *theErr = aRet;
@@ -971,18 +980,18 @@ namespace MED
         EXCEPTION(std::runtime_error,"GetPolygoneInfo - MEDmeshPolygonRd(...)");
 
       if(theInfo.myIsElemNames){
-        GetNames(theInfo,aNbElem,theInfo.myEntity,ePOLYGONE,&aRet);
+        GetNames(theInfo,aNbElem,theInfo.myEntity,theInfo.myGeom,&aRet);
         if(theErr) 
           *theErr = aRet;
       }
 
       if(theInfo.myIsElemNum){
-        GetNumeration(theInfo,aNbElem,theInfo.myEntity,ePOLYGONE,&aRet);
+        GetNumeration(theInfo,aNbElem,theInfo.myEntity,theInfo.myGeom,&aRet);
         if(theErr) 
           *theErr = aRet;
       }
 
-      GetFamilies(theInfo,aNbElem,theInfo.myEntity,ePOLYGONE,&aRet);
+      GetFamilies(theInfo,aNbElem,theInfo.myEntity,theInfo.myGeom,&aRet);
       if(theErr) 
         *theErr = aRet;
     }
@@ -1011,37 +1020,32 @@ namespace MED
       MED::TPolygoneInfo& anInfo = const_cast<MED::TPolygoneInfo&>(theInfo);
       MED::TMeshInfo& aMeshInfo = *anInfo.myMeshInfo;
 
-      TValueHolder<TString, char> aMeshName(aMeshInfo.myName);
-      TValueHolder<TElemNum, med_int> anIndex(anInfo.myIndex);
-      TValueHolder<TElemNum, med_int> aConn(anInfo.myConn);
-      TValueHolder<EEntiteMaillage, med_entity_type> anEntity(anInfo.myEntity);
+      TValueHolder<TString, char                       > aMeshName(aMeshInfo.myName);
+      TValueHolder<TElemNum, med_int                   > anIndex  (anInfo.myIndex);
+      TValueHolder<TElemNum, med_int                   > aConn    (anInfo.myConn);
+      TValueHolder<EEntiteMaillage, med_entity_type    > anEntity (anInfo.myEntity);
+      TValueHolder<EGeometrieElement, med_geometry_type> aGeom    (anInfo.myGeom);
       TValueHolder<EConnectivite, med_connectivity_mode> aConnMode(anInfo.myConnMode);
 
-      TErr aRet = MEDmeshPolygonWr(myFile->Id(),
-                                   &aMeshName,
-                                   MED_NO_DT,
-                                   MED_NO_IT,
-                                   MED_UNDEF_DT,
-                                   anEntity,
-                                   aConnMode,
-                                   anInfo.myNbElem + 1,
-                                   &anIndex,
-                                   &aConn);
-      
-      if(theErr) 
+      TErr aRet = MEDmeshPolygon2Wr(myFile->Id(), &aMeshName,
+                                    MED_NO_DT, MED_NO_IT, MED_UNDEF_DT,
+                                    anEntity, aGeom,
+                                    aConnMode, anInfo.myNbElem + 1,
+                                    &anIndex, &aConn);
+      if(theErr)
         *theErr = aRet;
       else if(aRet < 0)
         EXCEPTION(std::runtime_error,"SetPolygoneInfo - MEDmeshPolygonWr(...)");
       
-      SetNames(anInfo,theInfo.myEntity,ePOLYGONE,&aRet);
+      SetNames(anInfo,theInfo.myEntity,anInfo.myGeom,&aRet);
       if(theErr) 
         *theErr = aRet;
       
-      SetNumeration(anInfo,theInfo.myEntity,ePOLYGONE,&aRet);
+      SetNumeration(anInfo,theInfo.myEntity,anInfo.myGeom,&aRet);
       if(theErr) 
         *theErr = aRet;
       
-      SetFamilies(anInfo,theInfo.myEntity,ePOLYGONE,&aRet);
+      SetFamilies(anInfo,theInfo.myEntity,anInfo.myGeom,&aRet);
       if(theErr) 
         *theErr = aRet;
     }
@@ -1082,7 +1086,7 @@ namespace MED
                              MED_NO_DT,
                              MED_NO_IT,
                              med_entity_type(theEntity),
-                             MED_POLYGON,
+                             med_geometry_type(theGeom),
                              MED_CONNECTIVITY,
                              med_connectivity_mode(theConnMode),
                              &chgt,
@@ -1418,16 +1422,14 @@ namespace MED
       }
       return anInfo;
     }
-    
-    
+
+
     //-----------------------------------------------------------------
-    TInt
-    TVWrapper
-    ::GetNbCells(const MED::TMeshInfo& theMeshInfo, 
-                 EEntiteMaillage theEntity, 
-                 EGeometrieElement theGeom, 
-                 EConnectivite theConnMode,
-                 TErr* theErr)
+    TInt TVWrapper::GetNbCells(const MED::TMeshInfo& theMeshInfo,
+                               EEntiteMaillage theEntity,
+                               EGeometrieElement theGeom,
+                               EConnectivite theConnMode,
+                               TErr* theErr)
     {
       TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
 
@@ -1437,48 +1439,50 @@ namespace MED
       MED::TMeshInfo& aMeshInfo = const_cast<MED::TMeshInfo&>(theMeshInfo);
       TValueHolder<TString, char> aMeshName(aMeshInfo.myName);
       med_bool chgt,trsf;
-      if(theGeom!=MED::ePOLYGONE && theGeom!=MED::ePOLYEDRE && theGeom != MED::eBALL)
+      switch ( theGeom )
       {
-        return MEDmeshnEntity(myFile->Id(),
-                              &aMeshName,
-                              MED_NO_DT,
-                              MED_NO_IT,
-                              med_entity_type(theEntity),
-                              med_geometry_type(theGeom),
-                              MED_CONNECTIVITY,
-                              med_connectivity_mode(theConnMode),
-                              &chgt,
-                              &trsf);
-      }
-      else if(theGeom==MED::ePOLYGONE)
+      case MED::ePOLYGONE:
+      case MED::ePOLYGON2:
       {
-        return MEDmeshnEntity(myFile->Id(),&aMeshName,MED_NO_DT,MED_NO_IT,med_entity_type(theEntity),
-                              MED_POLYGON,MED_INDEX_NODE,med_connectivity_mode(theConnMode),&chgt,&trsf)-1;
+        return MEDmeshnEntity(myFile->Id(),&aMeshName,
+                              MED_NO_DT,MED_NO_IT,
+                              med_entity_type(theEntity),med_geometry_type(theGeom),
+                              MED_INDEX_NODE,med_connectivity_mode(theConnMode),
+                              &chgt,&trsf)-1;
       }
-      else if ( theGeom==MED::ePOLYEDRE )
+      case MED::ePOLYEDRE:
       {
-        return MEDmeshnEntity(myFile->Id(),&aMeshName,MED_NO_DT,MED_NO_IT,med_entity_type(theEntity),
-                              MED_POLYHEDRON,MED_INDEX_FACE,med_connectivity_mode(theConnMode),&chgt,&trsf)-1;
+        return MEDmeshnEntity(myFile->Id(),&aMeshName,
+                              MED_NO_DT,MED_NO_IT,
+                              med_entity_type(theEntity),MED_POLYHEDRON,
+                              MED_INDEX_FACE,med_connectivity_mode(theConnMode),
+                              &chgt,&trsf)-1;
       }
-      else if ( theGeom==MED::eBALL )
+      case MED::eBALL:
       {
         return GetNbBalls( theMeshInfo );
       }
+      default:
+      {
+        return MEDmeshnEntity(myFile->Id(),&aMeshName,
+                              MED_NO_DT,MED_NO_IT,
+                              med_entity_type(theEntity),med_geometry_type(theGeom),
+                              MED_CONNECTIVITY,med_connectivity_mode(theConnMode),
+                              &chgt,&trsf);
+      }
+      }
       return 0;
     }
 
 
     //----------------------------------------------------------------------------
-    void
-    TVWrapper
-    ::GetCellInfo(MED::TCellInfo& theInfo,
-                  TErr* theErr)
+    void TVWrapper::GetCellInfo(MED::TCellInfo& theInfo, TErr* theErr)
     {
       TFileWrapper aFileWrapper(myFile,eLECTURE,theErr);
 
       if(theErr && *theErr < 0)
         return;
-      
+
       MED::TMeshInfo& aMeshInfo = *theInfo.myMeshInfo;
 
       TValueHolder<TString, char>                        aMeshName    (aMeshInfo.myName);
@@ -2874,5 +2878,5 @@ namespace MED
         EXCEPTION(std::runtime_error,"GetGrilleInfo - MEDmeshGridStructRd(...)");
     }
 
-  }  
+  }
 }
index 2eb860dd07a75ef622162af3bb778c42564d28d4..e9408d1cd75b7d5fbd3349cc177603034c2ac8d1 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 5841fbcda5c9cc46204dde9a4fa2cf6f03e60119..72ed216e5b20ab972a65b824c562d663c9359367 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2012-2015  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
index 5950ca88f7978d4a083d04e550ec44d8d99d06ad..6ec871d932ebe6884230eff2afa768298ee28bc4 100755 (executable)
@@ -1,6 +1,6 @@
 //  MEFISTO :  library to compute 2D triangulation from segmented boundaries
 //
-// Copyright (C) 2006-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2006-2015  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
index 8be578cfc4ad4a1f8b218e84163e00ab058b86b1..ca2474262911681b847433498632c4a1f640baa1 100755 (executable)
@@ -1,7 +1,7 @@
 //  MEFISTO2: a library to compute 2D triangulation from segmented boundaries
 //
 //
-// Copyright (C) 2006-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2006-2015  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
index 6c4ad1dbdc82135b899579612a025ff169a48d72..6f1dc7bc48b9bd04205a58cbfe25636d65134a55 100755 (executable)
@@ -1,6 +1,6 @@
 //  SMESH MEFISTO2 : algorithm for meshing
 //
-// Copyright (C) 2006-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2006-2015  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
index 0aef3446ef3455d98250375d32d29c385e87bd78..6ecfb9bc1a2e7d6501a583627ecc39a315856df2 100755 (executable)
@@ -1,6 +1,6 @@
 c  MEFISTO : library to compute 2D triangulation from segmented boundaries
 c
-c Copyright (C) 2006-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+c Copyright (C) 2006-2015  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
index d0e401f4665824e73eb8384384d97bc3f77b486a..8561887621339de0d22f9945d6b10383b2ba3899 100755 (executable)
@@ -1,6 +1,6 @@
 c  MEFISTO2: a library to compute 2D triangulation from segmented boundaries
 c
-c Copyright (C) 2006-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+c Copyright (C) 2006-2015  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
index 4d92e790991e0d743ba6208f270746c20e30f7de..859e3da5a5d46b2be29d089d7766bfd2f8ecc042 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2012-2015  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
@@ -61,13 +61,18 @@ SET(_link_LIBRARIES
   ${GUI_qtx}
   ${GUI_suit}
   ${GUI_std}
-  ${GUI_Plot2d}
-  ${GUI_SPlot2d}
   SMESHClient
   SMDS
   SMESHControls
 )
 
+IF(SALOME_USE_PLOT2DVIEWER)
+  LIST(APPEND _link_LIBRARIES
+    ${GUI_Plot2d}
+    ${GUI_SPlot2d}
+    )
+ENDIF()
+
 # --- headers ---
 
 # header files / no moc processing
index 20582c7b15e86b08b563136643caef13ca732414..1c9af415d5b13b7b52435b590c1e1d92b1f71808 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -222,10 +222,11 @@ SMESH_ActorDef::SMESH_ActorDef()
   aFilter = my2DActor->GetExtractUnstructuredGrid();
   aFilter->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding);
   aFilter->RegisterCellsWithType(VTK_TRIANGLE);
-  aFilter->RegisterCellsWithType(VTK_POLYGON);
   aFilter->RegisterCellsWithType(VTK_QUAD);
+  aFilter->RegisterCellsWithType(VTK_POLYGON);
   aFilter->RegisterCellsWithType(VTK_QUADRATIC_TRIANGLE);
   aFilter->RegisterCellsWithType(VTK_QUADRATIC_QUAD);
+  aFilter->RegisterCellsWithType(VTK_QUADRATIC_POLYGON);
   aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_QUAD);
   aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_TRIANGLE);
 
@@ -245,10 +246,11 @@ SMESH_ActorDef::SMESH_ActorDef()
   my2DExtActor->SetRepresentation(SMESH_DeviceActor::eInsideframe);
   aFilter = my2DExtActor->GetExtractUnstructuredGrid();
   aFilter->RegisterCellsWithType(VTK_TRIANGLE);
-  aFilter->RegisterCellsWithType(VTK_POLYGON);
   aFilter->RegisterCellsWithType(VTK_QUAD);
+  aFilter->RegisterCellsWithType(VTK_POLYGON);
   aFilter->RegisterCellsWithType(VTK_QUADRATIC_TRIANGLE);
   aFilter->RegisterCellsWithType(VTK_QUADRATIC_QUAD);
+  aFilter->RegisterCellsWithType(VTK_QUADRATIC_POLYGON);
   aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_QUAD);
   aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_TRIANGLE);
 
@@ -275,10 +277,7 @@ SMESH_ActorDef::SMESH_ActorDef()
   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
 
   my3DExtProp = vtkProperty::New();
   my3DExtProp->DeepCopy(myNormalVProp);
@@ -1565,18 +1564,20 @@ void SMESH_ActorDef::SetEntityMode(unsigned int theMode)
   if (myEntityMode & eFaces) {
     if (MYDEBUG) MESSAGE("FACES");
     aFilter->RegisterCellsWithType(VTK_TRIANGLE);
-    aFilter->RegisterCellsWithType(VTK_POLYGON);
     aFilter->RegisterCellsWithType(VTK_QUAD);
+    aFilter->RegisterCellsWithType(VTK_POLYGON);
     aFilter->RegisterCellsWithType(VTK_QUADRATIC_TRIANGLE);
     aFilter->RegisterCellsWithType(VTK_QUADRATIC_QUAD);
+    aFilter->RegisterCellsWithType(VTK_QUADRATIC_POLYGON);
     aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_QUAD);
     aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_TRIANGLE);
 
     aHightFilter->RegisterCellsWithType(VTK_TRIANGLE);
-    aHightFilter->RegisterCellsWithType(VTK_POLYGON);
     aHightFilter->RegisterCellsWithType(VTK_QUAD);
+    aHightFilter->RegisterCellsWithType(VTK_POLYGON);
     aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_TRIANGLE);
     aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_QUAD);
+    aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_POLYGON);
     aHightFilter->RegisterCellsWithType(VTK_BIQUADRATIC_QUAD);
     aHightFilter->RegisterCellsWithType(VTK_BIQUADRATIC_TRIANGLE);
   }
@@ -1595,9 +1596,7 @@ void SMESH_ActorDef::SetEntityMode(unsigned int theMode)
     aFilter->RegisterCellsWithType(VTK_QUADRATIC_PYRAMID);
     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);
@@ -1611,9 +1610,7 @@ void SMESH_ActorDef::SetEntityMode(unsigned int theMode)
     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());
@@ -2116,6 +2113,14 @@ double SMESH_ActorDef::GetBallScale()
 void SMESH_ActorDef::SetBallScale( double theVal )
 {
   myBallActor->SetBallScale( theVal );
+  if(SMESH_SVTKActor* aCustom = SMESH_SVTKActor::SafeDownCast( myHighlightActor )) {
+    aCustom->SetBallScale(theVal);
+  }
+  if(SMESH_SVTKActor* aCustom = SMESH_SVTKActor::SafeDownCast( myPreHighlightActor )) {
+    aCustom->SetBallScale(theVal);
+  }
+
+  Modified();
 }
 
 int SMESH_ActorDef::GetObjDimension( const int theObjId )
index 2688e99a60358ebf295a48a9f14df8d985a0d851..cdd839c30b5b872a9fa9e783a4da6f31c7b2e241 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index add4fb6bee5d1a9706d5c14541710ae304c52863..b754ec73098fbbe96f4302c7cab5e0c245c818fc 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index f5477356eeb8bc3397f79fe598fe04379e4fbbe3..98a104e1d8430e062a62558ce0d91cedaff516ae 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 946f27e4f9ea1f3519a199b7ea4c5ace4b1ebf45..87a7c84017af611678139273700022fc95b8f12b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 0d7d428d6f6d276f96a5b4ab64acc4d82c3b1721..6ca1b023de5b2e9bfe860accd78c9a48842fdb3b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 414abc8465cd7a166c7143404f431e80568240f5..7d181f37b17c2d837275a86851f54353b5045454 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index dd7c3480b7968332244c586e04e135ef0fd9a6a2..aeba34ad97d1ed7c87277dc2227842e659864a2d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -297,7 +297,7 @@ SMESH_DeviceActor
                  SMESH_ScalarBarActor* theScalarBarActor,
                  vtkLookupTable* theLookupTable)
 {
-  bool anIsInitialized = theFunctor;
+  bool anIsInitialized = theFunctor != NULL;
   if(anIsInitialized){
     vtkUnstructuredGrid* aDataSet = vtkUnstructuredGrid::New();
 
@@ -363,7 +363,7 @@ SMESH_DeviceActor
                     SMESH_ScalarBarActor* theScalarBarActor,
                     vtkLookupTable* theLookupTable)
 {
-  bool anIsInitialized = theFunctor;
+  bool anIsInitialized = theFunctor != NULL;
   myExtractUnstructuredGrid->ClearRegisteredCells();
   myExtractUnstructuredGrid->ClearRegisteredCellsWithType();
   myExtractUnstructuredGrid->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::ePassAll);
@@ -393,12 +393,13 @@ SMESH_DeviceActor
       vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
       aCellTypesArray->SetNumberOfComponents( 1 );
       aCellTypesArray->Allocate( aNbCells * aCellTypesArray->GetNumberOfComponents() );
-      
+
       vtkIdList *anIdList = vtkIdList::New();
       anIdList->SetNumberOfIds(2);
-      
+
       Length2D::TValues::const_iterator anIter = aValues.begin();
-      for(vtkIdType aVtkId = 0; anIter != aValues.end(); anIter++,aVtkId++){
+      aNbCells = 0;
+      for(; anIter != aValues.end(); anIter++){
         const Length2D::Value& aValue = *anIter;
         int aNode[2] = {
           myVisualObj->GetNodeVTKId(aValue.myPntId[0]),
@@ -409,27 +410,30 @@ SMESH_DeviceActor
           anIdList->SetId( 1, aNode[1] );
           aConnectivity->InsertNextCell( anIdList );
           aCellTypesArray->InsertNextValue( VTK_LINE );
-          aScalars->SetValue(aVtkId,aValue.myLength);
+          aScalars->SetValue(aNbCells,aValue.myLength);
+          aNbCells++;
         }
       }
-      
+      aCellTypesArray->SetNumberOfTuples( aNbCells );
+      aScalars->SetNumberOfTuples( aNbCells );
+
       VTKViewer_CellLocationsArray* aCellLocationsArray = VTKViewer_CellLocationsArray::New();
       aCellLocationsArray->SetNumberOfComponents( 1 );
       aCellLocationsArray->SetNumberOfTuples( aNbCells );
-      
+
       aConnectivity->InitTraversal();
       for( vtkIdType idType = 0, *pts, npts; aConnectivity->GetNextCell( npts, pts ); idType++ )
         aCellLocationsArray->SetValue( idType, aConnectivity->GetTraversalLocation( npts ) );
-      
-      aDataSet->SetCells( aCellTypesArray, aCellLocationsArray,aConnectivity );
+
+      aDataSet->SetCells( aCellTypesArray, aCellLocationsArray, aConnectivity );
       SetUnstructuredGrid(aDataSet);
 
       aDataSet->GetCellData()->SetScalars(aScalars);
       aScalars->Delete();
-      
+
       theLookupTable->SetRange(aScalars->GetRange());
       theLookupTable->Build();
-      
+
       myMergeFilter->SetScalarsData(aDataSet);
       aDataSet->Delete();
     }
@@ -449,16 +453,17 @@ SMESH_DeviceActor
       vtkIdType aCellsSize = 3*aNbCells;
       vtkCellArray* aConnectivity = vtkCellArray::New();
       aConnectivity->Allocate( aCellsSize, 0 );
-      
+
       vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
       aCellTypesArray->SetNumberOfComponents( 1 );
       aCellTypesArray->Allocate( aNbCells * aCellTypesArray->GetNumberOfComponents() );
-      
+
       vtkIdList *anIdList = vtkIdList::New();
       anIdList->SetNumberOfIds(2);
-      
+
       MultiConnection2D::MValues::const_iterator anIter = aValues.begin();
-      for(vtkIdType aVtkId = 0; anIter != aValues.end(); anIter++,aVtkId++){
+      aNbCells = 0;
+      for(; anIter != aValues.end(); anIter++){
         const MultiConnection2D::Value& aValue = (*anIter).first;
         int aNode[2] = {
           myVisualObj->GetNodeVTKId(aValue.myPntId[0]),
@@ -469,27 +474,30 @@ SMESH_DeviceActor
           anIdList->SetId( 1, aNode[1] );
           aConnectivity->InsertNextCell( anIdList );
           aCellTypesArray->InsertNextValue( VTK_LINE );
-          aScalars->SetValue(aVtkId,(*anIter).second);
+          aScalars->SetValue( aNbCells,(*anIter).second);
+          aNbCells++;
         }
       }
-      
+      aCellTypesArray->SetNumberOfTuples( aNbCells );
+      aScalars->SetNumberOfTuples( aNbCells );
+
       VTKViewer_CellLocationsArray* aCellLocationsArray = VTKViewer_CellLocationsArray::New();
       aCellLocationsArray->SetNumberOfComponents( 1 );
       aCellLocationsArray->SetNumberOfTuples( aNbCells );
-      
+
       aConnectivity->InitTraversal();
       for( vtkIdType idType = 0, *pts, npts; aConnectivity->GetNextCell( npts, pts ); idType++ )
         aCellLocationsArray->SetValue( idType, aConnectivity->GetTraversalLocation( npts ) );
-      
+
       aDataSet->SetCells( aCellTypesArray, aCellLocationsArray,aConnectivity );
       SetUnstructuredGrid(aDataSet);
 
       aDataSet->GetCellData()->SetScalars(aScalars);
       aScalars->Delete();
-      
+
       theLookupTable->SetRange(aScalars->GetRange());
       theLookupTable->Build();
-      
+
       myMergeFilter->SetScalarsData(aDataSet);
       aDataSet->Delete();
     }
@@ -508,17 +516,17 @@ SMESH_DeviceActor
   myVisualObj->UpdateFunctor(theFunctor);
 
   using namespace SMESH::Controls;
-  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 = 0;
+  if (( aPredicate =  dynamic_cast<FreeBorders          *>(theFunctor.get())) ||
+      ( aPredicate =  dynamic_cast<FreeFaces            *>(theFunctor.get())) ||
+      ( aPredicate =  dynamic_cast<BareBorderVolume     *>(theFunctor.get())) ||
+      ( aPredicate =  dynamic_cast<BareBorderFace       *>(theFunctor.get())) ||
+      ( aPredicate =  dynamic_cast<OverConstrainedVolume*>(theFunctor.get())) ||
+      ( aPredicate =  dynamic_cast<CoincidentElements1D *>(theFunctor.get())) ||
+      ( aPredicate =  dynamic_cast<CoincidentElements2D *>(theFunctor.get())) ||
+      ( aPredicate =  dynamic_cast<CoincidentElements3D *>(theFunctor.get())) ||
+      ( aPredicate =  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();
@@ -580,10 +588,9 @@ SMESH_DeviceActor
     SetUnstructuredGrid(aDataSet);
     aDataSet->Delete();
   }
-  else if(dynamic_cast<FreeNodes      *>(theFunctor.get()) ||
-          dynamic_cast<CoincidentNodes*>(theFunctor.get()))
+  else if (( aPredicate = dynamic_cast<FreeNodes      *>(theFunctor.get())) ||
+           ( aPredicate = dynamic_cast<CoincidentNodes*>(theFunctor.get())))
   {
-    Predicate* aPredicate = dynamic_cast<Predicate*>(theFunctor.get());
     myExtractUnstructuredGrid->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding);
     vtkIdType aNbNodes = myVisualObj->GetNbEntities(SMDSAbs_Node);
     for( vtkIdType i = 0; i < aNbNodes; i++ ){
index ce8f74362c1a17957474d13229c0760476324b0d..c447e34a35afe2edaa03e20692271400c19b1d1c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 709ce985319ebb9c4eb0150c1632e5ce186418ba..b3ff7d74bd630b151851c9b49d1328db5e190d08 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -55,35 +55,36 @@ SMESH_ExtractGeometry::SMESH_ExtractGeometry()
 {}
 
 
-SMESH_ExtractGeometry::~SMESH_ExtractGeometry(){}
-
+SMESH_ExtractGeometry::~SMESH_ExtractGeometry()
+{}
 
-vtkIdType SMESH_ExtractGeometry::GetElemObjId(int theVtkID){
+vtkIdType SMESH_ExtractGeometry::GetElemObjId(int theVtkID)
+{
   if( theVtkID < 0 || theVtkID >= myElemVTK2ObjIds.size()) return -1;
   return myElemVTK2ObjIds[theVtkID];
 }
 
 
-vtkIdType SMESH_ExtractGeometry::GetNodeObjId(int theVtkID){
+vtkIdType SMESH_ExtractGeometry::GetNodeObjId(int theVtkID)
+{
   if ( theVtkID < 0 || theVtkID >= myNodeVTK2ObjIds.size()) return -1;
   return myNodeVTK2ObjIds[theVtkID];
 }
 
 
-int SMESH_ExtractGeometry::RequestData(
-  vtkInformation *vtkNotUsed(request),
-  vtkInformationVector **inputVector,
-  vtkInformationVector *outputVector)
+int SMESH_ExtractGeometry::RequestData(vtkInformation *vtkNotUsed(request),
+                                       vtkInformationVector **inputVector,
+                                       vtkInformationVector *outputVector)
 {
   // get the info objects
   vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
   vtkInformation *outInfo = outputVector->GetInformationObject(0);
 
   // get the input and ouptut
-  vtkDataSet *input = vtkDataSet::SafeDownCast(
-    inInfo->Get(vtkDataObject::DATA_OBJECT()));
-  vtkUnstructuredGrid *output = vtkUnstructuredGrid::SafeDownCast(
-    outInfo->Get(vtkDataObject::DATA_OBJECT()));
+  vtkDataSet *input =
+    vtkDataSet::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT()));
+  vtkUnstructuredGrid *output =
+    vtkUnstructuredGrid::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()));
 
   vtkIdType ptId, numPts, numCells, i, cellId, newCellId, newId, *pointMap;
   vtkIdList *cellPts;
@@ -100,35 +101,35 @@ int SMESH_ExtractGeometry::RequestData(
   int npts;
   numCells = input->GetNumberOfCells();
   numPts = input->GetNumberOfPoints();
-  
+
   vtkDebugMacro(<< "Extracting geometry");
 
   if ( ! this->ImplicitFunction )
-    {
+  {
     vtkErrorMacro(<<"No implicit function specified");
     return 0;
-    }
+  }
 
   newCellPts = vtkIdList::New();
   newCellPts->Allocate(VTK_CELL_SIZE);
 
   if ( this->ExtractInside )
-    {
+  {
     multiplier = 1.0;
-    }
-  else 
-    {
+  }
+  else
+  {
     multiplier = -1.0;
-    }
+  }
 
   // Loop over all points determining whether they are inside the
   // implicit function. Copy the points and point data if they are.
   //
   pointMap = new vtkIdType[numPts]; // maps old point ids into new
   for (i=0; i < numPts; i++)
-    {
+  {
     pointMap[i] = -1;
-    }
+  }
 
   output->Allocate(numCells/4); //allocate storage for geometry/topology
   newPts = vtkPoints::New();
@@ -136,7 +137,7 @@ int SMESH_ExtractGeometry::RequestData(
   outputPD->CopyAllocate(pd);
   outputCD->CopyAllocate(cd);
   vtkFloatArray *newScalars = NULL;
-  
+
   if(myStoreMapping){
     myElemVTK2ObjIds.clear();
     myElemVTK2ObjIds.reserve(numCells);
@@ -145,110 +146,110 @@ int SMESH_ExtractGeometry::RequestData(
   }
 
   if ( ! this->ExtractBoundaryCells )
-    {
+  {
     for ( ptId=0; ptId < numPts; ptId++ )
-      {
+    {
       x = input->GetPoint(ptId);
       if ( (this->ImplicitFunction->FunctionValue(x)*multiplier) < 0.0 )
-        {
+      {
         newId = newPts->InsertNextPoint(x);
         pointMap[ptId] = newId;
         myNodeVTK2ObjIds.push_back(ptId);
         outputPD->CopyData(pd,ptId,newId);
-        }
       }
     }
+  }
   else
-    {
+  {
     // To extract boundary cells, we have to create supplemental information
     if ( this->ExtractBoundaryCells )
-      {
+    {
       double val;
       newScalars = vtkFloatArray::New();
       newScalars->SetNumberOfValues(numPts);
 
       for (ptId=0; ptId < numPts; ptId++ )
-        {
+      {
         x = input->GetPoint(ptId);
         val = this->ImplicitFunction->FunctionValue(x) * multiplier;
         newScalars->SetValue(ptId, val);
         if ( val < 0.0 )
-          {
+        {
           newId = newPts->InsertNextPoint(x);
           pointMap[ptId] = newId;
           myNodeVTK2ObjIds.push_back(ptId);
           outputPD->CopyData(pd,ptId,newId);
-          }
         }
       }
     }
+  }
 
   // Now loop over all cells to see whether they are inside implicit
   // function (or on boundary if ExtractBoundaryCells is on).
   //
   for (cellId=0; cellId < numCells; cellId++)
-    {
+  {
     cell = input->GetCell(cellId);
     cellPts = cell->GetPointIds();
     numCellPts = cell->GetNumberOfPoints();
 
     newCellPts->Reset();
     if ( ! this->ExtractBoundaryCells ) //requires less work
-      {
+    {
       for ( npts=0, i=0; i < numCellPts; i++, npts++)
-        {
+      {
         ptId = cellPts->GetId(i);
         if ( pointMap[ptId] < 0 )
-          {
+        {
           break; //this cell won't be inserted
-          }
+        }
         else
-          {
+        {
           newCellPts->InsertId(i,pointMap[ptId]);
-          }
         }
-      } //if don't want to extract boundary cells
-    
+      }
+    } //if don't want to extract boundary cells
+
     else //want boundary cells
-      {
+    {
       for ( npts=0, i=0; i < numCellPts; i++ )
-        {
+      {
         ptId = cellPts->GetId(i);
         if ( newScalars->GetValue(ptId) <= 0.0 )
-          {
+        {
           npts++;
-          }
         }
+      }
       if ( npts > 0 )
-        {
+      {
         for ( i=0; i < numCellPts; i++ )
-          {
+        {
           ptId = cellPts->GetId(i);
           if ( pointMap[ptId] < 0 )
-            {
+          {
             x = input->GetPoint(ptId);
             newId = newPts->InsertNextPoint(x);
             pointMap[ptId] = newId;
             myNodeVTK2ObjIds.push_back(ptId);
             outputPD->CopyData(pd,ptId,newId);
-            }
-          newCellPts->InsertId(i,pointMap[ptId]);
           }
-        }//a boundary or interior cell
-      }//if mapping boundary cells
-      
-    if ( npts >= numCellPts || (this->ExtractBoundaryCells && npts > 0) )
-      {
-        if(cell->GetCellType() == VTK_POLYHEDRON) {
-          newCellPts->Reset();
-          vtkUnstructuredGrid::SafeDownCast(input)->GetFaceStream( cellId ,newCellPts );        
-          vtkUnstructuredGrid::ConvertFaceStreamPointIds(newCellPts, pointMap);
+          newCellPts->InsertId(i,pointMap[ptId]);
         }
-          newCellId = output->InsertNextCell(cell->GetCellType(),newCellPts);
-          myElemVTK2ObjIds.push_back(cellId);
-          outputCD->CopyData(cd,cellId,newCellId);
+      }//a boundary or interior cell
+    }//if mapping boundary cells
+
+    if ( npts >= numCellPts || (this->ExtractBoundaryCells && npts > 0) )
+    {
+      if(cell->GetCellType() == VTK_POLYHEDRON) {
+        newCellPts->Reset();
+        vtkUnstructuredGrid::SafeDownCast(input)->GetFaceStream( cellId ,newCellPts );
+        vtkUnstructuredGrid::ConvertFaceStreamPointIds(newCellPts, pointMap);
       }
-    }//for all cells
+      newCellId = output->InsertNextCell(cell->GetCellType(),newCellPts);
+      myElemVTK2ObjIds.push_back(cellId);
+      outputCD->CopyData(cd,cellId,newCellId);
+    }
+  }//for all cells
 
   // Update ourselves and release memory
   //
@@ -256,11 +257,11 @@ int SMESH_ExtractGeometry::RequestData(
   newCellPts->Delete();
   output->SetPoints(newPts);
   newPts->Delete();
-  
+
   if ( this->ExtractBoundaryCells )
-    {
+  {
     newScalars->Delete();
-    }
+  }
 
   output->Squeeze();
   return 1;
index fda9595d18bdae2e60fd50a22f66874a71a8ced6..06fad91bbbdbe201f7302321feb90301b4b518c4 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index ce85f22fc7fef9a28f31454851288bff9442195e..59ed6c33f3129c728a22cfb0949e0c289b2cc4a4 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index 2832ace693377d27b920e3f817c042e86e1bc65e..155828000700f4d5dbcf407476cc90f3b3124259 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index 604db28ee83298d5dac0ef6602ce8c66125600bb..1862cc7cc7525b57b41979812276e04564a6a932 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 2c11348bbeee7ed3a2aa9c8b9d60762ad9dd1b67..6aa2cae452defeaf5a4016465997c312a46a339a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 71711f81aaae0caf663eb07aea1fbeff8899e998..44d70da65188d8ad8cef4bc91a923efda8ed5eef 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 #include "SMESH_ObjectDef.h"
 #include "SMESH_ActorUtils.h"
 
+#include "SMDS_BallElement.hxx"
 #include "SMDS_Mesh.hxx"
+#include "SMDS_MeshCell.hxx"
 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
-#include "SMDS_BallElement.hxx"
 #include "SMESH_Actor.h"
 #include "SMESH_ControlsDef.hxx"
-#include "SalomeApp_Application.h"
-#include "VTKViewer_ExtractUnstructuredGrid.h"
-#include "VTKViewer_CellLocationsArray.h"
+
+#include <SalomeApp_Application.h>
+#include <VTKViewer_ExtractUnstructuredGrid.h>
+#include <VTKViewer_CellLocationsArray.h>
 
 #include CORBA_SERVER_HEADER(SMESH_Gen)
 #include CORBA_SERVER_HEADER(SALOME_Exception)
@@ -82,48 +84,48 @@ static int MYDEBUGWITHFILES = 0;
 // function : getCellType
 // purpose  : Get type of VTK cell
 //=================================================================================
-static inline vtkIdType getCellType( const SMDSAbs_ElementType theType,
-                                     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;
-      else return VTK_EMPTY_CELL;
-
-    case SMDSAbs_Face  :
-      if (thePoly && theNbNodes>2 ) return VTK_POLYGON;
-      else if ( theNbNodes == 3 )   return VTK_TRIANGLE;
-      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 if ( theNbNodes == 7 )   return VTK_BIQUADRATIC_TRIANGLE;
-      else return VTK_EMPTY_CELL;
+// static inline vtkIdType getCellType( const SMDSAbs_ElementType theType,
+//                                      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;
+//       else return VTK_EMPTY_CELL;
+
+//     case SMDSAbs_Face  :
+//       if (thePoly && theNbNodes>2 ) return VTK_POLYGON;
+//       else if ( theNbNodes == 3 )   return VTK_TRIANGLE;
+//       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 if ( theNbNodes == 7 )   return VTK_BIQUADRATIC_TRIANGLE;
+//       else return VTK_EMPTY_CELL;
       
-    case SMDSAbs_Volume:
-      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 == 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;
-  }
-}
+//     case SMDSAbs_Volume:
+//       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 == 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;
+//   }
+// }
 
 //=================================================================================
 // functions : SMESH_VisualObjDef
@@ -151,48 +153,56 @@ SMESH_VisualObjDef::~SMESH_VisualObjDef()
 //=================================================================================
 vtkIdType SMESH_VisualObjDef::GetNodeObjId( int theVTKID )
 {
-        if (myLocalGrid)
-        {
-                TMapOfIds::const_iterator i = myVTK2SMDSNodes.find(theVTKID);
-                return i == myVTK2SMDSNodes.end() ? -1 : i->second;
-        }
-  return this->GetMesh()->FindNodeVtk(theVTKID)->GetID();
+  if (myLocalGrid)
+  {
+    TMapOfIds::const_iterator i = myVTK2SMDSNodes.find(theVTKID);
+    return i == myVTK2SMDSNodes.end() ? -1 : i->second;
+  }
+  const SMDS_MeshNode* aNode = 0;
+  if( this->GetMesh() )
+    aNode = this->GetMesh()->FindNodeVtk( theVTKID );
+
+  return aNode ? aNode->GetID() : -1;
 }
 
 vtkIdType SMESH_VisualObjDef::GetNodeVTKId( int theObjID )
 {
-        if (myLocalGrid)
-        {
-                TMapOfIds::const_iterator i = mySMDS2VTKNodes.find(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;
+  const SMDS_MeshNode* aNode = 0;
+  if( this->GetMesh() ) {
+    aNode = this->GetMesh()->FindNode(theObjID);
+  }
+  return aNode ? aNode->getVtkId() : -1;
 }
 
 vtkIdType SMESH_VisualObjDef::GetElemObjId( int theVTKID )
 {
-        if (myLocalGrid)
-        {
-                TMapOfIds::const_iterator i = myVTK2SMDSElems.find(theVTKID);
-                return i == myVTK2SMDSElems.end() ? -1 : i->second;
-        }
+  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 )
 {
-        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);
+  if (myLocalGrid)
+  {
+    TMapOfIds::const_iterator i = mySMDS2VTKElems.find(theObjID);
+    return i == mySMDS2VTKElems.end() ? -1 : i->second;
+  }
+
+  const SMDS_MeshElement* e = 0;
+  if ( this->GetMesh() )
+    e = this->GetMesh()->FindElement(theObjID);
+
+  return e ? e->getVtkId() : -1;
 }
 
 //=================================================================================
@@ -430,23 +440,23 @@ void SMESH_VisualObjDef::buildElemPrs()
   for ( int i = 0; i < nbTypes; i++ ) // iterate through all types of elements
   {
     if ( nbEnts[ aTypes[ i ] ] > 0 ) {
-      
+
       const SMDSAbs_ElementType& aType = aTypes[ i ];
       const TEntityList& aList = anEnts[ aType ];
       TEntityList::const_iterator anIter;
       for ( anIter = aList.begin(); anIter != aList.end(); ++anIter )
       {
         const SMDS_MeshElement* anElem = *anIter;
-        
+
         vtkIdType aNbNodes = anElem->NbNodes();
         anIdList->SetNumberOfIds( aNbNodes );
-        const vtkIdType vtkElemType = getCellType( aType, anElem->IsPoly(), aNbNodes );
-        
+        const vtkIdType vtkElemType = SMDS_MeshCell::toVtkType( anElem->GetEntityType() );
+
         int anId = anElem->GetID();
-        
+
         mySMDS2VTKElems.insert( TMapOfIds::value_type( anId, iElem ) );
         myVTK2SMDSElems.insert( TMapOfIds::value_type( iElem, anId ) );
-        
+
         SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
         {
           // Convertions connectivities from SMDS to VTK
@@ -529,7 +539,7 @@ void SMESH_VisualObjDef::buildElemPrs()
 
 //=================================================================================
 // function : GetEdgeNodes
-// purpose  : Retrieve ids of nodes from edge of elements ( edge is numbered from 1 )
+// purpose  : Retrieve ids of nodes from edge of elements ( edge is numbered from 0 )
 //=================================================================================
 bool SMESH_VisualObjDef::GetEdgeNodes( const int theElemId,
                                        const int theEdgeNum,
@@ -546,25 +556,13 @@ bool SMESH_VisualObjDef::GetEdgeNodes( const int theElemId,
     
   int nbNodes = anElem->NbCornerNodes();
 
-  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 );
-  SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
-  int i = 0;
-  while( anIter->more() && i < nbNodes )
-    anIds[ i++ ] = anIter->next()->GetID();
-
-  if ( theEdgeNum < nbNodes - 1 )
-  {
-    theNodeId1 = anIds[ theEdgeNum ];
-    theNodeId2 = anIds[ theEdgeNum + 1 ];
-  }
-  else
-  {
-    theNodeId1 = anIds[ nbNodes - 1 ];
-    theNodeId2 = anIds[ 0 ];
-  }
+  theNodeId1 = anElem->GetNode(  theEdgeNum                 )->GetID();
+  theNodeId2 = anElem->GetNode(( theEdgeNum + 1 ) % nbNodes )->GetID();
 
   return true;
 }
@@ -574,7 +572,7 @@ vtkUnstructuredGrid* SMESH_VisualObjDef::GetUnstructuredGrid()
   if ( !myLocalGrid && !GetMesh()->isCompacted() )
   {
     GetMesh()->compactMesh();
-        updateEntitiesFlags();
+    updateEntitiesFlags();
     vtkUnstructuredGrid *theGrid = GetMesh()->getGrid();
     myGrid->ShallowCopy(theGrid);
   }
@@ -588,10 +586,9 @@ vtkUnstructuredGrid* SMESH_VisualObjDef::GetUnstructuredGrid()
 //=================================================================================
 bool SMESH_VisualObjDef::IsValid() const
 {
-        //MESSAGE("SMESH_VisualObjDef::IsValid");
-  return ( GetNbEntities(SMDSAbs_0DElement) > 0 || 
-           GetNbEntities(SMDSAbs_Ball     ) > 0 || 
-           GetNbEntities(SMDSAbs_Edge     ) > 0 || 
+  return ( GetNbEntities(SMDSAbs_0DElement) > 0 ||
+           GetNbEntities(SMDSAbs_Ball     ) > 0 ||
+           GetNbEntities(SMDSAbs_Edge     ) > 0 ||
            GetNbEntities(SMDSAbs_Face     ) > 0 ||
            GetNbEntities(SMDSAbs_Volume   ) > 0 ||
            GetNbEntities(SMDSAbs_Node     ) > 0 );
@@ -601,59 +598,67 @@ bool SMESH_VisualObjDef::IsValid() const
 // function : updateEntitiesFlags
 // purpose  : Update entities flags
 //=================================================================================
-void SMESH_VisualObjDef::updateEntitiesFlags() {
+void SMESH_VisualObjDef::updateEntitiesFlags()
+{
+  unsigned int tmp = myEntitiesState;
+  ClearEntitiesFlags();
 
-        unsigned int tmp = myEntitiesState;
-        ClearEntitiesFlags();
+  map<SMDSAbs_ElementType,int> entities = SMESH::GetEntitiesFromObject(this);
 
-        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_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_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_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_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( myEntitiesCache[SMDSAbs_Volume] != 0 ||
+      myEntitiesCache[SMDSAbs_Volume] >= entities[SMDSAbs_Volume] )
+    myEntitiesState &= ~SMESH_Actor::eVolumes;
 
-        if( tmp != myEntitiesState ) {
-                myEntitiesFlag = true;
-        }
-        
-        myEntitiesCache = entities;
+  if( tmp != myEntitiesState ) {
+    myEntitiesFlag = true;
+  }
+
+  myEntitiesCache = entities;
 }
 
 //=================================================================================
 // function : ClearEntitiesFlags
 // purpose  : Clear the entities flags
 //=================================================================================
-void SMESH_VisualObjDef::ClearEntitiesFlags() {
-        myEntitiesState = SMESH_Actor::eAllEntity;
-        myEntitiesFlag = false;
+void SMESH_VisualObjDef::ClearEntitiesFlags()
+{
+  myEntitiesState = SMESH_Actor::eAllEntity;
+  myEntitiesFlag = false;
 }
 
 //=================================================================================
 // function : GetEntitiesFlag
 // purpose  : Return the entities flag
 //=================================================================================
-bool SMESH_VisualObjDef::GetEntitiesFlag() {
-        return myEntitiesFlag;
+bool SMESH_VisualObjDef::GetEntitiesFlag()
+{
+  return myEntitiesFlag;
 }
 
 //=================================================================================
 // function : GetEntitiesState
 // purpose  : Return the entities state
 //=================================================================================
-unsigned int SMESH_VisualObjDef::GetEntitiesState() {
-        return myEntitiesState;
+unsigned int SMESH_VisualObjDef::GetEntitiesState()
+{
+  return myEntitiesState;
 }
 
 /*
@@ -703,20 +708,20 @@ bool SMESH_MeshObj::Update( int theIsClear )
 
 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;
+  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
index 9d4804d992c63438cc82f641a9110cfedc04f88a..a405ddce3c3229d1d84b636a91c16ff98f9d0aa0 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 5fe4212d7ced742edbd34c07c0a93b54dba474f5..916978abb90309f25517cee86fecfa336af260a5 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 397aeebb967a4c4a15619fdfd86f1d2cbbc1eb31..06c67439c32213fcd0f24ef3b5c4e75f93ab5d22 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
@@ -65,8 +65,9 @@ SMESH_PreviewActorsCollection::~SMESH_PreviewActorsCollection()
 }
 
 bool SMESH_PreviewActorsCollection::Init( const TopoDS_Shape& theShape,
-                                          TopAbs_ShapeEnum theType,
-                                          const QString& theEntry )
+                                          const TopoDS_Shape& theMainShape,
+                                          TopAbs_ShapeEnum    theType,
+                                          const QString&      theEntry )
 {
   SUIT_ResourceMgr* mgr = SUIT_Session::session()->resourceMgr();
 
@@ -82,17 +83,17 @@ bool SMESH_PreviewActorsCollection::Init( const TopoDS_Shape& theShape,
   if ( theShape.IsNull() )
     return false;
 
-  Handle( SALOME_InteractiveObject ) anIO = new SALOME_InteractiveObject();
-  anIO->setEntry( theEntry.toLatin1().constData() );
+  // Handle( SALOME_InteractiveObject ) anIO = new SALOME_InteractiveObject();
+  // anIO->setEntry( theEntry.toLatin1().constData() );
   
   // get indexes of seleted elements
-  TopExp::MapShapes( theShape, myMapOfShapes );
+  TopExp::MapShapes( theMainShape, myMapOfShapes );
   TopExp_Explorer exp( theShape, theType );
   QSet<int> indices;
   for ( ; exp.More(); exp.Next() )
     indices << myMapOfShapes.FindIndex( exp.Current() );
   myIndices = indices.toList();
-  qSort(myIndices);
+  //qSort(myIndices);
 
   // show current chunk
   showCurrentChunk();
@@ -112,11 +113,41 @@ GEOM_Actor* SMESH_PreviewActorsCollection::GetActorByIndex(int index)
   return myMapOfActors.value( index );
 }
 
+bool SMESH_PreviewActorsCollection::IsValidIndex( int index )
+{
+  return 0 < index && index <= myMapOfShapes.Extent();
+}
+
 int SMESH_PreviewActorsCollection::GetIndexByShape( const TopoDS_Shape& theShape )
 {
   return myMapOfShapes.FindIndex( theShape );
 }
 
+TopoDS_Shape SMESH_PreviewActorsCollection::GetShapeByIndex( int index )
+{
+  return IsValidIndex( index ) ? myMapOfShapes.FindKey( index ) : TopoDS_Shape();
+}
+
+int SMESH_PreviewActorsCollection::NbShapesOfType( TopAbs_ShapeEnum type )
+{
+  if ( type == TopAbs_SHAPE ) return myMapOfShapes.Extent();
+
+  int nb = 0;
+  for ( int i = 1; i <= myMapOfShapes.Extent(); ++i )
+    nb += ( myMapOfShapes(i).ShapeType() == type );
+
+  return nb;
+}
+
+void SMESH_PreviewActorsCollection::SetIndices( const QList<int>& indices)
+{
+  if ( myIndices != indices )
+  {
+    myIndices = indices;
+    showCurrentChunk();
+  }
+}
+
 void SMESH_PreviewActorsCollection::AddToRender(vtkRenderer* theRenderer)
 {
   myRenderer = theRenderer;
@@ -229,7 +260,8 @@ void SMESH_PreviewActorsCollection::showCurrentChunk()
       myMapOfActors.insert(index, anActor);
     }
   }
-  mySelector->ClearIObjects();
+  if ( mySelector )
+    mySelector->ClearIObjects();
   if ( myRenderer )
     AddToRender( myRenderer );
 }
index 8fcd55449d74531d897fd89e231581106908e8cf..afb0730c52277a8c02ce5c592395157acb5aed96 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
@@ -19,9 +19,7 @@
 
 //  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
@@ -45,10 +43,13 @@ public:
   SMESH_PreviewActorsCollection();
   ~SMESH_PreviewActorsCollection();
 
-  virtual void    AddToRender(vtkRenderer* theRenderer);
+  virtual void    AddToRender     (vtkRenderer* theRenderer);
   virtual void    RemoveFromRender(vtkRenderer* theRenderer);
 
-  bool            Init( const TopoDS_Shape& theShape, TopAbs_ShapeEnum subShapeType = TopAbs_EDGE, const QString& = QString("") );
+  bool            Init( const TopoDS_Shape& theShape,
+                        const TopoDS_Shape& theMainShape,
+                        TopAbs_ShapeEnum    subShapeType = TopAbs_EDGE,
+                        const QString& = QString("") );
 
   void            SetSelector( SVTK_Selector* );
 
@@ -56,8 +57,14 @@ public:
   void            HighlightID( int );
 
   GEOM_Actor*     GetActorByIndex( int );
+  bool            IsValidIndex( int );
 
   int             GetIndexByShape( const TopoDS_Shape& );
+  TopoDS_Shape    GetShapeByIndex( int i );
+  int             NbShapesOfType( TopAbs_ShapeEnum type );
+
+  void            SetIndices( const QList<int>& indices);
+  const QList<int>& GetIndices() const { return myIndices; }
 
   void            SetShown( bool );
 
index 073714d296a965f2d1ac9cdfe31d8501f28463dc..78ec260d66517867302678585c98df832596c352 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -123,7 +123,7 @@ SMESH_SVTKActor
   SVTK::CopyPoints( GetSource(), aSourceDataSet );
   SVTK::CopyPoints( myBallGrid, aSourceDataSet );
   SVTK::CopyPoints( my0DGrid,    aSourceDataSet );
-  
+
 
   int aNbOfParts = theMapIndex.Extent();
 
@@ -143,12 +143,14 @@ SMESH_SVTKActor
       {
         if(aCell->GetCellType() == VTK_VERTEX ) {
           my0DGrid->InsertNextCell(aCell->GetCellType(),aCell->GetPointIds());
-        } else if(aCell->GetCellType() == VTK_POLY_VERTEX ) {
+        }
+        else if(aCell->GetCellType() == VTK_POLY_VERTEX ) {
           vtkIdType newCellId = myBallGrid->InsertNextCell(aCell->GetCellType(),aCell->GetPointIds());
           if(myVisualObj) {
             outputCD->CopyData(cd, myVisualObj->GetElemVTKId(aPartId), newCellId);
           }
-        } else {
+        }
+        else {
           myUnstructuredGrid->InsertNextCell(aCell->GetCellType(),aCell->GetPointIds());
         }
       }
@@ -197,6 +199,10 @@ void SMESH_SVTKActor::SetBallSize(float theSize) {
   myBallActor->GetProperty()->SetPointSize(theSize);
 }
 
+void SMESH_SVTKActor::SetBallScale(double theScale) {
+  myBallActor->SetBallScale(theScale);
+}
+
 void SMESH_SVTKActor::SetVisualObject(TVisualObjPtr theVisualObj) {
   myVisualObj = theVisualObj;
 }
index 0a555a15a63a5c395359c7c0221f4b61cfcb9ea8..fa9b51245359eed1f04bd06c6747d6881ada098f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -43,6 +43,7 @@ public:
 
   vtkTypeMacro(SMESH_SVTKActor, SVTK_Actor);
 
+  void SetBallScale(double theSize);
   void SetBallSize(float theSize);
   void Set0DSize(float theSize);
 
index 6ece6aa5376fc0e8db67fad08599d804c1fd5593..d82962cb9553341b1df2cbaac31906bdb2306316 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 771b369c14e8b65b151e0e39f99a37270608198f..77546227f5b99dbca90cd7704d1657eaf1b420a7 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -122,7 +122,7 @@ class SMESHOBJECT_EXPORT SMESH_ScalarBarActor: public vtkActor2D {
   // 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);
+  vtkSetClampMacro(MaximumNumberOfColors, int, 2, VTK_INT_MAX);
   vtkGetMacro(MaximumNumberOfColors, int);
   
   // Description:
index 11550d46b4cc9a913c6cb52adfb4ebfb081c44fc..370f311831ec5005280d7639d61c9383877ec9a5 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2012-2015  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
index c248771a4e3f6441ae59625b706a2a16bb195277..03151a6405b4420d3df7b491b9ff234e8acb4b48 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index 31c34360660ffa0a1c2da9b50b0b861afea5fac9..218a3d3e73ef32c8f39dabe5a47cb56cbb914cde 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index 2187eeea9931bc858dd7febb6216d1b54dba4d01..644a7df74934d46c39110fc089e974a440c3c70b 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2012-2015  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
@@ -41,7 +41,6 @@ SET(_link_LIBRARIES
 
 # header files / no moc processing
 SET(SMDS_HEADERS
-  chrono.hxx
   ObjectPool.hxx
   SMDS_TypeOfPosition.hxx
   SMDSAbs_ElementType.hxx
index 7af2283c61a3e34f2132258905a46946e45c1316..f27161122c983743511211b7e7a6b744c7500d11 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2010-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2010-2015  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
index f80b41e9f54f7316213f70e227232bce43a718fb..6abda28391546c9ce2b5a925465f6ef5b1bb7070 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index e3b4c3a94f7b6964a1f6400ac8fc2f2d833b663b..299093c94f6e81a3a865f1f730ff3d6680737ccb 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2010-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2010-2015  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
index 400b9ceeab7ebcca9e9bad2cbda861aad33d1286..d54b207123f110dc4e3f0baa8d7389ecf9c29722 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index b36078f422e81430c47f14cc282de50b9446b7bb..d6049c0bd198a319d4a3b15bc20e35fb38d4570b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2010-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2010-2015  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
index 1d3b91a905c3c6a4780b4ae28646abf443140cdc..34cded571b2c67a24af71c8f79154840a0811509 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2010-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2010-2015  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
index d6bdb7abbcd8ff5459f0bd4d5b8ffc55c105af15..7c847044fb27b80addf3242e74bbb4d198ade714 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 59929c8cb9dcb233575e376a8752aec455a5afd0..1a38e20b8d1064a99f8c5f860e437ef7b0371b7d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index a28d44f61999e452cd8f25d6d30616aa34661019..6a38073e2b7587cfeaa127797e992605262aec84 100755 (executable)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index bf11dd6dad27e38929a21afb9ce733169d99b7b1..5f80713bf283ad52337542317929c53fe3c50478 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 16ce76acea9deb79be4575b4c8f68275dfef45c2..e8dfdc85ddc289274638308c643201bdf8786cc2 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 127fc04b4b7c5c19bc96dddd9e47a4d5598b7097..42859c88a233a1dcb2e0e8167883322e341b7b59 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -90,7 +90,7 @@ class SMDS_FaceOfNodes_MyIterator:public SMDS_NodeArrayElemIterator
 class _MyEdgeIterator : public SMDS_ElemIterator
 {
   vector< const SMDS_MeshElement* > myElems;
-  int myIndex;
+  size_t                            myIndex;
 public:
   _MyEdgeIterator(const SMDS_FaceOfNodes* face):myIndex(0) {
     myElems.reserve( face->NbNodes() );
@@ -108,8 +108,7 @@ public:
   virtual const SMDS_MeshElement* next() { return myElems[ myIndex++ ]; }
 };
 
-SMDS_ElemIteratorPtr SMDS_FaceOfNodes::elementsIterator
-                         (SMDSAbs_ElementType type) const
+SMDS_ElemIteratorPtr SMDS_FaceOfNodes::elementsIterator( SMDSAbs_ElementType type ) const
 {
   switch(type)
   {
index c43507506c78f8b9d73ac94b9ad4ddae1598f451..71471df368896f731e351b0ab2932c47e2fcb8cb 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 97374cf4265a3518209cc5e6d486c0f3d2753896..5097c6b57628043f2d167fcea7f4b7ed547eeb54 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 84cdd1033c190db883d7397c0c29c71678cea03e..3bbe79e566cc5bc1b0edae2ec1d7c467ecd17415 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 65182de41e3096ea8160583a01230c34bdcde8f4..6f8100c0ea65b2e3d6b8e6f35b4daff2f68027ce 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 166e5c36041bff6e1f8d31108817f6150a49b7d5..3719c6b56ee174d5c68f51807c15d602e4ff48fe 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index cd0f969ec3f12b7b102dbe477e67f9166d352252..e0756198c9d2512d6635a3d3d786246cf30bf2ca 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 4ffc644819634a836f947755c511be2a712ccaa4..4eace32e68ef4cf56a98dcb707d62c728a121f9f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 8c924b77e4bd84dc3df1f4381a1fc35f58e1c5c8..37a3cc3e709d01d595a78d6df9dd236d33815905 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 3c9b2f040ced5c299a999d3db45c6bab7c196677..38a29e7ddace0d0f3240eac8c9c3b53602928b52 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index f0e80af310389bb50902e85c594ce591d84fc8bb..f9fdbddcf9df655abe4f6b57ef54bc1281152736 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index 930b1b9b738ad56f74265ea1c9d2aff1d1b241a2..c4cadf10f7161484d7faab35556867fdd00f873d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -124,16 +124,16 @@ 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_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)
+SMDS_Mesh::SMDS_Mesh():
+  myNodePool(0), myVolumePool(0), myFacePool(0), myEdgePool(0), myBallPool(0),
+  myParent(NULL),
+  myNodeIDFactory(new SMDS_MeshNodeIDFactory()),
+  myElementIDFactory(new SMDS_MeshElementIDFactory()),
+  myModified(false), myModifTime(0), myCompactTime(0),
+  myNodeMin(0), myNodeMax(0),
+  myHasConstructionEdges(false), myHasConstructionFaces(false),
+  myHasInverseElements(true),
+  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
   myNodeIDFactory->SetMesh(this);
@@ -169,16 +169,16 @@ SMDS_Mesh::SMDS_Mesh()
 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
 /// (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),
-         myNodePool(parent->myNodePool),
-         myEdgePool(parent->myEdgePool),
-         myFacePool(parent->myFacePool),
-         myVolumePool(parent->myVolumePool),
-         myBallPool(parent->myBallPool)
+SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent):
+  myNodePool(parent->myNodePool),
+  myVolumePool(parent->myVolumePool),
+  myFacePool(parent->myFacePool),
+  myEdgePool(parent->myEdgePool),
+  myBallPool(parent->myBallPool),
+  myParent(parent), myNodeIDFactory(parent->myNodeIDFactory),
+  myElementIDFactory(parent->myElementIDFactory),
+  myHasConstructionEdges(false), myHasConstructionFaces(false),
+  myHasInverseElements(true)
 {
 }
 
@@ -188,9 +188,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;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -223,7 +223,7 @@ SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID)
     SMDS_MeshNode * node = myNodePool->getNew();
     node->init(ID, myMeshId, 0, x, y, z);
 
-    if (ID >= myNodes.size())
+    if (ID >= (int)myNodes.size())
     {
         myNodes.resize(ID+SMDS_Mesh::chunkSize, 0);
 //         MESSAGE(" ------------------ myNodes resize " << ID << " --> " << ID+SMDS_Mesh::chunkSize);
@@ -322,11 +322,11 @@ SMDS_BallElement* SMDS_Mesh::AddBallWithID(const SMDS_MeshNode * n, double diame
   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;
-    }
+  {
+    this->myGrid->GetCellTypesArray()->SetValue(ball->getVtkId(), VTK_EMPTY_CELL);
+    myBallPool->destroy(ball);
+    return 0;
+  }
   adjustmyCellsCapacity(ID);
   myCells[ID] = ball;
   myInfo.myNbBalls++;
@@ -1339,8 +1339,6 @@ SMDS_Mesh::AddPolygonalFaceWithID (const vector<const SMDS_MeshNode*> & nodes,
   }
   else
   {
-    //#ifdef VTK_HAVE_POLYHEDRON
-    //MESSAGE("AddPolygonalFaceWithID vtk " << ID);
     myNodeIds.resize( nodes.size() );
     for ( size_t i = 0; i < nodes.size(); ++i )
       myNodeIds[i] = nodes[i]->getVtkId();
@@ -1354,25 +1352,12 @@ SMDS_Mesh::AddPolygonalFaceWithID (const vector<const SMDS_MeshNode*> & nodes,
       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++;
   }
 
-  //#ifndef VTK_HAVE_POLYHEDRON
-  //  if (!registerElement(ID, face))
-  //    {
-  //      registerElement(myElementIDFactory->GetFreeID(), face);
-  //      //RemoveElement(face, false);
-  //      //face = NULL;
-  //    }
-  //#endif
   return face;
 }
 
@@ -1386,6 +1371,69 @@ SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (const vector<const SMDS_MeshNode*> &
   return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID());
 }
 
+///////////////////////////////////////////////////////////////////////////////
+/// Add a quadratic polygon defined by its nodes IDs
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshFace* SMDS_Mesh::AddQuadPolygonalFaceWithID (const vector<int> & nodes_ids,
+                                                      const int           ID)
+{
+  vector<const SMDS_MeshNode*> nodes( nodes_ids.size() );
+  for ( size_t i = 0; i < nodes.size(); i++) {
+    nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
+    if (!nodes[i]) return NULL;
+  }
+  return SMDS_Mesh::AddQuadPolygonalFaceWithID(nodes, ID);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Add a quadratic polygon defined by its nodes
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshFace*
+SMDS_Mesh::AddQuadPolygonalFaceWithID (const vector<const SMDS_MeshNode*> & nodes,
+                                       const int                            ID)
+{
+  SMDS_MeshFace * face;
+
+  if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+  if (hasConstructionEdges())
+  {
+    MESSAGE("Error : Not implemented");
+    return NULL;
+  }
+  else
+  {
+    myNodeIds.resize( nodes.size() );
+    for ( size_t i = 0; i < nodes.size(); ++i )
+      myNodeIds[i] = nodes[i]->getVtkId();
+
+    SMDS_VtkFace *facevtk = myFacePool->getNew();
+    facevtk->initQuadPoly(myNodeIds, 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.myNbQuadPolygons++;
+  }
+  return face;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Add a quadratic polygon defined by its nodes.
+/// An ID is automatically affected to the created face.
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshFace* SMDS_Mesh::AddQuadPolygonalFace (const vector<const SMDS_MeshNode*> & nodes)
+{
+  return SMDS_Mesh::AddQuadPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID());
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 /// Create a new polyhedral volume and add it to the mesh.
 /// @param ID The ID of the new volume
@@ -1601,7 +1649,7 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceFromVtkIdsWithID(const std::vector<vtkIdType>&
 bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement* element)
 {
   //MESSAGE("registerElement " << ID);
-  if ((ID >=0) && (ID < myCells.size()) && myCells[ID]) // --- already bound
+  if ((ID >=0) && (ID < (int)myCells.size()) && myCells[ID]) // --- already bound
   {
     MESSAGE(" ------------------ already bound "<< ID << " " << myCells[ID]->getVtkId());
     return false;
@@ -1616,7 +1664,7 @@ bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement* element)
   if (vtkId == -1)
     vtkId = myElementIDFactory->SetInVtkGrid(element);
 
-  if (vtkId >= myCellIdVtkToSmds.size()) // --- resize local vector
+  if (vtkId >= (int)myCellIdVtkToSmds.size()) // --- resize local vector
   {
 //     MESSAGE(" --------------------- resize myCellIdVtkToSmds " << vtkId << " --> " << vtkId + SMDS_Mesh::chunkSize);
     myCellIdVtkToSmds.resize(vtkId + SMDS_Mesh::chunkSize, -1);
@@ -1643,7 +1691,7 @@ void SMDS_Mesh::MoveNode(const SMDS_MeshNode *n, double x, double y, double z)
 ///////////////////////////////////////////////////////////////////////////////
 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
 {
-  if (ID < 1 || ID >= myNodes.size())
+  if (ID < 1 || ID >= (int)myNodes.size())
   {
 //     MESSAGE("------------------------------------------------------------------------- ");
 //     MESSAGE("----------------------------------- bad ID " << ID << " " << myNodes.size());
@@ -1659,7 +1707,7 @@ const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
 const SMDS_MeshNode * SMDS_Mesh::FindNodeVtk(int vtkId) const
 {
   // TODO if needed use mesh->nodeIdFromVtkToSmds
-  if (vtkId < 0 || vtkId >= (myNodes.size() -1))
+  if ( vtkId < 0 || vtkId+1 >= (int) myNodes.size() )
   {
     MESSAGE("------------------------------------------------------------------------- ");
     MESSAGE("---------------------------- bad VTK ID " << vtkId << " " << myNodes.size());
@@ -1779,8 +1827,8 @@ SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
 
 void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
 {
-    MESSAGE("RemoveNode");
-        RemoveElement(node, true);
+  MESSAGE("RemoveNode");
+  RemoveElement(node, true);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1789,7 +1837,7 @@ void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
 
 void SMDS_Mesh::Remove0DElement(const SMDS_Mesh0DElement * elem0d)
 {
-    MESSAGE("Remove0DElement");
+  MESSAGE("Remove0DElement");
   RemoveElement(elem0d,true);
 }
 
@@ -1799,8 +1847,8 @@ void SMDS_Mesh::Remove0DElement(const SMDS_Mesh0DElement * elem0d)
 
 void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
 {
-    MESSAGE("RemoveEdge");
-        RemoveElement(edge,true);
+  MESSAGE("RemoveEdge");
+  RemoveElement(edge,true);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1809,8 +1857,8 @@ void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
 
 void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
 {
-    MESSAGE("RemoveFace");
-        RemoveElement(face, true);
+  MESSAGE("RemoveFace");
+  RemoveElement(face, true);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1819,8 +1867,8 @@ void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
 
 void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
 {
-    MESSAGE("RemoveVolume");
-        RemoveElement(volume, true);
+  MESSAGE("RemoveVolume");
+  RemoveElement(volume, true);
 }
 
 //=======================================================================
@@ -1830,8 +1878,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));
 }
 
 //=======================================================================
@@ -1841,20 +1889,20 @@ 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;
 }
 
 //=======================================================================
@@ -1874,10 +1922,10 @@ bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
   bool Ok = false;
   SMDS_MeshCell* cell = dynamic_cast<SMDS_MeshCell*>((SMDS_MeshElement*) element);
   if (cell)
-    {
-      Ok = cell->vtkOrder(nodes, nbnodes);
-      Ok = cell->ChangeNodes(nodes, nbnodes);
-    }
+  {
+    Ok = cell->vtkOrder(nodes, nbnodes);
+    Ok = cell->ChangeNodes(nodes, nbnodes);
+  }
 
   if ( Ok ) { // update InverseElements
 
@@ -2378,7 +2426,7 @@ const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
 
 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
 {
-  if ((IDelem <= 0) || IDelem >= myCells.size())
+  if ( IDelem <= 0 || IDelem >= (int)myCells.size() )
   {
     MESSAGE("--------------------------------------------------------------------------------- ");
     MESSAGE("----------------------------------- bad IDelem " << IDelem << " " << myCells.size());
@@ -2434,9 +2482,9 @@ const SMDS_MeshElement* SMDS_Mesh::FindElement (const vector<const SMDS_MeshNode
     {
       const SMDS_MeshElement* e = itF->next();
       int nbNodesToCheck = noMedium ? e->NbCornerNodes() : e->NbNodes();
-      if ( nbNodesToCheck == nodes.size() )
+      if ( nbNodesToCheck == (int)nodes.size() )
       {
-        for ( int i = 1; e && i < nodes.size(); ++ i )
+        for ( size_t i = 1; e && i < nodes.size(); ++i )
         {
           int nodeIndex = e->GetNodeIndex( nodes[ i ]);
           if ( nodeIndex < 0 || nodeIndex >= nbNodesToCheck )
@@ -3062,28 +3110,27 @@ static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement *
 ///////////////////////////////////////////////////////////////////////////////
 /// Return the list of nodes used only by the given elements
 ///////////////////////////////////////////////////////////////////////////////
-static set<const SMDS_MeshElement*> * getExclusiveNodes(
-        set<const SMDS_MeshElement*>& 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();
+  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(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;
+    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;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -3097,62 +3144,63 @@ void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>& setOfChildren
                                      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())
     {
-    case SMDSAbs_Node:
-      MESSAGE("Internal Error: This should not happen");
-      break;
-    case SMDSAbs_0DElement:
+      const SMDS_MeshElement * e=itn->next();
+      if(nodes.find(e)!=nodes.end())
       {
+        setOfChildren.insert(element);
+        break;
       }
-      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())
-                        {
-                          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);
-                }
-        }
     }
+  } 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);
+    }
+  }
+  case SMDSAbs_All: break;
+  }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -3299,6 +3347,9 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *        elem,
           else
             delete (*it);
           break;
+
+        case SMDSAbs_All:
+        case SMDSAbs_NbElementTypes: break;
       }
       if (vtkid >= 0)
         {
@@ -4637,7 +4688,7 @@ void SMDS_Mesh::updateNodeMinMax()
     myNodeMax=0;
     return;
   }
-  while (!myNodes[myNodeMin] && (myNodeMin<myNodes.size()))
+  while ( !myNodes[myNodeMin] && myNodeMin < (int)myNodes.size() )
     myNodeMin++;
   myNodeMax=myNodes.size()-1;
   while (!myNodes[myNodeMax] && (myNodeMin>=0))
@@ -4727,7 +4778,7 @@ void SMDS_Mesh::compactMesh()
 
 int SMDS_Mesh::fromVtkToSmds(int vtkid)
 {
-  if (vtkid >= 0 && vtkid < myCellIdVtkToSmds.size())
+  if (vtkid >= 0 && vtkid < (int)myCellIdVtkToSmds.size())
     return myCellIdVtkToSmds[vtkid];
   throw SALOME_Exception(LOCALIZED ("vtk id out of bounds"));
 }
index 6b3402d0b3628bd0a43346c768133adfe9e9ed69..b561d7571cc9f809ee0ac7437d4942d22501ceff 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -58,7 +58,7 @@
 
 #define MYASSERT(val) if (!(val)) throw SALOME_Exception(LOCALIZED("assertion not verified"));
 
-class SMDS_EXPORT SMDS_Mesh:public SMDS_MeshObject
+class SMDS_EXPORT SMDS_Mesh : public SMDS_MeshObject
 {
 public:
   friend class SMDS_MeshIDFactory;
@@ -576,14 +576,22 @@ public:
 
   virtual SMDS_MeshFace* AddPolygonalFace (const std::vector<const SMDS_MeshNode*> & nodes);
 
+  virtual SMDS_MeshFace* AddQuadPolygonalFaceWithID(const std::vector<int> & nodes_ids,
+                                                    const int                ID);
+
+  virtual SMDS_MeshFace* AddQuadPolygonalFaceWithID(const std::vector<const SMDS_MeshNode*> & nodes,
+                                                    const int                                 ID);
+
+  virtual SMDS_MeshFace* AddQuadPolygonalFace(const std::vector<const SMDS_MeshNode*> & nodes);
+
   virtual SMDS_MeshVolume* AddPolyhedralVolumeWithID
-                           (const std::vector<int> & nodes_ids,
-                            const 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
-                           (const std::vector<const SMDS_MeshNode*> & nodes,
-                            const std::vector<int>                  & quantities,
+    (const std::vector<const SMDS_MeshNode*> & nodes,
+     const std::vector<int>                  & quantities,
                             const int                                 ID);
 
   virtual SMDS_MeshVolume* AddPolyhedralVolume
@@ -781,7 +789,7 @@ protected:
   {
     assert(ID >= 0);
     myElementIDFactory->adjustMaxId(ID);
-    if (ID >= myCells.size())
+    if (ID >= (int)myCells.size())
       myCells.resize(ID+SMDS_Mesh::chunkSize,0);
   }
 
@@ -830,6 +838,8 @@ protected:
   SMDS_MeshElementIDFactory *myElementIDFactory;
   SMDS_MeshInfo          myInfo;
 
+  //! any add, remove or change of node or cell
+  bool myModified;
   //! use a counter to keep track of modifications
   unsigned long myModifTime, myCompactTime;
 
@@ -840,9 +850,6 @@ protected:
   bool myHasConstructionFaces;
   bool myHasInverseElements;
 
-  //! any add, remove or change of node or cell
-  bool myModified;
-
   double xmin;
   double xmax;
   double ymin;
index 6f1c7f83f41e2cd9ec4f4fd16c3bd8bb2a41d924..95438eab06489782eb060766051d2ef23861e0d2 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
@@ -28,6 +28,8 @@
 #include "SMDS_Mesh0DElement.hxx"
 #include "SMDS_IteratorOfElements.hxx"
 #include "SMDS_MeshNode.hxx"
+#include "SMDS_Mesh.hxx"
+
 #include "utilities.h"
 
 using namespace std;
@@ -139,8 +141,24 @@ const SMDS_MeshNode* SMDS_Mesh0DElement::GetNode(const int ind) const
 //function : ChangeNode
 //purpose  :
 //=======================================================================
-bool SMDS_Mesh0DElement::ChangeNode (const SMDS_MeshNode * node)
+bool SMDS_Mesh0DElement::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes)
 {
-  myNode = node;
-  return true;
+  if ( nbNodes == 1 )
+  {
+    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;
+    }
+    myNode = nodes[0];
+    pts[0] = myNode->getVtkId();
+
+    SMDS_Mesh::_meshList[myMeshId]->setMyModified();
+    return true;
+  }
+  return false;
 }
index 58c26a7ed1ad708dde257a0c567afe349a6359ac..d0c07696067c9a5dd3237f0c34b90f2ddcc90e10 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
@@ -34,8 +34,7 @@ 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 bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes);
   virtual void Print (std::ostream & OS) const;
 
   virtual SMDSAbs_ElementType  GetType() const;
index fe15abccad5c57ecdb80f1833c8c6944274aad7a..e629a2f5b7a02a7e18fb5f5ba9c5889044ed34c0 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2010-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2010-2015  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
@@ -56,7 +56,7 @@ VTKCellType SMDS_MeshCell::toVtkType (SMDSAbs_EntityType smdsType)
     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_Quad_Polygon ]      = VTK_QUADRATIC_POLYGON;
     vtkTypes[ SMDSEntity_Tetra ]             = VTK_TETRA;
     vtkTypes[ SMDSEntity_Quad_Tetra ]        = VTK_QUADRATIC_TETRA;
     vtkTypes[ SMDSEntity_Pyramid ]           = VTK_PYRAMID;
@@ -166,12 +166,14 @@ const std::vector< int >& SMDS_MeshCell::toVtkOrder(SMDSAbs_EntityType smdsType)
 
 //================================================================================
 /*!
- * \brief Return indices to reverse an SMDS cell of given type
+ * \brief Return indices to reverse an SMDS cell of given type.
+ *        nbNodes is useful for polygons
  * Usage: reverseIDs[i] = forwardIDs[ indices[ i ]]
  */
 //================================================================================
 
-const std::vector<int>& SMDS_MeshCell::reverseSmdsOrder(SMDSAbs_EntityType smdsType)
+const std::vector<int>& SMDS_MeshCell::reverseSmdsOrder(SMDSAbs_EntityType smdsType,
+                                                        const size_t       nbNodes)
 {
   static std::vector< std::vector< int > > reverseInterlaces;
   if ( reverseInterlaces.empty() )
@@ -256,6 +258,31 @@ const std::vector<int>& SMDS_MeshCell::reverseSmdsOrder(SMDSAbs_EntityType smdsT
       reverseInterlaces[SMDSEntity_Hexagonal_Prism].assign( &ids[0], &ids[0]+12 );
     }
   }
+
+  if ( smdsType == SMDSEntity_Polygon )
+  {
+    if ( reverseInterlaces[ smdsType ].size() != nbNodes )
+    {
+      reverseInterlaces[ smdsType ].resize( nbNodes );
+      for ( size_t i = 0; i < nbNodes; ++i )
+        reverseInterlaces[ smdsType ][i] = nbNodes - i - 1;
+    }
+  }
+  else if ( smdsType == SMDSEntity_Quad_Polygon )
+  {
+    if ( reverseInterlaces[ smdsType ].size() != nbNodes )
+    {
+      // e.g. for 8 nodes: [ 0, 3,2,1, 7,6,5,4 ]
+      reverseInterlaces[ smdsType ].resize( nbNodes );
+      size_t pos = 0;
+      reverseInterlaces[ smdsType ][pos++] = 0;
+      for ( int i = nbNodes / 2 - 1; i > 0 ; --i ) // 3,2,1
+        reverseInterlaces[ smdsType ][pos++] = i;
+      for ( int i = nbNodes - 1; i >= nbNodes / 2; --i ) // 7,6,5,4
+        reverseInterlaces[ smdsType ][pos++] = i;
+    }
+  }
+  
   return reverseInterlaces[smdsType];
 }
 
@@ -266,7 +293,8 @@ const std::vector<int>& SMDS_MeshCell::reverseSmdsOrder(SMDSAbs_EntityType smdsT
  */
 //================================================================================
 
-const std::vector<int>& SMDS_MeshCell::interlacedSmdsOrder(SMDSAbs_EntityType smdsType)
+const std::vector<int>& SMDS_MeshCell::interlacedSmdsOrder(SMDSAbs_EntityType smdsType,
+                                                           const size_t       nbNodes)
 {
   static std::vector< std::vector< int > > interlace;
   if ( interlace.empty() )
@@ -278,15 +306,28 @@ const std::vector<int>& SMDS_MeshCell::interlacedSmdsOrder(SMDSAbs_EntityType sm
     }
     {
       const int ids[] = {0,3,1,4,2,5,6};
-      interlace[SMDSEntity_Quad_Triangle].assign( &ids[0], &ids[0]+6 );
+      interlace[SMDSEntity_Quad_Triangle  ].assign( &ids[0], &ids[0]+6 );
       interlace[SMDSEntity_BiQuad_Triangle].assign( &ids[0], &ids[0]+7 );
     }
     {
       const int ids[] = {0,4,1,5,2,6,3,7,8};
-      interlace[SMDSEntity_Quad_Quadrangle].assign( &ids[0], &ids[0]+8 );
+      interlace[SMDSEntity_Quad_Quadrangle  ].assign( &ids[0], &ids[0]+8 );
       interlace[SMDSEntity_BiQuad_Quadrangle].assign( &ids[0], &ids[0]+9 );
     }
   }
+
+  if ( smdsType == SMDSEntity_Quad_Polygon )
+  {
+    if ( interlace[smdsType].size() != nbNodes )
+    {
+      interlace[smdsType].resize( nbNodes );
+      for ( size_t i = 0; i < nbNodes / 2; ++i )
+      {
+        interlace[smdsType][i*2+0] = i;
+        interlace[smdsType][i*2+1] = i + nbNodes / 2;
+      }
+    }
+  }
   return interlace[smdsType];
 }
 
index aeae71851cfcb374036884723534c88a994dbcdb..d56f7b5dea636bbb2a22330c23522f399f37d3c8 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2010-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2010-2015  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
@@ -45,10 +45,12 @@ public:
   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);
+  static const std::vector<int>& reverseSmdsOrder(SMDSAbs_EntityType smdsType,
+                                                  const size_t       nbNodes=0);
+  static const std::vector<int>& interlacedSmdsOrder(SMDSAbs_EntityType smdsType,
+                                                     const size_t       nbNodes=0);
 
-  template< class VECT >
+  template< class VECT > // interlacedIDs[i] = smdsIDs[ indices[ i ]]
     static void applyInterlace( const std::vector<int>& interlace, VECT & data)
   {
     if ( interlace.empty() ) return;
@@ -57,6 +59,15 @@ public:
       tmpData[i] = data[ interlace[i] ];
     data.swap( tmpData );
   }
+  template< class VECT > // interlacedIDs[ indices[ i ]] = smdsIDs[i]
+    static void applyInterlaceRev( 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[ interlace[i] ] = data[i];
+    data.swap( tmpData );
+  }
 
   static int nbCells;
 
index c1fa7dacce76044c78755d27ad3268f768781c8c..d381349414e581a4f9fa3cbec62509994b3a566a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2010-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2010-2015  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
index 2f742a729a938f8c30cb5d87e031b1b57731b6d9..782bb67da71e41dcc5b0f16d1a906479edc1221b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2010-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2010-2015  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
index c78c3bbf591a8f6386fd3d0690b8854cbf78306c..13ee2d9b3ebc47af37e6e8332e0cb4eb071af7f5 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index f28ff597a8b6146066504b47f3f04f3c64b5c37f..8d0d674e09166beed2108b114a915e6260369296 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -79,7 +79,7 @@ public:
   virtual int NbNodes() const;
   virtual int NbEdges() const;
   virtual int NbFaces() const;
-  inline int GetID() const { return myID; };
+  inline int GetID() const { return myID; }
 
   ///Return the type of the current element
   virtual SMDSAbs_ElementType GetType() const = 0;
index 602fc4620dd300ee557e6a049ef56402f691e3d7..5bf7398cac956df65479e8ccf8044d814cefb66c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -95,7 +95,7 @@ bool SMDS_MeshElementIDFactory::BindID(int ID, SMDS_MeshElement * elem)
 //=======================================================================
 SMDS_MeshElement* SMDS_MeshElementIDFactory::MeshElement(int ID)
 {
-  if ((ID<1) || (ID>=myMesh->myCells.size()))
+  if ( ID<1 || ID >= (int) myMesh->myCells.size() )
     return NULL;
   const SMDS_MeshElement* elem = GetMesh()->FindElement(ID);
   return (SMDS_MeshElement*)(elem);
@@ -129,7 +129,7 @@ void SMDS_MeshElementIDFactory::ReleaseID(int ID, int vtkId)
   //MESSAGE("~~~~~~~~~~~~~~ SMDS_MeshElementIDFactory::ReleaseID smdsId vtkId " << ID << " " << vtkId);
   if (vtkId >= 0)
     {
-      assert(vtkId < myMesh->myCellIdVtkToSmds.size());
+      assert(vtkId < (int)myMesh->myCellIdVtkToSmds.size());
       myMesh->myCellIdVtkToSmds[vtkId] = -1;
       myMesh->setMyModified();
     }
@@ -149,7 +149,7 @@ void SMDS_MeshElementIDFactory::updateMinMax() const
 {
   myMin = INT_MAX;
   myMax = 0;
-  for (int i = 0; i < myMesh->myCells.size(); i++)
+  for (size_t i = 0; i < myMesh->myCells.size(); i++)
     {
       if (myMesh->myCells[i])
         {
index 723f1fd010c07ac9c6fc99bda85562721aa5944c..9b8ee15b7a063f347420257eb863b0b0b72e45c7 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 50513ee368a00e2204c76cda7a388fe183fde7e6..53ce3166109b0fd793f0477d333e824eea676746 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index e276f6cae9aeaa3b42c82966eef6b7e89a720081..76a32c867fb22a700fa664eb98a77819bc0a6628 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index ecbf4bed561f5a0357a7d98bed39d2b1c3388898..14b71412da646301cb751175cfda69c5cb634816 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 010a6373e2eb3a841a4137d5a8baa3cb16878caa..dc630439492f4709319c4513c7e576ae941e0923 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index a32602602eeb37b35cdaee53055f9e70356b206b..1cd2a7b69aaf1b7372320ef4be4e47d9edf93474 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 34cef85352103a93f31d1c61b3329ce4cd84e94b..587a72746262b706435a712577e1906580c124c0 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 94a27f7a823ad639a7fe8d69fc3a3375e85f7aee..4c6dba726a1cc72f9c8911231a6c23d2d170ee8b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
@@ -56,7 +56,7 @@ public:
   inline int NbQuadrangles(SMDSAbs_ElementOrder order = ORDER_ANY) const;
   int NbBiQuadTriangles() const { return myNbBiQuadTriangles; }
   int NbBiQuadQuadrangles() const { return myNbBiQuadQuadrangles; }
-  int NbPolygons() const { return myNbPolygons; }
+  inline int NbPolygons(SMDSAbs_ElementOrder order = ORDER_ANY) const;
 
   inline int NbVolumes (SMDSAbs_ElementOrder order = ORDER_ANY) const;
   inline int NbTetras  (SMDSAbs_ElementOrder order = ORDER_ANY) const;
@@ -90,7 +90,7 @@ private:
   int myNbEdges      , myNbQuadEdges      ;
   int myNbTriangles  , myNbQuadTriangles,   myNbBiQuadTriangles  ;
   int myNbQuadrangles, myNbQuadQuadrangles, myNbBiQuadQuadrangles;
-  int myNbPolygons;
+  int myNbPolygons   , myNbQuadPolygons;
 
   int myNbTetras  , myNbQuadTetras  ;
   int myNbHexas   , myNbQuadHexas,    myNbTriQuadHexas;
@@ -110,7 +110,7 @@ inline SMDS_MeshInfo::SMDS_MeshInfo():
   myNbEdges      (0), myNbQuadEdges      (0),
   myNbTriangles  (0), myNbQuadTriangles  (0), myNbBiQuadTriangles(0),
   myNbQuadrangles(0), myNbQuadQuadrangles(0), myNbBiQuadQuadrangles(0),
-  myNbPolygons   (0),
+  myNbPolygons   (0), myNbQuadPolygons   (0),
   myNbTetras     (0), myNbQuadTetras  (0),
   myNbHexas      (0), myNbQuadHexas   (0), myNbTriQuadHexas(0),
   myNbPyramids   (0), myNbQuadPyramids(0),
@@ -128,21 +128,21 @@ inline SMDS_MeshInfo::SMDS_MeshInfo():
   // 0 ------------------  - DON't USE 0!!!
   // 1            .  * .
   // 2         .       *
-  // 3      .     *
-  // 4   *  .  .
+  // 3      .  .  *
+  // 4   *  .
   // 5   *
   // 6   *  .
-  // 7      .  *
+  // 7      .
   // 8   *  .
-  // 9      .  *
+  // 9      .
   // 10  *
   // 11
   // 12  *
   // 13  *
   // 14
   // 15  *
-  // 16     
-  // 17     
+  // 16        *
+  // 17        *
   // 18     *
   // 19     *
   // 20  *   
@@ -158,7 +158,7 @@ inline SMDS_MeshInfo::SMDS_MeshInfo():
   myShift.resize(SMDSAbs_NbElementTypes, 0);
 
   myShift[ SMDSAbs_Face      ] = +15;// 3->18, 4->19, etc.
-  myShift[ SMDSAbs_Edge      ] = +5; // 2->7, 4->9
+  myShift[ SMDSAbs_Edge      ] = +14;// 2->16, 3->17
   myShift[ SMDSAbs_0DElement ] = +2; // 1->3
   myShift[ SMDSAbs_Ball      ] = +1; // 1->2
 
@@ -169,7 +169,7 @@ inline SMDS_MeshInfo::SMDS_MeshInfo():
   myNb[ index( SMDSAbs_Ball,1 )] = & myNbBalls;
 
   myNb[ index( SMDSAbs_Edge,2 )] = & myNbEdges;
-  myNb[ index( SMDSAbs_Edge,4 )] = & myNbQuadEdges;
+  myNb[ index( SMDSAbs_Edge,3 )] = & myNbQuadEdges;
 
   myNb[ index( SMDSAbs_Face,3 )] = & myNbTriangles;
   myNb[ index( SMDSAbs_Face,4 )] = & myNbQuadrangles;
@@ -192,16 +192,17 @@ inline SMDS_MeshInfo::SMDS_MeshInfo():
 
 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;
+{ for ( size_t i=0; i<myNb.size(); ++i ) if ( myNb[i] ) (*myNb[i])=(*other.myNb[i]);
+  myNbPolygons     = other.myNbPolygons;
+  myNbQuadPolygons = other.myNbQuadPolygons;
+  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;
-  myNbPolygons=myNbPolyhedrons=0;
+{ for ( size_t i=0; i<myNb.size(); ++i ) if ( myNb[i] ) (*myNb[i])=0;
+  myNbPolygons=myNbQuadPolygons=myNbPolyhedrons=0;
 }
 
 inline int // index
@@ -217,20 +218,26 @@ 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);
+SMDS_MeshInfo::addWithPoly(const SMDS_MeshElement* el) {
+  switch ( el->GetEntityType() ) {
+  case SMDSEntity_Polygon:      ++myNbPolygons; break;
+  case SMDSEntity_Quad_Polygon: ++myNbQuadPolygons; break;
+  case SMDSEntity_Polyhedra:    ++myNbPolyhedrons; break;
+  default:                      add(el);
+  }
 }
 inline void // RemoveEdge
 SMDS_MeshInfo::RemoveEdge(const SMDS_MeshElement* el)
 { if ( el->IsQuadratic() ) --myNbQuadEdges; else --myNbEdges; }
 
 inline void // RemoveFace
-SMDS_MeshInfo::RemoveFace(const SMDS_MeshElement* el)
-{ if ( el->IsPoly() ) --myNbPolygons; else remove( el ); }
+SMDS_MeshInfo::RemoveFace(const SMDS_MeshElement* el) {
+  switch ( el->GetEntityType() ) {
+  case SMDSEntity_Polygon:      --myNbPolygons; break;
+  case SMDSEntity_Quad_Polygon: --myNbQuadPolygons; break;
+  default:                      remove(el);
+  }
+}
 
 inline void // RemoveVolume
 SMDS_MeshInfo::RemoveVolume(const SMDS_MeshElement* el)
@@ -242,7 +249,7 @@ SMDS_MeshInfo::NbEdges      (SMDSAbs_ElementOrder order) const
 
 inline int  // NbFaces
 SMDS_MeshInfo::NbFaces      (SMDSAbs_ElementOrder order) const
-{ return NbTriangles(order)+NbQuadrangles(order)+(order == ORDER_QUADRATIC ? 0 : myNbPolygons); }
+{ return NbTriangles(order)+NbQuadrangles(order)+(order == ORDER_ANY ? myNbPolygons+myNbQuadPolygons : order == ORDER_LINEAR ? myNbPolygons : myNbQuadPolygons ); }
 
 inline int  // NbTriangles
 SMDS_MeshInfo::NbTriangles  (SMDSAbs_ElementOrder order) const
@@ -252,6 +259,10 @@ inline int  // NbQuadrangles
 SMDS_MeshInfo::NbQuadrangles(SMDSAbs_ElementOrder order) const
 { return order == ORDER_ANY ? myNbQuadrangles+myNbQuadQuadrangles+myNbBiQuadQuadrangles : order == ORDER_LINEAR ? myNbQuadrangles : myNbQuadQuadrangles+myNbBiQuadQuadrangles; }
 
+inline int  // NbPolygons
+SMDS_MeshInfo::NbPolygons(SMDSAbs_ElementOrder order) const
+{ return order == ORDER_ANY ? myNbPolygons+myNbQuadPolygons : order == ORDER_LINEAR ? myNbPolygons : myNbQuadPolygons; }
+
 inline int  // NbVolumes
 SMDS_MeshInfo::NbVolumes (SMDSAbs_ElementOrder order) const
 { return NbTetras(order) + NbHexas(order) + NbPyramids(order) + NbPrisms(order) + NbHexPrisms(order) + (order == ORDER_QUADRATIC ? 0 : myNbPolyhedrons); }
@@ -282,8 +293,8 @@ 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;
+    for ( size_t i=1+index( SMDSAbs_Node,1 ); i<myNb.size(); ++i ) if ( myNb[i] ) nb += *myNb[i];
+    nb += myNbPolygons + myNbQuadPolygons + myNbPolyhedrons;
     break;
   case SMDSAbs_Volume:
     nb = ( myNbTetras+     myNbPyramids+     myNbPrisms+     myNbHexas+     myNbHexPrism+
@@ -293,7 +304,7 @@ SMDS_MeshInfo::NbElements(SMDSAbs_ElementType type) const
   case SMDSAbs_Face:
     nb = ( myNbTriangles+       myNbQuadrangles+
            myNbQuadTriangles+   myNbBiQuadTriangles+
-           myNbQuadQuadrangles+ myNbBiQuadQuadrangles+ myNbPolygons );
+           myNbQuadQuadrangles+ myNbBiQuadQuadrangles+ myNbPolygons+ myNbQuadPolygons );
     break;
   case SMDSAbs_Edge:
     nb = myNbEdges + myNbQuadEdges;
@@ -339,8 +350,9 @@ SMDS_MeshInfo::NbEntities(SMDSAbs_EntityType type) const
   case SMDSEntity_Polyhedra:        return myNbPolyhedrons;
   case SMDSEntity_0D:               return myNb0DElements;
   case SMDSEntity_Ball:             return myNbBalls;
-  case SMDSEntity_Quad_Polygon:
+  case SMDSEntity_Quad_Polygon:     return myNbQuadPolygons;
   case SMDSEntity_Quad_Polyhedra:
+  case SMDSEntity_Last:
     break;
   }
   return 0;
@@ -362,7 +374,7 @@ SMDS_MeshInfo::NbElementsOfGeom(SMDSAbs_GeometryType geom) const
   case SMDSGeom_QUADRANGLE:      return (myNbQuadrangles +
                                          myNbQuadQuadrangles +
                                          myNbBiQuadQuadrangles );
-  case SMDSGeom_POLYGON:         return myNbPolygons;
+  case SMDSGeom_POLYGON:         return (myNbPolygons + myNbQuadPolygons );
     // 3D:
   case SMDSGeom_TETRA:           return (myNbTetras +
                                          myNbQuadTetras);
@@ -411,8 +423,9 @@ SMDS_MeshInfo::setNb(const SMDSAbs_EntityType geomType, const int nb)
   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_Polygon:     myNbQuadPolygons      = nb; break;
   case SMDSEntity_Quad_Polyhedra:
+  case SMDSEntity_Last:
     break;
   }
 }
index 00d663b1a3a72fd2390192badf634a899bb1c3e6..3524480cca6644fcc349cd9888dbc19cfa1eea96 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -42,7 +42,7 @@ int SMDS_MeshNode::nbNodes =0;
 
 //=======================================================================
 //function : SMDS_MeshNode
-//purpose  : 
+//purpose  :
 //=======================================================================
 SMDS_MeshNode::SMDS_MeshNode() :
   SMDS_MeshElement(-1, -1, 0),
@@ -83,31 +83,31 @@ SMDS_MeshNode::~SMDS_MeshNode()
 
 //=======================================================================
 //function : RemoveInverseElement
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 void SMDS_MeshNode::RemoveInverseElement(const SMDS_MeshElement * parent)
 {
-    //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());
+  //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());
 }
 
 //=======================================================================
 //function : Print
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 void SMDS_MeshNode::Print(ostream & OS) const
 {
-        OS << "Node <" << myID << "> : X = " << X() << " Y = "
-                << Y() << " Z = " << Z() << endl;
+  OS << "Node <" << myID << "> : X = " << X() << " Y = "
+     << Y() << " Z = " << Z() << endl;
 }
 
 //=======================================================================
 //function : SetPosition
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 void SMDS_MeshNode::SetPosition(const SMDS_PositionPtr& aPos)
@@ -121,12 +121,12 @@ void SMDS_MeshNode::SetPosition(const SMDS_PositionPtr& aPos)
 
 //=======================================================================
 //function : GetPosition
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 const SMDS_PositionPtr& SMDS_MeshNode::GetPosition() const
 {
-        return myPosition;
+  return myPosition;
 }
 
 //=======================================================================
@@ -149,30 +149,26 @@ 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();
+    cellList.reserve( ncells );
     if (type == SMDSAbs_All)
+      cellList.assign( cells, cells + ncells );
+    else
       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);
-          }
+        {
+          cellList.push_back(vtkId);
+        }
       }
     myCells = cellList.empty() ? 0 : &cellList[0];
     myNcells = cellList.size();
-    //MESSAGE("myNcells="<<myNcells);
   }
 
   bool more()
   {
-    //MESSAGE("iter " << iter << " ncells " << myNcells);
     return (iter < myNcells);
   }
 
@@ -182,10 +178,10 @@ public:
     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("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;
@@ -193,11 +189,11 @@ public:
 };
 
 SMDS_ElemIteratorPtr SMDS_MeshNode::
-        GetInverseElementIterator(SMDSAbs_ElementType type) const
+GetInverseElementIterator(SMDSAbs_ElementType type) const
 {
-    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));
+  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
@@ -212,47 +208,47 @@ private:
   int  iter;
   vector<SMDS_MeshElement*> myFiltCells;
 
- public:
+public:
   SMDS_MeshNode_MyIterator(SMDS_Mesh *mesh,
                            vtkIdType* cells,
                            int ncells,
                            SMDSAbs_ElementType type):
     myMesh(mesh), myCells(cells), myNcells(ncells), myType(type), iter(0)
   {
-        //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);
+    //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 (iter< myNcells);
+    return (iter< myNcells);
   }
 
   const SMDS_MeshElement* next()
   {
-      const SMDS_MeshElement* elem = myFiltCells[iter];
-      iter++;
-      return elem;
+    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); 
+    return SMDS_MeshElement::elementsIterator(SMDSAbs_Node);
   else
   {
     vtkCellLinks::Link l = SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetCellLinks()->GetLink(myVtkID);
@@ -262,7 +258,7 @@ SMDS_ElemIteratorPtr SMDS_MeshNode::
 
 int SMDS_MeshNode::NbNodes() const
 {
-        return 1;
+  return 1;
 }
 
 double* SMDS_MeshNode::getCoord() const
@@ -309,7 +305,7 @@ void SMDS_MeshNode::setXYZ(double x, double y, double z)
 
 SMDSAbs_ElementType SMDS_MeshNode::GetType() const
 {
-        return SMDSAbs_Node;
+  return SMDSAbs_Node;
 }
 
 vtkIdType SMDS_MeshNode::GetVtkType() const
@@ -362,11 +358,11 @@ int SMDS_MeshNode::NbInverseElements(SMDSAbs_ElementType type) const
   int nb = 0;
   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++;
-        }
+  {
+    const SMDS_MeshElement* elem = mesh->FindElement(mesh->fromVtkToSmds(l.cells[i]));
+    if (elem->GetType() == type)
+      nb++;
+  }
   return nb;
 }
 
@@ -375,14 +371,14 @@ int SMDS_MeshNode::NbInverseElements(SMDSAbs_ElementType type) const
 ///////////////////////////////////////////////////////////////////////////////
 bool operator<(const SMDS_MeshNode& e1, const SMDS_MeshNode& e2)
 {
-        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;*/
+  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 d3bf53264c15889bf720ef16b5411b3174824463..dde85682e6dcb1532807fd929f10094d4fdd8103 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 7de1ea56ee1fe71fedc10302947c8de6824934f8..f50cdca04df0281ad00909fb60bdc771c203bcd9 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 5d9693301d0105c62274969d32cc02cfa3f55e2d..eb786c3e210ffecdc892ad683222af085aadbf18 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index de3388a03c1ca538cb0ca726b6a368ac707e0703..50adf413fabcfbb85b12fa43acc1ec663d304842 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index f9fbaa6f7b241f2d87e6803bba07044157663486..1a30daff3a562ba255ff4ed757ed99859efdc7f5 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index c20bd9b914d29fc0f8799b4f2d5cbd1ce611e811..1f7a6a001c9c01cd7ec76c5e13d2ec72d095154f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 28628079fac61700cad9c587b1ba908cabf8ca5d..f91b03ac23fe91dafd2e2f2ad15e4845a06021a6 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 396b709a306623445eca39c0627708a85dab262f..d636b1d18ee8f8ff8c6b64d81786e9a97b7588a1 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -41,7 +41,7 @@ using namespace std;
 //purpose  : 
 //=======================================================================
 SMDS_PolygonalFaceOfNodes::SMDS_PolygonalFaceOfNodes
-                          (std::vector<const SMDS_MeshNode *> nodes)
+                          (const std::vector<const SMDS_MeshNode *>& nodes)
 {
   //MESSAGE("******************************************** SMDS_PolygonalFaceOfNodes");
   myNodes = nodes;
@@ -150,7 +150,7 @@ class SMDS_PolygonalFaceOfNodes_MyIterator:public SMDS_NodeVectorElemIterator
 class _MyEdgeIterator : public SMDS_ElemIterator
 {
   vector< const SMDS_MeshElement* > myElems;
-  int myIndex;
+  size_t                            myIndex;
 public:
   _MyEdgeIterator(const SMDS_MeshFace* face):myIndex(0) {
     myElems.reserve( face->NbNodes() );
index 0bfbaa965a198b6621dc9d95b53a78bf4efc7d0f..bf6a1a5ff21abb092ae1bef5af94e88ee217731b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -38,7 +38,7 @@
 class SMDS_EXPORT SMDS_PolygonalFaceOfNodes:public SMDS_MeshFace
 {
  public:
-  SMDS_PolygonalFaceOfNodes (std::vector<const SMDS_MeshNode *> nodes);
+  SMDS_PolygonalFaceOfNodes (const std::vector<const SMDS_MeshNode *>& nodes);
 
   virtual SMDSAbs_ElementType GetType() const;
   virtual SMDSAbs_EntityType  GetEntityType() const { return SMDSEntity_Polygon; }
index 2c497944abe64d26a2231b2c55ee470e4f41e90e..2dfa337db3a4b16ee7359143bf73f5bc64f5768b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 76482e8e605d3f4a744af1b0ee625c9088d0f94d..ef8addebdebb69a1f6a4144ea0254da145d1e6a9 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 3457fd4a9904e94a3dbec5fdc241958fd10243d7..2e3b6488d488769979e230b77d8f3b92436b3763 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 59adccb4546decf30f586cad3b553fe26394a33f..d3265cd0088083c602d8de5e313ac27473830841 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 1d30931e5d5df080b40d326493997983fc5420ef..8475c62cd8663a4981266799c7ed8cf9d3a4acad 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index e55bce6a594aba5e59deb5c33f633a05e55714b0..c9bb8a04cc6b267b02a63afd5ddd2fcb1ead9aac 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 01c73f57f53032720f8f3f1b178e8971c8e08d37..a308239eb21d5f72037c57bb5588147e4e179a5c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -168,14 +168,14 @@ namespace {
 
   //=======================================================================
   //class : _MyInterlacedNodeIterator
-  //purpose  : 
+  //purpose  :
   //=======================================================================
 
   class _MyInterlacedNodeIterator:public SMDS_NodeIterator
   {
     const vector<const SMDS_MeshNode *>& mySet;
-    int myIndex;
-    const int * myInterlace;
+    size_t                               myIndex;
+    const int *                          myInterlace;
   public:
     _MyInterlacedNodeIterator(const vector<const SMDS_MeshNode *>& s,
                               const int * interlace):
@@ -228,7 +228,7 @@ SMDS_NodeIteratorPtr SMDS_QuadraticFaceOfNodes::interlacedNodesIterator() const
 class _MyEdgeIterator : public SMDS_ElemIterator
 {
   vector< const SMDS_MeshElement* > myElems;
-  int myIndex;
+  size_t                            myIndex;
 public:
   _MyEdgeIterator(const SMDS_QuadraticFaceOfNodes* face):myIndex(0) {
     myElems.reserve( face->NbNodes() );
index 2e9f43c3b0e1445bdd5325a0c8ca625624f42579..0a82c7f361662681adec2e69e25343f77c785e5f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index af4389af100b18a8c5732134e4a0c0503b81fb15..2a356d5810647bb4e02d3b03695d1af6b85bfac7 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 9b39579ff79448462373cb2c78e906310e1adc75..ae7b9aa0918597c48191931ff68ae04895e30c7f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 70a8a15ff934dd036e8c3cda4fccc5a6092f3840..b604abc776e2c851a7de9730ee32383dc387a935 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index f627b14e04c92f42e47135248b478ddffe2ed585..413dacd8e8b718a97268b548717e1efe9abf1c74 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index d04a469872476d6bc57db823274fc405f03bd4f8..31f64234429bbeeeeb570a7634ddb907ccd3fadf 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 2eedb2e7b9df0d996543c5b71b7832c2193de008..034b61983113ad914d62aa48cd69e26bb64a4da8 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index f500276d36c92529a4234b0405b2ae6618b15354..49807b3a9f5af9aef0f0c58fc498569fb729bb1d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 6012a4f38595e5d3befeb7539b86b784a7796395..52916ec724c12d491ed92982b26e50e30fae467b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2010-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2010-2015  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
@@ -24,6 +24,7 @@
 #include "SMDS_MeshVolume.hxx"
 
 #include "utilities.h"
+#include "chrono.hxx"
 
 #include <vtkCellArray.h>
 #include <vtkCellData.h>
@@ -353,12 +354,12 @@ void SMDS_UnstructuredGrid::copyBloc(vtkUnsignedCharArray *newTypes,
 
 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;
-    }
+  if ((vtkCellId < 0) || (vtkCellId >= (int)_cellIdToDownId.size()))
+  {
+    //MESSAGE("SMDS_UnstructuredGrid::CellIdToDownId structure not up to date: vtkCellId="
+    //    << vtkCellId << " max="<< _cellIdToDownId.size());
+    return -1;
+  }
   return _cellIdToDownId[vtkCellId];
 }
 
@@ -370,12 +371,12 @@ void SMDS_UnstructuredGrid::setCellIdToDownId(int vtkCellId, int downId)
 
 void SMDS_UnstructuredGrid::CleanDownwardConnectivity()
 {
-  for (int i = 0; i < _downArray.size(); i++)
-    {
-      if (_downArray[i])
-        delete _downArray[i];
-      _downArray[i] = 0;
-    }
+  for (size_t i = 0; i < _downArray.size(); i++)
+  {
+    if (_downArray[i])
+      delete _downArray[i];
+    _downArray[i] = 0;
+  }
   _cellIdToDownId.clear();
 }
 
index 5063adc21762b29c35f778e92a2fbfe6b3351880..e5ce97512a007a6604f5ac0422760a606eda6f99 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2010-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2010-2015  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
@@ -28,7 +28,6 @@
 
 #include <vtkUnstructuredGrid.h>
 #include <vtkCellLinks.h>
-#include "chrono.hxx"
 
 #include <vector>
 #include <set>
index a68f90ea66754ef0b45d440ebc2c6dcc5ee71936..6f05329daefd0f5a327037e2caf47341d38232dd 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index ef9c51e0418c53f2beaa4022b97f8b4ea5c42b00..a42dee62bb6b0c10d3e74cca4dbe517ac79c2299 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 83d6f022a64709d6540b64c23b41c0ecadffc825..09a16f785b573aa1137efa6211bf229af33f3e52 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 7b4047180f35f494451291c7d12ed9e4ad4adeff..58d56168cf940e8a9f5b45e732d4dd867b16a194 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 5aa40e5b0738488eaf47b3949498aa466fa38c79..612e6e7f44ea6bb80c671c1f15302514eeb3a43f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -191,7 +191,7 @@ class SMDS_VolumeOfNodes_MyIterator:public SMDS_NodeArrayElemIterator
 class _MySubIterator : public SMDS_ElemIterator
 {
   vector< const SMDS_MeshElement* > myElems;
-  int myIndex;
+  size_t myIndex;
 public:
   _MySubIterator(const SMDS_VolumeOfNodes* vol, SMDSAbs_ElementType type):myIndex(0) {
     SMDS_VolumeTool vTool(vol);
index 80ece59324d9809a1e31a5c22094c63c186752a0..af79410fca5ef23a1dcdc9ecb2c57f59d8391647 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 0162914e7647d763de5b6bf64ba0e0517f1e6cdc..c0c506d9cc13ba79e607cbf392d6f612bd1cd4e2 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 #include <map>
 #include <limits>
 #include <cmath>
+#include <numeric>
+#include <algorithm>
 
 using namespace std;
 
+namespace
+{
 // ======================================================
 // Node indices in faces depending on volume orientation
 // making most faces normals external
@@ -349,8 +353,6 @@ 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;
@@ -396,7 +398,7 @@ inline double XYZ::SquareMagnitude() {
   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 );
+    const int           nbCornersByQuad = SMDS_VolumeTool::NbCornerNodes( quadType );
     if ( SMDS_VolumeTool::NbCornerNodes( linType ) == nbCornersByQuad )
       return linType;
 
@@ -410,14 +412,33 @@ inline double XYZ::SquareMagnitude() {
 
 } // namespace
 
+//================================================================================
+/*!
+ * \brief Saver/restorer of a SMDS_VolumeTool::myCurFace
+ */
+//================================================================================
+
+struct SMDS_VolumeTool::SaveFacet
+{
+  SMDS_VolumeTool::Facet  mySaved;
+  SMDS_VolumeTool::Facet& myToRestore;
+  SaveFacet( SMDS_VolumeTool::Facet& facet ): myToRestore( facet )
+  {
+    mySaved = facet;
+  }
+  ~SaveFacet()
+  {
+    if ( myToRestore.myIndex != mySaved.myIndex )
+      myToRestore = mySaved;
+  }
+};
+
 //=======================================================================
 //function : SMDS_VolumeTool
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 SMDS_VolumeTool::SMDS_VolumeTool ()
-  : myVolumeNodes( NULL ),
-    myFaceNodes( NULL )
 {
   Set( 0 );
 }
@@ -429,8 +450,6 @@ SMDS_VolumeTool::SMDS_VolumeTool ()
 
 SMDS_VolumeTool::SMDS_VolumeTool (const SMDS_MeshElement* theVolume,
                                   const bool              ignoreCentralNodes)
-  : myVolumeNodes( NULL ),
-    myFaceNodes( NULL )
 {
   Set( theVolume, ignoreCentralNodes );
 }
@@ -442,11 +461,7 @@ SMDS_VolumeTool::SMDS_VolumeTool (const SMDS_MeshElement* theVolume,
 
 SMDS_VolumeTool::~SMDS_VolumeTool()
 {
-  if ( myVolumeNodes != NULL ) delete [] myVolumeNodes;
-  if ( myFaceNodes != NULL   ) delete [] myFaceNodes;
-
-  myFaceNodeIndices = NULL;
-  myVolumeNodes = myFaceNodes = NULL;
+  myCurFace.myNodeIndices = NULL;
 }
 
 //=======================================================================
@@ -464,42 +479,37 @@ bool SMDS_VolumeTool::Set (const SMDS_MeshElement* theVolume,
 
   myVolForward = true;
   myNbFaces = 0;
-  myVolumeNbNodes = 0;
-  if (myVolumeNodes != NULL) {
-    delete [] myVolumeNodes;
-    myVolumeNodes = NULL;
-  }
+  myVolumeNodes.clear();
   myPolyIndices.clear();
+  myPolyQuantities.clear();
+  myPolyFacetOri.clear();
+  myFwdLinks.clear();
 
   myExternalFaces = false;
 
   myAllFacesNodeIndices_F  = 0;
-  //myAllFacesNodeIndices_FE = 0;
   myAllFacesNodeIndices_RE = 0;
   myAllFacesNbNodes        = 0;
 
-  myCurFace = -1;
-  myFaceNbNodes = 0;
-  myFaceNodeIndices = NULL;
-  if (myFaceNodes != NULL) {
-    delete [] myFaceNodes;
-    myFaceNodes = NULL;
-  }
+  myCurFace.myIndex = -1;
+  myCurFace.myNodeIndices = NULL;
+  myCurFace.myNodes.clear();
 
   // set volume data
   if ( !theVolume || theVolume->GetType() != SMDSAbs_Volume )
     return false;
 
   myVolume = theVolume;
-  if (myVolume->IsPoly())
-    myPolyedre = dynamic_cast<const SMDS_VtkVolume*>( myVolume );
-
   myNbFaces = theVolume->NbFaces();
-  myVolumeNbNodes = theVolume->NbNodes();
+  if ( myVolume->IsPoly() )
+  {
+    myPolyedre = dynamic_cast<const SMDS_VtkVolume*>( myVolume );
+    myPolyFacetOri.resize( myNbFaces, 0 );
+  }
 
   // set nodes
   int iNode = 0;
-  myVolumeNodes = new const SMDS_MeshNode* [myVolumeNbNodes];
+  myVolumeNodes.resize( myVolume->NbNodes() );
   SMDS_ElemIteratorPtr nodeIt = myVolume->nodesIterator();
   while ( nodeIt->more() )
     myVolumeNodes[ iNode++ ] = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
@@ -512,18 +522,19 @@ bool SMDS_VolumeTool::Set (const SMDS_MeshElement* theVolume,
   {
     // 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 ( 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
+      myCurFace.myIndex = -1; // previous setFace(0) didn't take myVolForward into account
   }
   return true;
 }
@@ -549,10 +560,10 @@ void SMDS_VolumeTool::Inverse ()
   }
 
   myVolForward = !myVolForward;
-  myCurFace = -1;
+  myCurFace.myIndex = -1;
 
   // inverse top and bottom faces
-  switch ( myVolumeNbNodes ) {
+  switch ( myVolumeNodes.size() ) {
   case 4:
     SWAP_NODES( myVolumeNodes, 1, 2 );
     break;
@@ -626,7 +637,7 @@ SMDS_VolumeTool::VolumeType SMDS_VolumeTool::GetVolumeType() const
   if ( myPolyedre )
     return POLYHEDA;
 
-  switch( myVolumeNbNodes ) {
+  switch( myVolumeNodes.size() ) {
   case 4: return TETRA;
   case 5: return PYRAM;
   case 6: return PENTA;
@@ -653,28 +664,18 @@ static double getTetraVolume(const SMDS_MeshNode* n1,
                              const SMDS_MeshNode* n3,
                              const SMDS_MeshNode* n4)
 {
-  double X1 = n1->X();
-  double Y1 = n1->Y();
-  double Z1 = n1->Z();
-
-  double X2 = n2->X();
-  double Y2 = n2->Y();
-  double Z2 = n2->Z();
-
-  double X3 = n3->X();
-  double Y3 = n3->Y();
-  double Z3 = n3->Z();
-
-  double X4 = n4->X();
-  double Y4 = n4->Y();
-  double Z4 = n4->Z();
-
-  double Q1 = -(X1-X2)*(Y3*Z4-Y4*Z3);
-  double Q2 =  (X1-X3)*(Y2*Z4-Y4*Z2);
-  double R1 = -(X1-X4)*(Y2*Z3-Y3*Z2);
-  double R2 = -(X2-X3)*(Y1*Z4-Y4*Z1);
-  double S1 =  (X2-X4)*(Y1*Z3-Y3*Z1);
-  double S2 = -(X3-X4)*(Y1*Z2-Y2*Z1);
+  double p1[3], p2[3], p3[3], p4[3];
+  n1->GetXYZ( p1 );
+  n2->GetXYZ( p2 );
+  n3->GetXYZ( p3 );
+  n4->GetXYZ( p4 );
+
+  double Q1 = -(p1[ 0 ]-p2[ 0 ])*(p3[ 1 ]*p4[ 2 ]-p4[ 1 ]*p3[ 2 ]);
+  double Q2 =  (p1[ 0 ]-p3[ 0 ])*(p2[ 1 ]*p4[ 2 ]-p4[ 1 ]*p2[ 2 ]);
+  double R1 = -(p1[ 0 ]-p4[ 0 ])*(p2[ 1 ]*p3[ 2 ]-p3[ 1 ]*p2[ 2 ]);
+  double R2 = -(p2[ 0 ]-p3[ 0 ])*(p1[ 1 ]*p4[ 2 ]-p4[ 1 ]*p1[ 2 ]);
+  double S1 =  (p2[ 0 ]-p4[ 0 ])*(p1[ 1 ]*p3[ 2 ]-p3[ 1 ]*p1[ 2 ]);
+  double S2 = -(p3[ 0 ]-p4[ 0 ])*(p1[ 1 ]*p2[ 2 ]-p2[ 1 ]*p1[ 2 ]);
 
   return (Q1+Q2+R1+R2+S1+S2)/6.0;
 }
@@ -697,23 +698,21 @@ double SMDS_VolumeTool::GetSize() const
 
     // split a polyhedron into tetrahedrons
 
-    int saveCurFace = myCurFace;
+    SaveFacet savedFacet( myCurFace );
     SMDS_VolumeTool* me = const_cast< SMDS_VolumeTool* > ( this );
     for ( int f = 0; f < NbFaces(); ++f )
     {
       me->setFace( f );
-      XYZ area (0,0,0), p1( myFaceNodes[0] );
-      for ( int n = 0; n < myFaceNbNodes; ++n )
+      XYZ area (0,0,0), p1( myCurFace.myNodes[0] );
+      for ( int n = 0; n < myCurFace.myNbNodes; ++n )
       {
-        XYZ p2( myFaceNodes[ n+1 ]);
+        XYZ p2( myCurFace.myNodes[ n+1 ]);
         area = area + p1.Crossed( p2 );
         p1 = p2;
       }
       V += p1.Dot( area );
     }
     V /= 6;
-    if ( saveCurFace > -1 && saveCurFace != myCurFace )
-      me->setFace( myCurFace );
   }
   else 
   {
@@ -844,14 +843,14 @@ bool SMDS_VolumeTool::GetBaryCenter(double & X, double & Y, double & Z) const
   if ( !myVolume )
     return false;
 
-  for ( int i = 0; i < myVolumeNbNodes; i++ ) {
+  for ( int i = 0; i < myVolumeNodes.size(); i++ ) {
     X += myVolumeNodes[ i ]->X();
     Y += myVolumeNodes[ i ]->Y();
     Z += myVolumeNodes[ i ]->Z();
   }
-  X /= myVolumeNbNodes;
-  Y /= myVolumeNbNodes;
-  Z /= myVolumeNbNodes;
+  X /= myVolumeNodes.size();
+  Y /= myVolumeNodes.size();
+  Z /= myVolumeNodes.size();
 
   return true;
 }
@@ -875,7 +874,7 @@ bool SMDS_VolumeTool::IsOut(double X, double Y, double Z, double tol) const
     if ( !IsFaceExternal( iF ))
       faceNormal = XYZ() - faceNormal; // reverse
 
-    XYZ face2p( p - XYZ( myFaceNodes[0] ));
+    XYZ face2p( p - XYZ( myCurFace.myNodes[0] ));
     if ( face2p.Dot( faceNormal ) > tol )
       return true;
   }
@@ -890,7 +889,7 @@ bool SMDS_VolumeTool::IsOut(double X, double Y, double Z, double tol) const
 void SMDS_VolumeTool::SetExternalNormal ()
 {
   myExternalFaces = true;
-  myCurFace = -1;
+  myCurFace.myIndex = -1;
 }
 
 //=======================================================================
@@ -900,9 +899,9 @@ void SMDS_VolumeTool::SetExternalNormal ()
 
 int SMDS_VolumeTool::NbFaceNodes( int faceIndex ) const
 {
-    if ( !setFace( faceIndex ))
-      return 0;
-    return myFaceNbNodes;
+  if ( !setFace( faceIndex ))
+    return 0;
+  return myCurFace.myNbNodes;
 }
 
 //=======================================================================
@@ -917,7 +916,7 @@ const SMDS_MeshNode** SMDS_VolumeTool::GetFaceNodes( int faceIndex ) const
 {
   if ( !setFace( faceIndex ))
     return 0;
-  return myFaceNodes;
+  return &myCurFace.myNodes[0];
 }
 
 //=======================================================================
@@ -933,15 +932,7 @@ const int* SMDS_VolumeTool::GetFaceNodesIndices( int faceIndex ) const
   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;
+  return myCurFace.myNodeIndices;
 }
 
 //=======================================================================
@@ -956,11 +947,44 @@ bool SMDS_VolumeTool::GetFaceNodes (int                        faceIndex,
     return false;
 
   theFaceNodes.clear();
-  theFaceNodes.insert( myFaceNodes, myFaceNodes + myFaceNbNodes );
+  theFaceNodes.insert( myCurFace.myNodes.begin(), myCurFace.myNodes.end() );
 
   return true;
 }
 
+namespace
+{
+  struct NLink : public std::pair<int,int>
+  {
+    int myOri;
+    NLink(const SMDS_MeshNode* n1=0, const SMDS_MeshNode* n2=0, int ori=1 )
+    {
+      if ( n1 )
+      {
+        if (( myOri = ( n1->GetID() < n2->GetID() )))
+        {
+          first  = n1->GetID();
+          second = n2->GetID();
+        }
+        else
+        {
+          myOri  = -1;
+          first  = n2->GetID();
+          second = n1->GetID();
+        }
+        myOri *= ori;
+      }
+      else
+      {
+        myOri = first = second = 0;
+      }
+    }
+    //int Node1() const { return myOri == -1 ? second : first; }
+
+    //bool IsSameOri( const std::pair<int,int>& link ) const { return link.first == Node1(); }
+  };
+}
+
 //=======================================================================
 //function : IsFaceExternal
 //purpose  : Check normal orientation of a given face
@@ -971,39 +995,179 @@ bool SMDS_VolumeTool::IsFaceExternal( int faceIndex ) const
   if ( myExternalFaces || !myVolume )
     return true;
 
-  if (myVolume->IsPoly()) {
-    XYZ aNormal, baryCenter, p0 (myPolyedre->GetFaceNode(faceIndex + 1, 1));
-    GetFaceNormal(faceIndex, aNormal.x, aNormal.y, aNormal.z);
-    GetBaryCenter(baryCenter.x, baryCenter.y, baryCenter.z);
-    XYZ insideVec (baryCenter - p0);
-    if (insideVec.Dot(aNormal) > 0)
-      return false;
+  if ( !myPolyedre ) // all classical volumes have external facet normals
     return true;
+
+  SMDS_VolumeTool* me = const_cast< SMDS_VolumeTool* >( this );
+
+  if ( myPolyFacetOri[ faceIndex ])
+    return myPolyFacetOri[ faceIndex ] > 0;
+
+  int ori = 0; // -1-in, +1-out, 0-undef
+  double minProj, maxProj;
+  if ( projectNodesToNormal( faceIndex, minProj, maxProj ))
+  {
+    // all nodes are on the same side of the facet
+    ori = ( minProj < 0 ? +1 : -1 );
+    me->myPolyFacetOri[ faceIndex ] = ori;
+
+    if ( !myFwdLinks.empty() ) // concave polyhedron; collect oriented links
+      for ( int i = 0; i < myCurFace.myNbNodes; ++i )
+      {
+        NLink link( myCurFace.myNodes[i], myCurFace.myNodes[i+1], ori );
+        me->myFwdLinks.insert( make_pair( link, link.myOri ));
+      }
+    return ori > 0;
   }
 
-  // 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 );
+  SaveFacet savedFacet( myCurFace );
+
+  // concave polyhedron
+
+  if ( myFwdLinks.empty() ) // get links of the least ambiguously oriented facet
+  {
+    for ( size_t i = 0; i < myPolyFacetOri.size() && !ori; ++i )
+      ori = myPolyFacetOri[ i ];
+
+    if ( !ori ) // none facet is oriented yet
+    {
+      // find the least ambiguously oriented facet
+      int faceMostConvex = -1;
+      std::map< double, int > convexity2face;
+      for ( size_t iF = 0; iF < myPolyFacetOri.size() && faceMostConvex < 0; ++iF )
+      {
+        if ( projectNodesToNormal( iF, minProj, maxProj ))
+        {
+          // all nodes are on the same side of the facet
+          me->myPolyFacetOri[ iF ] = ( minProj < 0 ? +1 : -1 );
+          faceMostConvex = iF;
+        }
+        else
+        {
+          ori = ( -minProj < maxProj ? -1 : +1 );
+          double convexity = std::min( -minProj, maxProj ) / std::max( -minProj, maxProj );
+          convexity2face.insert( make_pair( convexity, iF * ori ));
+        }
+      }
+      if ( faceMostConvex < 0 ) // none facet has nodes on the same side
+      {
+        // use the least ambiguous facet
+        faceMostConvex = convexity2face.begin()->second;
+        ori = ( faceMostConvex < 0 ? -1 : +1 );
+        faceMostConvex = std::abs( faceMostConvex );
+        me->myPolyFacetOri[ faceMostConvex ] = ori;
+      }
+    }
+    // collect links of the oriented facets in myFwdLinks
+    for ( size_t iF = 0; iF < myPolyFacetOri.size(); ++iF )
+    {
+      ori = myPolyFacetOri[ iF ];
+      if ( !ori ) continue;
+      setFace( iF );
+      for ( int i = 0; i < myCurFace.myNbNodes; ++i )
+      {
+        NLink link( myCurFace.myNodes[i], myCurFace.myNodes[i+1], ori );
+        me->myFwdLinks.insert( make_pair( link, link.myOri ));
+      }
+    }
+  }
+
+  // compare orientation of links of the facet with myFwdLinks
+  ori = 0;
+  setFace( faceIndex );
+  vector< NLink > links( myCurFace.myNbNodes ), links2;
+  for ( int i = 0; i < myCurFace.myNbNodes && !ori; ++i )
+  {
+    NLink link( myCurFace.myNodes[i], myCurFace.myNodes[i+1] );
+    std::map<Link, int>::const_iterator l2o = myFwdLinks.find( link );
+    if ( l2o != myFwdLinks.end() )
+      ori = link.myOri * l2o->second * -1;
+    links[ i ] = link;
+  }
+  while ( !ori ) // the facet has no common links with already oriented facets
+  {
+    // orient and collect links of other non-oriented facets
+    for ( size_t iF = 0; iF < myPolyFacetOri.size(); ++iF )
+    {
+      if ( myPolyFacetOri[ iF ] ) continue; // already oriented
+      setFace( iF );
+      links2.clear();
+      ori = 0;
+      for ( int i = 0; i < myCurFace.myNbNodes && !ori; ++i )
+      {
+        NLink link( myCurFace.myNodes[i], myCurFace.myNodes[i+1] );
+        std::map<Link, int>::const_iterator l2o = myFwdLinks.find( link );
+        if ( l2o != myFwdLinks.end() )
+          ori = link.myOri * l2o->second * -1;
+        links2.push_back( link );
+      }
+      if ( ori ) // one more facet oriented
+      {
+        me->myPolyFacetOri[ iF ] = ori;
+        for ( size_t i = 0; i < links2.size(); ++i )
+          me->myFwdLinks.insert( make_pair( links2[i], links2[i].myOri * ori ));
+        break;
+      }
+    }
+    if ( !ori )
+      return false; // error in algorithm: infinite loop
+
+    // try to orient the facet again
+    ori = 0;
+    for ( size_t i = 0; i < links.size() && !ori; ++i )
+    {
+      std::map<Link, int>::const_iterator l2o = myFwdLinks.find( links[i] );
+      if ( l2o != myFwdLinks.end() )
+        ori = links[i].myOri * l2o->second * -1;
+    }
+    me->myPolyFacetOri[ faceIndex ] = ori;
+  }
+
+  return ori > 0;
+}
+
+//=======================================================================
+//function : projectNodesToNormal
+//purpose  : compute min and max projections of all nodes to normal of a facet.
+//=======================================================================
+
+bool SMDS_VolumeTool::projectNodesToNormal( int     faceIndex,
+                                            double& minProj,
+                                            double& maxProj ) const
+{
+  minProj = std::numeric_limits<double>::max();
+  maxProj = std::numeric_limits<double>::min();
+
+  XYZ normal;
+  if ( !GetFaceNormal( faceIndex, normal.x, normal.y, normal.z ))
+    return false;
+  XYZ p0 ( myCurFace.myNodes[0] );
+  for ( size_t i = 0; i < myVolumeNodes.size(); ++i )
+  {
+    if ( std::find( myCurFace.myNodes.begin() + 1,
+                    myCurFace.myNodes.end(),
+                    myVolumeNodes[ i ] ) != myCurFace.myNodes.end() )
+      continue; // node of the faceIndex-th facet
+
+    double proj = normal.Dot( XYZ( myVolumeNodes[ i ]) - p0 );
+    if ( proj < minProj ) minProj = proj;
+    if ( proj > maxProj ) maxProj = proj;
+  }
+  const double tol = 1e-7;
+  minProj += tol;
+  maxProj -= tol;
+  bool diffSize = ( minProj * maxProj < 0 );
+  // if ( diffSize )
+  // {
+  //   minProj = -minProj;
   // }
-  // default:;
+  // else if ( minProj < 0 )
+  // {
+  //   minProj = -minProj;
+  //   maxProj = -maxProj;
   // }
-  // return false;
-  return true;
+
+  return !diffSize; // ? 0 : (minProj >= 0);
 }
 
 //=======================================================================
@@ -1016,16 +1180,16 @@ bool SMDS_VolumeTool::GetFaceNormal (int faceIndex, double & X, double & Y, doub
   if ( !setFace( faceIndex ))
     return false;
 
-  const int iQuad = ( myFaceNbNodes > 6 && !myPolyedre ) ? 2 : 1;
-  XYZ p1 ( myFaceNodes[0*iQuad] );
-  XYZ p2 ( myFaceNodes[1*iQuad] );
-  XYZ p3 ( myFaceNodes[2*iQuad] );
+  const int iQuad = ( !myPolyedre && myCurFace.myNbNodes > 6 ) ? 2 : 1;
+  XYZ p1 ( myCurFace.myNodes[0*iQuad] );
+  XYZ p2 ( myCurFace.myNodes[1*iQuad] );
+  XYZ p3 ( myCurFace.myNodes[2*iQuad] );
   XYZ aVec12( p2 - p1 );
   XYZ aVec13( p3 - p1 );
   XYZ cross = aVec12.Crossed( aVec13 );
 
-  if ( myFaceNbNodes >3*iQuad ) {
-    XYZ p4 ( myFaceNodes[3*iQuad] );
+  if ( myCurFace.myNbNodes >3*iQuad ) {
+    XYZ p4 ( myCurFace.myNodes[3*iQuad] );
     XYZ aVec14( p4 - p1 );
     XYZ cross2 = aVec13.Crossed( aVec14 );
     cross = cross + cross2;
@@ -1054,11 +1218,11 @@ bool SMDS_VolumeTool::GetFaceBaryCenter (int faceIndex, double & X, double & Y,
     return false;
 
   X = Y = Z = 0.0;
-  for ( int i = 0; i < myFaceNbNodes; ++i )
+  for ( int i = 0; i < myCurFace.myNbNodes; ++i )
   {
-    X += myFaceNodes[i]->X() / myFaceNbNodes;
-    Y += myFaceNodes[i]->Y() / myFaceNbNodes;
-    Z += myFaceNodes[i]->Z() / myFaceNbNodes;
+    X += myCurFace.myNodes[i]->X() / myCurFace.myNbNodes;
+    Y += myCurFace.myNodes[i]->Y() / myCurFace.myNbNodes;
+    Z += myCurFace.myNodes[i]->Z() / myCurFace.myNbNodes;
   }
   return true;
 }
@@ -1070,27 +1234,36 @@ bool SMDS_VolumeTool::GetFaceBaryCenter (int faceIndex, double & X, double & Y,
 
 double SMDS_VolumeTool::GetFaceArea( int faceIndex ) const
 {
-  if (myVolume->IsPoly()) {
-    MESSAGE("Warning: attempt to obtain area of a face of polyhedral volume");
-    return 0;
-  }
-
+  double area = 0;
   if ( !setFace( faceIndex ))
-    return 0;
+    return area;
 
-  XYZ p1 ( myFaceNodes[0] );
-  XYZ p2 ( myFaceNodes[1] );
-  XYZ p3 ( myFaceNodes[2] );
+  XYZ p1 ( myCurFace.myNodes[0] );
+  XYZ p2 ( myCurFace.myNodes[1] );
+  XYZ p3 ( myCurFace.myNodes[2] );
   XYZ aVec12( p2 - p1 );
   XYZ aVec13( p3 - p1 );
-  double area = aVec12.Crossed( aVec13 ).Magnitude() * 0.5;
+  area += aVec12.Crossed( aVec13 ).Magnitude();
 
-  if ( myFaceNbNodes == 4 ) {
-    XYZ p4 ( myFaceNodes[3] );
-    XYZ aVec14( p4 - p1 );
-    area += aVec14.Crossed( aVec13 ).Magnitude() * 0.5;
+  if (myVolume->IsPoly())
+  {
+    for ( int i = 3; i < myCurFace.myNbNodes; ++i )
+    {
+      XYZ pI ( myCurFace.myNodes[i] );
+      XYZ aVecI( pI - p1 );
+      area += aVec13.Crossed( aVecI ).Magnitude();
+      aVec13 = aVecI;
+    }
+  }
+  else
+  {
+    if ( myCurFace.myNbNodes == 4 ) {
+      XYZ p4 ( myCurFace.myNodes[3] );
+      XYZ aVec14( p4 - p1 );
+      area += aVec14.Crossed( aVec13 ).Magnitude();
+    }
   }
-  return area;
+  return area / 2;
 }
 
 //================================================================================
@@ -1101,7 +1274,7 @@ double SMDS_VolumeTool::GetFaceArea( int faceIndex ) const
 
 int SMDS_VolumeTool::GetCenterNodeIndex( int faceIndex ) const
 {
-  if ( myAllFacesNbNodes && myVolumeNbNodes == 27 ) // classic element with 27 nodes
+  if ( myAllFacesNbNodes && myVolumeNodes.size() == 27 ) // classic element with 27 nodes
   {
     switch ( faceIndex ) {
     case 0: return 20;
@@ -1129,7 +1302,7 @@ int SMDS_VolumeTool::GetOppFaceIndex( int faceIndex ) const
   const int nbHoriFaces = 2;
 
   if ( faceIndex >= 0 && faceIndex < NbFaces() ) {
-    switch ( myVolumeNbNodes ) {
+    switch ( myVolumeNodes.size() ) {
     case 6:
     case 15:
       if ( faceIndex == 0 || faceIndex == 1 )
@@ -1182,31 +1355,42 @@ bool SMDS_VolumeTool::IsLinked (const SMDS_MeshNode* theNode1,
       MESSAGE("Warning: bad volumic element");
       return false;
     }
-    bool isLinked = false;
-    int iface;
-    for (iface = 1; iface <= myNbFaces && !isLinked; iface++) {
-      int inode, nbFaceNodes = myPolyedre->NbFaceNodes(iface);
-
-      for (inode = 1; inode <= nbFaceNodes && !isLinked; inode++) {
-        const SMDS_MeshNode* curNode = myPolyedre->GetFaceNode(iface, inode);
-
-        if (curNode == theNode1 || curNode == theNode2) {
-          int inextnode = (inode == nbFaceNodes) ? 1 : inode + 1;
-          const SMDS_MeshNode* nextNode = myPolyedre->GetFaceNode(iface, inextnode);
-
-          if ((curNode == theNode1 && nextNode == theNode2) ||
-              (curNode == theNode2 && nextNode == theNode1)) {
-            isLinked = true;
-          }
-        }
+    if ( !myAllFacesNbNodes ) {
+      SMDS_VolumeTool*  me = const_cast< SMDS_VolumeTool* >( this );
+      me->myPolyQuantities = myPolyedre->GetQuantities();
+      myAllFacesNbNodes    = &myPolyQuantities[0];
+    }
+    int from, to = 0, d1 = 1, d2 = 2;
+    if ( myPolyedre->IsQuadratic() ) {
+      if ( theIgnoreMediumNodes ) {
+        d1 = 2; d2 = 0;
+      }
+    } else {
+      d2 = 0;
+    }
+    vector<const SMDS_MeshNode*>::const_iterator i;
+    for (int iface = 0; iface < myNbFaces; iface++)
+    {
+      from = to;
+      to  += myPolyQuantities[iface];
+      i    = std::find( myVolumeNodes.begin() + from, myVolumeNodes.begin() + to, theNode1 );
+      if ( i != myVolumeNodes.end() )
+      {
+        if ((  theNode2 == *( i-d1 ) ||
+               theNode2 == *( i+d1 )))
+          return true;
+        if (( d2 ) &&
+            (( theNode2 == *( i-d2 ) ||
+               theNode2 == *( i+d2 ))))
+          return true;
       }
     }
-    return isLinked;
+    return false;
   }
 
   // find nodes indices
   int i1 = -1, i2 = -1, nbFound = 0;
-  for ( int i = 0; i < myVolumeNbNodes && nbFound < 2; i++ )
+  for ( int i = 0; i < myVolumeNodes.size() && nbFound < 2; i++ )
   {
     if ( myVolumeNodes[ i ] == theNode1 )
       i1 = i, ++nbFound;
@@ -1234,7 +1418,7 @@ bool SMDS_VolumeTool::IsLinked (const int theNode1Index,
   int minInd = min( theNode1Index, theNode2Index );
   int maxInd = max( theNode1Index, theNode2Index );
 
-  if ( minInd < 0 || maxInd > myVolumeNbNodes - 1 || maxInd == minInd )
+  if ( minInd < 0 || maxInd > myVolumeNodes.size() - 1 || maxInd == minInd )
     return false;
 
   VolumeType type = GetVolumeType();
@@ -1351,7 +1535,7 @@ bool SMDS_VolumeTool::IsLinked (const int theNode1Index,
 int SMDS_VolumeTool::GetNodeIndex(const SMDS_MeshNode* theNode) const
 {
   if ( myVolume ) {
-    for ( int i = 0; i < myVolumeNbNodes; i++ ) {
+    for ( int i = 0; i < myVolumeNodes.size(); i++ ) {
       if ( myVolumeNodes[ i ] == theNode )
         return i;
     }
@@ -1370,24 +1554,32 @@ int SMDS_VolumeTool::GetNodeIndex(const SMDS_MeshNode* theNode) const
 int SMDS_VolumeTool::GetAllExistingFaces(vector<const SMDS_MeshElement*> & faces) const
 {
   faces.clear();
-  for ( int iF = 0; iF < NbFaces(); ++iF ) {
-    const SMDS_MeshFace* face = 0;
-    const SMDS_MeshNode** nodes = GetFaceNodes( iF );
-    switch ( NbFaceNodes( iF )) {
-    case 3:
-      face = SMDS_Mesh::FindFace( nodes[0], nodes[1], nodes[2] ); break;
-    case 4:
-      face = SMDS_Mesh::FindFace( nodes[0], nodes[1], nodes[2], nodes[3] ); break;
-    case 6:
-      face = SMDS_Mesh::FindFace( nodes[0], nodes[1], nodes[2],
-                                  nodes[3], nodes[4], nodes[5]); break;
-    case 8:
-      face = SMDS_Mesh::FindFace( nodes[0], nodes[1], nodes[2], nodes[3],
-                                  nodes[4], nodes[5], nodes[6], nodes[7]); break;
+  SaveFacet savedFacet( myCurFace );
+  if ( IsPoly() )
+    for ( int iF = 0; iF < NbFaces(); ++iF ) {
+      if ( setFace( iF ))
+        if ( const SMDS_MeshElement* face = SMDS_Mesh::FindFace( myCurFace.myNodes ))
+          faces.push_back( face );
+    }
+  else
+    for ( int iF = 0; iF < NbFaces(); ++iF ) {
+      const SMDS_MeshFace* face = 0;
+      const SMDS_MeshNode** nodes = GetFaceNodes( iF );
+      switch ( NbFaceNodes( iF )) {
+      case 3:
+        face = SMDS_Mesh::FindFace( nodes[0], nodes[1], nodes[2] ); break;
+      case 4:
+        face = SMDS_Mesh::FindFace( nodes[0], nodes[1], nodes[2], nodes[3] ); break;
+      case 6:
+        face = SMDS_Mesh::FindFace( nodes[0], nodes[1], nodes[2],
+                                    nodes[3], nodes[4], nodes[5]); break;
+      case 8:
+        face = SMDS_Mesh::FindFace( nodes[0], nodes[1], nodes[2], nodes[3],
+                                    nodes[4], nodes[5], nodes[6], nodes[7]); break;
+      }
+      if ( face )
+        faces.push_back( face );
     }
-    if ( face )
-      faces.push_back( face );
-  }
   return faces.size();
 }
 
@@ -1395,17 +1587,17 @@ int SMDS_VolumeTool::GetAllExistingFaces(vector<const SMDS_MeshElement*> & faces
 //================================================================================
 /*!
  * \brief Fill vector with boundary edges existing in the mesh
 * \param edges - vector of found edges
 * \retval int - nb of found faces
+ * \param edges - vector of found edges
+ * \retval int - nb of found faces
  */
 //================================================================================
 
 int SMDS_VolumeTool::GetAllExistingEdges(vector<const SMDS_MeshElement*> & edges) const
 {
   edges.clear();
-  edges.reserve( myVolumeNbNodes * 2 );
-  for ( int i = 0; i < myVolumeNbNodes-1; ++i ) {
-    for ( int j = i + 1; j < myVolumeNbNodes; ++j ) {
+  edges.reserve( myVolumeNodes.size() * 2 );
+  for ( int i = 0; i < myVolumeNodes.size()-1; ++i ) {
+    for ( int j = i + 1; j < myVolumeNodes.size(); ++j ) {
       if ( IsLinked( i, j )) {
         const SMDS_MeshElement* edge =
           SMDS_Mesh::FindEdge( myVolumeNodes[i], myVolumeNodes[j] );
@@ -1428,30 +1620,20 @@ double SMDS_VolumeTool::MinLinearSize2() const
   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;
-  
+  SaveFacet savedFacet( myCurFace );
+
   // it seems that compute distance twice is faster than organization of a sole computing
-  myCurFace = -1;
+  myCurFace.myIndex = -1;
   for ( int iF = 0; iF < myNbFaces; ++iF )
   {
     setFace( iF );
-    for ( int iN = 0; iN < myFaceNbNodes; iN += iQ )
+    for ( int iN = 0; iN < myCurFace.myNbNodes; iN += iQ )
     {
-      XYZ n1( myFaceNodes[ iN ]);
-      XYZ n2( myFaceNodes[(iN + iQ) % myFaceNbNodes]);
+      XYZ n1( myCurFace.myNodes[ iN ]);
+      XYZ n2( myCurFace.myNodes[(iN + iQ) % myCurFace.myNbNodes]);
       minSize = std::min( minSize, (n1 - n2).SquareMagnitude());
     }
   }
-  // restore current face data
-  myCurFace = curFace;
-  myFaceNbNodes = nbN;
-  myFaceNodeIndices = ind;
-  delete [] myFaceNodes; myFaceNodes = nodes;
 
   return minSize;
 }
@@ -1467,30 +1649,20 @@ double SMDS_VolumeTool::MaxLinearSize2() const
   double maxSize = -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;
+  SaveFacet savedFacet( myCurFace );
   
   // it seems that compute distance twice is faster than organization of a sole computing
-  myCurFace = -1;
+  myCurFace.myIndex = -1;
   for ( int iF = 0; iF < myNbFaces; ++iF )
   {
     setFace( iF );
-    for ( int iN = 0; iN < myFaceNbNodes; iN += iQ )
+    for ( int iN = 0; iN < myCurFace.myNbNodes; iN += iQ )
     {
-      XYZ n1( myFaceNodes[ iN ]);
-      XYZ n2( myFaceNodes[(iN + iQ) % myFaceNbNodes]);
+      XYZ n1( myCurFace.myNodes[ iN ]);
+      XYZ n2( myCurFace.myNodes[(iN + iQ) % myCurFace.myNbNodes]);
       maxSize = std::max( maxSize, (n1 - n2).SquareMagnitude());
     }
   }
-  // restore current face data
-  myCurFace         = curFace;
-  myFaceNbNodes     = nbN;
-  myFaceNodeIndices = ind;
-  delete [] myFaceNodes; myFaceNodes = nodes;
 
   return maxSize;
 }
@@ -1498,6 +1670,7 @@ double SMDS_VolumeTool::MaxLinearSize2() const
 //================================================================================
 /*!
  * \brief fast check that only one volume is build on the face nodes
+ *        This check is valid for conformal meshes only
  */
 //================================================================================
 
@@ -1505,33 +1678,37 @@ bool SMDS_VolumeTool::IsFreeFace( int faceIndex, const SMDS_MeshElement** otherV
 {
   const bool isFree = true;
 
-  if (!setFace( faceIndex ))
+  if ( !setFace( faceIndex ))
     return !isFree;
 
   const SMDS_MeshNode** nodes = GetFaceNodes( faceIndex );
 
-  // a set of facet nodes w/o medium ones and w/o nodes[0]
-  set< const SMDS_MeshElement* > nodeSet;
-  const int di = myVolume->IsQuadratic() ? 2 : 1;
-  for ( int i = di; i < myFaceNbNodes; i += di )
-    nodeSet.insert( nodes[i] );
+  const int  di = myVolume->IsQuadratic() ? 2 : 1;
+  const int nbN = ( myCurFace.myNbNodes/di <= 4 && !IsPoly()) ? 3 : myCurFace.myNbNodes/di; // nb nodes to check
 
   SMDS_ElemIteratorPtr eIt = nodes[0]->GetInverseElementIterator( SMDSAbs_Volume );
-  SMDS_ElemIteratorPtr nIt;
-  while ( eIt->more() ) {
+  while ( eIt->more() )
+  {
     const SMDS_MeshElement* vol = eIt->next();
-    if ( vol != myVolume ) {
-      size_t nbShared = 0;
-      if ( const SMDS_VtkVolume* v = dynamic_cast< const SMDS_VtkVolume* >( vol ))
-        nIt = v->uniqueNodesIterator();
-      else
-        nIt = vol->nodesIterator();
-      while ( nIt->more() )
-        if (( nbShared += nodeSet.count( nIt->next() )) == nodeSet.size() )
-        {
-          if ( otherVol ) *otherVol = vol;
-          return !isFree;
-        }
+    if ( vol == myVolume )
+      continue;
+    int iN;
+    for ( iN = 1; iN < nbN; ++iN )
+      if ( vol->GetNodeIndex( nodes[ iN*di ]) < 0 )
+        break;
+    if ( iN == nbN ) // nbN nodes are shared with vol
+    {
+      // if ( vol->IsPoly() || vol->NbFaces() > 6 ) // vol is polyhed or hex prism 
+      // {
+      //   int nb = myCurFace.myNbNodes;
+      //   if ( myVolume->GetEntityType() != vol->GetEntityType() )
+      //     nb -= ( GetCenterNodeIndex(0) > 0 );
+      //   set<const SMDS_MeshNode*> faceNodes( nodes, nodes + nb );
+      //   if ( SMDS_VolumeTool( vol ).GetFaceIndex( faceNodes ) < 0 )
+      //     continue;
+      // }
+      if ( otherVol ) *otherVol = vol;
+      return !isFree;
     }
   }
   if ( otherVol ) *otherVol = 0;
@@ -1552,7 +1729,7 @@ bool SMDS_VolumeTool::IsFreeFaceAdv( int faceIndex, const SMDS_MeshElement** oth
     return !isFree;
 
   const SMDS_MeshNode** nodes = GetFaceNodes( faceIndex );
-  const int nbFaceNodes = myFaceNbNodes;
+  const int nbFaceNodes = myCurFace.myNbNodes;
 
   // evaluate nb of face nodes shared by other volumes
   int maxNbShared = -1;
@@ -1731,19 +1908,14 @@ bool SMDS_VolumeTool::setFace( int faceIndex ) const
   if ( !myVolume )
     return false;
 
-  if ( myCurFace == faceIndex )
+  if ( myCurFace.myIndex == faceIndex )
     return true;
 
-  myCurFace = -1;
+  myCurFace.myIndex = -1;
 
   if ( faceIndex < 0 || faceIndex >= NbFaces() )
     return false;
 
-  if (myFaceNodes != NULL) {
-    delete [] myFaceNodes;
-    myFaceNodes = NULL;
-  }
-
   if (myVolume->IsPoly())
   {
     if (!myPolyedre) {
@@ -1752,21 +1924,31 @@ bool SMDS_VolumeTool::setFace( int faceIndex ) const
     }
 
     // set face nodes
-    int iNode;
-    myFaceNbNodes = myPolyedre->NbFaceNodes(faceIndex + 1);
-    myFaceNodes = new const SMDS_MeshNode* [myFaceNbNodes + 1];
-    for ( iNode = 0; iNode < myFaceNbNodes; iNode++ )
-      myFaceNodes[ iNode ] = myPolyedre->GetFaceNode(faceIndex + 1, iNode + 1);
-    myFaceNodes[ myFaceNbNodes ] = myFaceNodes[ 0 ]; // last = first
+    SMDS_VolumeTool* me = const_cast< SMDS_VolumeTool* >( this );
+    if ( !myAllFacesNbNodes ) {
+      me->myPolyQuantities = myPolyedre->GetQuantities();
+      myAllFacesNbNodes    = &myPolyQuantities[0];
+    }
+    myCurFace.myNbNodes = myAllFacesNbNodes[ faceIndex ];
+    myCurFace.myNodes.resize( myCurFace.myNbNodes + 1 );
+    me->myPolyIndices.resize( myCurFace.myNbNodes + 1 );
+    myCurFace.myNodeIndices = & me->myPolyIndices[0];
+    int shift = std::accumulate( myAllFacesNbNodes, myAllFacesNbNodes+faceIndex, 0 );
+    for ( int iNode = 0; iNode < myCurFace.myNbNodes; iNode++ )
+    {
+      myCurFace.myNodes      [ iNode ] = myVolumeNodes[ shift + iNode ];
+      myCurFace.myNodeIndices[ iNode ] = shift + iNode;
+    }
+    myCurFace.myNodes      [ myCurFace.myNbNodes ] = myCurFace.myNodes[ 0 ]; // last = first
+    myCurFace.myNodeIndices[ myCurFace.myNbNodes ] = myCurFace.myNodeIndices[ 0 ];
 
     // check orientation
     if (myExternalFaces)
     {
-      myCurFace = faceIndex; // avoid infinite recursion in IsFaceExternal()
+      myCurFace.myIndex = 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] );
+        std::reverse( myCurFace.myNodes.begin(), myCurFace.myNodes.end() );
       myExternalFaces = true;
     }
   }
@@ -1775,7 +1957,7 @@ bool SMDS_VolumeTool::setFace( int faceIndex ) const
     if ( !myAllFacesNodeIndices_F )
     {
       // choose data for an element type
-      switch ( myVolumeNbNodes ) {
+      switch ( myVolumeNodes.size() ) {
       case 4:
         myAllFacesNodeIndices_F  = &Tetra_F [0][0];
         //myAllFacesNodeIndices_FE = &Tetra_F [0][0];
@@ -1832,7 +2014,7 @@ bool SMDS_VolumeTool::setFace( int faceIndex ) const
         myAllFacesNodeIndices_RE = &QuadHexa_RE[0][0];
         myAllFacesNbNodes        = QuadHexa_nbN;
         myMaxFaceNbNodes         = sizeof(QuadHexa_F[0])/sizeof(QuadHexa_F[0][0]);
-        if ( !myIgnoreCentralNodes && myVolumeNbNodes == 27 )
+        if ( !myIgnoreCentralNodes && myVolumeNodes.size() == 27 )
         {
           myAllFacesNodeIndices_F  = &TriQuadHexa_F [0][0];
           //myAllFacesNodeIndices_FE = &TriQuadHexa_FE[0][0];
@@ -1852,21 +2034,21 @@ bool SMDS_VolumeTool::setFace( int faceIndex ) const
         return false;
       }
     }
-    myFaceNbNodes = myAllFacesNbNodes[ faceIndex ];
+    myCurFace.myNbNodes = myAllFacesNbNodes[ faceIndex ];
     // if ( myExternalFaces )
-    //   myFaceNodeIndices = (int*)( myVolForward ? myAllFacesNodeIndices_FE + faceIndex*myMaxFaceNbNodes : myAllFacesNodeIndices_RE + faceIndex*myMaxFaceNbNodes );
+    //   myCurFace.myNodeIndices = (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 );
+    //   myCurFace.myNodeIndices = (int*)( myAllFacesNodeIndices_F + faceIndex*myMaxFaceNbNodes );
+    myCurFace.myNodeIndices = (int*)( myVolForward ? myAllFacesNodeIndices_F + faceIndex*myMaxFaceNbNodes : myAllFacesNodeIndices_RE + faceIndex*myMaxFaceNbNodes );
 
     // set face nodes
-    myFaceNodes = new const SMDS_MeshNode* [myFaceNbNodes + 1];
-    for ( int iNode = 0; iNode < myFaceNbNodes; iNode++ )
-      myFaceNodes[ iNode ] = myVolumeNodes[ myFaceNodeIndices[ iNode ]];
-    myFaceNodes[ myFaceNbNodes ] = myFaceNodes[ 0 ];
+    myCurFace.myNodes.resize( myCurFace.myNbNodes + 1 );
+    for ( int iNode = 0; iNode < myCurFace.myNbNodes; iNode++ )
+      myCurFace.myNodes[ iNode ] = myVolumeNodes[ myCurFace.myNodeIndices[ iNode ]];
+    myCurFace.myNodes[ myCurFace.myNbNodes ] = myCurFace.myNodes[ 0 ];
   }
 
-  myCurFace = faceIndex;
+  myCurFace.myIndex = faceIndex;
 
   return true;
 }
index 69e20860a8996e69681ac49295e1f7dec751d99d..7e88f7c1a309c48061daf61a8ee4092da20c374e 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -38,6 +38,7 @@ class SMDS_MeshVolume;
 
 #include <vector>
 #include <set>
+#include <map>
 
 // =========================================================================
 //
@@ -90,10 +91,10 @@ class SMDS_EXPORT SMDS_VolumeTool
   // top and bottom faces are reversed.
   // Result of IsForward() and methods returning nodes change
 
-  const SMDS_MeshNode** GetNodes() { return myVolumeNodes; }
+  const SMDS_MeshNode** GetNodes() { return &myVolumeNodes[0]; }
   // Return array of volume nodes
 
-  int NbNodes() { return myVolumeNbNodes; }
+  int NbNodes() { return myVolumeNodes.size(); }
   // Return array of volume nodes
 
   double GetSize() const;
@@ -242,31 +243,42 @@ class SMDS_EXPORT SMDS_VolumeTool
   static int GetOppFaceIndexOfHex( int faceIndex );
   // Return index of the opposite face of the hexahedron
 
-private:
+ private:
 
   bool setFace( int faceIndex ) const;
 
+  bool projectNodesToNormal( int faceIndex, double& minProj, double& maxProj ) const;
+
   const SMDS_MeshElement* myVolume;
   const SMDS_VtkVolume*   myPolyedre;
   bool                    myIgnoreCentralNodes;
 
   bool                    myVolForward;
   int                     myNbFaces;
-  int                     myVolumeNbNodes;
-  const SMDS_MeshNode**   myVolumeNodes;
-  std::vector< int >      myPolyIndices;
-
-  mutable bool                    myExternalFaces;
-
-  mutable const int*              myAllFacesNodeIndices_F;
-  mutable const int*              myAllFacesNodeIndices_RE;
-  mutable const int*              myAllFacesNbNodes;
-  mutable int                     myMaxFaceNbNodes;
-
-  mutable int                     myCurFace;
-  mutable int                     myFaceNbNodes;
-  mutable int*                    myFaceNodeIndices;
-  mutable const SMDS_MeshNode**   myFaceNodes;
+  std::vector<const SMDS_MeshNode*> myVolumeNodes;
+  std::vector< int >      myPolyIndices; // of a myCurFace
+  std::vector< int >      myPolyQuantities;
+  std::vector< int >      myPolyFacetOri; // -1-in, +1-out, 0-undef
+
+  typedef std::pair<int,int> Link;
+  std::map<Link, int>     myFwdLinks; // used in IsFaceExternal() to find out myPolyFacetOri
+
+  mutable bool            myExternalFaces;
+
+  mutable const int*      myAllFacesNodeIndices_F;
+  mutable const int*      myAllFacesNodeIndices_RE;
+  mutable const int*      myAllFacesNbNodes;
+  mutable int             myMaxFaceNbNodes;
+
+  struct SaveFacet;
+  struct Facet
+  {
+    int                   myIndex;
+    int                   myNbNodes;
+    int*                  myNodeIndices;
+    std::vector<const SMDS_MeshNode*> myNodes;
+  };
+  mutable Facet           myCurFace;
 
 };
 #endif
index ce511047bf8fc355f08317a9cecc667da386e055..d050097fba3139295005ad6ba30851fcbf18b0da 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2010-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2010-2015  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
@@ -71,75 +71,73 @@ SMDS_VtkCellIteratorToUNV::SMDS_VtkCellIteratorToUNV(SMDS_Mesh* mesh, int vtkCel
   vtkUnstructuredGrid* grid = _mesh->getGrid();
   grid->GetCellPoints((vtkIdType)_cellId, (vtkIdType&)_nbNodes, pts);
   _vtkIdList->SetNumberOfIds(_nbNodes);
-  int *ids = 0;
+  const int *ids = 0;
   switch (_type)
   {
-    case SMDSEntity_Quad_Edge:
-      {
-        static int id[] = { 0, 2, 1 };
-        ids = id;
-        break;
-      }
-    case SMDSEntity_Quad_Triangle:
-    case SMDSEntity_BiQuad_Triangle:
-      {
-        static int id[] = { 0, 3, 1, 4, 2, 5 };
-        ids = id;
-        _nbNodes = 6;
-        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;
-      }
+  case SMDSEntity_Quad_Edge:
+  {
+    static int id[] = { 0, 2, 1 };
+    ids = id;
+    break;
+  }
+  case SMDSEntity_Quad_Triangle:
+  case SMDSEntity_BiQuad_Triangle:
+  {
+    static int id[] = { 0, 3, 1, 4, 2, 5 };
+    ids = id;
+    _nbNodes = 6;
+    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:
+    const std::vector<int>& i = SMDS_MeshCell::interlacedSmdsOrder(aType, _nbNodes);
+    if ( !i.empty() )
+      ids = & i[0];
+  }
+
   if ( ids )
     for (int i = 0; i < _nbNodes; i++)
       _vtkIdList->SetId(i, pts[ids[i]]);
@@ -176,34 +174,34 @@ SMDS_VtkCellIteratorPolyH::SMDS_VtkCellIteratorPolyH(SMDS_Mesh* mesh, int vtkCel
   _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);
+  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);
   }
 }
 
index 1581785d4e64297a4688b862ed97447cde0f8aa2..0ff0a6d637ad93acf9144e7ac47cef5ee987ee5b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2010-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2010-2015  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
index f205cff6da962a6c9f6cec3be66b2403849ed6a7..ba42087ed117415403a91beb360c3b87c2d411a0 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2010-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2010-2015  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
index 8dc2f2af607d3c51d098687d9c3efd02f73f0eab..c68812ad73717f33ee5b0e433f2444c9d81c5047 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2010-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2010-2015  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
index c0bf69cc766d0cde482af656c7624f613cd507ba..0a772f53bc6be24307a17afbf475a3365fb03c1a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2010-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2010-2015  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
@@ -85,6 +85,15 @@ void SMDS_VtkFace::initPoly(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh* me
   mesh->setMyModified();
 }
 
+void SMDS_VtkFace::initQuadPoly(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh* mesh)
+{
+  SMDS_MeshFace::init();
+  vtkUnstructuredGrid* grid = mesh->getGrid();
+  myMeshId = mesh->getMeshId();
+  myVtkID = grid->InsertNextLinkedCell(VTK_QUADRATIC_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();
@@ -111,26 +120,28 @@ void SMDS_VtkFace::Print(std::ostream & OS) const
 
 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:
-    case VTK_BIQUADRATIC_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;
+  case VTK_TRIANGLE:
+  case VTK_QUADRATIC_TRIANGLE:
+  case VTK_BIQUADRATIC_TRIANGLE:
+    nbEdges = 3;
+    break;
+  case VTK_QUAD:
+  case VTK_QUADRATIC_QUAD:
+  case VTK_BIQUADRATIC_QUAD:
+    nbEdges = 4;
+    break;
+  case VTK_QUADRATIC_POLYGON:
+    nbEdges = grid->GetCell(myVtkID)->GetNumberOfPoints() / 2;
+    break;
+  case VTK_POLYGON:
+  default:
+    nbEdges = grid->GetCell(myVtkID)->GetNumberOfPoints();
+    break;
   }
   return nbEdges;
 }
@@ -186,6 +197,7 @@ bool SMDS_VtkFace::IsQuadratic() const
   {
     case VTK_QUADRATIC_TRIANGLE:
     case VTK_QUADRATIC_QUAD:
+    case VTK_QUADRATIC_POLYGON:
     case VTK_BIQUADRATIC_QUAD:
     case VTK_BIQUADRATIC_TRIANGLE:
       return true;
@@ -199,7 +211,7 @@ bool SMDS_VtkFace::IsPoly() const
 {
   vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
   vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
-  return (aVtkType == VTK_POLYGON);
+  return ( aVtkType == VTK_POLYGON || aVtkType == VTK_QUADRATIC_POLYGON );
 }
 
 bool SMDS_VtkFace::IsMediumNode(const SMDS_MeshNode* node) const
@@ -209,33 +221,36 @@ bool SMDS_VtkFace::IsMediumNode(const SMDS_MeshNode* node) const
   int rankFirstMedium = 0;
   switch (aVtkType)
   {
-    case VTK_QUADRATIC_TRIANGLE:
-    case VTK_BIQUADRATIC_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;
+  case VTK_QUADRATIC_TRIANGLE:
+  case VTK_BIQUADRATIC_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;
+  case VTK_QUADRATIC_POLYGON:
+    rankFirstMedium = grid->GetCell(myVtkID)->GetNumberOfPoints() / 2;
+    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)
     {
-      if (pts[rank] == nodeId)
-        {
-          //MESSAGE("rank " << rank << " is medium node " << (rank < rankFirstMedium));
-          if (rank < rankFirstMedium)
-            return false;
-          else
-            return true;
-        }
+      //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 =");
@@ -248,8 +263,17 @@ 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;
+  switch ( aVtkType )
+  {
+  case VTK_POLYGON:
+    break;
+  case VTK_QUADRATIC_POLYGON:
+    nbPoints /= 2;
+    break;
+  default:
+    if ( nbPoints > 4 )
+      nbPoints /= 2;
+  }
   return nbPoints;
 }
 
@@ -273,7 +297,8 @@ SMDSAbs_GeometryType SMDS_VtkFace::GetGeomType() const
   case VTK_QUADRATIC_QUAD:
   case VTK_BIQUADRATIC_QUAD: return SMDSGeom_QUADRANGLE;
 
-  case VTK_POLYGON: return SMDSGeom_POLYGON;
+  case VTK_POLYGON:
+  case VTK_QUADRATIC_POLYGON: return SMDSGeom_POLYGON;
   default:;
   }
   return SMDSGeom_NONE;
index e2f136f67bd8f920ab09349ebc39e269ae12e952..235a9c2d8046535af8361fe1f80c35bd40fa3faa 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2010-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2010-2015  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
@@ -34,6 +34,7 @@ public:
   ~SMDS_VtkFace();
   void init(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh* mesh);
   void initPoly(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh* mesh);
+  void initQuadPoly(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
index f97e31969e2b531b2d7091d7fae5d53b0ac1bd88..d6da4357986d5150ab18dd623a541fae7e17e679 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2010-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2010-2015  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
@@ -165,7 +165,7 @@ bool SMDS_VtkVolume::vtkOrder(const SMDS_MeshNode* nodes[], const int nbNodes)
   const std::vector<int>& interlace = SMDS_MeshCell::toVtkOrder( VTKCellType( aVtkType ));
   if ( !interlace.empty() )
   {
-    ASSERT( interlace.size() == nbNodes );
+    ASSERT( (int)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] ];
index 1378aa3660e2131b8b3b25ee0ee1dcdf80776798..09d61fc5c1ae3ab061e64d23efafde2afa61444e 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2010-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2010-2015  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
index 5f5afd1fd8fd02e963a648decb75cb97fbcfa445..9e55e313f428bd089f6c4261f479de75d31ecb80 100755 (executable)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 0fae4a48d26862d8c95c4b36812fbc36370630de..caa6031f404cba316ac1d7653271020a00cb00a4 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2006-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2006-2015  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
index ec417b0c8d0bec7271fd69ebf08d4273bbe3486d..ba4c3c57212a9e44e2be238817e23c0c8b7cd1ca 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2006-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2006-2015  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
index a23c8c468a3d071107cb18d412fc9ed8ee3e8c65..55f73df68900b384f6144131d72fabc0a83118d7 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2012-2015  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
index 5ec1240b00bdcb9c8fd007e413b47c2d9b18a589..56d41720d7988588403367d37329c6a2c44fcb77 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -403,7 +403,8 @@ bool SMESH_Algo::GetNodeParamOnEdge(const SMESHDS_Mesh* theMesh,
 bool SMESH_Algo::GetSortedNodesOnEdge(const SMESHDS_Mesh*                   theMesh,
                                       const TopoDS_Edge&                    theEdge,
                                       const bool                            ignoreMediumNodes,
-                                      map< double, const SMDS_MeshNode* > & theNodes)
+                                      map< double, const SMDS_MeshNode* > & theNodes,
+                                      const SMDSAbs_ElementType             typeToCheck)
 {
   theNodes.clear();
 
@@ -423,27 +424,22 @@ bool SMESH_Algo::GetSortedNodesOnEdge(const SMESHDS_Mesh*                   theM
     while ( nIt->more() )
     {
       const SMDS_MeshNode* node = nIt->next();
-      if ( ignoreMediumNodes ) {
-        SMDS_ElemIteratorPtr elemIt = node->GetInverseElementIterator();
-        if ( elemIt->more() && elemIt->next()->IsMediumNode( node ))
-          continue;
-      }
+      if ( ignoreMediumNodes && SMESH_MesherHelper::IsMedium( node, typeToCheck ))
+        continue;
       const SMDS_PositionPtr& pos = node->GetPosition();
       if ( pos->GetTypeOfPosition() != SMDS_TOP_EDGE )
         return false;
       const SMDS_EdgePosition* epos =
         static_cast<const SMDS_EdgePosition*>(node->GetPosition());
       theNodes.insert( theNodes.end(), make_pair( epos->GetUParameter(), node ));
-      //MESSAGE("U " << epos->GetUParameter() << " ID " << node->GetID());
       ++nbNodes;
     }
   }
   // add vertex nodes
   TopoDS_Vertex v1, v2;
   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());
+  const SMDS_MeshNode* n1 = VertexNode( v1, eSubMesh, 0 );
+  const SMDS_MeshNode* n2 = VertexNode( v2, eSubMesh, 0 );
   Standard_Real f, l;
   BRep_Tool::Range(theEdge, f, l);
   if ( v1.Orientation() != TopAbs_FORWARD )
@@ -453,7 +449,7 @@ bool SMESH_Algo::GetSortedNodesOnEdge(const SMESHDS_Mesh*                   theM
   if ( n2 && ++nbNodes )
     theNodes.insert( make_pair( l, n2 ));
 
-  return theNodes.size() == nbNodes;
+  return (int)theNodes.size() == nbNodes;
 }
 
 //================================================================================
@@ -473,7 +469,7 @@ SMESH_Algo::GetCompatibleHypoFilter(const bool ignoreAuxiliary) const
     {
       SMESH_HypoFilter* filter = new SMESH_HypoFilter();
       filter->Init( filter->HasName( _compatibleHypothesis[0] ));
-      for ( int i = 1; i < _compatibleHypothesis.size(); ++i )
+      for ( size_t i = 1; i < _compatibleHypothesis.size(); ++i )
         filter->Or( filter->HasName( _compatibleHypothesis[ i ] ));
 
       SMESH_HypoFilter* filterNoAux = new SMESH_HypoFilter( filter );
@@ -568,7 +564,7 @@ bool SMESH_Algo::IsStraight( const TopoDS_Edge & E,
   if ( v1Len < std::numeric_limits< double >::min() )
     return false; // E seems closed
   const double tol = Min( 10 * curve.Tolerance(), v1Len * 1e-2 );
-  const int nbSamples = 7;
+  const double nbSamples = 7;
   for ( int i = 0; i < nbSamples; ++i )
   {
     const double  r = ( i + 1 ) / nbSamples;
@@ -616,6 +612,118 @@ const SMDS_MeshNode* SMESH_Algo::VertexNode(const TopoDS_Vertex& V,
   return 0;
 }
 
+//=======================================================================
+/*!
+ * \brief Return the node built on a vertex.
+ *        A node moved to other geometry by MergeNodes() is also returned.
+ * \param V - the vertex
+ * \param mesh - mesh
+ * \retval const SMDS_MeshNode* - found node or NULL
+ */
+//=======================================================================
+
+const SMDS_MeshNode* SMESH_Algo::VertexNode(const TopoDS_Vertex& V,
+                                            const SMESH_Mesh*    mesh)
+{
+  const SMDS_MeshNode* node = VertexNode( V, mesh->GetMeshDS() );
+
+  if ( !node && mesh->HasModificationsToDiscard() )
+  {
+    PShapeIteratorPtr edgeIt = SMESH_MesherHelper::GetAncestors( V, *mesh, TopAbs_EDGE );
+    while ( const TopoDS_Shape* edge = edgeIt->next() )
+      if ( SMESHDS_SubMesh* edgeSM = mesh->GetMeshDS()->MeshElements( *edge ))
+        if ( edgeSM->NbElements() > 0 )
+          return VertexNode( V, edgeSM, mesh, /*checkV=*/false );
+  }
+  return node;
+}
+
+//=======================================================================
+/*!
+ * \brief Return the node built on a vertex.
+ *        A node moved to other geometry by MergeNodes() is also returned.
+ * \param V - the vertex
+ * \param edgeSM - sub-mesh of a meshed EDGE sharing the vertex
+ * \param checkV - if \c true, presence of a node on the vertex is checked
+ * \retval const SMDS_MeshNode* - found node or NULL
+ */
+//=======================================================================
+
+const SMDS_MeshNode* SMESH_Algo::VertexNode(const TopoDS_Vertex&   V,
+                                            const SMESHDS_SubMesh* edgeSM,
+                                            const SMESH_Mesh*      mesh,
+                                            const bool             checkV)
+{
+  const SMDS_MeshNode* node = checkV ? VertexNode( V, edgeSM->GetParent() ) : 0;
+
+  if ( !node && edgeSM )
+  {
+    // find nodes not shared by mesh segments
+    typedef set< const SMDS_MeshNode* >                       TNodeSet;
+    typedef map< const SMDS_MeshNode*, const SMDS_MeshNode* > TNodeMap;
+    TNodeMap notSharedNodes;
+    TNodeSet otherShapeNodes;
+    vector< const SMDS_MeshNode* > segNodes(3);
+    SMDS_ElemIteratorPtr segIt = edgeSM->GetElements();
+    while ( segIt->more() )
+    {
+      const SMDS_MeshElement* seg = segIt->next();
+      if ( seg->GetType() != SMDSAbs_Edge )
+        return node;
+      segNodes.assign( seg->begin_nodes(), seg->end_nodes() );
+      for ( int i = 0; i < 2; ++i )
+      {
+        const SMDS_MeshNode* n1 = segNodes[i];
+        const SMDS_MeshNode* n2 = segNodes[1-i];
+        pair<TNodeMap::iterator, bool> it2new = notSharedNodes.insert( make_pair( n1, n2 ));
+        if ( !it2new.second ) // n encounters twice
+          notSharedNodes.erase( it2new.first );
+        if ( n1->getshapeId() != edgeSM->GetID() )
+          otherShapeNodes.insert( n1 );
+      }
+    }
+    if ( otherShapeNodes.size() == 1 && notSharedNodes.empty() ) // a closed EDGE
+      return *otherShapeNodes.begin();
+
+    if ( notSharedNodes.size() == 2 ) // two end nodes found
+    {
+      SMESHDS_Mesh*  meshDS = edgeSM->GetParent();
+      const TopoDS_Shape& E = meshDS->IndexToShape( edgeSM->GetID() );
+      if ( E.IsNull() || E.ShapeType() != TopAbs_EDGE )
+        return node;
+      const SMDS_MeshNode* n1 = notSharedNodes.begin ()->first;
+      const SMDS_MeshNode* n2 = notSharedNodes.rbegin()->first;
+      TopoDS_Shape S1 = SMESH_MesherHelper::GetSubShapeByNode( n1, meshDS );
+      if ( S1.ShapeType() == TopAbs_VERTEX && SMESH_MesherHelper::IsSubShape( S1, E ))
+        return n2;
+      TopoDS_Shape S2 = SMESH_MesherHelper::GetSubShapeByNode( n2, meshDS );
+      if ( S2.ShapeType() == TopAbs_VERTEX && SMESH_MesherHelper::IsSubShape( S2, E ))
+        return n1;
+      if ( edgeSM->NbElements() <= 2 || !mesh ) // one-two segments
+      {
+        gp_Pnt pV = BRep_Tool::Pnt( V );
+        double dist1 = pV.SquareDistance( SMESH_TNodeXYZ( n1 ));
+        double dist2 = pV.SquareDistance( SMESH_TNodeXYZ( n2 ));
+        return dist1 < dist2 ? n1 : n2;
+      }
+      if ( mesh )
+      {
+        SMESH_MesherHelper helper( const_cast<SMESH_Mesh&>( *mesh ));
+        const SMDS_MeshNode* n1i = notSharedNodes.begin ()->second;
+        const SMDS_MeshNode* n2i = notSharedNodes.rbegin()->second;
+        const TopoDS_Edge&  edge = TopoDS::Edge( E );
+        bool  posOK = true;
+        double pos1 = helper.GetNodeU( edge, n1i, n2i, &posOK );
+        double pos2 = helper.GetNodeU( edge, n2i, n1i, &posOK );
+        double posV = BRep_Tool::Parameter( V, edge );
+        if ( Abs( pos1 - posV ) < Abs( pos2 - posV )) return n1;
+        else                                          return n2;
+      }
+    }
+  }
+  return node;
+}
+
 //=======================================================================
 //function : GetMeshError
 //purpose  : Finds topological errors of a sub-mesh
index 4e5dc4afcbe137f27e5510248c4910c4e4290c8b..6363dc469d4949411d6f380e7d869e937475893b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -179,10 +179,10 @@ class SMESH_EXPORT SMESH_Algo : public SMESH_Hypothesis
 
   /*!
    * \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
+    \param aMesh - the mesh
+    \param aShape - the shape
+   *  \param aResMap - prospective number of elements by SMDSAbs_ElementType by a sub-mesh
+    \retval bool - is a success
    */
   virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
                         MapShapeNbElems& aResMap) = 0;
@@ -313,6 +313,7 @@ public:
    * \param theEdge - The geometrical edge of interest
    * \param theParams - The resulting vector of sorted node parameters
    * \retval bool - false if not all parameters are OK
+   * \warning Nodes moved to other geometry by MergeNodes() are NOT returned.
    */
   static bool GetNodeParamOnEdge(const SMESHDS_Mesh*     theMesh,
                                  const TopoDS_Edge&      theEdge,
@@ -323,17 +324,16 @@ public:
    * \param theEdge - The geometrical edge of interest
    * \param theNodes - The resulting map
    * \param ignoreMediumNodes - to store medium nodes of quadratic elements or not
+   * \param typeToCheck - type of elements to check for medium nodes
    * \retval bool - false if not all parameters are OK
+   * \warning Nodes moved to other geometry by MergeNodes() are NOT returned.
    */
   static bool GetSortedNodesOnEdge(const SMESHDS_Mesh*                        theMesh,
                                    const TopoDS_Edge&                         theEdge,
                                    const bool                                 ignoreMediumNodes,
-                                   std::map< double, const SMDS_MeshNode* > & theNodes);
-  /*!
-   * Moved to SMESH_MesherHelper
-   */
-  // static bool IsReversedSubMesh (const TopoDS_Face&  theFace,
-  //                                SMESHDS_Mesh*       theMeshDS);
+                                   std::map< double, const SMDS_MeshNode* > & theNodes,
+                                   const SMDSAbs_ElementType                  typeToCheck = SMDSAbs_All);
+
   /*!
    * \brief Compute length of an edge
     * \param E - the edge
@@ -341,7 +341,6 @@ public:
    */
   static double EdgeLength(const TopoDS_Edge & E);
 
-  //static int NumberOfWires(const TopoDS_Shape& S);
   int NumberOfPoints(SMESH_Mesh& aMesh,const TopoDS_Wire& W);
 
   /*!
@@ -370,11 +369,34 @@ public:
   /*!
    * \brief Return the node built on a vertex
     * \param V - the vertex
-    * \param meshDS - mesh
+    * \param meshDS - mesh data structure
     * \retval const SMDS_MeshNode* - found node or NULL
    */
   static const SMDS_MeshNode* VertexNode(const TopoDS_Vertex& V, const SMESHDS_Mesh* meshDS);
 
+  /*!
+   * \brief Return the node built on a vertex.
+   *        A node moved to other geometry by MergeNodes() is also returned.
+    * \param V - the vertex
+    * \param mesh - mesh
+    * \retval const SMDS_MeshNode* - found node or NULL
+   */
+  static const SMDS_MeshNode* VertexNode(const TopoDS_Vertex& V, const SMESH_Mesh* mesh);
+
+  /*!
+   * \brief Return the node built on a vertex.
+   *        A node moved to other geometry by MergeNodes() is also returned.
+    * \param V - the vertex
+    * \param edgeSM - sub-mesh of a meshed EDGE sharing the vertex
+    * \param mesh - the mesh
+    * \param checkV - if \c true, presence of a node on the vertex is checked
+    * \retval const SMDS_MeshNode* - found node or NULL
+   */
+  static const SMDS_MeshNode* VertexNode(const TopoDS_Vertex&   V,
+                                         const SMESHDS_SubMesh* edgeSM,
+                                         const SMESH_Mesh*      mesh,
+                                         const bool             checkV=true);
+
   enum EMeshError { MEr_OK = 0, MEr_HOLES, MEr_BAD_ORI, MEr_EMPTY };
 
   /*!
@@ -423,7 +445,7 @@ protected:
   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 !_requireDiscreteBoundary. Default FALSE
-  bool _neededLowerHyps[4];     // hyp dims needed by algo that !NeedDiscreteBoundary(). Df. FALSE
+  bool _neededLowerHyps[4];     // hyp dims needed by algo that !_requireDiscreteBoundary. Df. FALSE
 
   // indicates if quadratic mesh creation is required,
   // is usually set like this: _quadraticMesh = SMESH_MesherHelper::IsQuadraticSubMesh(shape)
index 864f50c21449346cb49b5ccccdfd2e718d5b4af9..4c264d50ae52a996e94983c8c87188d0ba7df108 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -70,9 +70,7 @@ SMESH_Gen::SMESH_Gen()
   _segmentation = _nbSegments = 10;
   SMDS_Mesh::_meshList.clear();
   MESSAGE(SMDS_Mesh::_meshList.size());
-  //_counters = new counters(100);
   _compute_canceled = false;
-  _sm_current = NULL;
   //vtkDebugLeaks::SetExitError(0);
 }
 
@@ -182,9 +180,9 @@ bool SMESH_Gen::Compute(SMESH_Mesh &          aMesh,
       {
         if (_compute_canceled)
           return false;
-        _sm_current = smToCompute;
+        setCurrentSubMesh( smToCompute );
         smToCompute->ComputeStateEngine( computeEvent );
-        _sm_current = NULL;
+        setCurrentSubMesh( NULL );
       }
 
       // we check all the sub-meshes here and detect if any of them failed to compute
@@ -269,9 +267,9 @@ bool SMESH_Gen::Compute(SMESH_Mesh &          aMesh,
         {
           if (_compute_canceled)
             return false;
-          _sm_current = smToCompute;
+          setCurrentSubMesh( smToCompute );
           smToCompute->ComputeStateEngine( computeEvent );
-          _sm_current = NULL;
+          setCurrentSubMesh( NULL );
           if ( aShapesId )
             aShapesId->insert( smToCompute->GetId() );
         }
@@ -356,9 +354,9 @@ bool SMESH_Gen::Compute(SMESH_Mesh &          aMesh,
 
           if (_compute_canceled)
             return false;
-          _sm_current = sm;
+          setCurrentSubMesh( sm );
           sm->ComputeStateEngine( computeEvent );
-          _sm_current = NULL;
+          setCurrentSubMesh( NULL );
           if ( aShapesId )
             aShapesId->insert( sm->GetId() );
         }
@@ -401,8 +399,9 @@ void SMESH_Gen::PrepareCompute(SMESH_Mesh &          aMesh,
                                const TopoDS_Shape &  aShape)
 {
   _compute_canceled = false;
-  _sm_current = NULL;
+  resetCurrentSubMesh();
 }
+
 //=============================================================================
 /*!
  * Cancel Compute a mesh
@@ -412,10 +411,44 @@ void SMESH_Gen::CancelCompute(SMESH_Mesh &          aMesh,
                               const TopoDS_Shape &  aShape)
 {
   _compute_canceled = true;
-  if(_sm_current)
-    {
-      _sm_current->ComputeStateEngine( SMESH_subMesh::COMPUTE_CANCELED );
-    }
+  if ( const SMESH_subMesh* sm = GetCurrentSubMesh() )
+  {
+    const_cast< SMESH_subMesh* >( sm )->ComputeStateEngine( SMESH_subMesh::COMPUTE_CANCELED );
+  }
+  resetCurrentSubMesh();
+}
+
+//================================================================================
+/*!
+ * \brief Returns a sub-mesh being currently computed
+ */
+//================================================================================
+
+const SMESH_subMesh* SMESH_Gen::GetCurrentSubMesh() const
+{
+  return _sm_current.empty() ? 0 : _sm_current.back();
+}
+
+//================================================================================
+/*!
+ * \brief Sets a sub-mesh being currently computed.
+ *
+ * An algorithm can call Compute() for a sub-shape, hence we keep a stack of sub-meshes
+ */
+//================================================================================
+
+void SMESH_Gen::setCurrentSubMesh(SMESH_subMesh* sm)
+{
+  if ( sm )
+    _sm_current.push_back( sm );
+
+  else if ( !_sm_current.empty() )
+    _sm_current.pop_back();
+}
+
+void SMESH_Gen::resetCurrentSubMesh()
+{
+  _sm_current.clear();
 }
 
 //=============================================================================
@@ -911,7 +944,7 @@ bool SMESH_Gen::GetAlgoState(SMESH_Mesh&               theMesh,
   if ( !hasAlgo ) {
     ret = false;
     theErrors.push_back( TAlgoStateError() );
-    theErrors.back().Set( SMESH_Hypothesis::HYP_MISSING, 1, true );
+    theErrors.back().Set( SMESH_Hypothesis::HYP_MISSING, theMesh.HasShapeToMesh() ? 1 : 3, true );
   }
 
   return ret;
index 4dac76d43965d1ddab2d68b995d92cba5d233094..94a28a2792f530bbc25f2d7ef4b5deb3fd5079ba 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -37,8 +37,6 @@
 #include "SMESH_Algo.hxx"
 #include "SMESH_Mesh.hxx"
 
-#include "chrono.hxx"
-
 #include <TopoDS_Shape.hxx>
 
 #include <map>
@@ -89,7 +87,7 @@ public:
   void CancelCompute(::SMESH_Mesh &        aMesh,
                      const TopoDS_Shape &  aShape);
 
-  const SMESH_subMesh* GetCurrentSubMesh() const { return _sm_current; }
+  const SMESH_subMesh* GetCurrentSubMesh() const;
 
   /*!
    * \brief evaluates size of prospective mesh on a shape 
@@ -127,7 +125,7 @@ public:
     int                 _algoDim;
     bool                _isGlobalAlgo;
 
-    TAlgoStateError(): _algoDim(0),_algo(0),_name(SMESH_Hypothesis::HYP_OK) {}
+    TAlgoStateError(): _name(SMESH_Hypothesis::HYP_OK), _algo(0), _algoDim(0) {}
     void Set(TAlgoStateErrorName name, const SMESH_Algo* algo, bool isGlobal)
     { _name = name; _algo = algo; _algoDim = algo->GetDim(); _isGlobalAlgo = isGlobal; }
     void Set(TAlgoStateErrorName name, const int algoDim,      bool isGlobal)
@@ -175,10 +173,11 @@ private:
   // default number of segments
   int _nbSegments;
 
-  counters *_counters;
+  void setCurrentSubMesh(SMESH_subMesh* sm);
+  void resetCurrentSubMesh();
 
-  volatile bool  _compute_canceled;
-  SMESH_subMesh* _sm_current;
+  volatile bool               _compute_canceled;
+  std::list< SMESH_subMesh* > _sm_current;
 };
 
 #endif
index 95507248676b4a675428d3907a6d0e566d8fc383..1b45d64eea70275c771b3b5a2f0c4c9a36f806ab 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 78564230e3c060aa867468bc4584e652dea5b09f..1dd657ed56b2f6b9f8938498e51bae027d58ef88 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index d0125d1e56083efe4f2c89912ffd6333a8196d01..a5fd2f45702a5dc5743b2ffb43688a4cfa61debf 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -131,19 +131,22 @@ void SMESH_HypoFilter::IsMoreLocalThanPredicate::findPreferable()
 {
   const int shapeID = _mesh.GetMeshDS()->ShapeToIndex( _shape );
   const TListOfListOfInt& listOfShapeIDList = _mesh.GetMeshOrder();
-  TListOfListOfInt::const_iterator listsIt = listOfShapeIDList.begin();
+  TListOfListOfInt::const_iterator  listsIt = listOfShapeIDList.begin();
   for ( ; listsIt != listOfShapeIDList.end(); ++listsIt )
   {
-    const TListOfInt& idList  = *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 )
+      for ( --idIt; true; --idIt )
       {
         const TopoDS_Shape& shape = _mesh.GetMeshDS()->IndexToShape( *idIt );
         if ( !shape.IsNull())
           _preferableShapes.Add( shape );
+
+        if ( idIt == idList.begin() )
+          break;
       }
     }
   }
index 7a9c47d7734aa3c3ae48c0d1b962dfbc8f533a11..e971dfae4bb03aaada6da646bea8a7e2b94b3f19 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index f6bfaf7a6a32a3dd843e8a091d04ac865118872f..3a21a0a318d5f25f316d3197d3e33ec516b529b3 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -78,6 +78,7 @@ int SMESH_Hypothesis::GetDim() const
     case ALGO_1D: dim = 1; break;
     case ALGO_2D: dim = 2; break;
     case ALGO_3D: dim = 3; break;
+    case ALGO_0D: dim = 0; break;
     case PARAM_ALGO:
       dim = ( _param_algo_dim < 0 ) ? -_param_algo_dim : _param_algo_dim; break;
     }
@@ -159,7 +160,7 @@ void SMESH_Hypothesis::SetLibName(const char* theLibName)
 SMESH_Mesh* SMESH_Hypothesis::GetMeshByPersistentID(int id)
 {
   StudyContextStruct* myStudyContext = _gen->GetStudyContext(_studyId);
-  map<int, SMESH_Mesh*>::iterator itm = itm = myStudyContext->mapMesh.begin();
+  map<int, SMESH_Mesh*>::iterator itm = myStudyContext->mapMesh.begin();
   for ( ; itm != myStudyContext->mapMesh.end(); itm++)
   {
     SMESH_Mesh* mesh = (*itm).second;
index 4454410c4885cea358857e1edca69926d1ffc8bf..0ff9df96f7a3d19e900d836cada02bab0c004753 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -79,13 +79,15 @@ public:
   virtual void NotifySubMeshesHypothesisModification();
   void  SetLibName(const char* theLibName);
 
-  //void  SetParameters(const char *theParameters);
-  //char* GetParameters() const;
+  /*!
+   * \brief The returned value is used by NotifySubMeshesHypothesisModification()
+   *        to decide to call subMesh->AlgoStateEngine( MODIF_HYP, hyp ) or not
+   *        if subMesh is ready to be computed (algo+hyp==OK)  but not yet computed.
+   *        True result is reasonable for example if EventListeners depend on
+   *        parameters of hypothesis.
+   */
+  virtual bool DataDependOnParams() const { return false; }
 
-  // void SetLastParameters(const char* theParameters);
-  // char* GetLastParameters() const;
-  // void ClearParameters();
-  
   /*!
    * \brief Initialize my parameter values by the mesh built on the geometry
    *  \param theMesh - the built mesh
index 72d7ef193b7e9c3950ba27c43e99c3a6db75bfdb..6436b9a5d3c440ad7c38308b5e9f25963e218f02 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -58,7 +58,7 @@
 #include <GEOMUtils.hxx>
 
 #undef _Precision_HeaderFile
-//#include <BRepBndLib.hxx>
+#include <BRepBndLib.hxx>
 #include <BRepPrimAPI_MakeBox.hxx>
 #include <Bnd_Box.hxx>
 #include <TColStd_MapOfInteger.hxx>
 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
 
 #include "Utils_ExceptHandlers.hxx"
+
 #ifndef WIN32
 #include <boost/thread/thread.hpp>
 #include <boost/bind.hpp>
 #else 
-#include <pthread.h> 
+#include <pthread.h>
 #endif
 
 using namespace std;
@@ -180,6 +181,11 @@ SMESH_Mesh::~SMESH_Mesh()
 {
   MESSAGE("SMESH_Mesh::~SMESH_Mesh");
 
+  // avoid usual removal of elements while processing RemoveHypothesis( algo ) event
+  SMESHDS_SubMeshIteratorPtr smIt = _myMeshDS->SubMeshes();
+  while ( smIt->more() )
+    const_cast<SMESHDS_SubMesh*>( smIt->next() )->Clear();
+
   // 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))
@@ -231,6 +237,26 @@ bool SMESH_Mesh::MeshExists( int meshId ) const
   return _myDocument ? bool( _myDocument->GetMesh( meshId )) : false;
 }
 
+//================================================================================
+/*!
+ * \brief Return a mesh by id
+ */
+//================================================================================
+
+SMESH_Mesh* SMESH_Mesh::FindMesh( int meshId ) const
+{
+  if ( _id == meshId )
+    return (SMESH_Mesh*) this;
+
+  if ( StudyContextStruct *aStudyContext = _gen->GetStudyContext( _studyId ))
+  {
+    std::map < int, SMESH_Mesh * >::iterator i_m = aStudyContext->mapMesh.find( meshId );
+    if ( i_m != aStudyContext->mapMesh.end() )
+      return i_m->second;
+  }
+  return NULL;
+}
+
 //=============================================================================
 /*!
  * \brief Set geometry to be meshed
@@ -329,7 +355,16 @@ double SMESH_Mesh::GetShapeDiagonalSize(const TopoDS_Shape & aShape)
 {
   if ( !aShape.IsNull() ) {
     Bnd_Box Box;
-    GEOMUtils::PreciseBoundingBox(aShape, Box);
+    // avoid too long waiting on large shapes. PreciseBoundingBox() was added
+    // to assure same result which else depends on presence of triangulation (IPAL52557).
+    const int maxNbFaces = 4000;
+    int nbFaces = 0;
+    for ( TopExp_Explorer f( aShape, TopAbs_FACE ); f.More() && nbFaces < maxNbFaces; f.Next() )
+      ++nbFaces;
+    if ( nbFaces < maxNbFaces )
+      GEOMUtils::PreciseBoundingBox(aShape, Box);
+    else
+      BRepBndLib::Add( aShape, Box);
     if ( !Box.IsVoid() )
       return sqrt( Box.SquareExtent() );
   }
@@ -717,7 +752,7 @@ SMESH_Hypothesis::Hypothesis_Status
   // shape 
   
   bool isAlgo = ( !anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO );
-  int event = isAlgo ? SMESH_subMesh::REMOVE_ALGO : SMESH_subMesh::REMOVE_HYP;
+  int   event = isAlgo ? SMESH_subMesh::REMOVE_ALGO : SMESH_subMesh::REMOVE_HYP;
 
   SMESH_subMesh *subMesh = GetSubMesh(aSubShape);
 
@@ -1082,7 +1117,7 @@ throw(SALOME_Exception)
 
 //================================================================================
 /*!
- * \brief Return submeshes of groups containing the given sub-shape
+ * \brief Return sub-meshes of groups containing the given sub-shape
  */
 //================================================================================
 
@@ -1096,8 +1131,8 @@ SMESH_Mesh::GetGroupSubMeshesContaining(const TopoDS_Shape & aSubShape) const
   if ( !subMesh )
     return found;
 
-  // submeshes of groups have max IDs, so search from the map end
-SMESH_subMeshIteratorPtr smIt( _subMeshHolder->GetIterator( /*reverse=*/true ) );
+  // sub-meshes of groups have max IDs, so search from the map end
+  SMESH_subMeshIteratorPtr smIt( _subMeshHolder->GetIterator( /*reverse=*/true ) );
   while ( smIt->more() ) {
     SMESH_subMesh*    sm = smIt->next();
     SMESHDS_SubMesh * ds = sm->GetSubMeshDS();
@@ -1123,6 +1158,12 @@ SMESH_subMeshIteratorPtr smIt( _subMeshHolder->GetIterator( /*reverse=*/true ) )
           found.push_back( mainSM );
       }
   }
+  else // issue 0023068
+  {
+    if ( SMESH_subMesh * mainSM = GetSubMeshContaining(1) )
+      if ( mainSM->GetSubShape().ShapeType() == TopAbs_COMPOUND )
+        found.push_back( mainSM );
+  }
   return found;
 }
 //=======================================================================
@@ -1215,7 +1256,8 @@ void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* h
     // other possible changes are not interesting. (IPAL0052457 - assigning hyp performance pb)
     if ( aSubMesh->GetComputeState() != SMESH_subMesh::COMPUTE_OK &&
          aSubMesh->GetComputeState() != SMESH_subMesh::FAILED_TO_COMPUTE &&
-         aSubMesh->GetAlgoState()    != SMESH_subMesh::MISSING_HYP )
+         aSubMesh->GetAlgoState()    != SMESH_subMesh::MISSING_HYP &&
+         !hyp->DataDependOnParams() )
       continue;
 
     const TopoDS_Shape & aSubShape = aSubMesh->GetSubShape();
@@ -1292,7 +1334,7 @@ bool SMESH_Mesh::HasModificationsToDiscard() const
   // return true if the next Compute() will be partial and
   // existing but changed elements may prevent successful re-compute
   bool hasComputed = false, hasNotComputed = false;
-SMESH_subMeshIteratorPtr smIt( _subMeshHolder->GetIterator() );
+  SMESH_subMeshIteratorPtr smIt( _subMeshHolder->GetIterator() );
   while ( smIt->more() )
   {
     const SMESH_subMesh* aSubMesh = smIt->next();
@@ -1307,6 +1349,8 @@ SMESH_subMeshIteratorPtr smIt( _subMeshHolder->GetIterator() );
         hasNotComputed = true;
       if ( hasComputed && hasNotComputed)
         return true;
+
+    default:;
     }
   }
   if ( NbNodes() < 1 )
@@ -1536,7 +1580,8 @@ void SMESH_Mesh::ExportSTL(const char *        file,
 //================================================================================
 
 void SMESH_Mesh::ExportCGNS(const char *        file,
-                            const SMESHDS_Mesh* meshDS)
+                            const SMESHDS_Mesh* meshDS,
+                            const char *        meshName)
 {
   int res = Driver_Mesh::DRS_FAIL;
 #ifdef WITH_CGNS
@@ -1544,6 +1589,8 @@ void SMESH_Mesh::ExportCGNS(const char *        file,
   myWriter.SetFile( file );
   myWriter.SetMesh( const_cast<SMESHDS_Mesh*>( meshDS ));
   myWriter.SetMeshName( SMESH_Comment("Mesh_") << meshDS->GetPersistentId());
+  if ( meshName && meshName[0] )
+    myWriter.SetMeshName( meshName );
   res = myWriter.Perform();
 #endif
   if ( res != Driver_Mesh::DRS_OK )
@@ -1744,10 +1791,10 @@ int SMESH_Mesh::NbBiQuadQuadrangles() const throw(SALOME_Exception)
  */
 //================================================================================
 
-int SMESH_Mesh::NbPolygons() const throw(SALOME_Exception)
+int SMESH_Mesh::NbPolygons(SMDSAbs_ElementOrder order) const throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
-  return _myMeshDS->GetMeshInfo().NbPolygons();
+  return _myMeshDS->GetMeshInfo().NbPolygons(order);
 }
 
 //================================================================================
@@ -1870,6 +1917,18 @@ int SMESH_Mesh::NbSubMesh() const throw(SALOME_Exception)
   return _myMeshDS->NbSubMesh();
 }
 
+//================================================================================
+/*!
+ * \brief Returns number of meshes in the Study, that is supposed to be
+ *        equal to SMESHDS_Document::NbMeshes()
+ */
+//================================================================================
+
+int SMESH_Mesh::NbMeshes() const // nb meshes in the Study
+{
+  return _myDocument->NbMeshes();
+}
+
 //=======================================================================
 //function : IsNotConformAllowed
 //purpose  : check if a hypothesis alowing notconform mesh is present
@@ -1953,7 +2012,7 @@ SMESH_Group* SMESH_Mesh::AddGroup (SMESHDS_GroupBase* groupDS) throw(SALOME_Exce
 
 bool SMESH_Mesh::SynchronizeGroups()
 {
-  int nbGroups = _mapGroup.size();
+  size_t nbGroups = _mapGroup.size();
   const set<SMESHDS_GroupBase*>& groups = _myMeshDS->GetGroups();
   set<SMESHDS_GroupBase*>::const_iterator gIt = groups.begin();
   for ( ; gIt != groups.end(); ++gIt )
@@ -2065,11 +2124,11 @@ ostream& SMESH_Mesh::Dump(ostream& save)
 {
   int clause = 0;
   save << "========================== Dump contents of mesh ==========================" << endl << endl;
-  save << ++clause << ") Total number of nodes:   \t"    << NbNodes() << endl;
-  save << ++clause << ") Total number of edges:   \t"    << NbEdges() << endl;
-  save << ++clause << ") Total number of faces:   \t"    << NbFaces() << endl;
-  save << ++clause << ") Total number of polygons:\t"    << NbPolygons() << endl;
-  save << ++clause << ") Total number of volumes:\t"     << NbVolumes() << endl;
+  save << ++clause << ") Total number of nodes:      \t" << NbNodes() << endl;
+  save << ++clause << ") Total number of edges:      \t" << NbEdges() << endl;
+  save << ++clause << ") Total number of faces:      \t" << NbFaces() << endl;
+  save << ++clause << ") Total number of polygons:   \t" << NbPolygons() << endl;
+  save << ++clause << ") Total number of volumes:    \t" << NbVolumes() << endl;
   save << ++clause << ") Total number of polyhedrons:\t" << NbPolyhedrons() << endl << endl;
   for ( int isQuadratic = 0; isQuadratic < 2; ++isQuadratic )
   {
@@ -2104,10 +2163,10 @@ ostream& SMESH_Mesh::Dump(ostream& save)
       int nb4 = NbTetras(order);
       int nb5 = NbPyramids(order);
       int nb6 = NbPrisms(order);
-      save << clause << ".1) Number of " << orderStr << " hexahedrons:\t" << nb8 << endl;
+      save << clause << ".1) Number of " << orderStr << " hexahedrons: \t" << nb8 << endl;
       save << clause << ".2) Number of " << orderStr << " tetrahedrons:\t" << nb4 << endl;
       save << clause << ".3) Number of " << orderStr << " prisms:      \t" << nb6 << endl;
-      save << clause << ".4) Number of " << orderStr << " pyramids:\t" << nb5 << endl;
+      save << clause << ".4) Number of " << orderStr << " pyramids:    \t" << nb5 << endl;
       if ( nb8 + nb4 + nb5 + nb6 != NbVolumes(order) ) {
         map<int,int> myVolumesMap;
         SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator();
@@ -2153,9 +2212,9 @@ SMESH_Group* SMESH_Mesh::ConvertToStandalone ( int theGroupID )
     return aGroup;
 
   SMESH_Group* anOldGrp = (*itg).second;
-  SMESHDS_GroupBase* anOldGrpDS = anOldGrp->GetGroupDS();
-  if ( !anOldGrp || !anOldGrpDS )
+  if ( !anOldGrp || !anOldGrp->GetGroupDS() )
     return aGroup;
+  SMESHDS_GroupBase* anOldGrpDS = anOldGrp->GetGroupDS();
 
   // create new standalone group
   aGroup = new SMESH_Group (theGroupID, this, anOldGrpDS->GetType(), anOldGrp->GetName() );
@@ -2236,8 +2295,8 @@ void SMESH_Mesh::fillAncestorsMap(const TopoDS_Shape& theShape)
         TopTools_ListIteratorOfListOfShape ancIt (ancList);
         while ( ancIt.More() && ancIt.Value().ShapeType() >= memberType )
           ancIt.Next();
-        if ( ancIt.More() )
-          ancList.InsertBefore( theShape, ancIt );
+        if ( ancIt.More() ) ancList.InsertBefore( theShape, ancIt );
+        else                ancList.Append( theShape );
       }
   }
   else // else added for 52457: Addition of hypotheses is 8 time longer than meshing
index c603c6a41ad7ddb549bbb3cf3bcabcd16552e467..5221ab7d2d1506486b714f020e07a7b49c986240 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -169,8 +169,10 @@ class SMESH_EXPORT SMESH_Mesh
   
   bool MeshExists( int meshId ) const;
   
+  SMESH_Mesh* FindMesh( int meshId ) const;
+
   SMESHDS_Mesh * GetMeshDS() { return _myMeshDS; }
-  
+
   const SMESHDS_Mesh * GetMeshDS() const { return _myMeshDS; }
   
   SMESH_Gen *GetGen()        { return _gen; }
@@ -259,7 +261,8 @@ class SMESH_EXPORT SMESH_Mesh
                  const bool          isascii,
                  const SMESHDS_Mesh* meshPart = 0) throw(SALOME_Exception);
   void ExportCGNS(const char *        file,
-                  const SMESHDS_Mesh* mesh);
+                  const SMESHDS_Mesh* mesh,
+                  const char *        meshName = 0);
   void ExportGMF(const char *        file,
                  const SMESHDS_Mesh* mesh,
                  bool                withRequiredGroups = true );
@@ -280,7 +283,7 @@ class SMESH_EXPORT SMESH_Mesh
   int NbQuadrangles(SMDSAbs_ElementOrder order = ORDER_ANY) const throw(SALOME_Exception);
   int NbBiQuadQuadrangles() const throw(SALOME_Exception);
   int NbBiQuadTriangles() const throw(SALOME_Exception);
-  int NbPolygons() const throw(SALOME_Exception);
+  int NbPolygons(SMDSAbs_ElementOrder order = ORDER_ANY) const throw(SALOME_Exception);
   
   int NbVolumes(SMDSAbs_ElementOrder order = ORDER_ANY) const throw(SALOME_Exception);
   int NbTetras(SMDSAbs_ElementOrder order = ORDER_ANY) const throw(SALOME_Exception);
@@ -295,6 +298,8 @@ class SMESH_EXPORT SMESH_Mesh
   
   int NbGroup() const { return _mapGroup.size(); }
 
+  int NbMeshes() const; // nb meshes in the Study
+
   SMESH_Group* AddGroup (const SMDSAbs_ElementType theType,
                          const char*               theName,
                          int&                      theId,
@@ -353,7 +358,6 @@ protected:
   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;
index 08cc1d9c2338fe8f628a01af17d75fa9593bd045..645882b40e2b8e26d2bb2ca29f35c761dfe17bba 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -50,6 +50,7 @@
 #include <Basics_OCCTVersion.hxx>
 
 #include "utilities.h"
+#include "chrono.hxx"
 
 #include <BRepAdaptor_Surface.hxx>
 #include <BRepBuilderAPI_MakeEdge.hxx>
@@ -130,12 +131,46 @@ SMESH_MeshEditor::SMESH_MeshEditor( SMESH_Mesh* theMesh )
  */
 //================================================================================
 
-void SMESH_MeshEditor::CrearLastCreated()
+void SMESH_MeshEditor::ClearLastCreated()
 {
   myLastCreatedNodes.Clear();
   myLastCreatedElems.Clear();
 }
 
+//================================================================================
+/*!
+ * \brief Initializes members by an existing element
+ *  \param [in] elem - the source element
+ *  \param [in] basicOnly - if true, does not set additional data of Ball and Polyhedron
+ */
+//================================================================================
+
+SMESH_MeshEditor::ElemFeatures&
+SMESH_MeshEditor::ElemFeatures::Init( const SMDS_MeshElement* elem, bool basicOnly )
+{
+  if ( elem )
+  {
+    myType = elem->GetType();
+    if ( myType == SMDSAbs_Face || myType == SMDSAbs_Volume )
+    {
+      myIsPoly = elem->IsPoly();
+      if ( myIsPoly )
+      {
+        myIsQuad = elem->IsQuadratic();
+        if ( myType == SMDSAbs_Volume && !basicOnly )
+        {
+          vector<int > quant = static_cast<const SMDS_VtkVolume* >( elem )->GetQuantities();
+          myPolyhedQuantities.swap( quant );
+        }
+      }
+    }
+    else if ( myType == SMDSAbs_Ball && !basicOnly )
+    {
+      myBallDiameter = static_cast<const SMDS_BallElement*>(elem)->GetDiameter();
+    }
+  }
+  return *this;
+}
 
 //=======================================================================
 /*!
@@ -145,18 +180,16 @@ void SMESH_MeshEditor::CrearLastCreated()
 
 SMDS_MeshElement*
 SMESH_MeshEditor::AddElement(const vector<const SMDS_MeshNode*> & node,
-                             const SMDSAbs_ElementType            type,
-                             const bool                           isPoly,
-                             const int                            ID,
-                             const double                         ballDiameter)
+                             const ElemFeatures&                  features)
 {
-  //MESSAGE("AddElement " <<node.size() << " " << type << " " << isPoly << " " << ID);
   SMDS_MeshElement* e = 0;
   int nbnode = node.size();
   SMESHDS_Mesh* mesh = GetMeshDS();
-  switch ( type ) {
+  const int ID = features.myID;
+
+  switch ( features.myType ) {
   case SMDSAbs_Face:
-    if ( !isPoly ) {
+    if ( !features.myIsPoly ) {
       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] );
@@ -189,14 +222,21 @@ SMESH_MeshEditor::AddElement(const vector<const SMDS_MeshNode*> & node,
         else           e = mesh->AddFace      (node[0], node[1], node[2], node[3],
                                                node[4], node[5], node[6], node[7], node[8] );
       }
-    } else {
+    }
+    else if ( !features.myIsQuad )
+    {
       if ( ID >= 1 ) e = mesh->AddPolygonalFaceWithID(node, ID);
       else           e = mesh->AddPolygonalFace      (node    );
     }
+    else if ( nbnode % 2 == 0 ) // just a protection
+    {
+      if ( ID >= 1 ) e = mesh->AddQuadPolygonalFaceWithID(node, ID);
+      else           e = mesh->AddQuadPolygonalFace      (node    );
+    }
     break;
 
   case SMDSAbs_Volume:
-    if ( !isPoly ) {
+    if ( !features.myIsPoly ) {
       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] );
@@ -284,6 +324,16 @@ SMESH_MeshEditor::AddElement(const vector<const SMDS_MeshNode*> & node,
                                                  node[24],node[25],node[26] );
       }
     }
+    else if ( !features.myIsQuad )
+    {
+      if ( ID >= 1 ) e = mesh->AddPolyhedralVolumeWithID(node, features.myPolyhedQuantities, ID);
+      else           e = mesh->AddPolyhedralVolume      (node, features.myPolyhedQuantities    );
+    }
+    else
+    {
+      // if ( ID >= 1 ) e = mesh->AddQuadPolyhedralVolumeWithID(node, features.myPolyhedQuantities,ID);
+      // else           e = mesh->AddQuadPolyhedralVolume      (node, features.myPolyhedQuantities   );
+    }
     break;
 
   case SMDSAbs_Edge:
@@ -306,12 +356,12 @@ SMESH_MeshEditor::AddElement(const vector<const SMDS_MeshNode*> & node,
 
   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());
+    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);
+    if ( ID >= 1 ) e = mesh->AddBallWithID(node[0], features.myBallDiameter, ID);
+    else           e = mesh->AddBall      (node[0], features.myBallDiameter    );
     break;
 
   default:;
@@ -326,10 +376,8 @@ SMESH_MeshEditor::AddElement(const vector<const SMDS_MeshNode*> & node,
  */
 //=======================================================================
 
-SMDS_MeshElement* SMESH_MeshEditor::AddElement(const vector<int> &       nodeIDs,
-                                               const SMDSAbs_ElementType type,
-                                               const bool                isPoly,
-                                               const int                 ID)
+SMDS_MeshElement* SMESH_MeshEditor::AddElement(const vector<int> & nodeIDs,
+                                               const ElemFeatures& features)
 {
   vector<const SMDS_MeshNode*> nodes;
   nodes.reserve( nodeIDs.size() );
@@ -340,7 +388,7 @@ SMDS_MeshElement* SMESH_MeshEditor::AddElement(const vector<int> &       nodeIDs
     else
       return 0;
   }
-  return AddElement( nodes, type, isPoly, ID );
+  return AddElement( nodes, features );
 }
 
 //=======================================================================
@@ -1099,12 +1147,12 @@ bool SMESH_MeshEditor::Reorient (const SMDS_MeshElement * theElem)
   else // other elements
   {
     vector<const SMDS_MeshNode*> nodes( theElem->begin_nodes(), theElem->end_nodes() );
-    const std::vector<int>& interlace = SMDS_MeshCell::reverseSmdsOrder( geomType );
+    const std::vector<int>& interlace = SMDS_MeshCell::reverseSmdsOrder( geomType, nodes.size() );
     if ( interlace.empty() )
     {
-      std::reverse( nodes.begin(), nodes.end() ); // polygon
+      std::reverse( nodes.begin(), nodes.end() ); // obsolete, just in case
     }
-    else if ( interlace.size() > 1 )
+    else
     {
       SMDS_MeshCell::applyInterlace( interlace, nodes );
     }
@@ -1277,7 +1325,7 @@ int SMESH_MeshEditor::Reorient2DBy3D (TIDSortedElemSet & theFaces,
     if ( face->GetType() != SMDSAbs_Face )
       continue;
 
-    const int nbCornersNodes = face->NbCornerNodes();
+    const size_t nbCornersNodes = face->NbCornerNodes();
     faceNodes.assign( face->begin_nodes(), face->end_nodes() );
 
     checkedVolumes.clear();
@@ -1293,7 +1341,7 @@ int SMESH_MeshEditor::Reorient2DBy3D (TIDSortedElemSet & theFaces,
 
       // is volume adjacent?
       bool allNodesCommon = true;
-      for ( int iN = 1; iN < nbCornersNodes && allNodesCommon; ++iN )
+      for ( size_t iN = 1; iN < nbCornersNodes && allNodesCommon; ++iN )
         allNodesCommon = ( volume->GetNodeIndex( faceNodes[ iN ]) > -1 );
       if ( !allNodesCommon )
         continue;
@@ -1313,7 +1361,7 @@ int SMESH_MeshEditor::Reorient2DBy3D (TIDSortedElemSet & theFaces,
       for ( int i = 0; i < 2; ++i )
       {
         const SMDS_MeshNode* n = facetNodes[ i*iQ ];
-        for ( int iN = 0; iN < nbCornersNodes; ++iN )
+        for ( size_t iN = 0; iN < nbCornersNodes; ++iN )
           if ( faceNodes[ iN ] == n )
           {
             iNN[ i ] = iN;
@@ -1877,7 +1925,7 @@ namespace
         if ( hasAdjacentSplits && method._nbSplits > 0 )
         {
           bool facetCreated = true;
-          for ( int iF = 0; facetCreated && iF < triaSplitsByFace.size(); ++iF )
+          for ( size_t iF = 0; facetCreated && iF < triaSplitsByFace.size(); ++iF )
           {
             list< TTriangleFacet >::const_iterator facet = triaSplitsByFace[iF].begin();
             for ( ; facetCreated && facet != triaSplitsByFace[iF].end(); ++facet )
@@ -2179,10 +2227,6 @@ namespace
 void SMESH_MeshEditor::SplitVolumes (const TFacetOfElem & 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()), fHelper(*GetMesh());
   fHelper.ToFixNodeParameters( true );
@@ -2195,6 +2239,7 @@ void SMESH_MeshEditor::SplitVolumes (const TFacetOfElem & theElems,
   // map face of volume to it's baricenrtic node
   map< TVolumeFaceKey, const SMDS_MeshNode* > volFace2BaryNode;
   double bc[3];
+  vector<const SMDS_MeshElement* > splitVols;
 
   TFacetOfElem::const_iterator elem2facet = theElems.begin();
   for ( ; elem2facet != theElems.end(); ++elem2facet )
@@ -2270,7 +2315,7 @@ void SMESH_MeshEditor::SplitVolumes (const TFacetOfElem & theElems,
     }
 
     // make new volumes
-    vector<const SMDS_MeshElement* > splitVols( splitMethod._nbSplits ); // splits of a volume
+    splitVols.resize( splitMethod._nbSplits ); // splits of a volume
     const int* volConn = splitMethod._connectivity;
     if ( splitMethod._nbCorners == 4 ) // tetra
       for ( int i = 0; i < splitMethod._nbSplits; ++i, volConn += splitMethod._nbCorners )
@@ -2387,12 +2432,12 @@ void SMESH_MeshEditor::SplitVolumes (const TFacetOfElem & theElems,
                                                  volNodes[ facet->_n3 ]));
           }
         }
-        for ( int i = 0; i < triangles.size(); ++i )
+        for ( size_t i = 0; i < triangles.size(); ++i )
         {
-          if ( !triangles[i] ) continue;
+          if ( !triangles[ i ]) continue;
           if ( fSubMesh )
-            fSubMesh->AddElement( triangles[i]);
-          newElems.Append( triangles[i] );
+            fSubMesh->AddElement( triangles[ i ]);
+          newElems.Append( triangles[ i ]);
         }
         ReplaceElemInGroups( face, triangles, GetMeshDS() );
         GetMeshDS()->RemoveFreeElement( face, fSubMesh, /*fromGroups=*/false );
@@ -2410,7 +2455,7 @@ void SMESH_MeshEditor::SplitVolumes (const TFacetOfElem & theElems,
           GetMeshDS()->RemoveNode( volNodes[i] );
     }
   } // loop on volumes to split
-  
+
   myLastCreatedNodes = newNodes;
   myLastCreatedElems = newElems;
 }
@@ -2485,7 +2530,7 @@ void SMESH_MeshEditor::GetHexaFacetsToSplit( TIDSortedElemSet& theHexas,
   set<const SMDS_MeshNode*> facetNodes;
   const SMDS_MeshElement*   curHex;
 
-  const bool allHex = ( theHexas.size() == myMesh->NbHexas() );
+  const bool allHex = ((int) theHexas.size() == myMesh->NbHexas() );
 
   while ( startHex )
   {
@@ -2575,7 +2620,7 @@ void SMESH_MeshEditor::GetHexaFacetsToSplit( TIDSortedElemSet& theHexas,
 
       startHex = curHex;
 
-      // find a facet of startHex to split 
+      // find a facet of startHex to split
 
       set<const SMDS_MeshNode*> lateralNodes;
       vTool.GetFaceNodes( lateralFacet, lateralNodes );
@@ -2605,6 +2650,188 @@ void SMESH_MeshEditor::GetHexaFacetsToSplit( TIDSortedElemSet& theHexas,
         throw SALOME_Exception( THIS_METHOD "facet of a new startHex not found");
     }
   } //   while ( startHex )
+
+  return;
+}
+
+namespace
+{
+  //================================================================================
+  /*!
+   * \brief Selects nodes of several elements according to a given interlace
+   *  \param [in] srcNodes - nodes to select from
+   *  \param [out] tgtNodesVec - array of nodes of several elements to fill in
+   *  \param [in] interlace - indices of nodes for all elements
+   *  \param [in] nbElems - nb of elements
+   *  \param [in] nbNodes - nb of nodes in each element
+   *  \param [in] mesh - the mesh
+   *  \param [out] elemQueue - a list to push elements found by the selected nodes
+   *  \param [in] type - type of elements to look for
+   */
+  //================================================================================
+
+  void selectNodes( const vector< const SMDS_MeshNode* >& srcNodes,
+                    vector< const SMDS_MeshNode* >*       tgtNodesVec,
+                    const int*                            interlace,
+                    const int                             nbElems,
+                    const int                             nbNodes,
+                    SMESHDS_Mesh*                         mesh = 0,
+                    list< const SMDS_MeshElement* >*      elemQueue=0,
+                    SMDSAbs_ElementType                   type=SMDSAbs_All)
+  {
+    for ( int iE = 0; iE < nbElems; ++iE )
+    {
+      vector< const SMDS_MeshNode* >& elemNodes = tgtNodesVec[iE];
+      const int*                         select = & interlace[iE*nbNodes];
+      elemNodes.resize( nbNodes );
+      for ( int iN = 0; iN < nbNodes; ++iN )
+        elemNodes[iN] = srcNodes[ select[ iN ]];
+    }
+    const SMDS_MeshElement* e;
+    if ( elemQueue )
+      for ( int iE = 0; iE < nbElems; ++iE )
+        if (( e = mesh->FindElement( tgtNodesVec[iE], type, /*noMedium=*/false)))
+          elemQueue->push_back( e );
+  }
+}
+
+//=======================================================================
+/*
+ * Split bi-quadratic elements into linear ones without creation of additional nodes
+ *   - bi-quadratic triangle will be split into 3 linear quadrangles;
+ *   - bi-quadratic quadrangle will be split into 4 linear quadrangles;
+ *   - tri-quadratic hexahedron will be split into 8 linear hexahedra;
+ *   Quadratic elements of lower dimension  adjacent to the split bi-quadratic element
+ *   will be split in order to keep the mesh conformal.
+ *  \param elems - elements to split
+ */
+//=======================================================================
+
+void SMESH_MeshEditor::SplitBiQuadraticIntoLinear(TIDSortedElemSet& theElems)
+{
+  vector< const SMDS_MeshNode* > elemNodes(27), subNodes[12], splitNodes[8];
+  vector<const SMDS_MeshElement* > splitElems;
+  list< const SMDS_MeshElement* > elemQueue;
+  list< const SMDS_MeshElement* >::iterator elemIt;
+
+  SMESHDS_Mesh * mesh = GetMeshDS();
+  ElemFeatures *elemType, hexaType(SMDSAbs_Volume), quadType(SMDSAbs_Face), segType(SMDSAbs_Edge);
+  int nbElems, nbNodes;
+
+  TIDSortedElemSet::iterator elemSetIt = theElems.begin();
+  for ( ; elemSetIt != theElems.end(); ++elemSetIt )
+  {
+    elemQueue.clear();
+    elemQueue.push_back( *elemSetIt );
+    for ( elemIt = elemQueue.begin(); elemIt != elemQueue.end(); ++elemIt )
+    {
+      const SMDS_MeshElement* elem = *elemIt;
+      switch( elem->GetEntityType() )
+      {
+      case SMDSEntity_TriQuad_Hexa: // HEX27
+      {
+        elemNodes.assign( elem->begin_nodes(), elem->end_nodes() );
+        nbElems  = nbNodes = 8;
+        elemType = & hexaType;
+
+        // get nodes for new elements
+        static int vInd[8][8] = {{ 0,8,20,11,   16,21,26,24 },
+                                 { 1,9,20,8,    17,22,26,21 },
+                                 { 2,10,20,9,   18,23,26,22 },
+                                 { 3,11,20,10,  19,24,26,23 },
+                                 { 16,21,26,24, 4,12,25,15  },
+                                 { 17,22,26,21, 5,13,25,12  },
+                                 { 18,23,26,22, 6,14,25,13  },
+                                 { 19,24,26,23, 7,15,25,14  }};
+        selectNodes( elemNodes, & splitNodes[0], &vInd[0][0], nbElems, nbNodes );
+
+        // add boundary faces to elemQueue
+        static int fInd[6][9] = {{ 0,1,2,3, 8,9,10,11,   20 },
+                                 { 4,5,6,7, 12,13,14,15, 25 },
+                                 { 0,1,5,4, 8,17,12,16,  21 },
+                                 { 1,2,6,5, 9,18,13,17,  22 },
+                                 { 2,3,7,6, 10,19,14,18, 23 },
+                                 { 3,0,4,7, 11,16,15,19, 24 }};
+        selectNodes( elemNodes, & subNodes[0], &fInd[0][0], 6,9, mesh, &elemQueue, SMDSAbs_Face );
+
+        // add boundary segments to elemQueue
+        static int eInd[12][3] = {{ 0,1,8 }, { 1,2,9 }, { 2,3,10 }, { 3,0,11 },
+                                  { 4,5,12}, { 5,6,13}, { 6,7,14 }, { 7,4,15 },
+                                  { 0,4,16}, { 1,5,17}, { 2,6,18 }, { 3,7,19 }};
+        selectNodes( elemNodes, & subNodes[0], &eInd[0][0], 12,3, mesh, &elemQueue, SMDSAbs_Edge );
+        break;
+      }
+      case SMDSEntity_BiQuad_Triangle: // TRIA7
+      {
+        elemNodes.assign( elem->begin_nodes(), elem->end_nodes() );
+        nbElems = 3;
+        nbNodes = 4;
+        elemType = & quadType;
+
+        // get nodes for new elements
+        static int fInd[3][4] = {{ 0,3,6,5 }, { 1,4,6,3 }, { 2,5,6,4 }};
+        selectNodes( elemNodes, & splitNodes[0], &fInd[0][0], nbElems, nbNodes );
+
+        // add boundary segments to elemQueue
+        static int eInd[3][3] = {{ 0,1,3 }, { 1,2,4 }, { 2,0,5 }};
+        selectNodes( elemNodes, & subNodes[0], &eInd[0][0], 3,3, mesh, &elemQueue, SMDSAbs_Edge );
+        break;
+      }
+      case SMDSEntity_BiQuad_Quadrangle: // QUAD9
+      {
+        elemNodes.assign( elem->begin_nodes(), elem->end_nodes() );
+        nbElems = 4;
+        nbNodes = 4;
+        elemType = & quadType;
+
+        // get nodes for new elements
+        static int fInd[4][4] = {{ 0,4,8,7 }, { 1,5,8,4 }, { 2,6,8,5 }, { 3,7,8,6 }};
+        selectNodes( elemNodes, & splitNodes[0], &fInd[0][0], nbElems, nbNodes );
+
+        // add boundary segments to elemQueue
+        static int eInd[4][3] = {{ 0,1,4 }, { 1,2,5 }, { 2,3,6 }, { 3,0,7 }};
+        selectNodes( elemNodes, & subNodes[0], &eInd[0][0], 4,3, mesh, &elemQueue, SMDSAbs_Edge );
+        break;
+      }
+      case SMDSEntity_Quad_Edge:
+      {
+        if ( elemIt == elemQueue.begin() )
+          continue; // an elem is in theElems
+        elemNodes.assign( elem->begin_nodes(), elem->end_nodes() );
+        nbElems = 2;
+        nbNodes = 2;
+        elemType = & segType;
+
+        // get nodes for new elements
+        static int eInd[2][2] = {{ 0,2 }, { 2,1 }};
+        selectNodes( elemNodes, & splitNodes[0], &eInd[0][0], nbElems, nbNodes );
+        break;
+      }
+      default: continue;
+      } // switch( elem->GetEntityType() )
+
+      // Create new elements
+
+      SMESHDS_SubMesh* subMesh = mesh->MeshElements( elem->getshapeId() );
+
+      splitElems.clear();
+
+      //elemType->SetID( elem->GetID() ); // create an elem with the same ID as a removed one
+      mesh->RemoveFreeElement( elem, subMesh, /*fromGroups=*/false );
+      //splitElems.push_back( AddElement( splitNodes[ 0 ], *elemType ));
+      //elemType->SetID( -1 );
+
+      for ( int iE = 0; iE < nbElems; ++iE )
+        splitElems.push_back( AddElement( splitNodes[ iE ], *elemType ));
+
+
+      ReplaceElemInGroups( elem, splitElems, mesh );
+
+      if ( subMesh )
+        for ( size_t i = 0; i < splitElems.size(); ++i )
+          subMesh->AddElement( splitElems[i] );
+    }
+  }
 }
 
 //=======================================================================
@@ -2686,7 +2913,7 @@ void SMESH_MeshEditor::ReplaceElemInGroups (const SMDS_MeshElement*
     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 )
+        for ( size_t i = 0; i < elemToAdd.size(); ++i )
           group->SMDSGroup().Add( elemToAdd[ i ] );
     }
   }
@@ -2748,7 +2975,6 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems,
         }
       AddToSameGroups( newElem1, elem, aMesh );
       AddToSameGroups( newElem2, elem, aMesh );
-      //aMesh->RemoveFreeElement(elem, aMesh->MeshElements(aShapeId), true);
       aMesh->RemoveElement( elem );
     }
 
@@ -3771,16 +3997,20 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet &          theElems,
   // smooth elements on each TopoDS_Face separately
   // ===============================================
 
-  set< int >::reverse_iterator fId = faceIdSet.rbegin(); // treate 0 fId at the end
-  for ( ; fId != faceIdSet.rend(); ++fId ) {
+  SMESH_MesherHelper helper( *GetMesh() );
+
+  set< int >::reverse_iterator fId = faceIdSet.rbegin(); // treat 0 fId at the end
+  for ( ; fId != faceIdSet.rend(); ++fId )
+  {
     // get face surface and submesh
     Handle(Geom_Surface) surface;
     SMESHDS_SubMesh* faceSubMesh = 0;
     TopoDS_Face face;
-    double fToler2 = 0, f,l;
+    double fToler2 = 0;
     double u1 = 0, u2 = 0, v1 = 0, v2 = 0;
     bool isUPeriodic = false, isVPeriodic = false;
-    if ( *fId ) {
+    if ( *fId )
+    {
       face = TopoDS::Face( aMesh->IndexToShape( *fId ));
       surface = BRep_Tool::Surface( face );
       faceSubMesh = aMesh->MeshElements( *fId );
@@ -3793,6 +4023,7 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet &          theElems,
       if ( isVPeriodic )
         surface->VPeriod();
       surface->Bounds( u1, u2, v1, v2 );
+      helper.SetSubShape( face );
     }
     // ---------------------------------------------------------
     // for elements on a face, find movable and fixed nodes and
@@ -3814,7 +4045,8 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet &          theElems,
     int nbElemOnFace = 0;
     itElem = theElems.begin();
     // loop on not yet smoothed elements: look for elems on a face
-    while ( itElem != theElems.end() ) {
+    while ( itElem != theElems.end() )
+    {
       if ( faceSubMesh && nbElemOnFace == faceSubMesh->NbElements() )
         break; // all elements found
 
@@ -3870,12 +4102,15 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet &          theElems,
 
       // get nodes to check UV
       list< const SMDS_MeshNode* > uvCheckNodes;
+      const SMDS_MeshNode* nodeInFace = 0;
       itN = elem->nodesIterator();
       nn = 0; nbn =  elem->NbNodes();
       if(elem->IsQuadratic())
         nbn = nbn/2;
       while ( nn++ < nbn ) {
         node = static_cast<const SMDS_MeshNode*>( itN->next() );
+        if ( node->GetPosition()->GetDim() == 2 )
+          nodeInFace = node;
         if ( uvMap.find( node ) == uvMap.end() )
           uvCheckNodes.push_back( node );
         // add nodes of elems sharing node
@@ -3901,41 +4136,21 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet &          theElems,
         const SMDS_PositionPtr& pos = node->GetPosition();
         posType = pos ? pos->GetTypeOfPosition() : SMDS_TOP_3DSPACE;
         // get existing UV
-        switch ( posType ) {
-        case SMDS_TOP_FACE: {
-          SMDS_FacePosition* fPos = ( SMDS_FacePosition* ) pos;
-          uv.SetCoord( fPos->GetUParameter(), fPos->GetVParameter() );
-          break;
-        }
-        case SMDS_TOP_EDGE: {
-          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 )->GetUParameter();
-            uv = pcurve->Value( u ).XY();
-          }
-          break;
-        }
-        case SMDS_TOP_VERTEX: {
-          TopoDS_Shape S = aMesh->IndexToShape( node->getshapeId() );
-          if ( !S.IsNull() && S.ShapeType() == TopAbs_VERTEX )
-            uv = BRep_Tool::Parameters( TopoDS::Vertex( S ), face ).XY();
-          break;
-        }
-        default:;
-        }
-        // check existing UV
-        bool project = true;
-        gp_Pnt pNode ( node->X(), node->Y(), node->Z() );
-        double dist1 = DBL_MAX, dist2 = 0;
-        if ( posType != SMDS_TOP_3DSPACE ) {
-          dist1 = pNode.SquareDistance( surface->Value( uv.X(), uv.Y() ));
-          project = dist1 > fToler2;
-        }
+        if ( pos )
+        {
+          bool toCheck = true;
+          uv = helper.GetNodeUV( face, node, nodeInFace, &toCheck );
+        }
+        // compute not existing UV
+        bool project = ( posType == SMDS_TOP_3DSPACE );
+        // double dist1 = DBL_MAX, dist2 = 0;
+        // if ( posType != SMDS_TOP_3DSPACE ) {
+        //   dist1 = pNode.SquareDistance( surface->Value( uv.X(), uv.Y() ));
+        //   project = dist1 > fToler2;
+        // }
         if ( project ) { // compute new UV
           gp_XY newUV;
+          gp_Pnt pNode = SMESH_TNodeXYZ( node );
           if ( !getClosestUV( projector, pNode, newUV )) {
             MESSAGE("Node Projection Failed " << node);
           }
@@ -3945,9 +4160,9 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet &          theElems,
             if ( isVPeriodic )
               newUV.SetY( ElCLib::InPeriod( newUV.Y(), v1, v2 ));
             // check new UV
-            if ( posType != SMDS_TOP_3DSPACE )
-              dist2 = pNode.SquareDistance( surface->Value( newUV.X(), newUV.Y() ));
-            if ( dist2 < dist1 )
+            // if ( posType != SMDS_TOP_3DSPACE )
+            //   dist2 = pNode.SquareDistance( surface->Value( newUV.X(), newUV.Y() ));
+            // if ( dist2 < dist1 )
               uv = newUV;
           }
         }
@@ -4015,9 +4230,8 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet &          theElems,
         uv2 = pcurve->Value( f );
         int iPar = Abs( uv1.X() - uv2.X() ) > Abs( uv1.Y() - uv2.Y() ) ? 1 : 2;
         // assure uv1 < uv2
-        if ( uv1.Coord( iPar ) > uv2.Coord( iPar )) {
-          gp_Pnt2d tmp = uv1; uv1 = uv2; uv2 = tmp;
-        }
+        if ( uv1.Coord( iPar ) > uv2.Coord( iPar ))
+          std::swap( uv1, uv2 );
         // get nodes on seam and its vertices
         list< const SMDS_MeshNode* > seamNodes;
         SMDS_NodeIteratorPtr nSeamIt = sm->GetNodes();
@@ -4067,12 +4281,14 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet &          theElems,
                   setMovableNodes.find( n ) == setMovableNodes.end() )
                 continue;
               // add only nodes being closer to uv2 than to uv1
-              gp_Pnt pMid (0.5 * ( n->X() + nSeam->X() ),
-                           0.5 * ( n->Y() + nSeam->Y() ),
-                           0.5 * ( n->Z() + nSeam->Z() ));
-              gp_XY uv;
-              getClosestUV( projector, pMid, uv );
-              if ( uv.Coord( iPar ) > uvMap[ n ]->Coord( iPar ) ) {
+              // gp_Pnt pMid (0.5 * ( n->X() + nSeam->X() ),
+              //              0.5 * ( n->Y() + nSeam->Y() ),
+              //              0.5 * ( n->Z() + nSeam->Z() ));
+              // gp_XY uv;
+              // getClosestUV( projector, pMid, uv );
+              double x = uvMap[ n ]->Coord( iPar );
+              if ( Abs( uv1.Coord( iPar ) - x ) >
+                   Abs( uv2.Coord( iPar ) - x )) {
                 nodesNearSeam.insert( n );
                 nbUseMap2++;
               }
@@ -4181,8 +4397,6 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet &          theElems,
     // move medium nodes of quadratic elements
     if ( isQuadratic )
     {
-      SMESH_MesherHelper helper( *GetMesh() );
-      helper.SetSubShape( face );
       vector<const SMDS_MeshNode*> nodes;
       bool checkUV;
       list< const SMDS_MeshElement* >::iterator elemIt = elemsOnFace.begin();
@@ -4219,26 +4433,49 @@ 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.
-//           If result is true then future volume orientation is OK
-//=======================================================================
-
-static bool isReverse(const SMDS_MeshElement*             face,
-                      const vector<const SMDS_MeshNode*>& prevNodes,
-                      const vector<const SMDS_MeshNode*>& nextNodes,
-                      const int                           iNotSame)
+namespace
 {
+  //=======================================================================
+  //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.
+  //           If result is true then future volume orientation is OK
+  //=======================================================================
+
+  bool isReverse(const SMDS_MeshElement*             face,
+                 const vector<const SMDS_MeshNode*>& prevNodes,
+                 const vector<const SMDS_MeshNode*>& nextNodes,
+                 const int                           iNotSame)
+  {
+
+    SMESH_TNodeXYZ pP = prevNodes[ iNotSame ];
+    SMESH_TNodeXYZ pN = nextNodes[ iNotSame ];
+    gp_XYZ extrDir( pN - pP ), faceNorm;
+    SMESH_MeshAlgos::FaceNormal( face, faceNorm, /*normalized=*/false );
 
-  SMESH_TNodeXYZ pP = prevNodes[ iNotSame ];
-  SMESH_TNodeXYZ pN = nextNodes[ iNotSame ];
-  gp_XYZ extrDir( pN - pP ), faceNorm;
-  SMESH_MeshAlgos::FaceNormal( face, faceNorm, /*normalized=*/false );
+    return faceNorm * extrDir < 0.0;
+  }
+
+  //================================================================================
+  /*!
+   * \brief Assure that theElemSets[0] holds elements, not nodes
+   */
+  //================================================================================
 
-  return faceNorm * extrDir < 0.0;
+  void setElemsFirst( TIDSortedElemSet theElemSets[2] )
+  {
+    if ( !theElemSets[0].empty() &&
+         (*theElemSets[0].begin())->GetType() == SMDSAbs_Node )
+    {
+      std::swap( theElemSets[0], theElemSets[1] );
+    }
+    else if ( !theElemSets[1].empty() &&
+              (*theElemSets[1].begin())->GetType() != SMDSAbs_Node )
+    {
+      std::swap( theElemSets[0], theElemSets[1] );
+    }
+  }
 }
 
 //=======================================================================
@@ -4255,7 +4492,7 @@ static bool isReverse(const SMDS_MeshElement*             face,
 void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement*               elem,
                                     const vector<TNodeOfNodeListMapItr> & newNodesItVec,
                                     list<const SMDS_MeshElement*>&        newElems,
-                                    const int                             nbSteps,
+                                    const size_t                          nbSteps,
                                     SMESH_SequenceOfElemPtr&              srcElements)
 {
   //MESSAGE("sweepElement " << nbSteps);
@@ -4318,7 +4555,7 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement*               elem,
     }
     else
     {
-      const vector<int>& ind = SMDS_MeshCell::reverseSmdsOrder( baseType );
+      const vector<int>& ind = SMDS_MeshCell::reverseSmdsOrder( baseType, nbNodes );
       SMDS_MeshCell::applyInterlace( ind, itNN );
       SMDS_MeshCell::applyInterlace( ind, prevNod );
       SMDS_MeshCell::applyInterlace( ind, nextNod );
@@ -4338,6 +4575,30 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement*               elem,
       }
     }
   }
+  else if ( elem->GetType() == SMDSAbs_Edge )
+  {
+    // orient a new face same as adjacent one
+    int i1, i2;
+    const SMDS_MeshElement* e;
+    TIDSortedElemSet dummy;
+    if (( e = SMESH_MeshAlgos::FindFaceInSet( nextNod[0], prevNod[0], dummy,dummy, &i1, &i2 )) ||
+        ( e = SMESH_MeshAlgos::FindFaceInSet( prevNod[1], nextNod[1], dummy,dummy, &i1, &i2 )) ||
+        ( e = SMESH_MeshAlgos::FindFaceInSet( prevNod[0], prevNod[1], dummy,dummy, &i1, &i2 )))
+    {
+      // there is an adjacent face, check order of nodes in it
+      bool sameOrder = ( Abs( i2 - i1 ) == 1 ) ? ( i2 > i1 ) : ( i2 < i1 );
+      if ( sameOrder )
+      {
+        std::swap( itNN[0],    itNN[1] );
+        std::swap( prevNod[0], prevNod[1] );
+        std::swap( nextNod[0], nextNod[1] );
+        isSingleNode.swap( isSingleNode[0], isSingleNode[1] );
+        if ( nbSame > 0 )
+          sames[0] = 1 - sames[0];
+        iNotSameNode = 1 - iNotSameNode;
+      }
+    }
+  }
 
   int iSameNode = 0, iBeforeSame = 0, iAfterSame = 0, iOpposSame = 0;
   if ( nbSame > 0 ) {
@@ -4347,8 +4608,19 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement*               elem,
     iOpposSame   = ( iSameNode - 2 < 0  ? iSameNode + 2 : iSameNode - 2 );
   }
 
+  if ( baseType == SMDSEntity_Polygon )
+  {
+    if      ( nbNodes == 3 ) baseType = SMDSEntity_Triangle;
+    else if ( nbNodes == 4 ) baseType = SMDSEntity_Quadrangle;
+  }
+  else if ( baseType == SMDSEntity_Quad_Polygon )
+  {
+    if      ( nbNodes == 6 ) baseType = SMDSEntity_Quad_Triangle;
+    else if ( nbNodes == 8 ) baseType = SMDSEntity_Quad_Quadrangle;
+  }
+
   // make new elements
-  for (int iStep = 0; iStep < nbSteps; iStep++ )
+  for ( size_t iStep = 0; iStep < nbSteps; iStep++ )
   {
     // get next nodes
     for ( iNode = 0; iNode < nbNodes; iNode++ )
@@ -4443,11 +4715,11 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement*               elem,
                 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]);
+                aNewElem = aMesh->AddFace(prevNod[0], prevNod[1], nextNod[1],
+                                          prevNod[2], midlNod[1], nextNod[2] );
               else // sames[0]==1
-                aNewElem = aMesh->AddFace(prevNod[0], nextNod[0], prevNod[1],
-                                          midlNod[0], nextNod[2], prevNod[2]);
+                aNewElem = aMesh->AddFace(prevNod[0], prevNod[1], nextNod[0],
+                                          prevNod[2], nextNod[2], midlNod[0]);
             }
           }
           else if ( nbDouble == 3 )
@@ -4492,7 +4764,7 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement*               elem,
         break;
       }
       case SMDSEntity_Quad_Triangle:  // sweep (Bi)Quadratic TRIANGLE --->
-      case SMDSEntity_BiQuad_Triangle: /* ??? */ { 
+      case SMDSEntity_BiQuad_Triangle: /* ??? */ {
         if ( nbDouble+nbSame != 3 ) break;
         if(nbSame==0) {
           // --->  pentahedron with 15 nodes
@@ -4544,7 +4816,7 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement*               elem,
         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" );
+          //INFOS( " Sweep for face " << elem->GetID() << " can not be created" );
           return;
         }
         else if( nbSame == 2 ) {
@@ -4613,14 +4885,14 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement*               elem,
 
       default:
         break;
-      }
-    }
+      } // switch ( baseType )
+    } // scope
 
     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);
+        const std::vector<int>& ind = SMDS_MeshCell::interlacedSmdsOrder(baseType,nbNodes);
         SMDS_MeshCell::applyInterlace( ind, prevNod );
         SMDS_MeshCell::applyInterlace( ind, nextNod );
         SMDS_MeshCell::applyInterlace( ind, midlNod );
@@ -4645,21 +4917,30 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement*               elem,
       quantities.push_back( nbNodes );
 
       // side faces
-      for (int iface = 0; iface < nbNodes; iface++)
+      // 3--6--2
+      // |     |
+      // 7     5
+      // |     |
+      // 0--4--1
+      const int iQuad = elem->IsQuadratic();
+      for (int iface = 0; iface < nbNodes; iface += 1+iQuad )
       {
-        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] )
+        const int prevNbNodes = polyedre_nodes.size(); // to detect degenerated face
+        int inextface = (iface+1+iQuad) % nbNodes;
+        int imid      = (iface+1) % nbNodes;
+        polyedre_nodes.push_back( prevNod[inextface] );         // 0
+        if ( iQuad ) polyedre_nodes.push_back( prevNod[imid] ); // 4
+        polyedre_nodes.push_back( prevNod[iface] );             // 1
+        if ( prevNod[iface] != nextNod[iface] ) // 1 != 2
         {
-          if ( midlNod[ iface ]) polyedre_nodes.push_back( midlNod[ iface ]);
-          polyedre_nodes.push_back( nextNod[iface] );
+          if ( midlNod[ iface ]) polyedre_nodes.push_back( midlNod[ iface ]); // 5
+          polyedre_nodes.push_back( nextNod[iface] );                         // 2
         }
-        if ( prevNod[inextface] != nextNod[inextface] )
+        if ( iQuad ) polyedre_nodes.push_back( nextNod[imid] );               // 6
+        if ( prevNod[inextface] != nextNod[inextface] ) // 0 != 3
         {
-          polyedre_nodes.push_back( nextNod[inextface] );
-          if ( midlNod[ inextface ]) polyedre_nodes.push_back( midlNod[ inextface ]);
+          polyedre_nodes.push_back( nextNod[inextface] );                            // 3
+          if ( midlNod[ inextface ]) polyedre_nodes.push_back( midlNod[ inextface ]);// 7
         }
         const int nbFaceNodes = polyedre_nodes.size() - prevNbNodes;
         if ( nbFaceNodes > 2 )
@@ -4668,7 +4949,8 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement*               elem,
           polyedre_nodes.resize( prevNbNodes );
       }
       aNewElem = aMesh->AddPolyhedralVolume (polyedre_nodes, quantities);
-    }
+
+    } // try to create a polyherdal prism
 
     if ( aNewElem ) {
       newElems.push_back( aNewElem );
@@ -4680,7 +4962,7 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement*               elem,
     for ( iNode = 0; iNode < nbNodes; iNode++ )
       prevNod[ iNode ] = nextNod[ iNode ];
 
-  } // for steps
+  } // loop on steps
 }
 
 //=======================================================================
@@ -4719,16 +5001,20 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap &     mapNewNodes,
     const SMDS_MeshElement* el = 0;
     SMDSAbs_ElementType highType = SMDSAbs_Edge; // count most complex elements only
     while ( eIt->more() && nbInitElems < 2 ) {
-      el = eIt->next();
-      SMDSAbs_ElementType type = el->GetType();
-      if ( type == SMDSAbs_Volume || type < highType ) continue;
+      const SMDS_MeshElement* e = eIt->next();
+      SMDSAbs_ElementType  type = e->GetType();
+      if ( type == SMDSAbs_Volume ||
+           type < highType ||
+           !elemSet.count(e))
+        continue;
       if ( type > highType ) {
         nbInitElems = 0;
-        highType = type;
+        highType    = type;
       }
-      nbInitElems += elemSet.count(el);
+      el = e;
+      ++nbInitElems;
     }
-    if ( nbInitElems < 2 ) {
+    if ( nbInitElems == 1 ) {
       bool NotCreateEdge = el && el->IsMediumNode(node);
       if(!NotCreateEdge) {
         vector<TNodeOfNodeListMapItr> newNodesItVec( 1, nList );
@@ -4741,6 +5027,8 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap &     mapNewNodes,
   // Make a ceiling for each element ie an equal element of last new nodes.
   // Find free links of faces - make edges and sweep them into faces.
 
+  ElemFeatures polyFace( SMDSAbs_Face, /*isPoly=*/true ), anyFace;
+
   TTElemOfElemListMap::iterator  itElem      = newElemsMap.begin();
   TElemOfVecOfNnlmiMap::iterator itElemNodes = elemNewNodesMap.begin();
   for ( ; itElem != newElemsMap.end(); itElem++, itElemNodes++ )
@@ -4844,7 +5132,7 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap &     mapNewNodes,
 
     // sweep free links into faces
 
-    if ( hasFreeLinks )  {
+    if ( hasFreeLinks ) {
       list<const SMDS_MeshElement*> & newVolumes = itElem->second;
       int iVol, volNb, nbVolumesByStep = newVolumes.size() / nbSteps;
 
@@ -4878,11 +5166,12 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap &     mapNewNodes,
             freeInd.push_back( iF );
             // find source edge of a free face iF
             vector<const SMDS_MeshNode*> commonNodes; // shared by the initial and free faces
-            commonNodes.resize( initNodeSet.size(), NULL ); // avoid spoiling memory
-            std::set_intersection( faceNodeSet.begin(), faceNodeSet.end(),
-                                   initNodeSet.begin(), initNodeSet.end(),
-                                   commonNodes.begin());
-            if ( (*v)->IsQuadratic() )
+            vector<const SMDS_MeshNode*>::iterator lastCommom;
+            commonNodes.resize( nbNodes, 0 );
+            lastCommom = std::set_intersection( faceNodeSet.begin(), faceNodeSet.end(),
+                                                initNodeSet.begin(), initNodeSet.end(),
+                                                commonNodes.begin());
+            if ( std::distance( commonNodes.begin(), lastCommom ) == 3 )
               srcEdges.push_back(aMesh->FindEdge (commonNodes[0],commonNodes[1],commonNodes[2]));
             else
               srcEdges.push_back(aMesh->FindEdge (commonNodes[0],commonNodes[1]));
@@ -4898,10 +5187,11 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap &     mapNewNodes,
         if ( freeInd.empty() )
           continue;
 
-        // create faces for all steps;
+        // create wall 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++ ) {
+        for ( int iStep = 0; iStep < nbSteps; iStep++ )
+        {
           vTool.Set( *v, /*ignoreCentralNodes=*/false );
           vTool.SetExternalNormal();
           const int nextShift = vTool.IsForward() ? +1 : -1;
@@ -5028,7 +5318,7 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap &     mapNewNodes,
                 if ( f )
                   aMesh->ChangeElementNodes( f, &polygon_nodes[0], nbn );
                 else
-                  AddElement(polygon_nodes, SMDSAbs_Face, polygon_nodes.size()>4);
+                  AddElement( polygon_nodes, polyFace.SetQuad( (*v)->IsQuadratic() ));
               }
             }
 
@@ -5055,36 +5345,20 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap &     mapNewNodes,
       aFaceLastNodes.erase( vecNewNodes.back()->second.back() );
       iF = lastVol.GetFaceIndex( aFaceLastNodes );
     }
-    if ( iF >= 0 ) {
+    if ( iF >= 0 )
+    {
       lastVol.SetExternalNormal();
       const SMDS_MeshNode** nodes = lastVol.GetFaceNodes( iF );
-      int nbn = lastVol.NbFaceNodes( iF );
-      // we do not use this->AddElement() because nodes are interlaced
+      const               int nbn = lastVol.NbFaceNodes( iF );
       vector<const SMDS_MeshNode*> nodeVec( nodes, nodes+nbn );
       if ( !hasFreeLinks ||
            !aMesh->FindElement( nodeVec, SMDSAbs_Face, /*noMedium=*/false) )
       {
-        if ( nbn == 3 )
-          myLastCreatedElems.Append(aMesh->AddFace( nodes[0], nodes[1], nodes[2] ));
-
-        else if ( nbn == 4 )
-          myLastCreatedElems.Append(aMesh->AddFace( nodes[0], nodes[1], nodes[2], nodes[3]));
-
-        else if ( nbn == 6 && isQuadratic )
-          myLastCreatedElems.Append(aMesh->AddFace( nodes[0], nodes[2], nodes[4],
-                                                    nodes[1], nodes[3], nodes[5]));
-        else if ( nbn == 7 && isQuadratic )
-          myLastCreatedElems.Append(aMesh->AddFace( nodes[0], nodes[2], nodes[4],
-                                                    nodes[1], nodes[3], nodes[5], nodes[6]));
-        else if ( nbn == 8 && isQuadratic )
-          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 )
-          myLastCreatedElems.Append(aMesh->AddFace( nodes[0], nodes[2], nodes[4], nodes[6],
-                                                    nodes[1], nodes[3], nodes[5], nodes[7],
-                                                    nodes[8]));
-        else
-          myLastCreatedElems.Append(aMesh->AddPolygonalFace( nodeVec ));
+        const vector<int>& interlace =
+          SMDS_MeshCell::interlacedSmdsOrder( elem->GetEntityType(), nbn );
+        SMDS_MeshCell::applyInterlaceRev( interlace, nodeVec );
+
+        AddElement( nodeVec, anyFace.Init( elem ));
 
         while ( srcElements.Length() < myLastCreatedElems.Length() )
           srcElements.Append( elem );
@@ -5099,7 +5373,7 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap &     mapNewNodes,
 //=======================================================================
 
 SMESH_MeshEditor::PGroupIDs
-SMESH_MeshEditor::RotationSweep(TIDSortedElemSet & theElems,
+SMESH_MeshEditor::RotationSweep(TIDSortedElemSet   theElemSets[2],
                                 const gp_Ax1&      theAxis,
                                 const double       theAngle,
                                 const int          theNbSteps,
@@ -5131,84 +5405,89 @@ SMESH_MeshEditor::RotationSweep(TIDSortedElemSet & theElems,
   const bool isQuadraticMesh = bool( myMesh->NbEdges(ORDER_QUADRATIC) +
                                      myMesh->NbFaces(ORDER_QUADRATIC) +
                                      myMesh->NbVolumes(ORDER_QUADRATIC) );
-  // loop on theElems
+  // loop on theElemSets
+  setElemsFirst( theElemSets );
   TIDSortedElemSet::iterator itElem;
-  for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
-    const SMDS_MeshElement* elem = *itElem;
-    if ( !elem || elem->GetType() == SMDSAbs_Volume )
-      continue;
-    vector<TNodeOfNodeListMapItr> & newNodesItVec = mapElemNewNodes[ elem ];
-    newNodesItVec.reserve( elem->NbNodes() );
+  for ( int is2ndSet = 0; is2ndSet < 2; ++is2ndSet )
+  {
+    TIDSortedElemSet& theElems = theElemSets[ is2ndSet ];
+    for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
+      const SMDS_MeshElement* elem = *itElem;
+      if ( !elem || elem->GetType() == SMDSAbs_Volume )
+        continue;
+      vector<TNodeOfNodeListMapItr> & newNodesItVec = mapElemNewNodes[ elem ];
+      newNodesItVec.reserve( elem->NbNodes() );
 
-    // loop on elem nodes
-    SMDS_ElemIteratorPtr itN = elem->nodesIterator();
-    while ( itN->more() )
-    {
-      // check if a node has been already sweeped
-      const SMDS_MeshNode* node = cast2Node( itN->next() );
+      // loop on elem nodes
+      SMDS_ElemIteratorPtr itN = elem->nodesIterator();
+      while ( itN->more() )
+      {
+        const SMDS_MeshNode* node = cast2Node( itN->next() );
 
-      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 );
+        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 )
+        // check if a node has been already sweeped
+        TNodeOfNodeListMapItr nIt =
+          mapNewNodes.insert( make_pair( node, list<const SMDS_MeshNode*>() )).first;
+        list<const SMDS_MeshNode*>& listNewNodes = nIt->second;
+        if ( listNewNodes.empty() )
         {
-          SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
-          while (it->more() && !needMediumNodes )
+          // check if we are to create medium nodes between corner ones
+          bool needMediumNodes = false;
+          if ( isQuadraticMesh )
           {
-            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;
+            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
-        const SMDS_MeshNode * newNode = node;
-        for ( int i = 0; i < theNbSteps; i++ ) {
-          if ( !isOnAxis ) {
-            if ( needMediumNodes )  // create a medium node
-            {
-              aTrsf2.Transforms( coord[0], coord[1], coord[2] );
+          // make new nodes
+          const SMDS_MeshNode * newNode = node;
+          for ( int i = 0; i < theNbSteps; i++ ) {
+            if ( !isOnAxis ) {
+              if ( needMediumNodes )  // create a medium 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 );
+                aTrsf2.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 );
-              aTrsf2.Transforms( coord[0], coord[1], coord[2] );
             }
             else {
-              aTrsf.Transforms( coord[0], coord[1], coord[2] );
+              listNewNodes.push_back( newNode );
+              // if ( needMediumNodes )
+              //   listNewNodes.push_back( newNode );
             }
-            // create a corner node
-            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 );
           }
         }
+        newNodesItVec.push_back( nIt );
       }
-      newNodesItVec.push_back( nIt );
+      // make new elements
+      sweepElement( elem, newNodesItVec, newElemsMap[elem], theNbSteps, srcElems );
     }
-    // make new elements
-    sweepElement( elem, newNodesItVec, newElemsMap[elem], theNbSteps, srcElems );
   }
 
   if ( theMakeWalls )
-    makeWalls( mapNewNodes, newElemsMap, mapElemNewNodes, theElems, theNbSteps, srcElems );
+    makeWalls( mapNewNodes, newElemsMap, mapElemNewNodes, theElemSets[0], theNbSteps, srcElems );
 
   PGroupIDs newGroupIDs;
   if ( theMakeGroups )
@@ -5217,196 +5496,448 @@ SMESH_MeshEditor::RotationSweep(TIDSortedElemSet & theElems,
   return newGroupIDs;
 }
 
-
 //=======================================================================
-//function : CreateNode
-//purpose  :
+//function : ExtrusParam
+//purpose  : standard construction
 //=======================================================================
-const SMDS_MeshNode* SMESH_MeshEditor::CreateNode(const double x,
-                                                  const double y,
-                                                  const double z,
-                                                  const double tolnode,
-                                                  SMESH_SequenceOfNode& aNodes)
-{
-  // myLastCreatedElems.Clear();
-  // myLastCreatedNodes.Clear();
 
-  gp_Pnt P1(x,y,z);
-  SMESHDS_Mesh * aMesh = myMesh->GetMeshDS();
+SMESH_MeshEditor::ExtrusParam::ExtrusParam( const gp_Vec&  theStep,
+                                            const int      theNbSteps,
+                                            const int      theFlags,
+                                            const double   theTolerance):
+  myDir( theStep ),
+  myFlags( theFlags ),
+  myTolerance( theTolerance ),
+  myElemsToUse( NULL )
+{
+  mySteps = new TColStd_HSequenceOfReal;
+  const double stepSize = theStep.Magnitude();
+  for (int i=1; i<=theNbSteps; i++ )
+    mySteps->Append( stepSize );
 
-  // try to search in sequence of existing nodes
-  // if aNodes.Length()>0 we 'nave to use given sequence
-  // else - use all nodes of mesh
-  if(aNodes.Length()>0) {
-    int i;
-    for(i=1; i<=aNodes.Length(); i++) {
-      gp_Pnt P2(aNodes.Value(i)->X(),aNodes.Value(i)->Y(),aNodes.Value(i)->Z());
-      if(P1.Distance(P2)<tolnode)
-        return aNodes.Value(i);
-    }
+  if (( theFlags & EXTRUSION_FLAG_SEW ) &&
+      ( theTolerance > 0 ))
+  {
+    myMakeNodesFun = & SMESH_MeshEditor::ExtrusParam::makeNodesByDirAndSew;
   }
-  else {
-    SMDS_NodeIteratorPtr itn = aMesh->nodesIterator();
-    while(itn->more()) {
-      const SMDS_MeshNode* aN = static_cast<const SMDS_MeshNode*> (itn->next());
-      gp_Pnt P2(aN->X(),aN->Y(),aN->Z());
-      if(P1.Distance(P2)<tolnode)
-        return aN;
-    }
+  else
+  {
+    myMakeNodesFun = & SMESH_MeshEditor::ExtrusParam::makeNodesByDir;
   }
-
-  // create new node and return it
-  const SMDS_MeshNode* NewNode = aMesh->AddNode(x,y,z);
-  //myLastCreatedNodes.Append(NewNode);
-  return NewNode;
 }
 
-
 //=======================================================================
-//function : ExtrusionSweep
-//purpose  :
+//function : ExtrusParam
+//purpose  : steps are given explicitly
 //=======================================================================
 
-SMESH_MeshEditor::PGroupIDs
-SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet &   theElems,
-                                  const gp_Vec&        theStep,
-                                  const int            theNbSteps,
-                                  TTElemOfElemListMap& newElemsMap,
-                                  const bool           theMakeGroups,
-                                  const int            theFlags,
-                                  const double         theTolerance)
+SMESH_MeshEditor::ExtrusParam::ExtrusParam( const gp_Dir&                   theDir,
+                                            Handle(TColStd_HSequenceOfReal) theSteps,
+                                            const int                       theFlags,
+                                            const double                    theTolerance):
+  myDir( theDir ),
+  mySteps( theSteps ),
+  myFlags( theFlags ),
+  myTolerance( theTolerance ),
+  myElemsToUse( NULL )
 {
-  ExtrusParam aParams;
-  aParams.myDir = gp_Dir(theStep);
-  aParams.myNodes.Clear();
-  aParams.mySteps = new TColStd_HSequenceOfReal;
-  int i;
-  for(i=1; i<=theNbSteps; i++)
-    aParams.mySteps->Append(theStep.Magnitude());
-
-  return
-    ExtrusionSweep(theElems,aParams,newElemsMap,theMakeGroups,theFlags,theTolerance);
+  if (( theFlags & EXTRUSION_FLAG_SEW ) &&
+      ( theTolerance > 0 ))
+  {
+    myMakeNodesFun = & SMESH_MeshEditor::ExtrusParam::makeNodesByDirAndSew;
+  }
+  else
+  {
+    myMakeNodesFun = & SMESH_MeshEditor::ExtrusParam::makeNodesByDir;
+  }
 }
 
-
 //=======================================================================
-//function : ExtrusionSweep
-//purpose  :
+//function : ExtrusParam
+//purpose  : for extrusion by normal
 //=======================================================================
 
-SMESH_MeshEditor::PGroupIDs
-SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet &   theElems,
-                                  ExtrusParam&         theParams,
-                                  TTElemOfElemListMap& newElemsMap,
-                                  const bool           theMakeGroups,
-                                  const int            theFlags,
-                                  const double         theTolerance)
+SMESH_MeshEditor::ExtrusParam::ExtrusParam( const double theStepSize,
+                                            const int    theNbSteps,
+                                            const int    theFlags,
+                                            const int    theDim ):
+  myDir( 1,0,0 ),
+  mySteps( new TColStd_HSequenceOfReal ),
+  myFlags( theFlags ),
+  myTolerance( 0 ),
+  myElemsToUse( NULL )
 {
-  myLastCreatedElems.Clear();
-  myLastCreatedNodes.Clear();
+  for (int i = 0; i < theNbSteps; i++ )
+    mySteps->Append( theStepSize );
 
-  // source elements for each generated one
-  SMESH_SequenceOfElemPtr srcElems, srcNodes;
+  if ( theDim == 1 )
+  {
+    myMakeNodesFun = & SMESH_MeshEditor::ExtrusParam::makeNodesByNormal1D;
+  }
+  else
+  {
+    myMakeNodesFun = & SMESH_MeshEditor::ExtrusParam::makeNodesByNormal2D;
+  }
+}
 
-  SMESHDS_Mesh* aMesh = GetMeshDS();
+//=======================================================================
+//function : ExtrusParam::SetElementsToUse
+//purpose  : stores elements to use for extrusion by normal, depending on
+//           state of EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY flag
+//=======================================================================
 
-  int nbsteps = theParams.mySteps->Length();
+void SMESH_MeshEditor::ExtrusParam::SetElementsToUse( const TIDSortedElemSet& elems )
+{
+  myElemsToUse = ToUseInpElemsOnly() ? & elems : 0;
+}
 
-  TNodeOfNodeListMap mapNewNodes;
-  //TNodeOfNodeVecMap mapNewNodes;
-  TElemOfVecOfNnlmiMap mapElemNewNodes;
-  //TElemOfVecOfMapNodesMap mapElemNewNodes;
+//=======================================================================
+//function : ExtrusParam::beginStepIter
+//purpose  : prepare iteration on steps
+//=======================================================================
 
-  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++ ) {
-    // check element type
-    const SMDS_MeshElement* elem = *itElem;
-    if ( !elem  || elem->GetType() == SMDSAbs_Volume )
-      continue;
+void SMESH_MeshEditor::ExtrusParam::beginStepIter( bool withMediumNodes )
+{
+  myWithMediumNodes = withMediumNodes;
+  myNextStep = 1;
+  myCurSteps.clear();
+}
+//=======================================================================
+//function : ExtrusParam::moreSteps
+//purpose  : are there more steps?
+//=======================================================================
 
-    vector<TNodeOfNodeListMapItr> & newNodesItVec = mapElemNewNodes[ elem ];
-    newNodesItVec.reserve( elem->NbNodes() );
+bool SMESH_MeshEditor::ExtrusParam::moreSteps()
+{
+  return myNextStep <= mySteps->Length() || !myCurSteps.empty();
+}
+//=======================================================================
+//function : ExtrusParam::nextStep
+//purpose  : returns the next step
+//=======================================================================
 
-    // loop on elem nodes
-    SMDS_ElemIteratorPtr itN = elem->nodesIterator();
-    while ( itN->more() )
+double SMESH_MeshEditor::ExtrusParam::nextStep()
+{
+  double res = 0;
+  if ( !myCurSteps.empty() )
+  {
+    res = myCurSteps.back();
+    myCurSteps.pop_back();
+  }
+  else if ( myNextStep <= mySteps->Length() )
+  {
+    myCurSteps.push_back( mySteps->Value( myNextStep ));
+    ++myNextStep;
+    if ( myWithMediumNodes )
     {
-      // check if a node has been already sweeped
-      const SMDS_MeshNode* node = cast2Node( itN->next() );
-      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
+      myCurSteps.back() /= 2.;
+      myCurSteps.push_back( myCurSteps.back() );
+    }
+    res = nextStep();
+  }
+  return res;
+}
 
-        // 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;
-          }
+//=======================================================================
+//function : ExtrusParam::makeNodesByDir
+//purpose  : create nodes for standard extrusion
+//=======================================================================
+
+int SMESH_MeshEditor::ExtrusParam::
+makeNodesByDir( SMESHDS_Mesh*                     mesh,
+                const SMDS_MeshNode*              srcNode,
+                std::list<const SMDS_MeshNode*> & newNodes,
+                const bool                        makeMediumNodes)
+{
+  gp_XYZ p = SMESH_TNodeXYZ( srcNode );
+
+  int nbNodes = 0;
+  for ( beginStepIter( makeMediumNodes ); moreSteps(); ++nbNodes ) // loop on steps
+  {
+    p += myDir.XYZ() * nextStep();
+    const SMDS_MeshNode * newNode = mesh->AddNode( p.X(), p.Y(), p.Z() );
+    newNodes.push_back( newNode );
+  }
+  return nbNodes;
+}
+
+//=======================================================================
+//function : ExtrusParam::makeNodesByDirAndSew
+//purpose  : create nodes for standard extrusion with sewing
+//=======================================================================
+
+int SMESH_MeshEditor::ExtrusParam::
+makeNodesByDirAndSew( SMESHDS_Mesh*                     mesh,
+                      const SMDS_MeshNode*              srcNode,
+                      std::list<const SMDS_MeshNode*> & newNodes,
+                      const bool                        makeMediumNodes)
+{
+  gp_XYZ P1 = SMESH_TNodeXYZ( srcNode );
+
+  int nbNodes = 0;
+  for ( beginStepIter( makeMediumNodes ); moreSteps(); ++nbNodes ) // loop on steps
+  {
+    P1 += myDir.XYZ() * nextStep();
+
+    // try to search in sequence of existing nodes
+    // if myNodes.Length()>0 we 'nave to use given sequence
+    // else - use all nodes of mesh
+    const SMDS_MeshNode * node = 0;
+    if ( myNodes.Length() > 0 ) {
+      int i;
+      for(i=1; i<=myNodes.Length(); i++) {
+        gp_XYZ P2 = SMESH_TNodeXYZ( myNodes.Value(i) );
+        if (( P1 - P2 ).SquareModulus() < myTolerance * myTolerance )
+        {
+          node = myNodes.Value(i);
+          break;
+        }
+      }
+    }
+    else {
+      SMDS_NodeIteratorPtr itn = mesh->nodesIterator();
+      while(itn->more()) {
+        SMESH_TNodeXYZ P2( itn->next() );
+        if (( P1 - P2 ).SquareModulus() < myTolerance * myTolerance )
+        {
+          node = P2._node;
+          break;
         }
+      }
+    }
+
+    if ( !node )
+      node = mesh->AddNode( P1.X(), P1.Y(), P1.Z() );
+
+    newNodes.push_back( node );
+
+  } // loop on steps
+
+  return nbNodes;
+}
+
+//=======================================================================
+//function : ExtrusParam::makeNodesByNormal2D
+//purpose  : create nodes for extrusion using normals of faces
+//=======================================================================
+
+int SMESH_MeshEditor::ExtrusParam::
+makeNodesByNormal2D( SMESHDS_Mesh*                     mesh,
+                     const SMDS_MeshNode*              srcNode,
+                     std::list<const SMDS_MeshNode*> & newNodes,
+                     const bool                        makeMediumNodes)
+{
+  const bool alongAvgNorm = ( myFlags & EXTRUSION_FLAG_BY_AVG_NORMAL );
+
+  gp_XYZ p = SMESH_TNodeXYZ( srcNode );
+
+  // get normals to faces sharing srcNode
+  vector< gp_XYZ > norms, baryCenters;
+  gp_XYZ norm, avgNorm( 0,0,0 );
+  SMDS_ElemIteratorPtr faceIt = srcNode->GetInverseElementIterator( SMDSAbs_Face );
+  while ( faceIt->more() )
+  {
+    const SMDS_MeshElement* face = faceIt->next();
+    if ( myElemsToUse && !myElemsToUse->count( face ))
+      continue;
+    if ( SMESH_MeshAlgos::FaceNormal( face, norm, /*normalized=*/true ))
+    {
+      norms.push_back( norm );
+      avgNorm += norm;
+      if ( !alongAvgNorm )
+      {
+        gp_XYZ bc(0,0,0);
+        int nbN = 0;
+        for ( SMDS_ElemIteratorPtr nIt = face->nodesIterator(); nIt->more(); ++nbN )
+          bc += SMESH_TNodeXYZ( nIt->next() );
+        baryCenters.push_back( bc / nbN );
+      }
+    }
+  }
+
+  if ( norms.empty() ) return 0;
+
+  double normSize = avgNorm.Modulus();
+  if ( normSize < std::numeric_limits<double>::min() )
+    return 0;
+
+  if ( myFlags & EXTRUSION_FLAG_BY_AVG_NORMAL ) // extrude along avgNorm
+  {
+    myDir = avgNorm;
+    return makeNodesByDir( mesh, srcNode, newNodes, makeMediumNodes );
+  }
+
+  avgNorm /= normSize;
+
+  int nbNodes = 0;
+  for ( beginStepIter( makeMediumNodes ); moreSteps(); ++nbNodes ) // loop on steps
+  {
+    gp_XYZ pNew = p;
+    double stepSize = nextStep();
+
+    if ( norms.size() > 1 )
+    {
+      for ( size_t iF = 0; iF < norms.size(); ++iF ) // loop on faces
+      {
+        // translate plane of a face
+        baryCenters[ iF ] += norms[ iF ] * stepSize;
+
+        // find point of intersection of the face plane located at baryCenters[ iF ]
+        // and avgNorm located at pNew
+        double d    = -( norms[ iF ] * baryCenters[ iF ]); // d of plane equation ax+by+cz+d=0
+        double dot  = ( norms[ iF ] * avgNorm );
+        if ( dot < std::numeric_limits<double>::min() )
+          dot = stepSize * 1e-3;
+        double step = -( norms[ iF ] * pNew + d ) / dot;
+        pNew += step * avgNorm;
+      }
+    }
+    else
+    {
+      pNew += stepSize * avgNorm;
+    }
+    p = pNew;
+
+    const SMDS_MeshNode * newNode = mesh->AddNode( p.X(), p.Y(), p.Z() );
+    newNodes.push_back( newNode );
+  }
+  return nbNodes;
+}
+
+//=======================================================================
+//function : ExtrusParam::makeNodesByNormal1D
+//purpose  : create nodes for extrusion using normals of edges
+//=======================================================================
+
+int SMESH_MeshEditor::ExtrusParam::
+makeNodesByNormal1D( SMESHDS_Mesh*                     mesh,
+                     const SMDS_MeshNode*              srcNode,
+                     std::list<const SMDS_MeshNode*> & newNodes,
+                     const bool                        makeMediumNodes)
+{
+  throw SALOME_Exception("Extrusion 1D by Normal not implemented");
+  return 0;
+}
+
+//=======================================================================
+//function : ExtrusionSweep
+//purpose  :
+//=======================================================================
+
+SMESH_MeshEditor::PGroupIDs
+SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet     theElems[2],
+                                  const gp_Vec&        theStep,
+                                  const int            theNbSteps,
+                                  TTElemOfElemListMap& newElemsMap,
+                                  const int            theFlags,
+                                  const double         theTolerance)
+{
+  ExtrusParam aParams( theStep, theNbSteps, theFlags, theTolerance );
+  return ExtrusionSweep( theElems, aParams, newElemsMap );
+}
+
+
+//=======================================================================
+//function : ExtrusionSweep
+//purpose  :
+//=======================================================================
+
+SMESH_MeshEditor::PGroupIDs
+SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet     theElemSets[2],
+                                  ExtrusParam&         theParams,
+                                  TTElemOfElemListMap& newElemsMap)
+{
+  myLastCreatedElems.Clear();
+  myLastCreatedNodes.Clear();
+
+  // source elements for each generated one
+  SMESH_SequenceOfElemPtr srcElems, srcNodes;
+
+  //SMESHDS_Mesh* aMesh = GetMeshDS();
+
+  setElemsFirst( theElemSets );
+  const int nbSteps = theParams.NbSteps();
+  theParams.SetElementsToUse( theElemSets[0] );
+
+  TNodeOfNodeListMap mapNewNodes;
+  //TNodeOfNodeVecMap mapNewNodes;
+  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 ( int is2ndSet = 0; is2ndSet < 2; ++is2ndSet )
+  {
+    TIDSortedElemSet& theElems = theElemSets[ is2ndSet ];
+    for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
+    {
+      // check element type
+      const SMDS_MeshElement* elem = *itElem;
+      if ( !elem  || elem->GetType() == SMDSAbs_Volume )
+        continue;
+
+      const size_t nbNodes = elem->NbNodes();
+      vector<TNodeOfNodeListMapItr> & newNodesItVec = mapElemNewNodes[ elem ];
+      newNodesItVec.reserve( nbNodes );
 
-        double coord[] = { node->X(), node->Y(), node->Z() };
-        for ( int i = 0; i < nbsteps; i++ )
+      // loop on elem nodes
+      SMDS_ElemIteratorPtr itN = elem->nodesIterator();
+      while ( itN->more() )
+      {
+        // check if a node has been already sweeped
+        const SMDS_MeshNode* node = cast2Node( itN->next() );
+        TNodeOfNodeListMap::iterator nIt =
+          mapNewNodes.insert( make_pair( node, list<const SMDS_MeshNode*>() )).first;
+        list<const SMDS_MeshNode*>& listNewNodes = nIt->second;
+        if ( listNewNodes.empty() )
         {
-          if ( needMediumNodes ) // create a medium node
+          // make new nodes
+
+          // check if we are to create medium nodes between corner ones
+          bool needMediumNodes = false;
+          if ( isQuadraticMesh )
           {
-            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.;
-            if( theFlags & EXTRUSION_FLAG_SEW ) {
-              const SMDS_MeshNode * newNode = CreateNode(x, y, z,
-                                                         theTolerance, theParams.myNodes);
-              listNewNodes.push_back( newNode );
+            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;
             }
-            else {
-              const SMDS_MeshNode * newNode = aMesh->AddNode(x, y, z);
-              myLastCreatedNodes.Append(newNode);
+          }
+          // create nodes for all steps
+          if ( theParams.MakeNodes( GetMeshDS(), node, listNewNodes, needMediumNodes ))
+          {
+            list<const SMDS_MeshNode*>::iterator newNodesIt = listNewNodes.begin();
+            for ( ; newNodesIt != listNewNodes.end(); ++newNodesIt )
+            {
+              myLastCreatedNodes.Append( *newNodesIt );
               srcNodes.Append( node );
-              listNewNodes.push_back( newNode );
             }
           }
-          // 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);
-          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 );
+          else
+          {
+            break; // newNodesItVec will be shorter than nbNodes
           }
         }
+        newNodesItVec.push_back( nIt );
       }
-      newNodesItVec.push_back( nIt );
+      // make new elements
+      if ( newNodesItVec.size() == nbNodes )
+        sweepElement( elem, newNodesItVec, newElemsMap[elem], nbSteps, srcElems );
     }
-    // make new elements
-    sweepElement( elem, newNodesItVec, newElemsMap[elem], nbsteps, srcElems );
   }
 
-  if( theFlags & EXTRUSION_FLAG_BOUNDARY ) {
-    makeWalls( mapNewNodes, newElemsMap, mapElemNewNodes, theElems, nbsteps, srcElems );
+  if ( theParams.ToMakeBoundary() ) {
+    makeWalls( mapNewNodes, newElemsMap, mapElemNewNodes, theElemSets[0], nbSteps, srcElems );
   }
   PGroupIDs newGroupIDs;
-  if ( theMakeGroups )
+  if ( theParams.ToMakeGroups() )
     newGroupIDs = generateGroups( srcNodes, srcElems, "extruded");
 
   return newGroupIDs;
@@ -5417,7 +5948,7 @@ SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet &   theElems,
 //purpose  :
 //=======================================================================
 SMESH_MeshEditor::Extrusion_Error
-SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet &   theElements,
+SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet     theElements[2],
                                        SMESH_subMesh*       theTrack,
                                        const SMDS_MeshNode* theN1,
                                        const bool           theHasAngles,
@@ -5446,7 +5977,7 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet &   theElements,
   TNodeOfNodeListMap mapNewNodes;
 
   // 1. Check data
-  aNbE = theElements.size();
+  aNbE = theElements[0].size() + theElements[1].size();
   // nothing to do
   if ( !aNbE )
     return EXTR_NO_ELEMENTS;
@@ -5455,6 +5986,10 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet &   theElements,
   ASSERT( theTrack );
 
   SMESHDS_SubMesh* pSubMeshDS = theTrack->GetSubMeshDS();
+  if ( !pSubMeshDS )
+    return ExtrusionAlongTrack( theElements, theTrack->GetFather(), theN1,
+                                theHasAngles, theAngles, theLinearVariation,
+                                theHasRefPoint, theRefPoint, theMakeGroups );
 
   aItE = pSubMeshDS->GetElements();
   while ( aItE->more() ) {
@@ -5589,7 +6124,7 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet &   theElements,
 //purpose  :
 //=======================================================================
 SMESH_MeshEditor::Extrusion_Error
-SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet &   theElements,
+SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet     theElements[2],
                                        SMESH_Mesh*          theTrack,
                                        const SMDS_MeshNode* theN1,
                                        const bool           theHasAngles,
@@ -5617,7 +6152,7 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet &   theElements,
   TNodeOfNodeListMap mapNewNodes;
 
   // 1. Check data
-  aNbE = theElements.size();
+  aNbE = theElements[0].size() + theElements[1].size();
   // nothing to do
   if ( !aNbE )
     return EXTR_NO_ELEMENTS;
@@ -5658,7 +6193,7 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet &   theElements,
     }
 
     conn = nbEdgeConnectivity(theN1);
-    if(conn > 2)
+    if( conn != 1 )
       return EXTR_PATH_NOT_EDGE;
 
     aItE = theN1->GetInverseElementIterator();
@@ -5709,21 +6244,19 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet &   theElements,
       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));
+    for ( size_t i = 1; i < aNodesList.size(); i++ )
+    {
+      gp_Pnt     p1 = SMESH_TNodeXYZ( aNodesList[i-1] );
+      gp_Pnt     p2 = SMESH_TNodeXYZ( aNodesList[i] );
+      TopoDS_Edge e = BRepBuilderAPI_MakeEdge( p1, p2 );
       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();
-
+      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();
@@ -5743,8 +6276,7 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet &   theElements,
       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 ) );
+      gp_Dir Dnew( 0.5 * ( D1.XYZ() + D2.XYZ() ));
       PP1.SetTangent(Dnew);
       fullList.push_back(PP1);
       itPP++;
@@ -5757,7 +6289,8 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet &   theElements,
     fullList.push_back(PP1);
 
   } // Sub-shape for the Pattern must be an Edge or Wire
-  else if( aS.ShapeType() == TopAbs_EDGE ) {
+  else if ( aS.ShapeType() == TopAbs_EDGE )
+  {
     aTrackEdge = TopoDS::Edge( aS );
     // the Edge must not be degenerated
     if ( SMESH_Algo::isDegenerated( aTrackEdge ) )
@@ -5858,7 +6391,7 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet &   theElements,
       SMESH_MeshEditor_PathPoint PP2 = currList.front();
       gp_Dir D1 = PP1.Tangent();
       gp_Dir D2 = PP2.Tangent();
-      gp_Dir Dnew( ( D1.XYZ() + D2.XYZ() ) / 2 );
+      gp_Dir Dnew( D1.XYZ() + D2.XYZ() );
       PP1.SetTangent(Dnew);
       fullList.push_back(PP1);
       fullList.splice( fullList.end(), currList, ++currList.begin(), currList.end() );
@@ -5923,7 +6456,7 @@ SMESH_MeshEditor::MakeEdgePathPoints(std::list<double>&                aPrms,
     aL2 = aVec.SquareMagnitude();
     if ( aL2 < aTolVec2 )
       return EXTR_CANT_GET_TANGENT;
-    gp_Dir aTgt( aVec );
+    gp_Dir aTgt( FirstIsStart ? aVec : -aVec );
     aPP.SetPnt( aP3D );
     aPP.SetTangent( aTgt );
     aPP.SetParameter( aT );
@@ -5938,7 +6471,7 @@ SMESH_MeshEditor::MakeEdgePathPoints(std::list<double>&                aPrms,
 //purpose  : auxilary for ExtrusionAlongTrack
 //=======================================================================
 SMESH_MeshEditor::Extrusion_Error
-SMESH_MeshEditor::MakeExtrElements(TIDSortedElemSet&                 theElements,
+SMESH_MeshEditor::MakeExtrElements(TIDSortedElemSet                  theElemSets[2],
                                    list<SMESH_MeshEditor_PathPoint>& fullList,
                                    const bool                        theHasAngles,
                                    list<double>&                     theAngles,
@@ -5948,9 +6481,11 @@ SMESH_MeshEditor::MakeExtrElements(TIDSortedElemSet&                 theElements
                                    const bool                        theMakeGroups)
 {
   const int aNbTP = fullList.size();
+
   // Angles
   if( theHasAngles && !theAngles.empty() && theLinearVariation )
     LinearAngleVariation(aNbTP-1, theAngles);
+
   // fill vector of path points with angles
   vector<SMESH_MeshEditor_PathPoint> aPPs;
   list<SMESH_MeshEditor_PathPoint>::iterator itPP = fullList.begin();
@@ -5976,15 +6511,19 @@ SMESH_MeshEditor::MakeExtrElements(TIDSortedElemSet&                 theElements
     gp_XYZ aGC( 0.,0.,0. );
     TIDSortedElemSet newNodes;
 
-    itElem = theElements.begin();
-    for ( ; itElem != theElements.end(); itElem++ ) {
-      const SMDS_MeshElement* elem = *itElem;
-
-      SMDS_ElemIteratorPtr itN = elem->nodesIterator();
-      while ( itN->more() ) {
-        const SMDS_MeshElement* node = itN->next();
-        if ( newNodes.insert( node ).second )
-          aGC += SMESH_TNodeXYZ( node );
+    for ( int is2ndSet = 0; is2ndSet < 2; ++is2ndSet )
+    {
+      TIDSortedElemSet& theElements = theElemSets[ is2ndSet ];
+      itElem = theElements.begin();
+      for ( ; itElem != theElements.end(); itElem++ )
+      {
+        const SMDS_MeshElement* elem = *itElem;
+        SMDS_ElemIteratorPtr     itN = elem->nodesIterator();
+        while ( itN->more() ) {
+          const SMDS_MeshElement* node = itN->next();
+          if ( newNodes.insert( node ).second )
+            aGC += SMESH_TNodeXYZ( node );
+        }
       }
     }
     aGC /= newNodes.size();
@@ -5993,112 +6532,110 @@ SMESH_MeshEditor::MakeExtrElements(TIDSortedElemSet&                 theElements
 
   // 4. Processing the elements
   SMESHDS_Mesh* aMesh = GetMeshDS();
+  list<const SMDS_MeshNode*> emptyList;
 
-  for ( itElem = theElements.begin(); itElem != theElements.end(); itElem++ ) {
-    // check element type
-    const SMDS_MeshElement* elem = *itElem;
-    SMDSAbs_ElementType   aTypeE = elem->GetType();
-    if ( !elem || ( aTypeE != SMDSAbs_Face && aTypeE != SMDSAbs_Edge ) )
-      continue;
+  setElemsFirst( theElemSets );
+  for ( int is2ndSet = 0; is2ndSet < 2; ++is2ndSet )
+  {
+    TIDSortedElemSet& theElements = theElemSets[ is2ndSet ];
+    for ( itElem = theElements.begin(); itElem != theElements.end(); itElem++ )
+    {
+      const SMDS_MeshElement* elem = *itElem;
 
-    vector<TNodeOfNodeListMapItr> & newNodesItVec = mapElemNewNodes[ elem ];
-    newNodesItVec.reserve( elem->NbNodes() );
+      vector<TNodeOfNodeListMapItr> & newNodesItVec = mapElemNewNodes[ elem ];
+      newNodesItVec.reserve( elem->NbNodes() );
 
-    // loop on elem nodes
-    int nodeIndex = -1;
-    SMDS_ElemIteratorPtr itN = elem->nodesIterator();
-    while ( itN->more() )
-    {
-      ++nodeIndex;
-      // check if a node has been already processed
-      const SMDS_MeshNode* node =
-        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;
+      // loop on elem nodes
+      int nodeIndex = -1;
+      SMDS_ElemIteratorPtr itN = elem->nodesIterator();
+      while ( itN->more() )
+      {
+        ++nodeIndex;
+        // check if a node has been already processed
+        const SMDS_MeshNode* node = cast2Node( itN->next() );
+        TNodeOfNodeListMap::iterator nIt = mapNewNodes.insert( make_pair( node, emptyList )).first;
         list<const SMDS_MeshNode*>& listNewNodes = nIt->second;
+        if ( listNewNodes.empty() )
+        {
+          // make new nodes
+          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 = SMESH_TNodeXYZ( node );
+
+          const SMESH_MeshEditor_PathPoint& aPP0 = aPPs[0];
+          aP0x = aPP0.Pnt();
+          aDT0x= aPP0.Tangent();
+
+          for ( int 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 );
 
-        // make new nodes
-        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 = SMESH_TNodeXYZ( node );
-
-        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 ( int 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 );
-          }
+              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
-          //MESSAGE("elem->IsQuadratic " << elem->IsQuadratic() << " " << elem->IsMediumNode(node));
-          if( elem->IsQuadratic() && !elem->IsMediumNode(node) ) {
-            // create additional node
-            double x = ( aPN1.X() + aPN0.X() )/2.;
-            double y = ( aPN1.Y() + aPN0.Y() )/2.;
-            double z = ( aPN1.Z() + aPN0.Z() )/2.;
-            const SMDS_MeshNode* newNode = aMesh->AddNode(x,y,z);
+            // make new node
+            if ( elem->IsQuadratic() && !elem->IsMediumNode(node) )
+            {
+              // create additional node
+              gp_XYZ midP = 0.5 * ( aPN1.XYZ() + aPN0.XYZ() );
+              const SMDS_MeshNode* newNode = aMesh->AddNode( midP.X(), midP.Y(), midP.Z() );
+              myLastCreatedNodes.Append(newNode);
+              srcNodes.Append( node );
+              listNewNodes.push_back( newNode );
+            }
+            const SMDS_MeshNode* newNode = aMesh->AddNode( aPN1.X(), aPN1.Y(), aPN1.Z() );
             myLastCreatedNodes.Append(newNode);
             srcNodes.Append( node );
             listNewNodes.push_back( newNode );
-          }
-          const SMDS_MeshNode* newNode = aMesh->AddNode( aPN1.X(), aPN1.Y(), aPN1.Z() );
-          myLastCreatedNodes.Append(newNode);
-          srcNodes.Append( node );
-          listNewNodes.push_back( newNode );
 
-          aPN0 = aPN1;
-          aP0x = aP1x;
-          aV0x = aV1x;
-          aDT0x = aDT1x;
+            aPN0 = aPN1;
+            aP0x = aP1x;
+            aV0x = aV1x;
+            aDT0x = aDT1x;
+          }
         }
-      }
-
-      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) ) {
+        else if( elem->IsQuadratic() && !elem->IsMediumNode(node) )
+        {
+          // if current elem is quadratic and current node is not medium
+          // we have to check - may be it is needed to insert additional nodes
           list< const SMDS_MeshNode* > & listNewNodes = nIt->second;
-          if(listNewNodes.size()==aNbTP-1) {
+          if ((int) listNewNodes.size() == aNbTP-1 )
+          {
             vector<const SMDS_MeshNode*> aNodes(2*(aNbTP-1));
             gp_XYZ P(node->X(), node->Y(), node->Z());
             list< const SMDS_MeshNode* >::iterator it = listNewNodes.begin();
@@ -6121,17 +6658,16 @@ SMESH_MeshEditor::MakeExtrElements(TIDSortedElemSet&                 theElements
             }
           }
         }
+
+        newNodesItVec.push_back( nIt );
       }
 
-      newNodesItVec.push_back( nIt );
+      // make new elements
+      sweepElement( elem, newNodesItVec, newElemsMap[elem], aNbTP-1, srcElems );
     }
-    // make new elements
-    //sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem],
-    //              newNodesItVec[0]->second.size(), myLastCreatedElems );
-    sweepElement( elem, newNodesItVec, newElemsMap[elem], aNbTP-1, srcElems );
   }
 
-  makeWalls( mapNewNodes, newElemsMap, mapElemNewNodes, theElements, aNbTP-1, srcElems );
+  makeWalls( mapNewNodes, newElemsMap, mapElemNewNodes, theElemSets[0], aNbTP-1, srcElems );
 
   if ( theMakeGroups )
     generateGroups( srcNodes, srcElems, "extruded");
@@ -6250,10 +6786,12 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
     groupPostfix = "transformed";
   }
 
-  SMESH_MeshEditor targetMeshEditor( theTargetMesh );
   SMESHDS_Mesh* aTgtMesh = theTargetMesh ? theTargetMesh->GetMeshDS() : 0;
   SMESHDS_Mesh* aMesh    = GetMeshDS();
 
+  SMESH_MeshEditor targetMeshEditor( theTargetMesh );
+  SMESH_MeshEditor* editor = theTargetMesh ? & targetMeshEditor : theCopy ? this : 0;
+  SMESH_MeshEditor::ElemFeatures elemType;
 
   // map old node to new one
   TNodeNodeMap nodeMap;
@@ -6285,224 +6823,141 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
 
   // loop on elements to transform nodes : first orphan nodes then elems
   TIDSortedElemSet::iterator itElem;
-  TIDSortedElemSet *elements[] = {&orphanNode, &theElems };
+  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;
-
-    // loop on elem nodes
-    SMDS_ElemIteratorPtr itN = elem->nodesIterator();
-    while ( itN->more() ) {
-
-      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 )
+    for ( itElem = elements[i]->begin(); itElem != elements[i]->end(); itElem++ )
+    {
+      const SMDS_MeshElement* elem = *itElem;
+      if ( !elem )
         continue;
 
+      // loop on elem nodes
       double coord[3];
-      coord[0] = node->X();
-      coord[1] = node->Y();
-      coord[2] = node->Z();
-      theTrsf.Transforms( coord[0], coord[1], coord[2] );
-      if ( theTargetMesh ) {
-        const SMDS_MeshNode * newNode = aTgtMesh->AddNode( coord[0], coord[1], coord[2] );
-        n2n_isnew.first->second = newNode;
-        myLastCreatedNodes.Append(newNode);
-        srcNodes.Append( node );
-      }
-      else if ( theCopy ) {
-        const SMDS_MeshNode * newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
-        n2n_isnew.first->second = newNode;
-        myLastCreatedNodes.Append(newNode);
-        srcNodes.Append( node );
-      }
-      else {
-        aMesh->MoveNode( node, coord[0], coord[1], coord[2] );
-        // node position on shape becomes invalid
-        const_cast< SMDS_MeshNode* > ( node )->SetPosition
-          ( SMDS_SpacePosition::originSpacePosition() );
-      }
+      SMDS_ElemIteratorPtr itN = elem->nodesIterator();
+      while ( itN->more() )
+      {
+        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 )
+          continue;
 
-      // keep inverse elements
-      if ( !theCopy && !theTargetMesh && needReverse ) {
-        SMDS_ElemIteratorPtr invElemIt = node->GetInverseElementIterator();
-        while ( invElemIt->more() ) {
-          const SMDS_MeshElement* iel = invElemIt->next();
-          inverseElemSet.insert( iel );
+        node->GetXYZ( coord );
+        theTrsf.Transforms( coord[0], coord[1], coord[2] );
+        if ( theTargetMesh ) {
+          const SMDS_MeshNode * newNode = aTgtMesh->AddNode( coord[0], coord[1], coord[2] );
+          n2n_isnew.first->second = newNode;
+          myLastCreatedNodes.Append(newNode);
+          srcNodes.Append( node );
+        }
+        else if ( theCopy ) {
+          const SMDS_MeshNode * newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
+          n2n_isnew.first->second = newNode;
+          myLastCreatedNodes.Append(newNode);
+          srcNodes.Append( node );
+        }
+        else {
+          aMesh->MoveNode( node, coord[0], coord[1], coord[2] );
+          // node position on shape becomes invalid
+          const_cast< SMDS_MeshNode* > ( node )->SetPosition
+            ( SMDS_SpacePosition::originSpacePosition() );
+        }
+
+        // keep inverse elements
+        if ( !theCopy && !theTargetMesh && needReverse ) {
+          SMDS_ElemIteratorPtr invElemIt = node->GetInverseElementIterator();
+          while ( invElemIt->more() ) {
+            const SMDS_MeshElement* iel = invElemIt->next();
+            inverseElemSet.insert( iel );
+          }
         }
       }
-    }
-  }
+    } // loop on elems in { &orphanNode, &theElems };
 
   // either create new elements or reverse mirrored ones
   if ( !theCopy && !needReverse && !theTargetMesh )
     return PGroupIDs();
 
-  TIDSortedElemSet::iterator invElemIt = inverseElemSet.begin();
-  for ( ; invElemIt != inverseElemSet.end(); invElemIt++ )
-    theElems.insert( *invElemIt );
+  theElems.insert( inverseElemSet.begin(),inverseElemSet.end() );
 
   // Replicate or reverse elements
 
   std::vector<int> iForw;
+  vector<const SMDS_MeshNode*> nodes;
   for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
   {
     const SMDS_MeshElement* elem = *itElem;
     if ( !elem ) continue;
 
     SMDSAbs_GeometryType geomType = elem->GetGeomType();
-    int                  nbNodes  = elem->NbNodes();
+    size_t               nbNodes  = elem->NbNodes();
     if ( geomType == SMDSGeom_NONE ) continue; // node
 
-    switch ( geomType ) {
+    nodes.resize( nbNodes );
 
-    case SMDSGeom_POLYGON:  // ---------------------- polygon
+    if ( geomType == SMDSGeom_POLYHEDRA )  // ------------------ polyhedral volume
+    {
+      const SMDS_VtkVolume* aPolyedre = dynamic_cast<const SMDS_VtkVolume*>( elem );
+      if (!aPolyedre)
+        continue;
+      nodes.clear();
+      bool allTransformed = true;
+      int nbFaces = aPolyedre->NbFaces();
+      for (int iface = 1; iface <= nbFaces && allTransformed; iface++)
       {
-        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());
+        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())
-            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 ( nodeMapIt == nodeMap.end() )
+            allTransformed = false; // not all nodes transformed
+          else
+            nodes.push_back((*nodeMapIt).second);
         }
-        if ( iNode != nbNodes )
-          continue; // not all nodes transformed
+        if ( needReverse && allTransformed )
+          std::reverse( nodes.end() - nbFaceNodes, nodes.end() );
+      }
+      if ( !allTransformed )
+        continue; // not all nodes transformed
+    }
+    else // ----------------------- the rest element types
+    {
+      while ( iForw.size() < nbNodes ) iForw.push_back( iForw.size() );
+      const vector<int>& iRev = SMDS_MeshCell::reverseSmdsOrder( elem->GetEntityType(), nbNodes );
+      const vector<int>&    i = needReverse ? iRev : iForw;
 
-        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);
-        }
+      // find transformed nodes
+      size_t 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;
       }
-      break;
+      if ( iNode != nbNodes )
+        continue; // not all nodes transformed
+    }
 
-    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);
-            }
-            if ( needReverse && allTransformed )
-              std::reverse( poly_nodes.end() - nbFaceNodes, poly_nodes.end() );
-          }
-          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;
-
-    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 {
-          myLastCreatedElems.Append(aMesh->AddBall( nodeMapIt->second, diameter ));
-          srcElems.Append( elem );
-        }
-      }
-      break;
-
-    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 );
-        }
-      }
-      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 );
-      }
-    } // switch ( geomType )
+    if ( editor ) {
+      // copy in this or a new mesh
+      if ( editor->AddElement( nodes, elemType.Init( elem, /*basicOnly=*/false )))
+        srcElems.Append( elem );
+    }
+    else {
+      // reverse element as it was reversed by transformation
+      if ( nbNodes > 2 )
+        aMesh->ChangeElementNodes( elem, &nodes[0], nbNodes );
+    }
 
   } // loop on elements
 
+  if ( editor && editor != this )
+    myLastCreatedElems = editor->myLastCreatedElems;
+
   PGroupIDs newGroupIDs;
 
   if ( ( theMakeGroups && theCopy ) ||
@@ -6706,32 +7161,72 @@ SMESH_MeshEditor::generateGroups(const SMESH_SequenceOfElemPtr& nodeGens,
 
 //================================================================================
 /*!
- * \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
+ *  * \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
+ *  \param [in,out] theNodes - the nodes to treat
+ *  \param [in]     theTolerance - the tolerance
+ *  \param [out]    theGroupsOfNodes - the result groups of coincident nodes
+ *  \param [in]     theSeparateCornersAndMedium - if \c true, in quadratic mesh puts 
+ *         corner and medium nodes in separate groups
  */
 //================================================================================
 
 void SMESH_MeshEditor::FindCoincidentNodes (TIDSortedNodeSet &   theNodes,
                                             const double         theTolerance,
-                                            TListOfListOfNodes & theGroupsOfNodes)
+                                            TListOfListOfNodes & theGroupsOfNodes,
+                                            bool                 theSeparateCornersAndMedium)
 {
   myLastCreatedElems.Clear();
   myLastCreatedNodes.Clear();
 
-  if ( theNodes.empty() )
-  { // get all nodes in the mesh
+  if ( myMesh->NbEdges  ( ORDER_QUADRATIC ) +
+       myMesh->NbFaces  ( ORDER_QUADRATIC ) +
+       myMesh->NbVolumes( ORDER_QUADRATIC ) == 0 )
+    theSeparateCornersAndMedium = false;
+
+  TIDSortedNodeSet& corners = theNodes;
+  TIDSortedNodeSet  medium;
+
+  if ( theNodes.empty() ) // get all nodes in the mesh
+  {
+    TIDSortedNodeSet* nodes[2] = { &corners, &medium };
     SMDS_NodeIteratorPtr nIt = GetMeshDS()->nodesIterator(/*idInceasingOrder=*/true);
-    while ( nIt->more() )
-      theNodes.insert( theNodes.end(),nIt->next());
+    if ( theSeparateCornersAndMedium )
+      while ( nIt->more() )
+      {
+        const SMDS_MeshNode* n = nIt->next();
+        TIDSortedNodeSet* & nodeSet = nodes[ SMESH_MesherHelper::IsMedium( n )];
+        nodeSet->insert( nodeSet->end(), n );
+      }
+    else
+      while ( nIt->more() )
+        theNodes.insert( theNodes.end(),nIt->next() );
+  }
+  else if ( theSeparateCornersAndMedium ) // separate corners from medium nodes
+  {
+    TIDSortedNodeSet::iterator nIt = corners.begin();
+    while ( nIt != corners.end() )
+      if ( SMESH_MesherHelper::IsMedium( *nIt ))
+      {
+        medium.insert( medium.end(), *nIt );
+        corners.erase( nIt++ );
+      }
+      else
+      {
+        ++nIt;
+      }
   }
 
-  SMESH_OctreeNode::FindCoincidentNodes ( theNodes, &theGroupsOfNodes, theTolerance);
+  if ( !corners.empty() )
+    SMESH_OctreeNode::FindCoincidentNodes ( corners, &theGroupsOfNodes, theTolerance );
+  if ( !medium.empty() )
+    SMESH_OctreeNode::FindCoincidentNodes ( medium, &theGroupsOfNodes, theTolerance );
 }
 
 //=======================================================================
 //function : SimplifyFace
-//purpose  :
+//purpose  : split a chain of nodes into several closed chains
 //=======================================================================
 
 int SMESH_MeshEditor::SimplifyFace (const vector<const SMDS_MeshNode *>& faceNodes,
@@ -6746,19 +7241,17 @@ int SMESH_MeshEditor::SimplifyFace (const vector<const SMDS_MeshNode *>& faceNod
   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;
+  int iSimple = 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++;
+      nodeSet.insert( faceNodes[iCur] );
     }
   }
+  int nbUnique = nodeSet.size();
   int nbSimple = iSimple;
   if (simpleNodes[nbSimple - 1] == simpleNodes[0]) {
     nbSimple--;
@@ -6834,16 +7327,17 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
   // Fill nodeNodeMap and elems
 
   TListOfListOfNodes::iterator grIt = theGroupsOfNodes.begin();
-  for ( ; grIt != theGroupsOfNodes.end(); grIt++ ) {
+  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++ ) {
+    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());
+      nodeNodeMap.insert( make_pair( nToRemove, nToKeep ));
+      if ( nToRemove != nToKeep )
+      {
         rmNodeIds.push_back( nToRemove->GetID() );
         AddToSameGroups( nToKeep, nToRemove, aMesh );
         // set _alwaysComputed to a sub-mesh of VERTEX to enable mesh computing
@@ -6853,7 +7347,6 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
           if ( SMESH_subMesh* sm = myMesh->GetSubMeshContaining( nToRemove->getshapeId() ))
             sm->SetIsAlwaysComputed( true );
       }
-
       SMDS_ElemIteratorPtr invElemIt = nToRemove->GetInverseElementIterator();
       while ( invElemIt->more() ) {
         const SMDS_MeshElement* elem = invElemIt->next();
@@ -6863,29 +7356,34 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
   }
   // Change element nodes or remove an element
 
+  set<const SMDS_MeshNode*> nodeSet;
+  vector< const SMDS_MeshNode*> curNodes, uniqueNodes;
+  vector<int> iRepl;
+  ElemFeatures elemType;
+
   set<const SMDS_MeshElement*>::iterator eIt = elems.begin();
-  for ( ; eIt != elems.end(); eIt++ ) {
+  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 );
+    const           int  nbNodes = elem->NbNodes();
+    const           int aShapeId = FindShape( elem );
 
-    set<const SMDS_MeshNode*> nodeSet;
-    vector< const SMDS_MeshNode*> curNodes( nbNodes ), uniqueNodes( nbNodes );
+    nodeSet.clear();
+    curNodes.resize( nbNodes );
+    uniqueNodes.resize( nbNodes );
+    iRepl.resize( 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() );
+    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
-        {
+        { ////////// BUG 0020185: begin
           bool stopRecur = false;
           set<const SMDS_MeshNode*> nodesRecur;
           nodesRecur.insert(n);
@@ -6901,8 +7399,7 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
             else
               stopRecur = true;
           }
-        }
-        // BUG 0020185: end
+        } ////////// BUG 0020185: end
       }
       curNodes[ iCur ] = n;
       bool isUnique = nodeSet.insert( n ).second;
@@ -6917,64 +7414,64 @@ 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()) {
-
-        if (elem->GetType() == SMDSAbs_Face) {
-          // Polygon
-          vector<const SMDS_MeshNode *> face_nodes (nbNodes);
-          int inode = 0;
-          for (; inode < nbNodes; inode++) {
-            face_nodes[inode] = curNodes[inode];
-          }
+    if ( nbNodes != nbUniqueNodes ) // some nodes stick
+    {
+      if (elem->IsPoly()) // Polygons and Polyhedral volumes
+      {
+        if (elem->GetType() == SMDSAbs_Face) // Polygon
+        {
+          elemType.Init( elem );
+          const bool isQuad = elemType.myIsQuad;
+          if ( isQuad )
+            SMDS_MeshCell::applyInterlace // interlace medium and corner nodes
+              ( SMDS_MeshCell::interlacedSmdsOrder( SMDSEntity_Quad_Polygon, nbNodes ), curNodes );
 
+          // a polygon can divide into several elements
           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; iface++) {
-              int nbNodes = quantities[iface];
-              vector<const SMDS_MeshNode *> poly_nodes (nbNodes);
-              for (int ii = 0; ii < nbNodes; ii++, inode++) {
-                poly_nodes[ii] = polygons_nodes[inode];
+          int nbNew = SimplifyFace( curNodes, polygons_nodes, quantities );
+          if (nbNew > 0)
+          {
+            vector<const SMDS_MeshNode *> face_nodes;
+            int inode = 0;
+            for (int iface = 0; iface < nbNew; iface++)
+            {
+              int nbNewNodes = quantities[iface];
+              face_nodes.assign( polygons_nodes.begin() + inode,
+                                 polygons_nodes.begin() + inode + nbNewNodes );
+              inode += nbNewNodes;
+              if ( isQuad ) // check if a result elem is a valid quadratic polygon
+              {
+                bool isValid = ( nbNewNodes % 2 == 0 );
+                for ( int i = 0; i < nbNewNodes && isValid; ++i )
+                  isValid = ( elem->IsMediumNode( face_nodes[i]) == bool( i % 2 ));
+                elemType.SetQuad( isValid );
+                if ( isValid ) // put medium nodes after corners
+                  SMDS_MeshCell::applyInterlaceRev
+                    ( SMDS_MeshCell::interlacedSmdsOrder( SMDSEntity_Quad_Polygon,
+                                                          nbNewNodes ), face_nodes );
               }
-              SMDS_MeshElement* newElem = aMesh->AddPolygonalFace(poly_nodes);
-              myLastCreatedElems.Append(newElem);
-              if (aShapeId)
+              elemType.SetPoly(( nbNewNodes / ( elemType.myIsQuad + 1 ) > 4 ));
+
+              SMDS_MeshElement* newElem = AddElement( face_nodes, elemType );
+              if ( aShapeId )
                 aMesh->SetMeshElementOnShape(newElem, aShapeId);
             }
-
-            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());
           }
+          rmElemIds.push_back(elem->GetID());
 
-        }
-        else if (elem->GetType() == SMDSAbs_Volume) {
-          // Polyhedral volume
+        } // Polygon
+
+        else if (elem->GetType() == SMDSAbs_Volume) // Polyhedral volume
+        {
           if (nbUniqueNodes < 4) {
             rmElemIds.push_back(elem->GetID());
           }
           else {
             // each face has to be analyzed in order to check volume validity
-            const SMDS_VtkVolume* aPolyedre =
-              dynamic_cast<const SMDS_VtkVolume*>( elem );
-            if (aPolyedre) {
+            const SMDS_VtkVolume* aPolyedre = dynamic_cast<const SMDS_VtkVolume*>( elem );
+            if (aPolyedre)
+            {
               int nbFaces = aPolyedre->NbFaces();
 
               vector<const SMDS_MeshNode *> poly_nodes;
@@ -7001,16 +7498,14 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
               }
 
               if (quantities.size() > 3)
-                {
-                  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());
-                }
+              {
+                const SMDS_MeshElement* 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());
@@ -7409,46 +7904,18 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
 
     } // if ( nbNodes != nbUniqueNodes ) // some nodes stick
 
-    if ( isOk ) { // the elem remains valid after sticking nodes
-      if (elem->IsPoly() && elem->GetType() == SMDSAbs_Volume)
-      {
-        // Change nodes of polyedre
-        const SMDS_VtkVolume* aPolyedre =
-          dynamic_cast<const SMDS_VtkVolume*>( elem );
-        if (aPolyedre) {
-          int nbFaces = aPolyedre->NbFaces();
-
-          vector<const SMDS_MeshNode *> poly_nodes;
-          vector<int> quantities (nbFaces);
-
-          for (int iface = 1; iface <= nbFaces; iface++) {
-            int inode, nbFaceNodes = aPolyedre->NbFaceNodes(iface);
-            quantities[iface - 1] = nbFaceNodes;
-
-            for (inode = 1; inode <= nbFaceNodes; inode++) {
-              const SMDS_MeshNode* curNode = aPolyedre->GetFaceNode(iface, inode);
-
-              TNodeNodeMap::iterator nnIt = nodeNodeMap.find( curNode );
-              if (nnIt != nodeNodeMap.end()) { // curNode sticks
-                curNode = (*nnIt).second;
-              }
-              poly_nodes.push_back(curNode);
-            }
-          }
-          aMesh->ChangePolyhedronNodes( elem, poly_nodes, quantities );
-        }
-      }
-      else // replace non-polyhedron elements
+    if ( isOk ) // the non-poly elem remains valid after sticking nodes
+    {
+      if ( nbNodes != nbUniqueNodes ||
+           !aMesh->ChangeElementNodes( elem, & curNodes[0], nbNodes ))
       {
-        const SMDSAbs_ElementType etyp = elem->GetType();
-        const int elemId               = elem->GetID();
-        const bool isPoly              = (elem->GetEntityType() == SMDSEntity_Polygon);
-        uniqueNodes.resize(nbUniqueNodes);
+        elemType.Init( elem ).SetID( elem->GetID() );
 
         SMESHDS_SubMesh * sm = aShapeId > 0 ? aMesh->MeshElements(aShapeId) : 0;
-
         aMesh->RemoveFreeElement(elem, sm, /*fromGroups=*/false);
-        SMDS_MeshElement* newElem = this->AddElement(uniqueNodes, etyp, isPoly, elemId);
+
+        uniqueNodes.resize(nbUniqueNodes);
+        SMDS_MeshElement* newElem = this->AddElement( uniqueNodes, elemType );
         if ( sm && newElem )
           sm->AddElement( newElem );
         if ( elem != newElem )
@@ -7467,6 +7934,7 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
   Remove( rmElemIds, false );
   Remove( rmNodeIds, true );
 
+  return;
 }
 
 
@@ -7489,10 +7957,6 @@ public:
   const SMDS_MeshElement* Get() const
   { return myElem; }
 
-  void Set(const SMDS_MeshElement* e) const
-  { myElem = e; }
-
-
 private:
   mutable const SMDS_MeshElement* myElem;
 };
@@ -7516,7 +7980,7 @@ void SMESH_MeshEditor::FindEqualElements(TIDSortedElemSet &        theElements,
   { // get all elements in the mesh
     SMDS_ElemIteratorPtr eIt = GetMeshDS()->elementsIterator();
     while ( eIt->more() )
-      theElements.insert( theElements.end(), eIt->next());
+      theElements.insert( theElements.end(), eIt->next() );
   }
 
   vector< TGroupOfElems > arrayOfGroups;
@@ -7524,31 +7988,32 @@ void SMESH_MeshEditor::FindEqualElements(TIDSortedElemSet &        theElements,
   TMapOfNodeSet mapOfNodeSet;
 
   TIDSortedElemSet::iterator elemIt = theElements.begin();
-  for ( int i = 0, j=0; elemIt != theElements.end(); ++elemIt, ++j ) {
+  for ( int i = 0; elemIt != theElements.end(); ++elemIt )
+  {
     const SMDS_MeshElement* curElem = *elemIt;
     SortableElement SE(curElem);
-    int ind = -1;
     // check uniqueness
     pair< TMapOfNodeSet::iterator, bool> pp = mapOfNodeSet.insert(make_pair(SE, i));
-    if( !(pp.second) ) {
+    if ( !pp.second ) { // one more coincident elem
       TMapOfNodeSet::iterator& itSE = pp.first;
-      ind = (*itSE).second;
-      arrayOfGroups[ind].push_back(curElem->GetID());
+      int ind = (*itSE).second;
+      arrayOfGroups[ind].push_back( curElem->GetID() );
     }
     else {
-      groupOfElems.clear();
-      groupOfElems.push_back(curElem->GetID());
-      arrayOfGroups.push_back(groupOfElems);
+      arrayOfGroups.push_back( groupOfElems );
+      arrayOfGroups.back().push_back( curElem->GetID() );
       i++;
     }
   }
 
+  groupOfElems.clear();
   vector< TGroupOfElems >::iterator groupIt = arrayOfGroups.begin();
-  for ( ; groupIt != arrayOfGroups.end(); ++groupIt ) {
-    groupOfElems = *groupIt;
-    if ( groupOfElems.size() > 1 ) {
-      groupOfElems.sort();
-      theGroupsOfElementsID.push_back(groupOfElems);
+  for ( ; groupIt != arrayOfGroups.end(); ++groupIt )
+  {
+    if ( groupIt->size() > 1 ) {
+      //groupOfElems.sort(); -- theElements is sorted already
+      theGroupsOfElementsID.push_back( groupOfElems );
+      theGroupsOfElementsID.back().splice( theGroupsOfElementsID.back().end(), *groupIt );
     }
   }
 }
@@ -7619,6 +8084,24 @@ static const SMDS_MeshElement* findAdjacentFace(const SMDS_MeshNode* n1,
   return SMESH_MeshAlgos::FindFaceInSet( n1, n2, elemSet, avoidSet );
 }
 
+//=======================================================================
+//function : findSegment
+//purpose  : Return a mesh segment by two nodes one of which can be medium
+//=======================================================================
+
+static const SMDS_MeshElement* findSegment(const SMDS_MeshNode* n1,
+                                           const SMDS_MeshNode* n2)
+{
+  SMDS_ElemIteratorPtr it = n1->GetInverseElementIterator( SMDSAbs_Edge );
+  while ( it->more() )
+  {
+    const SMDS_MeshElement* seg = it->next();
+    if ( seg->GetNodeIndex( n2 ) >= 0 )
+      return seg;
+  }
+  return 0;
+}
+
 //=======================================================================
 //function : FindFreeBorder
 //purpose  :
@@ -7643,7 +8126,6 @@ bool SMESH_MeshEditor::FindFreeBorder (const SMDS_MeshNode*             theFirst
   theNodes.push_back( theFirstNode );
   theNodes.push_back( theSecondNode );
 
-  //vector<const SMDS_MeshNode*> nodes;
   const SMDS_MeshNode *nIgnore = theFirstNode, *nStart = theSecondNode;
   TIDSortedElemSet foundElems;
   bool needTheLast = ( theLastNode != 0 );
@@ -7655,17 +8137,16 @@ bool SMESH_MeshEditor::FindFreeBorder (const SMDS_MeshNode*             theFirst
     // find all free border faces sharing form nStart
 
     list< const SMDS_MeshElement* > curElemList;
-    list< const SMDS_MeshNode* > nStartList;
+    list< const SMDS_MeshNode* >    nStartList;
     SMDS_ElemIteratorPtr invElemIt = nStart->GetInverseElementIterator(SMDSAbs_Face);
     while ( invElemIt->more() ) {
       const SMDS_MeshElement* e = invElemIt->next();
       if ( e == curElem || foundElems.insert( e ).second ) {
         // get nodes
         int iNode = 0, nbNodes = e->NbNodes();
-        //const SMDS_MeshNode* nodes[nbNodes+1];
         vector<const SMDS_MeshNode*> nodes(nbNodes+1);
 
-        if(e->IsQuadratic()) {
+        if ( e->IsQuadratic() ) {
           const SMDS_VtkFace* F =
             dynamic_cast<const SMDS_VtkFace*>(e);
           if (!F) throw SALOME_Exception(LOCALIZED("not an SMDS_VtkFace"));
@@ -7782,6 +8263,8 @@ bool SMESH_MeshEditor::CheckFreeBorderNodes(const SMDS_MeshNode* theNode1,
 //=======================================================================
 //function : SewFreeBorder
 //purpose  :
+//warning  : for border-to-side sewing theSideSecondNode is considered as
+//           the last side node and theSideThirdNode is not used
 //=======================================================================
 
 SMESH_MeshEditor::Sew_Error
@@ -7805,9 +8288,9 @@ SMESH_MeshEditor::SewFreeBorder (const SMDS_MeshNode* theBordFirstNode,
   //    find side nodes and elements
   // ====================================
 
-  list< const SMDS_MeshNode* > nSide[ 2 ];
+  list< const SMDS_MeshNode* >    nSide[ 2 ];
   list< const SMDS_MeshElement* > eSide[ 2 ];
-  list< const SMDS_MeshNode* >::iterator nIt[ 2 ];
+  list< const SMDS_MeshNode* >::iterator    nIt[ 2 ];
   list< const SMDS_MeshElement* >::iterator eIt[ 2 ];
 
   // Free border 1
@@ -8043,12 +8526,26 @@ SMESH_MeshEditor::SewFreeBorder (const SMDS_MeshNode* theBordFirstNode,
   // sew the border to the side 2
   // ============================
 
-  int nbNodes[]  = { nSide[0].size(), nSide[1].size() };
+  int nbNodes[]  = { (int)nSide[0].size(), (int)nSide[1].size() };
   int maxNbNodes = Max( nbNodes[0], nbNodes[1] );
 
+  bool toMergeConformal = ( nbNodes[0] == nbNodes[1] );
+  if ( toMergeConformal && toCreatePolygons )
+  {
+    // do not merge quadrangles if polygons are OK (IPAL0052824)
+    eIt[0] = eSide[0].begin();
+    eIt[1] = eSide[1].begin();
+    bool allQuads[2] = { true, true };
+    for ( int iBord = 0; iBord < 2; iBord++ ) { // loop on 2 borders
+      for ( ; allQuads[iBord] && eIt[iBord] != eSide[iBord].end(); ++eIt[iBord] )
+        allQuads[iBord] = ( (*eIt[iBord])->NbCornerNodes() == 4 );
+    }
+    toMergeConformal = ( !allQuads[0] && !allQuads[1] );
+  }
+
   TListOfListOfNodes nodeGroupsToMerge;
-  if ( nbNodes[0] == nbNodes[1] ||
-       ( theSideIsFreeBorder && !theSideThirdNode)) {
+  if (( toMergeConformal ) ||
+      ( theSideIsFreeBorder && !theSideThirdNode )) {
 
     // all nodes are to be merged
 
@@ -8066,10 +8563,9 @@ SMESH_MeshEditor::SewFreeBorder (const SMDS_MeshNode* theBordFirstNode,
     // insert new nodes into the border and the side to get equal nb of segments
 
     // get normalized parameters of nodes on the borders
-    //double param[ 2 ][ maxNbNodes ];
-    double* param[ 2 ];
-    param[0] = new double [ maxNbNodes ];
-    param[1] = new double [ maxNbNodes ];
+    vector< double > param[ 2 ];
+    param[0].resize( maxNbNodes );
+    param[1].resize( maxNbNodes );
     int iNode, iBord;
     for ( iBord = 0; iBord < 2; iBord++ ) { // loop on 2 borders
       list< const SMDS_MeshNode* >& nodes = nSide[ iBord ];
@@ -8114,8 +8610,8 @@ SMESH_MeshEditor::SewFreeBorder (const SMDS_MeshNode* theBordFirstNode,
         if ( i[ iBord ] > 0 )
           prevParam = Max( prevParam, param[iBord][ i[iBord] - 1 ]);
       }
-      double minParam = Min( param[ 0 ][ i[0] ], param[ 1 ][ i[1] ]);
-      double maxParam = Max( param[ 0 ][ i[0] ], param[ 1 ][ i[1] ]);
+      double  minParam = Min( param[ 0 ][ i[0] ], param[ 1 ][ i[1] ]);
+      double  maxParam = Max( param[ 0 ][ i[0] ], param[ 1 ][ i[1] ]);
       double minSegLen = Min( nextParam - minParam, maxParam - prevParam );
 
       // choose to insert or to merge nodes
@@ -8139,10 +8635,10 @@ SMESH_MeshEditor::SewFreeBorder (const SMDS_MeshNode* theBordFirstNode,
         // insert
         // ------
         int intoBord = ( du < 0 ) ? 0 : 1;
-        const SMDS_MeshElement* elem = *eIt[ intoBord ];
+        const SMDS_MeshElement* elem = *eIt [ intoBord ];
         const SMDS_MeshNode*    n1   = nPrev[ intoBord ];
-        const SMDS_MeshNode*    n2   = *nIt[ intoBord ];
-        const SMDS_MeshNode*    nIns = *nIt[ 1 - intoBord ];
+        const SMDS_MeshNode*    n2   = *nIt [ intoBord ];
+        const SMDS_MeshNode*    nIns = *nIt [ 1 - intoBord ];
         if ( intoBord == 1 ) {
           // move node of the border to be on a link of elem of the side
           gp_XYZ p1 (n1->X(), n1->Y(), n1->Z());
@@ -8152,7 +8648,7 @@ SMESH_MeshEditor::SewFreeBorder (const SMDS_MeshNode* theBordFirstNode,
           GetMeshDS()->MoveNode( nIns, p.X(), p.Y(), p.Z() );
         }
         insertMapIt = insertMap.find( elem );
-        bool notFound = ( insertMapIt == insertMap.end() );
+        bool  notFound = ( insertMapIt == insertMap.end() );
         bool otherLink = ( !notFound && (*insertMapIt).second.front() != n1 );
         if ( otherLink ) {
           // insert into another link of the same element:
@@ -8162,12 +8658,11 @@ SMESH_MeshEditor::SewFreeBorder (const SMDS_MeshNode* theBordFirstNode,
           const SMDS_MeshNode* n22 = nodeList.front(); nodeList.pop_front();
           InsertNodesIntoLink( elem, n12, n22, nodeList, toCreatePolygons );
           // 2. perform insertion into the link of adjacent faces
-          while (true) {
-            const SMDS_MeshElement* adjElem = findAdjacentFace( n12, n22, elem );
-            if ( adjElem )
-              InsertNodesIntoLink( adjElem, n12, n22, nodeList, toCreatePolygons );
-            else
-              break;
+          while ( const SMDS_MeshElement* adjElem = findAdjacentFace( n12, n22, elem )) {
+            InsertNodesIntoLink( adjElem, n12, n22, nodeList, toCreatePolygons );
+          }
+          while ( const SMDS_MeshElement* seg = findSegment( n12, n22 )) {
+            InsertNodesIntoLink( seg, n12, n22, nodeList );
           }
           if (toCreatePolyedrs) {
             // perform insertion into the links of adjacent volumes
@@ -8179,8 +8674,7 @@ SMESH_MeshEditor::SewFreeBorder (const SMDS_MeshNode* theBordFirstNode,
         }
         if ( notFound || otherLink ) {
           // add element and nodes of the side into the insertMap
-          insertMapIt = insertMap.insert
-            ( TElemOfNodeListMap::value_type( elem, list<const SMDS_MeshNode*>() )).first;
+          insertMapIt = insertMap.insert( make_pair( elem, list<const SMDS_MeshNode*>() )).first;
           (*insertMapIt).second.push_back( n1 );
           (*insertMapIt).second.push_back( n2 );
         }
@@ -8214,14 +8708,14 @@ SMESH_MeshEditor::SewFreeBorder (const SMDS_MeshNode* theBordFirstNode,
 
       InsertNodesIntoLink( elem, n1, n2, nodeList, toCreatePolygons );
 
+      while ( const SMDS_MeshElement* seg = findSegment( n1, n2 )) {
+        InsertNodesIntoLink( seg, n1, n2, nodeList );
+      }
+
       if ( !theSideIsFreeBorder ) {
         // look for and insert nodes into the faces adjacent to elem
-        while (true) {
-          const SMDS_MeshElement* adjElem = findAdjacentFace( n1, n2, elem );
-          if ( adjElem )
-            InsertNodesIntoLink( adjElem, n1, n2, nodeList, toCreatePolygons );
-          else
-            break;
+        while ( const SMDS_MeshElement* adjElem = findAdjacentFace( n1, n2, elem )) {
+          InsertNodesIntoLink( adjElem, n1, n2, nodeList, toCreatePolygons );
         }
       }
       if (toCreatePolyedrs) {
@@ -8229,69 +8723,155 @@ SMESH_MeshEditor::SewFreeBorder (const SMDS_MeshNode* theBordFirstNode,
         UpdateVolumes(n1, n2, nodeList);
       }
     }
-
-    delete param[0];
-    delete param[1];
   } // end: insert new nodes
 
   MergeNodes ( nodeGroupsToMerge );
 
+
+  // Remove coincident segments
+
+  // get new segments
+  TIDSortedElemSet segments;
+  SMESH_SequenceOfElemPtr newFaces;
+  for ( int i = 1; i <= myLastCreatedElems.Length(); ++i )
+  {
+    if ( !myLastCreatedElems(i) ) continue;
+    if ( myLastCreatedElems(i)->GetType() == SMDSAbs_Edge )
+      segments.insert( segments.end(), myLastCreatedElems(i) );
+    else
+      newFaces.Append( myLastCreatedElems(i) );
+  }
+  // get segments adjacent to merged nodes
+  TListOfListOfNodes::iterator groupIt = nodeGroupsToMerge.begin();
+  for ( ; groupIt != nodeGroupsToMerge.end(); groupIt++ )
+  {
+    const list<const SMDS_MeshNode*>& nodes = *groupIt;
+    SMDS_ElemIteratorPtr segIt = nodes.front()->GetInverseElementIterator( SMDSAbs_Edge );
+    while ( segIt->more() )
+      segments.insert( segIt->next() );
+  }
+
+  // find coincident
+  TListOfListOfElementsID equalGroups;
+  if ( !segments.empty() )
+    FindEqualElements( segments, equalGroups );
+  if ( !equalGroups.empty() )
+  {
+    // remove from segments those that will be removed
+    TListOfListOfElementsID::iterator itGroups = equalGroups.begin();
+    for ( ; itGroups != equalGroups.end(); ++itGroups )
+    {
+      list< int >& group = *itGroups;
+      list< int >::iterator id = group.begin();
+      for ( ++id; id != group.end(); ++id )
+        if ( const SMDS_MeshElement* seg = GetMeshDS()->FindElement( *id ))
+          segments.erase( seg );
+    }
+    // remove equal segments
+    MergeElements( equalGroups );
+
+    // restore myLastCreatedElems
+    myLastCreatedElems = newFaces;
+    TIDSortedElemSet::iterator seg = segments.begin();
+    for ( ; seg != segments.end(); ++seg )
+      myLastCreatedElems.Append( *seg );
+  }
+
   return aResult;
 }
 
 //=======================================================================
 //function : InsertNodesIntoLink
-//purpose  : insert theNodesToInsert into theFace between theBetweenNode1
+//purpose  : insert theNodesToInsert into theElement between theBetweenNode1
 //           and theBetweenNode2 and split theElement
 //=======================================================================
 
-void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
+void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theElement,
                                            const SMDS_MeshNode*        theBetweenNode1,
                                            const SMDS_MeshNode*        theBetweenNode2,
                                            list<const SMDS_MeshNode*>& theNodesToInsert,
                                            const bool                  toCreatePoly)
 {
+  if ( !theElement ) return;
+
+  SMESHDS_Mesh *aMesh = GetMeshDS();
+  vector<const SMDS_MeshElement*> newElems;
+
+  if ( theElement->GetType() == SMDSAbs_Edge )
+  {
+    theNodesToInsert.push_front( theBetweenNode1 );
+    theNodesToInsert.push_back ( theBetweenNode2 );
+    list<const SMDS_MeshNode*>::iterator n = theNodesToInsert.begin();
+    const SMDS_MeshNode* n1 = *n;
+    for ( ++n; n != theNodesToInsert.end(); ++n )
+    {
+      const SMDS_MeshNode* n2 = *n;
+      if ( const SMDS_MeshElement* seg = aMesh->FindEdge( n1, n2 ))
+        AddToSameGroups( seg, theElement, aMesh );
+      else
+        newElems.push_back( aMesh->AddEdge ( n1, n2 ));
+      n1 = n2;
+    }
+    theNodesToInsert.pop_front();
+    theNodesToInsert.pop_back();
+
+    if ( theElement->IsQuadratic() ) // add a not split part
+    {
+      vector<const SMDS_MeshNode*> nodes( theElement->begin_nodes(),
+                                          theElement->end_nodes() );
+      int iOther = 0, nbN = nodes.size();
+      for ( ; iOther < nbN; ++iOther )
+        if ( nodes[iOther] != theBetweenNode1 &&
+             nodes[iOther] != theBetweenNode2 )
+          break;
+      if      ( iOther == 0 )
+      {
+        if ( const SMDS_MeshElement* seg = aMesh->FindEdge( nodes[0], nodes[1] ))
+          AddToSameGroups( seg, theElement, aMesh );
+        else
+          newElems.push_back( aMesh->AddEdge ( nodes[0], nodes[1] ));
+      }
+      else if ( iOther == 2 )
+      {
+        if ( const SMDS_MeshElement* seg = aMesh->FindEdge( nodes[1], nodes[2] ))
+          AddToSameGroups( seg, theElement, aMesh );
+        else
+          newElems.push_back( aMesh->AddEdge ( nodes[1], nodes[2] ));
+      }
+    }
+    // treat new elements
+    for ( size_t i = 0; i < newElems.size(); ++i )
+      if ( newElems[i] )
+      {
+        aMesh->SetMeshElementOnShape( newElems[i], theElement->getshapeId() );
+        myLastCreatedElems.Append( newElems[i] );
+      }
+    ReplaceElemInGroups( theElement, newElems, aMesh );
+    aMesh->RemoveElement( theElement );
+    return;
+
+  } // if ( theElement->GetType() == SMDSAbs_Edge )
+
+  const SMDS_MeshElement* theFace = theElement;
   if ( theFace->GetType() != SMDSAbs_Face ) return;
 
   // find indices of 2 link nodes and of the rest nodes
   int iNode = 0, il1, il2, i3, i4;
   il1 = il2 = i3 = i4 = -1;
-  //const SMDS_MeshNode* nodes[ theFace->NbNodes() ];
   vector<const SMDS_MeshNode*> nodes( theFace->NbNodes() );
 
-  if(theFace->IsQuadratic()) {
-    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_ElemIteratorPtr anIter = F->interlacedNodesElemIterator();
-    while( anIter->more() ) {
-      const SMDS_MeshNode* n = cast2Node(anIter->next());
-      if ( n == theBetweenNode1 )
-        il1 = iNode;
-      else if ( n == theBetweenNode2 )
-        il2 = iNode;
-      else if ( i3 < 0 )
-        i3 = iNode;
-      else
-        i4 = iNode;
-      nodes[ iNode++ ] = n;
-    }
-  }
-  else {
-    SMDS_ElemIteratorPtr nodeIt = theFace->nodesIterator();
-    while ( nodeIt->more() ) {
-      const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
-      if ( n == theBetweenNode1 )
-        il1 = iNode;
-      else if ( n == theBetweenNode2 )
-        il2 = iNode;
-      else if ( i3 < 0 )
-        i3 = iNode;
-      else
-        i4 = iNode;
-      nodes[ iNode++ ] = n;
-    }
+  SMDS_NodeIteratorPtr nodeIt = theFace->interlacedNodesIterator();
+  while ( nodeIt->more() ) {
+    const SMDS_MeshNode* n = nodeIt->next();
+    if ( n == theBetweenNode1 )
+      il1 = iNode;
+    else if ( n == theBetweenNode2 )
+      il2 = iNode;
+    else if ( i3 < 0 )
+      i3 = iNode;
+    else
+      i4 = iNode;
+    nodes[ iNode++ ] = n;
   }
   if ( il1 < 0 || il2 < 0 || i3 < 0 )
     return ;
@@ -8321,9 +8901,8 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
     // add nodes of face up to first node of link
     bool isFLN = false;
 
-    if(theFace->IsQuadratic()) {
-      const SMDS_VtkFace* F =
-        dynamic_cast<const SMDS_VtkFace*>(theFace);
+    if ( theFace->IsQuadratic() ) {
+      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_ElemIteratorPtr anIter = F->interlacedNodesElemIterator();
@@ -8365,28 +8944,12 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
       }
     }
 
-    // edit or replace the face
-    SMESHDS_Mesh *aMesh = GetMeshDS();
-
-    if (theFace->IsPoly()) {
-      aMesh->ChangePolygonNodes(theFace, poly_nodes);
-    }
-    else {
-      int aShapeId = FindShape( theFace );
-
-      SMDS_MeshElement* newElem = aMesh->AddPolygonalFace(poly_nodes);
-      myLastCreatedElems.Append(newElem);
-      if ( aShapeId && newElem )
-        aMesh->SetMeshElementOnShape( newElem, aShapeId );
-
-      aMesh->RemoveElement(theFace);
-    }
-    return;
+    // make a new face
+    newElems.push_back( aMesh->AddPolygonalFace( poly_nodes ));
   }
 
-  SMESHDS_Mesh *aMesh = GetMeshDS();
-  if( !theFace->IsQuadratic() ) {
-
+  else if ( !theFace->IsQuadratic() )
+  {
     // put aNodesToInsert between theBetweenNode1 and theBetweenNode2
     int nbLinkNodes = 2 + aNodesToInsert.size();
     //const SMDS_MeshNode* linkNodes[ nbLinkNodes ];
@@ -8435,41 +8998,32 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
     }
 
     // create new elements
-    int aShapeId = FindShape( theFace );
-
     i1 = 0; i2 = 1;
-    for ( iSplit = 0; iSplit < nbSplits - 1; iSplit++ ) {
-      SMDS_MeshElement* newElem = 0;
+    for ( iSplit = 0; iSplit < nbSplits - 1; iSplit++ )
+    {
       if ( iSplit == iBestQuad )
-        newElem = aMesh->AddFace (linkNodes[ i1++ ],
-                                  linkNodes[ i2++ ],
-                                  nodes[ i3 ],
-                                  nodes[ i4 ]);
+        newElems.push_back( aMesh->AddFace (linkNodes[ i1++ ],
+                                            linkNodes[ i2++ ],
+                                            nodes[ i3 ],
+                                            nodes[ i4 ]));
       else
-        newElem = aMesh->AddFace (linkNodes[ i1++ ],
-                                  linkNodes[ i2++ ],
-                                  nodes[ iSplit < iBestQuad ? i4 : i3 ]);
-      myLastCreatedElems.Append(newElem);
-      if ( aShapeId && newElem )
-        aMesh->SetMeshElementOnShape( newElem, aShapeId );
+        newElems.push_back( aMesh->AddFace (linkNodes[ i1++ ],
+                                            linkNodes[ i2++ ],
+                                            nodes[ iSplit < iBestQuad ? i4 : i3 ]));
     }
 
-    // change nodes of theFace
     const SMDS_MeshNode* newNodes[ 4 ];
     newNodes[ 0 ] = linkNodes[ i1 ];
     newNodes[ 1 ] = linkNodes[ i2 ];
     newNodes[ 2 ] = nodes[ iSplit >= iBestQuad ? i3 : i4 ];
     newNodes[ 3 ] = nodes[ i4 ];
-    //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] );
+      newElems.push_back( 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())
+      newElems.push_back( aMesh->AddFace( newNodes[0], newNodes[1], newNodes[2] ));
+
+  } // end if(!theFace->IsQuadratic())
+
   else { // theFace is quadratic
     // we have to split theFace on simple triangles and one simple quadrangle
     int tmp = il1/2;
@@ -8496,66 +9050,38 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
     //           n4           n6      n5     n4
 
     // create new elements
-    int aShapeId = FindShape( theFace );
-
     int n1,n2,n3;
-    if(nbFaceNodes==6) { // quadratic triangle
-      SMDS_MeshElement* newElem =
-        aMesh->AddFace(nodes[3],nodes[4],nodes[5]);
-      myLastCreatedElems.Append(newElem);
-      if ( aShapeId && newElem )
-        aMesh->SetMeshElementOnShape( newElem, aShapeId );
-      if(theFace->IsMediumNode(nodes[il1])) {
+    if ( nbFaceNodes == 6 ) { // quadratic triangle
+      newElems.push_back( aMesh->AddFace( nodes[3], nodes[4], nodes[5] ));
+      if ( theFace->IsMediumNode(nodes[il1]) ) {
         // create quadrangle
-        newElem = aMesh->AddFace(nodes[0],nodes[1],nodes[3],nodes[5]);
-        myLastCreatedElems.Append(newElem);
-        if ( aShapeId && newElem )
-          aMesh->SetMeshElementOnShape( newElem, aShapeId );
+        newElems.push_back( aMesh->AddFace( nodes[0], nodes[1], nodes[3], nodes[5] ));
         n1 = 1;
         n2 = 2;
         n3 = 3;
       }
       else {
         // create quadrangle
-        newElem = aMesh->AddFace(nodes[1],nodes[2],nodes[3],nodes[5]);
-        myLastCreatedElems.Append(newElem);
-        if ( aShapeId && newElem )
-          aMesh->SetMeshElementOnShape( newElem, aShapeId );
+        newElems.push_back( aMesh->AddFace( nodes[1], nodes[2], nodes[3], nodes[5] ));
         n1 = 0;
         n2 = 1;
         n3 = 5;
       }
     }
     else { // nbFaceNodes==8 - quadratic quadrangle
-      SMDS_MeshElement* newElem =
-        aMesh->AddFace(nodes[3],nodes[4],nodes[5]);
-      myLastCreatedElems.Append(newElem);
-      if ( aShapeId && newElem )
-        aMesh->SetMeshElementOnShape( newElem, aShapeId );
-      newElem = aMesh->AddFace(nodes[5],nodes[6],nodes[7]);
-      myLastCreatedElems.Append(newElem);
-      if ( aShapeId && newElem )
-        aMesh->SetMeshElementOnShape( newElem, aShapeId );
-      newElem = aMesh->AddFace(nodes[5],nodes[7],nodes[3]);
-      myLastCreatedElems.Append(newElem);
-      if ( aShapeId && newElem )
-        aMesh->SetMeshElementOnShape( newElem, aShapeId );
-      if(theFace->IsMediumNode(nodes[il1])) {
+      newElems.push_back( aMesh->AddFace( nodes[3], nodes[4], nodes[5] ));
+      newElems.push_back( aMesh->AddFace( nodes[5], nodes[6], nodes[7] ));
+      newElems.push_back( aMesh->AddFace( nodes[5], nodes[7], nodes[3] ));
+      if ( theFace->IsMediumNode( nodes[ il1 ])) {
         // create quadrangle
-        newElem = aMesh->AddFace(nodes[0],nodes[1],nodes[3],nodes[7]);
-        myLastCreatedElems.Append(newElem);
-        if ( aShapeId && newElem )
-          aMesh->SetMeshElementOnShape( newElem, aShapeId );
+        newElems.push_back( aMesh->AddFace( nodes[0], nodes[1], nodes[3], nodes[7] ));
         n1 = 1;
         n2 = 2;
         n3 = 3;
       }
       else {
         // create quadrangle
-        newElem = aMesh->AddFace(nodes[1],nodes[2],nodes[3],nodes[7]);
-        myLastCreatedElems.Append(newElem);
-        if ( aShapeId && newElem )
-          aMesh->SetMeshElementOnShape( newElem, aShapeId );
+        newElems.push_back( aMesh->AddFace( nodes[1], nodes[2], nodes[3], nodes[7] ));
         n1 = 0;
         n2 = 1;
         n3 = 7;
@@ -8563,30 +9089,34 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
     }
     // create needed triangles using n1,n2,n3 and inserted nodes
     int nbn = 2 + aNodesToInsert.size();
-    //const SMDS_MeshNode* aNodes[nbn];
     vector<const SMDS_MeshNode*> aNodes(nbn);
-    aNodes[0] = nodes[n1];
+    aNodes[0    ] = nodes[n1];
     aNodes[nbn-1] = nodes[n2];
     list<const SMDS_MeshNode*>::iterator nIt = aNodesToInsert.begin();
     for ( iNode = 1; nIt != aNodesToInsert.end(); nIt++ ) {
       aNodes[iNode++] = *nIt;
     }
-    for(i=1; i<nbn; i++) {
-      SMDS_MeshElement* newElem =
-        aMesh->AddFace(aNodes[i-1],aNodes[i],nodes[n3]);
-      myLastCreatedElems.Append(newElem);
-      if ( aShapeId && newElem )
-        aMesh->SetMeshElementOnShape( newElem, aShapeId );
-    }
+    for ( i = 1; i < nbn; i++ )
+      newElems.push_back( aMesh->AddFace( aNodes[i-1], aNodes[i], nodes[n3] ));
   }
-  // remove old face
+
+  // remove the old face
+  for ( size_t i = 0; i < newElems.size(); ++i )
+    if ( newElems[i] )
+    {
+      aMesh->SetMeshElementOnShape( newElems[i], theFace->getshapeId() );
+      myLastCreatedElems.Append( newElems[i] );
+    }
+  ReplaceElemInGroups( theFace, newElems, aMesh );
   aMesh->RemoveElement(theFace);
-}
+
+} // InsertNodesIntoLink()
 
 //=======================================================================
 //function : UpdateVolumes
 //purpose  :
 //=======================================================================
+
 void SMESH_MeshEditor::UpdateVolumes (const SMDS_MeshNode*        theBetweenNode1,
                                       const SMDS_MeshNode*        theBetweenNode2,
                                       list<const SMDS_MeshNode*>& theNodesToInsert)
@@ -8648,24 +9178,16 @@ void SMESH_MeshEditor::UpdateVolumes (const SMDS_MeshNode*        theBetweenNode
       quantities[iface] = nbFaceNodes + nbInserted;
     }
 
-    // Replace or update the volume
+    // Replace the volume
     SMESHDS_Mesh *aMesh = GetMeshDS();
 
-    if (elem->IsPoly()) {
-      aMesh->ChangePolyhedronNodes(elem, poly_nodes, quantities);
-
-    }
-    else {
-      int aShapeId = FindShape( elem );
-
-      SMDS_MeshElement* newElem =
-        aMesh->AddPolyhedralVolume(poly_nodes, quantities);
-      myLastCreatedElems.Append(newElem);
-      if (aShapeId && newElem)
-        aMesh->SetMeshElementOnShape(newElem, aShapeId);
-
-      aMesh->RemoveElement(elem);
+    if ( SMDS_MeshElement* newElem = aMesh->AddPolyhedralVolume( poly_nodes, quantities ))
+    {
+      aMesh->SetMeshElementOnShape( newElem, elem->getshapeId() );
+      myLastCreatedElems.Append( newElem );
+      ReplaceElemInGroups( elem, newElem, aMesh );
     }
+    aMesh->RemoveElement( elem );
   }
 }
 
@@ -8695,7 +9217,7 @@ namespace
 
 //=======================================================================
 /*!
- * \brief Convert elements contained in a submesh to quadratic
+ * \brief Convert elements contained in a sub-mesh to quadratic
  * \return int - nb of checked elements
  */
 //=======================================================================
@@ -9218,6 +9740,8 @@ int SMESH_MeshEditor::removeQuadElem(SMESHDS_SubMesh *    theSm,
 {
   int nbElem = 0;
   SMESHDS_Mesh* meshDS = GetMeshDS();
+  ElemFeatures elemType;
+  vector<const SMDS_MeshNode *> nodes;
 
   while( theItr->more() )
   {
@@ -9225,11 +9749,11 @@ int SMESH_MeshEditor::removeQuadElem(SMESHDS_SubMesh *    theSm,
     nbElem++;
     if( elem && elem->IsQuadratic())
     {
-      int id                    = elem->GetID();
-      int nbCornerNodes         = elem->NbCornerNodes();
-      SMDSAbs_ElementType aType = elem->GetType();
+      // get elem data
+      int nbCornerNodes = elem->NbCornerNodes();
+      nodes.assign( elem->begin_nodes(), elem->end_nodes() );
 
-      vector<const SMDS_MeshNode *> nodes( elem->begin_nodes(), elem->end_nodes() );
+      elemType.Init( elem, /*basicOnly=*/false ).SetID( elem->GetID() ).SetQuad( false );
 
       //remove a quadratic element
       if ( !theSm || !theSm->Contains( elem ))
@@ -9237,13 +9761,13 @@ int SMESH_MeshEditor::removeQuadElem(SMESHDS_SubMesh *    theSm,
       meshDS->RemoveFreeElement( elem, theSm, /*fromGroups=*/false );
 
       // remove medium nodes
-      for ( unsigned i = nbCornerNodes; i < nodes.size(); ++i )
+      for ( size_t 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 );
+      SMDS_MeshElement * newElem = AddElement( nodes, elemType );
       ReplaceElemInGroups(elem, newElem, meshDS);
       if( theSm && newElem )
         theSm->AddElement( newElem );
@@ -9834,11 +10358,15 @@ SMESH_MeshEditor::SewSideElements (TIDSortedElemSet&    theSide1,
   if ( aResult != SEW_OK)
     return aResult;
 
-  list< int > nodeIDsToRemove/*, elemIDsToRemove*/;
+  list< int > nodeIDsToRemove;
+  vector< const SMDS_MeshNode*> nodes;
+  ElemFeatures elemType;
+
   // loop on nodes replacement map
   TNodeNodeMap::iterator nReplaceMapIt = nReplaceMap.begin(), nnIt;
   for ( ; nReplaceMapIt != nReplaceMap.end(); nReplaceMapIt++ )
-    if ( (*nReplaceMapIt).first != (*nReplaceMapIt).second ) {
+    if ( (*nReplaceMapIt).first != (*nReplaceMapIt).second )
+    {
       const SMDS_MeshNode* nToRemove = (*nReplaceMapIt).first;
       nodeIDsToRemove.push_back( nToRemove->GetID() );
       // loop on elements sharing nToRemove
@@ -9847,11 +10375,10 @@ SMESH_MeshEditor::SewSideElements (TIDSortedElemSet&    theSide1,
         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 );
+        nodes.resize( nbNodes );
         SMDS_ElemIteratorPtr nIt = e->nodesIterator();
         while ( nIt->more() ) {
-          const SMDS_MeshNode* n =
-            static_cast<const SMDS_MeshNode*>( nIt->next() );
+          const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nIt->next() );
           nnIt = nReplaceMap.find( n );
           if ( nnIt != nReplaceMap.end() ) {
             nbReplaced++;
@@ -9863,21 +10390,17 @@ SMESH_MeshEditor::SewSideElements (TIDSortedElemSet&    theSide1,
         //         elemIDsToRemove.push_back( e->GetID() );
         //       else
         if ( nbReplaced )
+        {
+          elemType.Init( e, /*basicOnly=*/false ).SetID( e->GetID() );
+          aMesh->RemoveElement( e );
+
+          if ( SMDS_MeshElement* newElem = this->AddElement( nodes, elemType ))
           {
-            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);
+            AddToSameGroups( newElem, e, aMesh );
+            if ( int aShapeId = e->getshapeId() )
+              aMesh->SetMeshElementOnShape( newElem, aShapeId );
           }
+        }
       }
     }
 
@@ -10069,7 +10592,7 @@ SMESH_MeshEditor::FindMatchingNodes(set<const SMDS_MeshElement*>& theSide1,
 
 void SMESH_MeshEditor::DoubleElements( const TIDSortedElemSet& theElements )
 {
-  CrearLastCreated();
+  ClearLastCreated();
   SMESHDS_Mesh* mesh = GetMeshDS();
 
   // get an element type and an iterator over elements
@@ -10107,44 +10630,19 @@ void SMESH_MeshEditor::DoubleElements( const TIDSortedElemSet& theElements )
 
   // duplicate elements
 
-  if ( type == SMDSAbs_Ball )
-  {
-    SMDS_UnstructuredGrid* vtkGrid = mesh->getGrid();
-    while ( elemIt->more() )
-    {
-      const SMDS_MeshElement* elem = elemIt->next();
-      if ( elem->GetType() != SMDSAbs_Ball )
-        continue;
-      if (( elem = mesh->AddBall( elem->GetNode(0),
-                                  vtkGrid->GetBallDiameter( elem->getVtkId() ))))
-        myLastCreatedElems.Append( elem );
-    }
-  }
-  else
+  ElemFeatures elemType;
+
+  vector< const SMDS_MeshNode* > nodes;
+  while ( elemIt->more() )
   {
-    vector< const SMDS_MeshNode* > nodes;
-    while ( elemIt->more() )
-    {
-      const SMDS_MeshElement* elem = elemIt->next();
-      if ( elem->GetType() != type )
-        continue;
+    const SMDS_MeshElement* elem = elemIt->next();
+    if ( elem->GetType() != type )
+      continue;
 
-      nodes.assign( elem->begin_nodes(), elem->end_nodes() );
+    elemType.Init( elem, /*basicOnly=*/false );
+    nodes.assign( elem->begin_nodes(), elem->end_nodes() );
 
-      if ( type == SMDSAbs_Volume  && elem->GetVtkType() == VTK_POLYHEDRON )
-      {
-        std::vector<int> quantities =
-          static_cast< const SMDS_VtkVolume* >( elem )->GetQuantities();
-        elem = mesh->AddPolyhedralVolume( nodes, quantities );
-      }
-      else
-      {
-        AddElement( nodes, type, elem->IsPoly() );
-        elem = 0; // myLastCreatedElems is already filled
-      }
-      if ( elem )
-        myLastCreatedElems.Append( elem );
-    }
+    AddElement( nodes, elemType );
   }
 }
 
@@ -10175,7 +10673,7 @@ bool SMESH_MeshEditor::DoubleNodes( const TIDSortedElemSet& theElems,
     return false;
 
   bool res = false;
-  std::map< const SMDS_MeshNode*, const SMDS_MeshNode* > anOldNodeToNewNode;
+  TNodeNodeMap anOldNodeToNewNode;
   // duplicate elements and nodes
   res = doubleNodes( aMeshDS, theElems, theNodesNot, anOldNodeToNewNode, true );
   // replce nodes by duplications
@@ -10195,16 +10693,18 @@ bool SMESH_MeshEditor::DoubleNodes( const TIDSortedElemSet& theElems,
 */
 //================================================================================
 
-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 )
+bool SMESH_MeshEditor::doubleNodes(SMESHDS_Mesh*           theMeshDS,
+                                   const TIDSortedElemSet& theElems,
+                                   const TIDSortedElemSet& theNodesNot,
+                                   TNodeNodeMap&           theNodeNodeMap,
+                                   const bool              theIsDoubleElem )
 {
   MESSAGE("doubleNodes");
-  // iterate on through element and duplicate them (by nodes duplication)
+  // iterate through element and duplicate them (by nodes duplication)
   bool res = false;
+  std::vector<const SMDS_MeshNode*> newNodes;
+  ElemFeatures elemType;
+
   TIDSortedElemSet::const_iterator elemItr = theElems.begin();
   for ( ;  elemItr != theElems.end(); ++elemItr )
   {
@@ -10212,22 +10712,25 @@ bool SMESH_MeshEditor::doubleNodes( SMESHDS_Mesh*     theMeshDS,
     if (!anElem)
       continue;
 
-    bool isDuplicate = false;
     // duplicate nodes to duplicate element
-    std::vector<const SMDS_MeshNode*> newNodes( anElem->NbNodes() );
+    bool isDuplicate = false;
+    newNodes.resize( 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() )
+      const SMDS_MeshNode* aCurrNode = static_cast<const SMDS_MeshNode*>( anIter->next() );
+      const SMDS_MeshNode*  aNewNode = aCurrNode;
+      TNodeNodeMap::iterator     n2n = theNodeNodeMap.find( aCurrNode );
+      if ( n2n != theNodeNodeMap.end() )
+      {
+        aNewNode = n2n->second;
+      }
+      else if ( theIsDoubleElem && !theNodesNot.count( aCurrNode ))
       {
         // duplicate node
         aNewNode = theMeshDS->AddNode( aCurrNode->X(), aCurrNode->Y(), aCurrNode->Z() );
+        copyPosition( aCurrNode, aNewNode );
         theNodeNodeMap[ aCurrNode ] = aNewNode;
         myLastCreatedNodes.Append( aNewNode );
       }
@@ -10238,12 +10741,10 @@ bool SMESH_MeshEditor::doubleNodes( SMESHDS_Mesh*     theMeshDS,
       continue;
 
     if ( theIsDoubleElem )
-      AddElement(newNodes, anElem->GetType(), anElem->IsPoly());
+      AddElement( newNodes, elemType.Init( anElem, /*basicOnly=*/false ));
     else
-      {
-      MESSAGE("ChangeElementNodes");
-      theMeshDS->ChangeElementNodes( anElem, &newNodes[ 0 ], anElem->NbNodes() );
-      }
+      theMeshDS->ChangeElementNodes( anElem, &newNodes[ 0 ], newNodes.size() );
+
     res = true;
   }
   return res;
@@ -10254,8 +10755,8 @@ bool SMESH_MeshEditor::doubleNodes( SMESHDS_Mesh*     theMeshDS,
   \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
+  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
 */
 //================================================================================
@@ -10291,6 +10792,7 @@ bool SMESH_MeshEditor::DoubleNodes( const std::list< int >& theListOfNodes,
     const SMDS_MeshNode* aNewNode = aMeshDS->AddNode( aNode->X(), aNode->Y(), aNode->Z() );
     if ( aNewNode )
     {
+      copyPosition( aNode, aNewNode );
       anOldNodeToNewNode[ aNode ] = aNewNode;
       myLastCreatedNodes.Append( aNewNode );
     }
@@ -10593,16 +11095,16 @@ bool SMESH_MeshEditor::DoubleNodesInRegion( const TIDSortedElemSet& theElems,
     return false;
 
   const double aTol = Precision::Confusion();
-  auto_ptr< BRepClass3d_SolidClassifier> bsc3d;
-  auto_ptr<_FaceClassifier>              aFaceClassifier;
+  SMESHUtils::Deleter< BRepClass3d_SolidClassifier> bsc3d;
+  SMESHUtils::Deleter<_FaceClassifier>              aFaceClassifier;
   if ( theShape.ShapeType() == TopAbs_SOLID )
   {
-    bsc3d.reset( new BRepClass3d_SolidClassifier(theShape));;
+    bsc3d._obj = new BRepClass3d_SolidClassifier( theShape );
     bsc3d->PerformInfinitePoint(aTol);
   }
   else if (theShape.ShapeType() == TopAbs_FACE )
   {
-    aFaceClassifier.reset( new _FaceClassifier(TopoDS::Face(theShape)));
+    aFaceClassifier._obj = new _FaceClassifier( TopoDS::Face( theShape ));
   }
 
   // iterates on indicated elements and get elements by back references from their nodes
@@ -10625,7 +11127,7 @@ bool SMESH_MeshEditor::DoubleNodesInRegion( const TIDSortedElemSet& theElems,
       {
         const SMDS_MeshElement* curElem = backElemItr->next();
         if ( curElem && theElems.find(curElem) == theElems.end() &&
-             ( bsc3d.get() ?
+             ( bsc3d ?
                isInside( curElem, *bsc3d, aTol ) :
                isInside( curElem, *aFaceClassifier, aTol )))
           anAffected.insert( curElem );
@@ -10717,83 +11219,84 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
 
   // Check if the domains do not share an element
   for (int idom = 0; idom < nbDomains-1; idom++)
-    {
-//       MESSAGE("... Check of domain #" << idom);
-      const TIDSortedElemSet& domain = theElems[idom];
-      TIDSortedElemSet::const_iterator elemItr = domain.begin();
-      for (; elemItr != domain.end(); ++elemItr)
+  {
+    //       MESSAGE("... Check of domain #" << idom);
+    const TIDSortedElemSet& domain = theElems[idom];
+    TIDSortedElemSet::const_iterator elemItr = domain.begin();
+    for (; elemItr != domain.end(); ++elemItr)
+    {
+      const SMDS_MeshElement* anElem = *elemItr;
+      int idombisdeb = idom + 1 ;
+      // check if the element belongs to a domain further in the list
+      for ( size_t idombis = idombisdeb; idombis < theElems.size(); idombis++ )
+      {
+        const TIDSortedElemSet& domainbis = theElems[idombis];
+        if ( domainbis.count( anElem ))
         {
-          const SMDS_MeshElement* anElem = *elemItr;
-          int idombisdeb = idom + 1 ;
-          for (int idombis = idombisdeb; idombis < theElems.size(); idombis++) // check if the element belongs to a domain further in the list
-          {
-            const TIDSortedElemSet& domainbis = theElems[idombis];
-            if ( domainbis.count(anElem) )
-            {
-              MESSAGE(".... Domain #" << idom);
-              MESSAGE(".... Domain #" << idombis);
-              throw SALOME_Exception("The domains are not disjoint.");
-              return false ;
-            }
-          }
+          MESSAGE(".... Domain #" << idom);
+          MESSAGE(".... Domain #" << idombis);
+          throw SALOME_Exception("The domains are not disjoint.");
+          return false ;
         }
+      }
     }
+  }
 
   for (int idom = 0; idom < nbDomains; idom++)
-    {
+  {
 
-      // --- 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 his domain.
+    // --- 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 his domain.
 
-      MESSAGE("... Neighbors of domain #" << idom);
-      const TIDSortedElemSet& domain = theElems[idom];
-      TIDSortedElemSet::const_iterator elemItr = domain.begin();
-      for (; elemItr != domain.end(); ++elemItr)
+    MESSAGE("... Neighbors of domain #" << idom);
+    const TIDSortedElemSet& domain = theElems[idom];
+    TIDSortedElemSet::const_iterator elemItr = domain.begin();
+    for (; elemItr != domain.end(); ++elemItr)
+    {
+      const SMDS_MeshElement* anElem = *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 (elem && ! domain.count(elem)) // neighbor is in another domain : face is shared
         {
-          const SMDS_MeshElement* anElem = *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++)
+          bool ok = false;
+          for ( size_t idombis = 0; idombis < theElems.size() && !ok; idombis++) // check if the neighbor belongs to another domain of the list
+          {
+            // MESSAGE("Domain " << idombis);
+            const TIDSortedElemSet& domainbis = theElems[idombis];
+            if ( domainbis.count(elem)) ok = true ; // neighbor is in a correct domain : face is kept
+          }
+          if ( ok || onAllBoundaries ) // the characteristics of the face is stored
+          {
+            DownIdType face(downIds[n], downTypes[n]);
+            if (!faceDomains[face].count(idom))
             {
-              int smdsId = meshDS->fromVtkToSmds(neighborsVtkIds[n]);
-              const SMDS_MeshElement* elem = meshDS->FindElement(smdsId);
-              if (elem && ! domain.count(elem)) // neighbor is in another domain : face is shared
-                {
-                  bool ok = false ;
-                  for (int idombis = 0; idombis < theElems.size() && !ok; idombis++) // check if the neighbor belongs to another domain of the list
-                  {
-                    // MESSAGE("Domain " << idombis);
-                    const TIDSortedElemSet& domainbis = theElems[idombis];
-                    if ( domainbis.count(elem)) ok = true ; // neighbor is in a correct domain : face is kept
-                  }
-                  if ( ok || onAllBoundaries ) // the characteristics of the face is stored
-                  {
-                    DownIdType face(downIds[n], downTypes[n]);
-                    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);
-                      }
-                    if ( !ok )
-                    {
-                      theRestDomElems.insert( elem );
-                      faceDomains[face][iRestDom] = neighborsVtkIds[n];
-                      celldom[neighborsVtkIds[n]] = iRestDom;
-                    }
-                  }
-                }
+              faceDomains[face][idom] = vtkId; // volume associated to face in this domain
+              celldom[vtkId] = idom;
+              //MESSAGE("       cell with a border " << vtkId << " domain " << idom);
+            }
+            if ( !ok )
+            {
+              theRestDomElems.insert( elem );
+              faceDomains[face][iRestDom] = neighborsVtkIds[n];
+              celldom[neighborsVtkIds[n]] = iRestDom;
             }
+          }
         }
+      }
     }
+  }
 
   //MESSAGE("Number of shared faces " << faceDomains.size());
   std::map<DownIdType, std::map<int, int>, DownIdCompare>::iterator itface;
@@ -10803,48 +11306,48 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
   //     which has only a node or an edge on the border (not a shared face)
 
   for (int idomain = idom0; idomain < nbDomains; idomain++)
+  {
+    //MESSAGE("Domain " << idomain);
+    const TIDSortedElemSet& domain = (idomain == iRestDom) ? theRestDomElems : theElems[idomain];
+    itface = faceDomains.begin();
+    for (; itface != faceDomains.end(); ++itface)
     {
-      //MESSAGE("Domain " << idomain);
-      const TIDSortedElemSet& domain = (idomain == iRestDom) ? theRestDomElems : theElems[idomain];
-      itface = faceDomains.begin();
-      for (; itface != faceDomains.end(); ++itface)
+      const 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);
+        vtkCellLinks::Link l = grid->GetCellLinks()->GetLink(oldId);
+        for (int i=0; i<l.ncells; i++)
         {
-          const std::map<int, int>& domvol = itface->second;
-          if (!domvol.count(idomain))
+          int vtkId = l.cells[i];
+          const SMDS_MeshElement* anElem = GetMeshDS()->FindElement(GetMeshDS()->fromVtkToSmds(vtkId));
+          if (!domain.count(anElem))
             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);
-              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);
-                  cellDomains[aCell][idomain] = vtkId;
-                  celldom[vtkId] = idomain;
-                  //MESSAGE("       cell " << vtkId << " domain " << idomain);
-                }
-            }
+          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);
+          cellDomains[aCell][idomain] = vtkId;
+          celldom[vtkId] = idomain;
+          //MESSAGE("       cell " << vtkId << " domain " << idomain);
         }
+      }
     }
+  }
 
   // --- explore the shared faces domain by domain, to duplicate the nodes in a coherent way
   //     for each shared face, get the nodes
@@ -10860,184 +11363,185 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
 
   MESSAGE(".. Duplication of the nodes");
   for (int idomain = idom0; idomain < nbDomains; idomain++)
+  {
+    itface = faceDomains.begin();
+    for (; itface != faceDomains.end(); ++itface)
     {
-      itface = faceDomains.begin();
-      for (; itface != faceDomains.end(); ++itface)
+      const 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;
+        if (nodeDomains[oldId].empty())
         {
-          const 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)
+          nodeDomains[oldId][idomain] = oldId; // keep the old node in the first domain
+          //MESSAGE("-+-+-b     oldNode " << oldId << " domain " << idomain);
+        }
+        std::map<int, int>::const_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
             {
-              int oldId = *itn;
-              if (nodeDomains[oldId].empty())
-                {
-                  nodeDomains[oldId][idomain] = oldId; // keep the old node in the first domain
-                  //MESSAGE("-+-+-b     oldNode " << oldId << " domain " << idomain);
-                }
-              std::map<int, int>::const_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);
-                          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("-+-+-c     oldNode " << oldId << " domain " << idomain << " newNode " << newId << " domain " << idom << " size=" <<nodeDomains[oldId].size());
-                    }
-                }
+              vector<int> orderedDoms;
+              //MESSAGE("multiple node " << oldId);
+              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]);
+            copyPosition( meshDS->FindNodeVtk( oldId ), newNode );
+            int newId = newNode->getVtkId();
+            nodeDomains[oldId][idom] = newId; // cloned node for other domains
+            //MESSAGE("-+-+-c     oldNode " << oldId << " domain " << idomain << " newNode " << newId << " domain " << idom << " size=" <<nodeDomains[oldId].size());
+          }
         }
+      }
     }
+  }
 
   MESSAGE(".. Creation of elements");
   for (int idomain = idom0; idomain < nbDomains; idomain++)
+  {
+    itface = faceDomains.begin();
+    for (; itface != faceDomains.end(); ++itface)
     {
-      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);
+      int nbMultipleNodes = 0;
+      std::set<int>::iterator itn = oldNodes.begin();
+      for (; itn != oldNodes.end(); ++itn)
+      {
+        int oldId = *itn;
+        if (mutipleNodes.count(oldId))
+          nbMultipleNodes++;
+      }
+      if (nbMultipleNodes > 1) // 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)
         {
-          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);
-          int nbMultipleNodes = 0;
-          std::set<int>::iterator itn = oldNodes.begin();
-          for (; itn != oldNodes.end(); ++itn)
-            {
-              int oldId = *itn;
-              if (mutipleNodes.count(oldId))
-                nbMultipleNodes++;
-            }
-          if (nbMultipleNodes > 1) // check if an edge of the face is shared between 3 or more domains
+          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 ]))
             {
-              //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)
+              vector<int> vn0 = mutipleNodes[nodes[0]];
+              vector<int> vn1 = mutipleNodes[nodes[nbNodes - 1]];
+              vector<int> doms;
+              for ( size_t i0 = 0; i0 < vn0.size(); i0++ )
+                for ( size_t i1 = 0; i1 < vn1.size(); i1++ )
+                  if ( vn0[i0] == vn1[i1] )
+                    doms.push_back( vn0[ i0 ]);
+              if ( doms.size() > 2 )
+              {
+                //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 ( size_t id = 0; id < doms.size(); id++ )
                 {
-                  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 idom = doms[id];
+                  const TIDSortedElemSet& domain = (idom == iRestDom) ? theRestDomElems : theElems[idom];
+                  for ( int ivol = 0; ivol < nbvol; ivol++ )
+                  {
+                    int smdsId = meshDS->fromVtkToSmds(vtkVolIds[ivol]);
+                    SMDS_MeshElement* elem = (SMDS_MeshElement*)meshDS->FindElement(smdsId);
+                    if (domain.count(elem))
                     {
-                      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]];
-                          vector<int> doms;
-                          for (int i0 = 0; i0 < vn0.size(); i0++)
-                            for (int i1 = 0; i1 < vn1.size(); i1++)
-                              if (vn0[i0] == vn1[i1])
-                                doms.push_back(vn0[i0]);
-                          if (doms.size() >2)
-                            {
-                              //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 < doms.size(); id++)
-                                {
-                                  int idom = doms[id];
-                                  const TIDSortedElemSet& domain = (idom == iRestDom) ? theRestDomElems : theElems[idom];
-                                  for (int ivol=0; ivol<nbvol; ivol++)
-                                    {
-                                      int smdsId = meshDS->fromVtkToSmds(vtkVolIds[ivol]);
-                                      SMDS_MeshElement* elem = (SMDS_MeshElement*)meshDS->FindElement(smdsId);
-                                      if (domain.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
-                            }
-                        }
+                      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
+              }
             }
+          }
         }
+      }
     }
+  }
 
   // --- iterate on shared faces (volumes to modify, face to extrude)
   //     get node id's of the face (id SMDS = id VTK)
@@ -11051,50 +11555,50 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
 
   MESSAGE(".. Creation of elements: simple junction");
   if (createJointElems)
-    {
-      int idg;
-      string joints2DName = "joints2D";
-      mapOfJunctionGroups[joints2DName] = this->myMesh->AddGroup(SMDSAbs_Face, joints2DName.c_str(), idg);
-      SMESHDS_Group *joints2DGrp = dynamic_cast<SMESHDS_Group*>(mapOfJunctionGroups[joints2DName]->GetGroupDS());
-      string joints3DName = "joints3D";
-      mapOfJunctionGroups[joints3DName] = this->myMesh->AddGroup(SMDSAbs_Volume, joints3DName.c_str(), idg);
-      SMESHDS_Group *joints3DGrp = dynamic_cast<SMESHDS_Group*>(mapOfJunctionGroups[joints3DName]->GetGroupDS());
-
-      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;
-          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());
-          if (vol->GetType() == SMDSAbs_Volume)
-            joints3DGrp->Add(vol->GetID());
-          else if (vol->GetType() == SMDSAbs_Face)
-            joints2DGrp->Add(vol->GetID());
-        }
+  {
+    int idg;
+    string joints2DName = "joints2D";
+    mapOfJunctionGroups[joints2DName] = this->myMesh->AddGroup(SMDSAbs_Face, joints2DName.c_str(), idg);
+    SMESHDS_Group *joints2DGrp = dynamic_cast<SMESHDS_Group*>(mapOfJunctionGroups[joints2DName]->GetGroupDS());
+    string joints3DName = "joints3D";
+    mapOfJunctionGroups[joints3DName] = this->myMesh->AddGroup(SMDSAbs_Volume, joints3DName.c_str(), idg);
+    SMESHDS_Group *joints3DGrp = dynamic_cast<SMESHDS_Group*>(mapOfJunctionGroups[joints3DName]->GetGroupDS());
+
+    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;
+      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());
+      if (vol->GetType() == SMDSAbs_Volume)
+        joints3DGrp->Add(vol->GetID());
+      else if (vol->GetType() == SMDSAbs_Face)
+        joints2DGrp->Add(vol->GetID());
     }
+  }
 
   // --- create volumes on multiple domain intersection if requested
   //     iterate on mutipleNodesToFace
@@ -11102,66 +11606,66 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
 
   MESSAGE(".. Creation of elements: multiple junction");
   if (createJointElems)
+  {
+    // --- iterate on mutipleNodesToFace
+
+    std::map<int, std::vector<int> >::iterator itn =  mutipleNodesToFace.begin();
+    for (; itn != mutipleNodesToFace.end(); ++itn)
     {
-      // --- iterate on mutipleNodesToFace
+      int node = itn->first;
+      vector<int> orderDom = itn->second;
+      vector<vtkIdType> orderedNodes;
+      for ( size_t idom = 0; idom < orderDom.size(); idom++ )
+        orderedNodes.push_back( nodeDomains[ node ][ orderDom[ idom ]]);
+      SMDS_MeshFace* face = this->GetMeshDS()->AddFaceFromVtkIds(orderedNodes);
 
-      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());
-        }
-
-      // --- iterate on edgesMultiDomains
-
-      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);
-
-              int idg;
-              string namegrp = "jointsMultiples";
-              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());
-            }
+      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());
+    }
+
+    // --- iterate on edgesMultiDomains
+
+    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 ( size_t ino = 0; ino < nodes.size(); ino++ )
+          if ( orderDom.size() == 3 )
+            for ( size_t idom = 0; idom < orderDom.size(); idom++ )
+              orderedNodes.push_back( nodeDomains[ nodes[ ino ]][ orderDom[ idom ]]);
           else
-            {
-              INFOS("Quadratic multiple joints not implemented");
-              // TODO quadratic nodes
-            }
-        }
+            for (int idom = orderDom.size()-1; idom >=0; idom--)
+              orderedNodes.push_back( nodeDomains[ nodes[ ino ]][ orderDom[ idom ]]);
+        SMDS_MeshVolume* vol = this->GetMeshDS()->AddVolumeFromVtkIds(orderedNodes);
+
+        int idg;
+        string namegrp = "jointsMultiples";
+        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
+      {
+        //INFOS("Quadratic multiple joints not implemented");
+        // TODO quadratic nodes
+      }
     }
+  }
 
   // --- 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.
@@ -11175,36 +11679,36 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
 
   MESSAGE(".. Modification of elements");
   for (int idomain = idom0; idomain < nbDomains; idomain++)
+  {
+    std::map<int, std::map<int, int> >::const_iterator itnod = nodeDomains.begin();
+    for (; itnod != nodeDomains.end(); ++itnod)
     {
-      std::map<int, std::map<int, int> >::const_iterator itnod = nodeDomains.begin();
-      for (; itnod != nodeDomains.end(); ++itnod)
-        {
-          int oldId = itnod->first;
-          //MESSAGE("     node " << oldId);
-          vtkCellLinks::Link l = grid->GetCellLinks()->GetLink(oldId);
-          for (int i = 0; i < l.ncells; i++)
+      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))
             {
-              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);
-                    }
+              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);
             }
-        }
+      }
     }
+  }
 
   // --- iterate on shared faces (volumes to modify, face to extrude)
   //     get node id's of the face
@@ -11212,40 +11716,48 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
 
   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)
+  {
+    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)
         {
-          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);
-            }
+          int oldId = *itn;
+          if (nodeDomains[oldId].count(idom))
+          {
+            localClonedNodeIds[oldId] = nodeDomains[oldId][idom];
+            //MESSAGE("     node " << oldId << " --> " << localClonedNodeIds[oldId]);
+          }
         }
+        meshDS->ModifyCellNodes(vtkVolId, localClonedNodeIds);
+      }
     }
+  }
+
+  // Remove empty groups (issue 0022812)
+  std::map<std::string, SMESH_Group*>::iterator name_group = mapOfJunctionGroups.begin();
+  for ( ; name_group != mapOfJunctionGroups.end(); ++name_group )
+  {
+    if ( name_group->second && name_group->second->GetGroupDS()->IsEmpty() )
+      myMesh->RemoveGroup( name_group->second->GetGroupDS()->GetID() );
+  }
 
   meshDS->CleanDownWardConnectivity(); // Mesh has been modified, downward connectivity is no more usable, free memory
   grid->BuildLinks();
@@ -11284,135 +11796,137 @@ bool SMESH_MeshEditor::CreateFlatElementsOnFacesGroups(const std::vector<TIDSort
   std::map<std::string, SMESH_Group*> mapOfJunctionGroups;
   mapOfJunctionGroups.clear();
 
-  for (int idom = 0; idom < theElems.size(); idom++)
+  for ( size_t idom = 0; idom < theElems.size(); idom++ )
+  {
+    const TIDSortedElemSet&           domain = theElems[idom];
+    TIDSortedElemSet::const_iterator elemItr = domain.begin();
+    for ( ; elemItr != domain.end(); ++elemItr )
     {
-      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;
-
-          // --- clone the nodes, create intermediate nodes for non medium nodes of a quad face
+      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;
 
-          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);
+      // --- clone the nodes, create intermediate nodes for non medium nodes of a quad face
 
-              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);
+      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* 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);
-                }
-            }
+        const SMDS_MeshNode* clone = 0;
+        if (!clonedNodes.count(node))
+        {
+          clone = meshDS->AddNode(node->X(), node->Y(), node->Z());
+          copyPosition( node, clone );
+          clonedNodes[node] = clone;
+        }
+        else
+          clone = clonedNodes[node];
 
-          // --- extrude the face
+        if (isMedium)
+          ln3.push_back(clone);
+        else
+          ln1.push_back(clone);
 
-          vector<const SMDS_MeshNode*> ln;
-          SMDS_MeshVolume* vol = 0;
-          vtkIdType aType = aFace->GetVtkType();
-          switch (aType)
+        const SMDS_MeshNode* inter = 0;
+        if (isQuad && (!isMedium))
+        {
+          if (!intermediateNodes.count(node))
           {
-            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;
+            inter = meshDS->AddNode(node->X(), node->Y(), node->Z());
+            copyPosition( node, inter );
+            intermediateNodes[node] = inter;
           }
+          else
+            inter = intermediateNodes[node];
+          ln4.push_back(inter);
+        }
+      }
 
-          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());
-            }
+      // --- extrude the face
 
-          // --- modify 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;
+      }
 
-          aFace->ChangeNodes(&ln[0], ln.size());
-        }
+      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;
 }
 
@@ -11422,11 +11936,11 @@ bool SMESH_MeshEditor::CreateFlatElementsOnFacesGroups(const std::vector<TIDSort
  *  groups of faces to remove inside the object, (idem edges).
  *  Build ordered list of nodes at the border of each group of faces to replace (to be used to build a geom subshape)
  */
-void SMESH_MeshEditor::CreateHoleSkin(double radius,
-                                      const TopoDS_Shape& theShape,
-                                      SMESH_NodeSearcher* theNodeSearcher,
-                                      const char* groupName,
-                                      std::vector<double>&   nodesCoords,
+void SMESH_MeshEditor::CreateHoleSkin(double                          radius,
+                                      const TopoDS_Shape&             theShape,
+                                      SMESH_NodeSearcher*             theNodeSearcher,
+                                      const char*                     groupName,
+                                      std::vector<double>&            nodesCoords,
                                       std::vector<std::vector<int> >& listOfListOfNodes)
 {
   MESSAGE("--------------------------------");
@@ -11444,28 +11958,28 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius,
   SMESHDS_GroupBase* groupDS = 0;
   SMESH_Mesh::GroupIteratorPtr groupIt = this->myMesh->GetGroups();
   while ( groupIt->more() )
-    {
+  {
+    groupDS = 0;
+    SMESH_Group * group = groupIt->next();
+    if ( !group ) continue;
+    groupDS = group->GetGroupDS();
+    if ( !groupDS || groupDS->IsEmpty() ) continue;
+    std::string grpName = group->GetName();
+    //MESSAGE("grpName=" << grpName);
+    if (grpName == groupName)
+      break;
+    else
       groupDS = 0;
-      SMESH_Group * group = groupIt->next();
-      if ( !group ) continue;
-      groupDS = group->GetGroupDS();
-      if ( !groupDS || groupDS->IsEmpty() ) continue;
-      std::string grpName = group->GetName();
-      //MESSAGE("grpName=" << grpName);
-      if (grpName == groupName)
-        break;
-      else
-        groupDS = 0;
-    }
+  }
 
   bool isNodeGroup = false;
   bool isNodeCoords = false;
   if (groupDS)
-    {
-      if (groupDS->GetType() != SMDSAbs_Node)
-        return;
-      isNodeGroup = true;     // a group of nodes exists and it is in this mesh
-    }
+  {
+    if (groupDS->GetType() != SMDSAbs_Node)
+      return;
+    isNodeGroup = true;     // a group of nodes exists and it is in this mesh
+  }
 
   if (nodesCoords.size() > 0)
     isNodeCoords = true; // a list o nodes given by their coordinates
@@ -11478,10 +11992,10 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius,
   grpvName += "_vol";
   SMESH_Group *grp = this->myMesh->AddGroup(SMDSAbs_Volume, grpvName.c_str(), idg);
   if (!grp)
-    {
-      MESSAGE("group not created " << grpvName);
-      return;
-    }
+  {
+    MESSAGE("group not created " << grpvName);
+    return;
+  }
   SMESHDS_Group *sgrp = dynamic_cast<SMESHDS_Group*>(grp->GetGroupDS());
 
   int idgs; // --- group of SMDS faces on the skin
@@ -11489,10 +12003,10 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius,
   grpsName += "_skin";
   SMESH_Group *grps = this->myMesh->AddGroup(SMDSAbs_Face, grpsName.c_str(), idgs);
   if (!grps)
-    {
-      MESSAGE("group not created " << grpsName);
-      return;
-    }
+  {
+    MESSAGE("group not created " << grpsName);
+    return;
+  }
   SMESHDS_Group *sgrps = dynamic_cast<SMESHDS_Group*>(grps->GetGroupDS());
 
   int idgi; // --- group of SMDS faces internal (several shapes)
@@ -11500,10 +12014,10 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius,
   grpiName += "_internalFaces";
   SMESH_Group *grpi = this->myMesh->AddGroup(SMDSAbs_Face, grpiName.c_str(), idgi);
   if (!grpi)
-    {
-      MESSAGE("group not created " << grpiName);
-      return;
-    }
+  {
+    MESSAGE("group not created " << grpiName);
+    return;
+  }
   SMESHDS_Group *sgrpi = dynamic_cast<SMESHDS_Group*>(grpi->GetGroupDS());
 
   int idgei; // --- group of SMDS faces internal (several shapes)
@@ -11511,10 +12025,10 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius,
   grpeiName += "_internalEdges";
   SMESH_Group *grpei = this->myMesh->AddGroup(SMDSAbs_Edge, grpeiName.c_str(), idgei);
   if (!grpei)
-    {
-      MESSAGE("group not created " << grpeiName);
-      return;
-    }
+  {
+    MESSAGE("group not created " << grpeiName);
+    return;
+  }
   SMESHDS_Group *sgrpei = dynamic_cast<SMESHDS_Group*>(grpei->GetGroupDS());
 
   // --- build downward connectivity
@@ -11532,157 +12046,157 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius,
   gpnts.clear();
 
   if (isNodeGroup) // --- a group of nodes is provided : find all the volumes using one or more of this nodes
+  {
+    MESSAGE("group of nodes provided");
+    SMDS_ElemIteratorPtr elemIt = groupDS->GetElements();
+    while ( elemIt->more() )
     {
-      MESSAGE("group of nodes provided");
-      SMDS_ElemIteratorPtr elemIt = groupDS->GetElements();
-      while ( elemIt->more() )
-        {
-          const SMDS_MeshElement* elem = elemIt->next();
-          if (!elem)
-            continue;
-          const SMDS_MeshNode* node = dynamic_cast<const SMDS_MeshNode*>(elem);
-          if (!node)
-            continue;
-          SMDS_MeshElement* vol = 0;
-          SMDS_ElemIteratorPtr volItr = node->GetInverseElementIterator(SMDSAbs_Volume);
-          while (volItr->more())
-            {
-              vol = (SMDS_MeshElement*)volItr->next();
-              setOfInsideVol.insert(vol->getVtkId());
-              sgrp->Add(vol->GetID());
-            }
-        }
+      const SMDS_MeshElement* elem = elemIt->next();
+      if (!elem)
+        continue;
+      const SMDS_MeshNode* node = dynamic_cast<const SMDS_MeshNode*>(elem);
+      if (!node)
+        continue;
+      SMDS_MeshElement* vol = 0;
+      SMDS_ElemIteratorPtr volItr = node->GetInverseElementIterator(SMDSAbs_Volume);
+      while (volItr->more())
+      {
+        vol = (SMDS_MeshElement*)volItr->next();
+        setOfInsideVol.insert(vol->getVtkId());
+        sgrp->Add(vol->GetID());
+      }
     }
+  }
   else if (isNodeCoords)
+  {
+    MESSAGE("list of nodes coordinates provided");
+    size_t i = 0;
+    int k = 0;
+    while ( i < nodesCoords.size()-2 )
     {
-      MESSAGE("list of nodes coordinates provided");
-      int i = 0;
-      int k = 0;
-      while (i < nodesCoords.size()-2)
-        {
-          double x = nodesCoords[i++];
-          double y = nodesCoords[i++];
-          double z = nodesCoords[i++];
-          gp_Pnt p = gp_Pnt(x, y ,z);
-          gpnts.push_back(p);
-          MESSAGE("TopoDS_Vertex " << k << " " << p.X() << " " << p.Y() << " " << p.Z());
-          k++;
-        }
+      double x = nodesCoords[i++];
+      double y = nodesCoords[i++];
+      double z = nodesCoords[i++];
+      gp_Pnt p = gp_Pnt(x, y ,z);
+      gpnts.push_back(p);
+      MESSAGE("TopoDS_Vertex " << k << " " << p.X() << " " << p.Y() << " " << p.Z());
+      k++;
     }
+  }
   else // --- no group, no coordinates : use the vertices of the geom shape provided, and radius
-    {
-      MESSAGE("no group of nodes provided, using vertices from geom shape, and radius");
-      TopTools_IndexedMapOfShape vertexMap;
-      TopExp::MapShapes( theShape, TopAbs_VERTEX, vertexMap );
-      gp_Pnt p = gp_Pnt(0,0,0);
-      if (vertexMap.Extent() < 1)
-        return;
+  {
+    MESSAGE("no group of nodes provided, using vertices from geom shape, and radius");
+    TopTools_IndexedMapOfShape vertexMap;
+    TopExp::MapShapes( theShape, TopAbs_VERTEX, vertexMap );
+    gp_Pnt p = gp_Pnt(0,0,0);
+    if (vertexMap.Extent() < 1)
+      return;
 
-      for ( int i = 1; i <= vertexMap.Extent(); ++i )
-        {
-          const TopoDS_Vertex& vertex = TopoDS::Vertex( vertexMap( i ));
-          p = BRep_Tool::Pnt(vertex);
-          gpnts.push_back(p);
-          MESSAGE("TopoDS_Vertex " << i << " " << p.X() << " " << p.Y() << " " << p.Z());
-        }
+    for ( int i = 1; i <= vertexMap.Extent(); ++i )
+    {
+      const TopoDS_Vertex& vertex = TopoDS::Vertex( vertexMap( i ));
+      p = BRep_Tool::Pnt(vertex);
+      gpnts.push_back(p);
+      MESSAGE("TopoDS_Vertex " << i << " " << p.X() << " " << p.Y() << " " << p.Z());
     }
+  }
 
   if (gpnts.size() > 0)
-    {
-      int nodeId = 0;
-      const SMDS_MeshNode* startNode = theNodeSearcher->FindClosestTo(gpnts[0]);
-      if (startNode)
-        nodeId = startNode->GetID();
-      MESSAGE("nodeId " << nodeId);
+  {
+    int nodeId = 0;
+    const SMDS_MeshNode* startNode = theNodeSearcher->FindClosestTo(gpnts[0]);
+    if (startNode)
+      nodeId = startNode->GetID();
+    MESSAGE("nodeId " << nodeId);
 
-      double radius2 = radius*radius;
-      MESSAGE("radius2 " << radius2);
+    double radius2 = radius*radius;
+    MESSAGE("radius2 " << radius2);
 
-      // --- volumes on start node
+    // --- volumes on start node
 
-      setOfVolToCheck.clear();
-      SMDS_MeshElement* startVol = 0;
-      SMDS_ElemIteratorPtr volItr = startNode->GetInverseElementIterator(SMDSAbs_Volume);
-      while (volItr->more())
-        {
-          startVol = (SMDS_MeshElement*)volItr->next();
-          setOfVolToCheck.insert(startVol->getVtkId());
-        }
-      if (setOfVolToCheck.empty())
-        {
-          MESSAGE("No volumes found");
-          return;
-        }
+    setOfVolToCheck.clear();
+    SMDS_MeshElement* startVol = 0;
+    SMDS_ElemIteratorPtr volItr = startNode->GetInverseElementIterator(SMDSAbs_Volume);
+    while (volItr->more())
+    {
+      startVol = (SMDS_MeshElement*)volItr->next();
+      setOfVolToCheck.insert(startVol->getVtkId());
+    }
+    if (setOfVolToCheck.empty())
+    {
+      MESSAGE("No volumes found");
+      return;
+    }
 
-      // --- starting with central volumes then their neighbors, check if they are inside
-      //     or outside the domain, until no more new neighbor volume is inside.
-      //     Fill the group of inside volumes
+    // --- starting with central volumes then their neighbors, check if they are inside
+    //     or outside the domain, until no more new neighbor volume is inside.
+    //     Fill the group of inside volumes
 
-      std::map<int, double> mapOfNodeDistance2;
-      mapOfNodeDistance2.clear();
-      std::set<int> setOfOutsideVol;
-      while (!setOfVolToCheck.empty())
+    std::map<int, double> mapOfNodeDistance2;
+    mapOfNodeDistance2.clear();
+    std::set<int> setOfOutsideVol;
+    while (!setOfVolToCheck.empty())
+    {
+      std::set<int>::iterator it = setOfVolToCheck.begin();
+      int vtkId = *it;
+      MESSAGE("volume to check,  vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId));
+      bool volInside = false;
+      vtkIdType npts = 0;
+      vtkIdType* pts = 0;
+      grid->GetCellPoints(vtkId, npts, pts);
+      for (int i=0; i<npts; i++)
+      {
+        double distance2 = 0;
+        if (mapOfNodeDistance2.count(pts[i]))
+        {
+          distance2 = mapOfNodeDistance2[pts[i]];
+          MESSAGE("point " << pts[i] << " distance2 " << distance2);
+        }
+        else
         {
-          std::set<int>::iterator it = setOfVolToCheck.begin();
-          int vtkId = *it;
-          MESSAGE("volume to check,  vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId));
-          bool volInside = false;
-          vtkIdType npts = 0;
-          vtkIdType* pts = 0;
-          grid->GetCellPoints(vtkId, npts, pts);
-          for (int i=0; i<npts; i++)
+          double *coords = grid->GetPoint(pts[i]);
+          gp_Pnt aPoint = gp_Pnt(coords[0], coords[1], coords[2]);
+          distance2 = 1.E40;
+          for ( size_t j = 0; j < gpnts.size(); j++ )
+          {
+            double d2 = aPoint.SquareDistance( gpnts[ j ]);
+            if (d2 < distance2)
             {
-              double distance2 = 0;
-              if (mapOfNodeDistance2.count(pts[i]))
-                {
-                  distance2 = mapOfNodeDistance2[pts[i]];
-                  MESSAGE("point " << pts[i] << " distance2 " << distance2);
-                }
-              else
-                {
-                  double *coords = grid->GetPoint(pts[i]);
-                  gp_Pnt aPoint = gp_Pnt(coords[0], coords[1], coords[2]);
-                  distance2 = 1.E40;
-                  for (int j=0; j<gpnts.size(); j++)
-                    {
-                      double d2 = aPoint.SquareDistance(gpnts[j]);
-                      if (d2 < distance2)
-                        {
-                          distance2 = d2;
-                          if (distance2 < radius2)
-                            break;
-                        }
-                    }
-                  mapOfNodeDistance2[pts[i]] = distance2;
-                  MESSAGE("  point "  << pts[i]  << " distance2 " << distance2 << " coords " << coords[0] << " " << coords[1] << " " <<  coords[2]);
-                }
+              distance2 = d2;
               if (distance2 < radius2)
-                {
-                  volInside = true; // one or more nodes inside the domain
-                  sgrp->Add(meshDS->fromVtkToSmds(vtkId));
-                  break;
-                }
-            }
-          if (volInside)
-            {
-              setOfInsideVol.insert(vtkId);
-              MESSAGE("  volume inside,  vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId));
-              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++)
-                if (!setOfInsideVol.count(neighborsVtkIds[n]) ||setOfOutsideVol.count(neighborsVtkIds[n]))
-                  setOfVolToCheck.insert(neighborsVtkIds[n]);
-            }
-          else
-            {
-              setOfOutsideVol.insert(vtkId);
-              MESSAGE("  volume outside, vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId));
+                break;
             }
-          setOfVolToCheck.erase(vtkId);
+          }
+          mapOfNodeDistance2[pts[i]] = distance2;
+          MESSAGE("  point "  << pts[i]  << " distance2 " << distance2 << " coords " << coords[0] << " " << coords[1] << " " <<  coords[2]);
         }
+        if (distance2 < radius2)
+        {
+          volInside = true; // one or more nodes inside the domain
+          sgrp->Add(meshDS->fromVtkToSmds(vtkId));
+          break;
+        }
+      }
+      if (volInside)
+      {
+        setOfInsideVol.insert(vtkId);
+        MESSAGE("  volume inside,  vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId));
+        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++)
+          if (!setOfInsideVol.count(neighborsVtkIds[n]) ||setOfOutsideVol.count(neighborsVtkIds[n]))
+            setOfVolToCheck.insert(neighborsVtkIds[n]);
+      }
+      else
+      {
+        setOfOutsideVol.insert(vtkId);
+        MESSAGE("  volume outside, vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId));
+      }
+      setOfVolToCheck.erase(vtkId);
     }
+  }
 
   // --- for outside hexahedrons, check if they have more than one neighbor volume inside
   //     If yes, add the volume to the inside set
@@ -11690,52 +12204,52 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius,
   bool addedInside = true;
   std::set<int> setOfVolToReCheck;
   while (addedInside)
+  {
+    MESSAGE(" --------------------------- re check");
+    addedInside = false;
+    std::set<int>::iterator itv = setOfInsideVol.begin();
+    for (; itv != setOfInsideVol.end(); ++itv)
     {
-      MESSAGE(" --------------------------- re check");
-      addedInside = false;
-      std::set<int>::iterator itv = setOfInsideVol.begin();
-      for (; itv != setOfInsideVol.end(); ++itv)
-        {
-          int vtkId = *itv;
-          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++)
-            if (!setOfInsideVol.count(neighborsVtkIds[n]))
-              setOfVolToReCheck.insert(neighborsVtkIds[n]);
-        }
-      setOfVolToCheck = setOfVolToReCheck;
-      setOfVolToReCheck.clear();
-      while  (!setOfVolToCheck.empty())
+      int vtkId = *itv;
+      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++)
+        if (!setOfInsideVol.count(neighborsVtkIds[n]))
+          setOfVolToReCheck.insert(neighborsVtkIds[n]);
+    }
+    setOfVolToCheck = setOfVolToReCheck;
+    setOfVolToReCheck.clear();
+    while  (!setOfVolToCheck.empty())
+    {
+      std::set<int>::iterator it = setOfVolToCheck.begin();
+      int vtkId = *it;
+      if (grid->GetCellType(vtkId) == VTK_HEXAHEDRON)
+      {
+        MESSAGE("volume to recheck,  vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId));
+        int countInside = 0;
+        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++)
+          if (setOfInsideVol.count(neighborsVtkIds[n]))
+            countInside++;
+        MESSAGE("countInside " << countInside);
+        if (countInside > 1)
         {
-          std::set<int>::iterator it = setOfVolToCheck.begin();
-          int vtkId = *it;
-          if (grid->GetCellType(vtkId) == VTK_HEXAHEDRON)
-            {
-              MESSAGE("volume to recheck,  vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId));
-              int countInside = 0;
-              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++)
-                if (setOfInsideVol.count(neighborsVtkIds[n]))
-                  countInside++;
-              MESSAGE("countInside " << countInside);
-              if (countInside > 1)
-                {
-                  MESSAGE("  volume inside,  vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId));
-                  setOfInsideVol.insert(vtkId);
-                  sgrp->Add(meshDS->fromVtkToSmds(vtkId));
-                  addedInside = true;
-                }
-              else
-                setOfVolToReCheck.insert(vtkId);
-            }
-          setOfVolToCheck.erase(vtkId);
+          MESSAGE("  volume inside,  vtkId " << vtkId << " smdsId " << meshDS->fromVtkToSmds(vtkId));
+          setOfInsideVol.insert(vtkId);
+          sgrp->Add(meshDS->fromVtkToSmds(vtkId));
+          addedInside = true;
         }
+        else
+          setOfVolToReCheck.insert(vtkId);
+      }
+      setOfVolToCheck.erase(vtkId);
     }
+  }
 
   // --- map of Downward faces at the boundary, inside the global volume
   //     map of Downward faces on the skin of the global volume (equivalent to SMDS faces on the skin)
@@ -11746,50 +12260,50 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius,
   std::map<DownIdType, int, DownIdCompare> skinFaces;     // faces on the skin of the global volume --> corresponding cell
   std::set<int>::iterator it = setOfInsideVol.begin();
   for (; it != setOfInsideVol.end(); ++it)
-    {
-      int vtkId = *it;
-      //MESSAGE("  vtkId " << vtkId  << " smdsId " << meshDS->fromVtkToSmds(vtkId));
-      int neighborsVtkIds[NBMAXNEIGHBORS];
-      int downIds[NBMAXNEIGHBORS];
-      unsigned char downTypes[NBMAXNEIGHBORS];
-      int nbNeighbors = grid->GetNeighbors(neighborsVtkIds, downIds, downTypes, vtkId, true);
-      for (int n = 0; n < nbNeighbors; n++)
+  {
+    int vtkId = *it;
+    //MESSAGE("  vtkId " << vtkId  << " smdsId " << meshDS->fromVtkToSmds(vtkId));
+    int neighborsVtkIds[NBMAXNEIGHBORS];
+    int downIds[NBMAXNEIGHBORS];
+    unsigned char downTypes[NBMAXNEIGHBORS];
+    int nbNeighbors = grid->GetNeighbors(neighborsVtkIds, downIds, downTypes, vtkId, true);
+    for (int n = 0; n < nbNeighbors; n++)
+    {
+      int neighborDim = SMDS_Downward::getCellDimension(grid->GetCellType(neighborsVtkIds[n]));
+      if (neighborDim == 3)
+      {
+        if (! setOfInsideVol.count(neighborsVtkIds[n])) // neighbor volume is not inside : face is boundary
         {
-          int neighborDim = SMDS_Downward::getCellDimension(grid->GetCellType(neighborsVtkIds[n]));
-          if (neighborDim == 3)
-            {
-              if (! setOfInsideVol.count(neighborsVtkIds[n])) // neighbor volume is not inside : face is boundary
-                {
-                  DownIdType face(downIds[n], downTypes[n]);
-                  boundaryFaces[face] = vtkId;
-                }
-              // if the face between to volumes is in the mesh, get it (internal face between shapes)
-              int vtkFaceId = grid->getDownArray(downTypes[n])->getVtkCellId(downIds[n]);
-              if (vtkFaceId >= 0)
-                {
-                  sgrpi->Add(meshDS->fromVtkToSmds(vtkFaceId));
-                  // find also the smds edges on this face
-                  int nbEdges = grid->getDownArray(downTypes[n])->getNumberOfDownCells(downIds[n]);
-                  const int* dEdges = grid->getDownArray(downTypes[n])->getDownCells(downIds[n]);
-                  const unsigned char* dTypes = grid->getDownArray(downTypes[n])->getDownTypes(downIds[n]);
-                  for (int i = 0; i < nbEdges; i++)
-                    {
-                      int vtkEdgeId = grid->getDownArray(dTypes[i])->getVtkCellId(dEdges[i]);
-                      if (vtkEdgeId >= 0)
-                        sgrpei->Add(meshDS->fromVtkToSmds(vtkEdgeId));
-                    }
-                }
-            }
-          else if (neighborDim == 2) // skin of the volume
-            {
-              DownIdType face(downIds[n], downTypes[n]);
-              skinFaces[face] = vtkId;
-              int vtkFaceId = grid->getDownArray(downTypes[n])->getVtkCellId(downIds[n]);
-              if (vtkFaceId >= 0)
-                sgrps->Add(meshDS->fromVtkToSmds(vtkFaceId));
-            }
+          DownIdType face(downIds[n], downTypes[n]);
+          boundaryFaces[face] = vtkId;
         }
+        // if the face between to volumes is in the mesh, get it (internal face between shapes)
+        int vtkFaceId = grid->getDownArray(downTypes[n])->getVtkCellId(downIds[n]);
+        if (vtkFaceId >= 0)
+        {
+          sgrpi->Add(meshDS->fromVtkToSmds(vtkFaceId));
+          // find also the smds edges on this face
+          int nbEdges = grid->getDownArray(downTypes[n])->getNumberOfDownCells(downIds[n]);
+          const int* dEdges = grid->getDownArray(downTypes[n])->getDownCells(downIds[n]);
+          const unsigned char* dTypes = grid->getDownArray(downTypes[n])->getDownTypes(downIds[n]);
+          for (int i = 0; i < nbEdges; i++)
+          {
+            int vtkEdgeId = grid->getDownArray(dTypes[i])->getVtkCellId(dEdges[i]);
+            if (vtkEdgeId >= 0)
+              sgrpei->Add(meshDS->fromVtkToSmds(vtkEdgeId));
+          }
+        }
+      }
+      else if (neighborDim == 2) // skin of the volume
+      {
+        DownIdType face(downIds[n], downTypes[n]);
+        skinFaces[face] = vtkId;
+        int vtkFaceId = grid->getDownArray(downTypes[n])->getVtkCellId(downIds[n]);
+        if (vtkFaceId >= 0)
+          sgrps->Add(meshDS->fromVtkToSmds(vtkFaceId));
+      }
     }
+  }
 
   // --- identify the edges constituting the wire of each subshape on the skin
   //     define polylines with the nodes of edges, equivalent to wires
@@ -11802,17 +12316,17 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius,
 
   SMDS_ElemIteratorPtr itelem = sgrps->GetElements();
   while (itelem->more())
+  {
+    const SMDS_MeshElement *elem = itelem->next();
+    int shapeId = elem->getshapeId();
+    int vtkId = elem->getVtkId();
+    if (!shapeIdToVtkIdSet.count(shapeId))
     {
-      const SMDS_MeshElement *elem = itelem->next();
-      int shapeId = elem->getshapeId();
-      int vtkId = elem->getVtkId();
-      if (!shapeIdToVtkIdSet.count(shapeId))
-        {
-          shapeIdToVtkIdSet[shapeId] = emptySet;
-          shapeIds.insert(shapeId);
-        }
-      shapeIdToVtkIdSet[shapeId].insert(vtkId);
+      shapeIdToVtkIdSet[shapeId] = emptySet;
+      shapeIds.insert(shapeId);
     }
+    shapeIdToVtkIdSet[shapeId].insert(vtkId);
+  }
 
   std::map<int, std::set<DownIdType, DownIdCompare> > shapeIdToEdges; // shapeId --> set of downward edges
   std::set<DownIdType, DownIdCompare> emptyEdges;
@@ -11820,125 +12334,125 @@ void SMESH_MeshEditor::CreateHoleSkin(double radius,
 
   std::map<int, std::set<int> >::iterator itShape =  shapeIdToVtkIdSet.begin();
   for (; itShape != shapeIdToVtkIdSet.end(); ++itShape)
-    {
-      int shapeId = itShape->first;
-      MESSAGE(" --- Shape ID --- "<< shapeId);
-      shapeIdToEdges[shapeId] = emptyEdges;
+  {
+    int shapeId = itShape->first;
+    MESSAGE(" --- Shape ID --- "<< shapeId);
+    shapeIdToEdges[shapeId] = emptyEdges;
 
-      std::vector<int> nodesEdges;
+    std::vector<int> nodesEdges;
 
-      std::set<int>::iterator its = itShape->second.begin();
-      for (; its != itShape->second.end(); ++its)
+    std::set<int>::iterator its = itShape->second.begin();
+    for (; its != itShape->second.end(); ++its)
+    {
+      int vtkId = *its;
+      MESSAGE("     " << vtkId);
+      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++)
+      {
+        if (neighborsVtkIds[n]<0) // only smds faces are considered as neighbors here
+          continue;
+        int smdsId = meshDS->fromVtkToSmds(neighborsVtkIds[n]);
+        const SMDS_MeshElement* elem = meshDS->FindElement(smdsId);
+        if ( shapeIds.count(elem->getshapeId()) && !sgrps->Contains(elem)) // edge : neighbor in the set of shape, not in the group
         {
-          int vtkId = *its;
-          MESSAGE("     " << vtkId);
-          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++)
-            {
-              if (neighborsVtkIds[n]<0) // only smds faces are considered as neighbors here
-                continue;
-              int smdsId = meshDS->fromVtkToSmds(neighborsVtkIds[n]);
-              const SMDS_MeshElement* elem = meshDS->FindElement(smdsId);
-              if ( shapeIds.count(elem->getshapeId()) && !sgrps->Contains(elem)) // edge : neighbor in the set of shape, not in the group
-                {
-                  DownIdType edge(downIds[n], downTypes[n]);
-                  if (!shapeIdToEdges[shapeId].count(edge))
-                    {
-                      shapeIdToEdges[shapeId].insert(edge);
-                      int vtkNodeId[3];
-                      int nbNodes = grid->getDownArray(downTypes[n])->getNodes(downIds[n],vtkNodeId);
-                      nodesEdges.push_back(vtkNodeId[0]);
-                      nodesEdges.push_back(vtkNodeId[nbNodes-1]);
-                      MESSAGE("       --- nodes " << vtkNodeId[0]+1 << " " << vtkNodeId[nbNodes-1]+1);
-                    }
-                }
-            }
+          DownIdType edge(downIds[n], downTypes[n]);
+          if (!shapeIdToEdges[shapeId].count(edge))
+          {
+            shapeIdToEdges[shapeId].insert(edge);
+            int vtkNodeId[3];
+            int nbNodes = grid->getDownArray(downTypes[n])->getNodes(downIds[n],vtkNodeId);
+            nodesEdges.push_back(vtkNodeId[0]);
+            nodesEdges.push_back(vtkNodeId[nbNodes-1]);
+            MESSAGE("       --- nodes " << vtkNodeId[0]+1 << " " << vtkNodeId[nbNodes-1]+1);
+          }
         }
+      }
+    }
 
-      std::list<int> order;
-      order.clear();
-      if (nodesEdges.size() > 0)
+    std::list<int> order;
+    order.clear();
+    if (nodesEdges.size() > 0)
+    {
+      order.push_back(nodesEdges[0]); MESSAGE("       --- back " << order.back()+1); // SMDS id = VTK id + 1;
+      nodesEdges[0] = -1;
+      order.push_back(nodesEdges[1]); MESSAGE("       --- back " << order.back()+1);
+      nodesEdges[1] = -1; // do not reuse this edge
+      bool found = true;
+      while (found)
+      {
+        int nodeTofind = order.back(); // try first to push back
+        int i = 0;
+        for ( i = 0; i < (int)nodesEdges.size(); i++ )
+          if (nodesEdges[i] == nodeTofind)
+            break;
+        if ( i == (int) nodesEdges.size() )
+          found = false; // no follower found on back
+        else
         {
-          order.push_back(nodesEdges[0]); MESSAGE("       --- back " << order.back()+1); // SMDS id = VTK id + 1;
-          nodesEdges[0] = -1;
-          order.push_back(nodesEdges[1]); MESSAGE("       --- back " << order.back()+1);
-          nodesEdges[1] = -1; // do not reuse this edge
-          bool found = true;
-          while (found)
+          if (i%2) // odd ==> use the previous one
+            if (nodesEdges[i-1] < 0)
+              found = false;
+            else
             {
-              int nodeTofind = order.back(); // try first to push back
-              int i = 0;
-              for (i = 0; i<nodesEdges.size(); i++)
-                if (nodesEdges[i] == nodeTofind)
-                  break;
-              if (i == nodesEdges.size())
-                found = false; // no follower found on back
-              else
-                {
-                  if (i%2) // odd ==> use the previous one
-                    if (nodesEdges[i-1] < 0)
-                      found = false;
-                    else
-                      {
-                        order.push_back(nodesEdges[i-1]); MESSAGE("       --- back " << order.back()+1);
-                        nodesEdges[i-1] = -1;
-                      }
-                  else // even ==> use the next one
-                    if (nodesEdges[i+1] < 0)
-                      found = false;
-                    else
-                      {
-                        order.push_back(nodesEdges[i+1]); MESSAGE("       --- back " << order.back()+1);
-                        nodesEdges[i+1] = -1;
-                      }
-                }
-              if (found)
-                continue;
-              // try to push front
-              found = true;
-              nodeTofind = order.front(); // try to push front
-              for (i = 0; i<nodesEdges.size(); i++)
-                if (nodesEdges[i] == nodeTofind)
-                  break;
-              if (i == nodesEdges.size())
-                {
-                  found = false; // no predecessor found on front
-                  continue;
-                }
-              if (i%2) // odd ==> use the previous one
-                if (nodesEdges[i-1] < 0)
-                  found = false;
-                else
-                  {
-                    order.push_front(nodesEdges[i-1]); MESSAGE("       --- front " << order.front()+1);
-                    nodesEdges[i-1] = -1;
-                  }
-              else // even ==> use the next one
-                if (nodesEdges[i+1] < 0)
-                  found = false;
-                else
-                  {
-                    order.push_front(nodesEdges[i+1]); MESSAGE("       --- front " << order.front()+1);
-                    nodesEdges[i+1] = -1;
-                  }
+              order.push_back(nodesEdges[i-1]); MESSAGE("       --- back " << order.back()+1);
+              nodesEdges[i-1] = -1;
+            }
+          else // even ==> use the next one
+            if (nodesEdges[i+1] < 0)
+              found = false;
+            else
+            {
+              order.push_back(nodesEdges[i+1]); MESSAGE("       --- back " << order.back()+1);
+              nodesEdges[i+1] = -1;
             }
         }
-
-
-      std::vector<int> nodes;
-      nodes.push_back(shapeId);
-      std::list<int>::iterator itl = order.begin();
-      for (; itl != order.end(); itl++)
+        if (found)
+          continue;
+        // try to push front
+        found = true;
+        nodeTofind = order.front(); // try to push front
+        for ( i = 0;  i < (int)nodesEdges.size(); i++ )
+          if ( nodesEdges[i] == nodeTofind )
+            break;
+        if ( i == (int)nodesEdges.size() )
         {
-          nodes.push_back((*itl) + 1); // SMDS id = VTK id + 1;
-          MESSAGE("              ordered node " << nodes[nodes.size()-1]);
+          found = false; // no predecessor found on front
+          continue;
         }
-      listOfListOfNodes.push_back(nodes);
+        if (i%2) // odd ==> use the previous one
+          if (nodesEdges[i-1] < 0)
+            found = false;
+          else
+          {
+            order.push_front(nodesEdges[i-1]); MESSAGE("       --- front " << order.front()+1);
+            nodesEdges[i-1] = -1;
+          }
+        else // even ==> use the next one
+          if (nodesEdges[i+1] < 0)
+            found = false;
+          else
+          {
+            order.push_front(nodesEdges[i+1]); MESSAGE("       --- front " << order.front()+1);
+            nodesEdges[i+1] = -1;
+          }
+      }
     }
 
+
+    std::vector<int> nodes;
+    nodes.push_back(shapeId);
+    std::list<int>::iterator itl = order.begin();
+    for (; itl != order.end(); itl++)
+    {
+      nodes.push_back((*itl) + 1); // SMDS id = VTK id + 1;
+      MESSAGE("              ordered node " << nodes[nodes.size()-1]);
+    }
+    listOfListOfNodes.push_back(nodes);
+  }
+
   //     partition geom faces with blocFissure
   //     mesh blocFissure and geom faces of the skin (external wires given, triangle algo to choose)
   //     mesh volume around blocFissure (skin triangles and quadrangle given, tetra algo to choose)
@@ -11961,7 +12475,8 @@ bool SMESH_MeshEditor::Make2DMeshFrom3D()
   SMESHDS_Mesh* aMesh = GetMeshDS();
   if (!aMesh)
     return false;
-  //bool res = false;
+
+  ElemFeatures faceType( SMDSAbs_Face );
   int nbFree = 0, nbExisted = 0, nbCreated = 0;
   SMDS_VolumeIteratorPtr vIt = aMesh->volumesIterator();
   while(vIt->more())
@@ -11969,8 +12484,8 @@ bool SMESH_MeshEditor::Make2DMeshFrom3D()
     const SMDS_MeshVolume* volume = vIt->next();
     SMDS_VolumeTool vTool( volume, /*ignoreCentralNodes=*/false );
     vTool.SetExternalNormal();
-    //const bool isPoly = volume->IsPoly();
     const int iQuad = volume->IsQuadratic();
+    faceType.SetQuad( iQuad );
     for ( int iface = 0, n = vTool.NbFaces(); iface < n; iface++ )
     {
       if (!vTool.IsFreeFace(iface))
@@ -11982,22 +12497,27 @@ bool SMESH_MeshEditor::Make2DMeshFrom3D()
       int inode = 0;
       for ( ; inode < nbFaceNodes; inode += iQuad+1)
         nodes.push_back(faceNodes[inode]);
-      if (iQuad) { // add medium nodes
+
+      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
+      if (aMesh->FindElement( nodes, SMDSAbs_Face, /*noMedium=*/false) )
+      {
+        nbExisted++; // face already exsist
+      }
+      else
+      {
+        AddElement( nodes, faceType.SetPoly( nbFaceNodes/(iQuad+1) > 4 ));
+        nbCreated++;
       }
-      AddElement(nodes, SMDSAbs_Face, ( !iQuad && nbFaceNodes/(iQuad+1) > 4 ));
-      nbCreated++;
     }
   }
-  return ( nbFree==(nbExisted+nbCreated) );
+  return ( nbFree == ( nbExisted + nbCreated ));
 }
 
 namespace
@@ -12059,9 +12579,16 @@ int SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements,
   SMDS_VolumeTool vTool;
   TIDSortedElemSet avoidSet;
   const TIDSortedElemSet emptySet, *elemSet = aroundElements ? &elements : &emptySet;
-  int inode;
+  size_t inode;
 
   typedef vector<const SMDS_MeshNode*> TConnectivity;
+  TConnectivity tgtNodes;
+  ElemFeatures elemKind( missType ), elemToCopy;
+
+  vector<const SMDS_MeshElement*> presentBndElems;
+  vector<TConnectivity>           missingBndElems;
+  vector<int>                     freeFacets;
+  TConnectivity nodes, elemNodes;
 
   SMDS_ElemIteratorPtr eIt;
   if (elements.empty()) eIt = aMesh->elementsIterator(elemType);
@@ -12071,33 +12598,40 @@ int SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements,
   {
     const SMDS_MeshElement* elem = eIt->next();
     const int              iQuad = elem->IsQuadratic();
+    elemKind.SetQuad( iQuad );
 
     // ------------------------------------------------------------------------------------
     // 1. For an elem, get present bnd elements and connectivities of missing bnd elements
     // ------------------------------------------------------------------------------------
-    vector<const SMDS_MeshElement*> presentBndElems;
-    vector<TConnectivity>           missingBndElems;
-    TConnectivity nodes, elemNodes;
+    presentBndElems.clear();
+    missingBndElems.clear();
+    freeFacets.clear(); nodes.clear(); elemNodes.clear();
     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;
+        freeFacets.push_back( iface );
+      }
+      if ( missType == SMDSAbs_Face )
+        vTool.SetExternalNormal();
+      for ( size_t i = 0; i < freeFacets.size(); ++i )
+      {
+        int                iface = freeFacets[i];
         const SMDS_MeshNode** nn = vTool.GetFaceNodes(iface);
-        const int    nbFaceNodes = vTool.NbFaceNodes (iface);
+        const size_t nbFaceNodes = vTool.NbFaceNodes (iface);
         if ( missType == SMDSAbs_Edge ) // boundary edges
         {
           nodes.resize( 2+iQuad );
-          for ( int i = 0; i < nbFaceNodes; i += 1+iQuad)
+          for ( size_t i = 0; i < nbFaceNodes; i += 1+iQuad )
           {
-            for ( int j = 0; j < nodes.size(); ++j )
-              nodes[j] =nn[i+j];
+            for ( size_t j = 0; j < nodes.size(); ++j )
+              nodes[ j ] = nn[ i+j ];
             if ( const SMDS_MeshElement* edge =
-                 aMesh->FindElement(nodes,SMDSAbs_Edge,/*noMedium=*/false))
+                 aMesh->FindElement( nodes, SMDSAbs_Edge, /*noMedium=*/false ))
               presentBndElems.push_back( edge );
             else
               missingBndElems.push_back( nodes );
@@ -12168,37 +12702,37 @@ int SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& 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 )
+      for ( size_t 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,
+        tgtNodes.resize( srcNodes.size() );
+        for ( inode = 0; inode < srcNodes.size(); ++inode )
+          tgtNodes[inode] = getNodeWithSameID( tgtMeshDS, srcNodes[inode] );
+        if ( aroundElements && tgtEditor.GetMeshDS()->FindElement( tgtNodes,
                                                                    missType,
                                                                    /*noMedium=*/false))
           continue;
-        tgtEditor.AddElement(nodes, missType, !iQuad && nodes.size()/(iQuad+1)>4);
+        tgtEditor.AddElement( tgtNodes, elemKind.SetPoly( tgtNodes.size()/(iQuad+1) > 4 ));
         ++nbAddedBnd;
       }
     else
-      for ( int i = 0; i < missingBndElems.size(); ++i )
+      for ( size_t i = 0; i < missingBndElems.size(); ++i )
       {
-        TConnectivity& nodes = missingBndElems[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;
+        SMDS_MeshElement* newElem =
+          tgtEditor.AddElement( nodes, elemKind.SetPoly( nodes.size()/(iQuad+1) > 4 ));
+        nbAddedBnd += bool( newElem );
 
         // 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 );
+          const size_t nbN = nodes.size() / (iQuad+1 );
           for ( inode = 0; inode < nbN && ok; ++inode )
           {
             pair<int, TopAbs_ShapeEnum> i_stype =
@@ -12218,7 +12752,7 @@ int SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements,
             }
           }
           if ( ok && mediumShapes.begin()->first == missShapeType )
-            aMesh->SetMeshElementOnShape( elem, mediumShapes.begin()->second );
+            aMesh->SetMeshElementOnShape( newElem, mediumShapes.begin()->second );
         }
       }
 
@@ -12226,18 +12760,18 @@ int SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements,
     // 3. Copy present boundary elements
     // ----------------------------------
     if ( toCopyExistingBoundary )
-      for ( int i = 0 ; i < presentBndElems.size(); ++i )
+      for ( size_t 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());
+        tgtNodes.resize( e->NbNodes() );
+        for ( inode = 0; inode < tgtNodes.size(); ++inode )
+          tgtNodes[inode] = getNodeWithSameID( tgtMeshDS, e->GetNode(inode) );
+        presentEditor->AddElement( tgtNodes, elemToCopy.Init( e ));
       }
     else // store present elements to add them to a group
-      for ( int i = 0 ; i < presentBndElems.size(); ++i )
+      for ( size_t i = 0 ; i < presentBndElems.size(); ++i )
       {
-        presentEditor->myLastCreatedElems.Append(presentBndElems[i]);
+        presentEditor->myLastCreatedElems.Append( presentBndElems[ i ]);
       }
 
   } // loop on given elements
@@ -12264,13 +12798,55 @@ int SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements,
     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());
+      tgtNodes.resize( elem->NbNodes() );
+      for ( inode = 0; inode < tgtNodes.size(); ++inode )
+        tgtNodes[inode] = getNodeWithSameID( tgtMeshDS, elem->GetNode(inode) );
+      tgtEditor.AddElement( tgtNodes, elemToCopy.Init( elem ));
 
       tgtEditor.myLastCreatedElems.Clear();
     }
   }
   return nbAddedBnd;
 }
+
+//================================================================================
+/*!
+ * \brief Copy node position and set \a to node on the same geometry
+ */
+//================================================================================
+
+void SMESH_MeshEditor::copyPosition( const SMDS_MeshNode* from,
+                                     const SMDS_MeshNode* to )
+{
+  if ( !from || !to ) return;
+
+  SMDS_PositionPtr pos = from->GetPosition();
+  if ( !pos || from->getshapeId() < 1 ) return;
+
+  switch ( pos->GetTypeOfPosition() )
+  {
+  case SMDS_TOP_3DSPACE: break;
+
+  case SMDS_TOP_FACE:
+  {
+    const SMDS_FacePosition* fPos = static_cast< const SMDS_FacePosition* >( pos );
+    GetMeshDS()->SetNodeOnFace( to, from->getshapeId(),
+                                fPos->GetUParameter(), fPos->GetVParameter() );
+    break;
+  }
+  case SMDS_TOP_EDGE:
+  {
+    // WARNING: it is dangerous to set equal nodes on one EDGE!!!!!!!!
+    const SMDS_EdgePosition* ePos = static_cast< const SMDS_EdgePosition* >( pos );
+    GetMeshDS()->SetNodeOnEdge( to, from->getshapeId(), ePos->GetUParameter() );
+    break;
+  }
+  case SMDS_TOP_VERTEX:
+  {
+    GetMeshDS()->SetNodeOnVertex( to, from->getshapeId() );
+    break;
+  }
+  case SMDS_TOP_UNSPEC:
+  default:;
+  }
+}
index 5adb43a4132c2fef50e9d3b54adf2c07b0ab8a19..a2039ac8a6e6d963c52abfb2d04ba783ab425104 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -70,24 +70,52 @@ public:
 
   const SMESH_SequenceOfElemPtr& GetLastCreatedNodes() const { return myLastCreatedNodes; }
   const SMESH_SequenceOfElemPtr& GetLastCreatedElems() const { return myLastCreatedElems; }
-  void                           CrearLastCreated();
+  void                           ClearLastCreated();
   SMESH_ComputeErrorPtr &        GetError() { return myError; }
 
+  // --------------------------------------------------------------------------------
+  struct ElemFeatures //!< Features of element to create
+  {
+    SMDSAbs_ElementType myType;
+    bool                myIsPoly, myIsQuad;
+    int                 myID;
+    double              myBallDiameter;
+    std::vector<int>    myPolyhedQuantities;
+
+    SMESH_EXPORT ElemFeatures( SMDSAbs_ElementType type=SMDSAbs_All, bool isPoly=false, bool isQuad=false )
+      :myType( type ), myIsPoly(isPoly), myIsQuad(isQuad), myID(-1), myBallDiameter(0) {}
+
+    SMESH_EXPORT ElemFeatures& Init( SMDSAbs_ElementType type, bool isPoly=false, bool isQuad=false )
+    { myType = type; myIsPoly = isPoly; myIsQuad = isQuad; return *this; }
+
+    SMESH_EXPORT ElemFeatures& Init( const SMDS_MeshElement* elem, bool basicOnly=true );
+
+    SMESH_EXPORT ElemFeatures& Init( double diameter )
+    { myType = SMDSAbs_Ball; myBallDiameter = diameter; return *this; }
+
+    SMESH_EXPORT ElemFeatures& Init( vector<int>& quanities, bool isQuad=false )
+    { myType = SMDSAbs_Volume; myIsPoly = 1; myIsQuad = isQuad;
+      myPolyhedQuantities.swap( quanities ); return *this; }
+
+    SMESH_EXPORT ElemFeatures& Init( const vector<int>& quanities, bool isQuad=false )
+    { myType = SMDSAbs_Volume; myIsPoly = 1; myIsQuad = isQuad;
+      myPolyhedQuantities = quanities; return *this; }
+
+    SMESH_EXPORT ElemFeatures& SetPoly(bool isPoly) { myIsPoly = isPoly; return *this; }
+    SMESH_EXPORT ElemFeatures& SetQuad(bool isQuad) { myIsQuad = isQuad; return *this; }
+    SMESH_EXPORT ElemFeatures& SetID  (int ID)      { myID = ID; return *this; }
+  };
+
   /*!
    * \brief Add element
    */
   SMDS_MeshElement* AddElement(const std::vector<const SMDS_MeshNode*> & nodes,
-                               const SMDSAbs_ElementType                 type,
-                               const bool                                isPoly,
-                               const int                                 ID = -1,
-                               const double                              ballDiameter=0.);
+                               const ElemFeatures&                       features);
   /*!
    * \brief Add element
    */
-  SMDS_MeshElement* AddElement(const std::vector<int>  & nodeIDs,
-                               const SMDSAbs_ElementType type,
-                               const bool                isPoly,
-                               const int                 ID = -1);
+  SMDS_MeshElement* AddElement(const std::vector<int> & nodeIDs,
+                               const ElemFeatures&      features);
 
   int Remove (const std::list< int >& theElemIDs, const bool isNodes);
   // Remove a node or an element.
@@ -193,7 +221,7 @@ public:
 
   /*!
    * \brief For hexahedra that will be split into prisms, finds facets to
-   *        split into triangles 
+   *        split into triangles
    *  \param [in,out] theHexas - the hexahedra
    *  \param [in]     theFacetNormal - facet normal
    *  \param [out]    theFacets - the hexahedra and found facet IDs
@@ -202,6 +230,16 @@ public:
                              const gp_Ax1&     theFacetNormal,
                              TFacetOfElem &    theFacets);
 
+  /*!
+   * \brief Split bi-quadratic elements into linear ones without creation of additional nodes
+   *   - bi-quadratic triangle will be split into 3 linear quadrangles;
+   *   - bi-quadratic quadrangle will be split into 4 linear quadrangles;
+   *   - tri-quadratic hexahedron will be split into 8 linear hexahedra;
+   *   Quadratic elements of lower dimension  adjacent to the split bi-quadratic element
+   *   will be split in order to keep the mesh conformal.
+   *  \param elems - elements to split
+   */
+  void SplitBiQuadraticIntoLinear(TIDSortedElemSet& theElems);
 
   enum SmoothMethod { LAPLACIAN = 0, CENTROIDAL };
 
@@ -229,7 +267,7 @@ public:
   typedef std::map<const SMDS_MeshElement*, TVecOfNnlmiMap, TElemSort >    TElemOfVecOfNnlmiMap;
   typedef std::auto_ptr< std::list<int> > PGroupIDs;
 
-  PGroupIDs RotationSweep (TIDSortedElemSet & theElements,
+  PGroupIDs RotationSweep (TIDSortedElemSet   theElements[2],
                            const gp_Ax1&      theAxis,
                            const double       theAngle,
                            const int          theNbSteps,
@@ -240,34 +278,99 @@ public:
   // by theAngle by theNbSteps
 
   /*!
-   * Auxilary flag for advanced extrusion.
+   * Flags of extrusion.
    * BOUNDARY: create or not boundary for result of extrusion
    * SEW:      try to use existing nodes or create new nodes in any case
+   * GROUPS:   to create groups
+   * BY_AVG_NORMAL: step size is measured along average normal to elements,
+   *                else step size is measured along average normal of any element
+   * USE_INPUT_ELEMS_ONLY: to use only input elements to compute extrusion direction
+   *                       for ExtrusionByNormal()
    */
   enum ExtrusionFlags {
     EXTRUSION_FLAG_BOUNDARY = 0x01,
-    EXTRUSION_FLAG_SEW = 0x02
+    EXTRUSION_FLAG_SEW = 0x02,
+    EXTRUSION_FLAG_GROUPS = 0x04,
+    EXTRUSION_FLAG_BY_AVG_NORMAL = 0x08,
+    EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY = 0x10
   };
-  
+
   /*!
-   * special structure for control of extrusion functionality
+   * Generator of nodes for extrusion functionality
    */
-  struct ExtrusParam {
-    gp_Dir myDir; // direction of extrusion
+  class SMESH_EXPORT ExtrusParam {
+    gp_Dir                          myDir;   // direction of extrusion
     Handle(TColStd_HSequenceOfReal) mySteps; // magnitudes for each step
-    SMESH_SequenceOfNode myNodes; // nodes for using in sewing
+    SMESH_SequenceOfNode            myNodes; // nodes for using in sewing
+    int                             myFlags; // see ExtrusionFlags
+    double                          myTolerance; // tolerance for sewing nodes
+    const TIDSortedElemSet*         myElemsToUse; // elements to use for extrusion by normal
+
+    int (ExtrusParam::*myMakeNodesFun)(SMESHDS_Mesh*                     mesh,
+                                       const SMDS_MeshNode*              srcNode,
+                                       std::list<const SMDS_MeshNode*> & newNodes,
+                                       const bool                        makeMediumNodes);
+
+  public:
+    ExtrusParam( const gp_Vec&  theStep,
+                 const int      theNbSteps,
+                 const int      theFlags = 0,
+                 const double   theTolerance = 1e-6);
+    ExtrusParam( const gp_Dir&                   theDir,
+                 Handle(TColStd_HSequenceOfReal) theSteps,
+                 const int                       theFlags = 0,
+                 const double                    theTolerance = 1e-6);
+    ExtrusParam( const double theStep,
+                 const int    theNbSteps,
+                 const int    theFlags,
+                 const int    theDim); // for extrusion by normal
+
+    SMESH_SequenceOfNode& ChangeNodes() { return myNodes; }
+    int& Flags()                   { return myFlags; }
+    bool ToMakeBoundary()    const { return myFlags & EXTRUSION_FLAG_BOUNDARY; }
+    bool ToMakeGroups()      const { return myFlags & EXTRUSION_FLAG_GROUPS; }
+    bool ToUseInpElemsOnly() const { return myFlags & EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY; }
+    int  NbSteps()           const { return mySteps->Length(); }
+
+    // stores elements to use for extrusion by normal, depending on
+    // state of EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY flag
+    void SetElementsToUse( const TIDSortedElemSet& elems );
+
+    // creates nodes and returns number of nodes added in \a newNodes
+    int MakeNodes( SMESHDS_Mesh*                     mesh,
+                   const SMDS_MeshNode*              srcNode,
+                   std::list<const SMDS_MeshNode*> & newNodes,
+                   const bool                        makeMediumNodes)
+    {
+      return (this->*myMakeNodesFun)( mesh, srcNode, newNodes, makeMediumNodes );
+    }
+  private:
+
+    int makeNodesByDir( SMESHDS_Mesh*                     mesh,
+                        const SMDS_MeshNode*              srcNode,
+                        std::list<const SMDS_MeshNode*> & newNodes,
+                        const bool                        makeMediumNodes);
+    int makeNodesByDirAndSew( SMESHDS_Mesh*                     mesh,
+                              const SMDS_MeshNode*              srcNode,
+                              std::list<const SMDS_MeshNode*> & newNodes,
+                              const bool                        makeMediumNodes);
+    int makeNodesByNormal2D( SMESHDS_Mesh*                     mesh,
+                             const SMDS_MeshNode*              srcNode,
+                             std::list<const SMDS_MeshNode*> & newNodes,
+                             const bool                        makeMediumNodes);
+    int makeNodesByNormal1D( SMESHDS_Mesh*                     mesh,
+                             const SMDS_MeshNode*              srcNode,
+                             std::list<const SMDS_MeshNode*> & newNodes,
+                             const bool                        makeMediumNodes);
+    // step iteration
+    void   beginStepIter( bool withMediumNodes );
+    bool   moreSteps();
+    double nextStep();
+    std::vector< double > myCurSteps;
+    bool                  myWithMediumNodes;
+    int                   myNextStep;
   };
 
-  /*!
-   * Create new node in the mesh with given coordinates
-   * (auxiliary for advanced extrusion)
-   */
-  const SMDS_MeshNode* CreateNode(const double x,
-                                  const double y,
-                                  const double z,
-                                  const double tolnode,
-                                  SMESH_SequenceOfNode& aNodes);
-
   /*!
    * Generate new elements by extrusion of theElements
    * It is a method used in .idl file. All functionality
@@ -280,12 +383,11 @@ public:
    * @param theTolerance - uses for comparing locations of nodes if flag
    *   EXTRUSION_FLAG_SEW is set
    */
-  PGroupIDs ExtrusionSweep (TIDSortedElemSet &   theElems,
+  PGroupIDs ExtrusionSweep (TIDSortedElemSet     theElems[2],
                             const gp_Vec&        theStep,
                             const int            theNbSteps,
                             TTElemOfElemListMap& newElemsMap,
-                            const bool           theMakeGroups,
-                            const int            theFlags = EXTRUSION_FLAG_BOUNDARY,
+                            const int            theFlags,
                             const double         theTolerance = 1.e-6);
   
   /*!
@@ -298,12 +400,9 @@ public:
    *   EXTRUSION_FLAG_SEW is set
    * @param theParams - special structure for manage of extrusion
    */
-  PGroupIDs ExtrusionSweep (TIDSortedElemSet &   theElems,
+  PGroupIDs ExtrusionSweep (TIDSortedElemSet     theElems[2],
                             ExtrusParam&         theParams,
-                            TTElemOfElemListMap& newElemsMap,
-                            const bool           theMakeGroups,
-                            const int            theFlags,
-                            const double         theTolerance);
+                            TTElemOfElemListMap& newElemsMap);
 
 
   // Generate new elements by extrusion of theElements 
@@ -319,7 +418,7 @@ public:
     EXTR_CANT_GET_TANGENT
     };
   
-  Extrusion_Error ExtrusionAlongTrack (TIDSortedElemSet &   theElements,
+  Extrusion_Error ExtrusionAlongTrack (TIDSortedElemSet     theElements[2],
                                        SMESH_subMesh*       theTrackPattern,
                                        const SMDS_MeshNode* theNodeStart,
                                        const bool           theHasAngles,
@@ -328,7 +427,7 @@ public:
                                        const bool           theHasRefPoint,
                                        const gp_Pnt&        theRefPoint,
                                        const bool           theMakeGroups);
-  Extrusion_Error ExtrusionAlongTrack (TIDSortedElemSet &   theElements,
+  Extrusion_Error ExtrusionAlongTrack (TIDSortedElemSet     theElements[2],
                                        SMESH_Mesh*          theTrackPattern,
                                        const SMDS_MeshNode* theNodeStart,
                                        const bool           theHasAngles,
@@ -351,7 +450,8 @@ public:
 
   void FindCoincidentNodes (TIDSortedNodeSet &   theNodes,
                             const double         theTolerance,
-                            TListOfListOfNodes & theGroupsOfNodes);
+                            TListOfListOfNodes & theGroupsOfNodes,
+                            bool                 theSeparateCornersAndMedium);
   // Return list of group of nodes close to each other within theTolerance.
   // Search among theNodes or in the whole mesh if theNodes is empty.
 
@@ -630,7 +730,7 @@ public:
   void sweepElement(const SMDS_MeshElement*                    elem,
                     const std::vector<TNodeOfNodeListMapItr> & newNodesItVec,
                     std::list<const SMDS_MeshElement*>&        newElems,
-                    const int                                  nbSteps,
+                    const size_t                               nbSteps,
                     SMESH_SequenceOfElemPtr&                   srcElements);
 
   /*!
@@ -669,7 +769,7 @@ public:
                                      const TopoDS_Edge&                     aTrackEdge,
                                      bool                                   aFirstIsStart,
                                      std::list<SMESH_MeshEditor_PathPoint>& aLPP);
-  Extrusion_Error MakeExtrElements(TIDSortedElemSet&                      theElements,
+  Extrusion_Error MakeExtrElements(TIDSortedElemSet                       theElements[2],
                                    std::list<SMESH_MeshEditor_PathPoint>& theFullList,
                                    const bool                             theHasAngles,
                                    std::list<double>&                     theAngles,
@@ -680,11 +780,14 @@ public:
   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 );
+  bool doubleNodes( SMESHDS_Mesh*           theMeshDS,
+                    const TIDSortedElemSet& theElems,
+                    const TIDSortedElemSet& theNodesNot,
+                    TNodeNodeMap&           theNodeNodeMap,
+                    const bool              theIsDoubleElem );
+
+  void copyPosition( const SMDS_MeshNode* from,
+                     const SMDS_MeshNode* to );
 
 private:
 
index c6c51ab37a9bdf0206d269593b9634ceaab1e929..3703a7215de3c4d0e89733d5da826d9c539f0615 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&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,6 +32,7 @@
 #include "SMDS_IteratorOnIterators.hxx"
 #include "SMDS_VolumeTool.hxx"
 #include "SMESH_Block.hxx"
+#include "SMESH_HypoFilter.hxx"
 #include "SMESH_MeshAlgos.hxx"
 #include "SMESH_ProxyMesh.hxx"
 #include "SMESH_subMesh.hxx"
@@ -70,7 +71,7 @@ using namespace std;
 
 namespace {
 
-  gp_XYZ XYZ(const SMDS_MeshNode* n) { return gp_XYZ(n->X(), n->Y(), n->Z()); }
+  inline SMESH_TNodeXYZ XYZ(const SMDS_MeshNode* n) { return SMESH_TNodeXYZ(n); }
 
   enum { U_periodic = 1, V_periodic = 2 };
 }
@@ -138,7 +139,7 @@ bool SMESH_MesherHelper::IsQuadraticSubMesh(const TopoDS_Shape& aSh)
   SMDSAbs_ElementType elemType( subType==TopAbs_FACE ? SMDSAbs_Face : SMDSAbs_Edge );
 
 
-  int nbOldLinks = myTLinkNodeMap.size();
+  //int nbOldLinks = myTLinkNodeMap.size();
 
   if ( !myMesh->HasShapeToMesh() )
   {
@@ -190,12 +191,13 @@ bool SMESH_MesherHelper::IsQuadraticSubMesh(const TopoDS_Shape& aSh)
     }
   }
 
-  if ( nbOldLinks == myTLinkNodeMap.size() )
+  // if ( nbOldLinks == myTLinkNodeMap.size() ) -- 0023068
+  if ( myTLinkNodeMap.empty() )
     myCreateQuadratic = false;
 
-  if(!myCreateQuadratic) {
+  if ( !myCreateQuadratic )
     myTLinkNodeMap.clear();
-  }
+
   SetSubShape( aSh );
 
   return myCreateQuadratic;
@@ -259,6 +261,7 @@ void SMESH_MesherHelper::SetSubShape(const TopoDS_Shape& aSh)
     {
       // look for a "seam" edge, a real seam or an edge on period boundary
       TopoDS_Edge edge = TopoDS::Edge( exp.Current() );
+      const int edgeID = meshDS->ShapeToIndex( edge );
       if ( myParIndex )
       {
         BRep_Tool::UVPoints( edge, face, uv1, uv2 );
@@ -301,11 +304,20 @@ void SMESH_MesherHelper::SetSubShape(const TopoDS_Shape& aSh)
             isSeam = ( Abs( uv1.Coord(2) - myPar1[1] ) < Precision::PConfusion() ||
                        Abs( uv1.Coord(2) - myPar2[1] ) < Precision::PConfusion() );
           }
+          if ( isSeam ) // vertices are on period boundary, check a middle point (23032)
+          {
+            double f,l, r = 0.2345;
+            Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface( edge, face, f, l );
+            uv2 = C2d->Value( f * r + l * ( 1.-r ));
+            if ( du < Precision::PConfusion() )
+              isSeam = ( Abs( uv1.Coord(1) - uv2.Coord(1) ) < Precision::PConfusion() );
+            else
+              isSeam = ( Abs( uv1.Coord(2) - uv2.Coord(2) ) < Precision::PConfusion() );
+          }
         }
         if ( isSeam )
         {
-          // store seam shape indices, negative if shape encounters twice
-          int edgeID = meshDS->ShapeToIndex( edge );
+          // store seam shape indices, negative if shape encounters twice ('real seam')
           mySeamShapeIds.insert( IsSeamShape( edgeID ) ? -edgeID : edgeID );
           for ( TopExp_Explorer v( edge, TopAbs_VERTEX ); v.More(); v.Next() ) {
             int vertexID = meshDS->ShapeToIndex( v.Current() );
@@ -315,10 +327,15 @@ void SMESH_MesherHelper::SetSubShape(const TopoDS_Shape& aSh)
       }
       // look for a degenerated edge
       if ( SMESH_Algo::isDegenerated( edge )) {
-        myDegenShapeIds.insert( meshDS->ShapeToIndex( edge ));
+        myDegenShapeIds.insert( edgeID );
         for ( TopExp_Explorer v( edge, TopAbs_VERTEX ); v.More(); v.Next() )
           myDegenShapeIds.insert( meshDS->ShapeToIndex( v.Current() ));
       }
+      if ( !BRep_Tool::SameParameter( edge ) ||
+           !BRep_Tool::SameRange( edge ))
+      {
+        setPosOnShapeValidity( edgeID, false );
+      }
     }
   }
 }
@@ -527,11 +544,11 @@ void SMESH_MesherHelper::ToFixNodeParameters(bool toFix)
 
 
 //=======================================================================
-//function : GetUVOnSeam
+//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
+gp_Pnt2d SMESH_MesherHelper::getUVOnSeam( const gp_Pnt2d& uv1, const gp_Pnt2d& uv2 ) const
 {
   gp_Pnt2d result = uv1;
   for ( int i = U_periodic; i <= V_periodic ; ++i )
@@ -568,38 +585,34 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face&   F,
 
   const SMDS_PositionPtr Pos = n->GetPosition();
   bool uvOK = false;
-  if(Pos->GetTypeOfPosition()==SMDS_TOP_FACE)
+  if ( Pos->GetTypeOfPosition() == SMDS_TOP_FACE )
   {
     // node has position on face
-    const SMDS_FacePosition* fpos =
-      static_cast<const SMDS_FacePosition*>( Pos );
-    uv.SetCoord(fpos->GetUParameter(),fpos->GetVParameter());
+    const SMDS_FacePosition* fpos = static_cast<const SMDS_FacePosition*>( Pos );
+    uv.SetCoord( fpos->GetUParameter(), fpos->GetVParameter() );
     if ( check )
-      uvOK = CheckNodeUV( F, n, uv.ChangeCoord(), 10*MaxTolerance( F ));
+      uvOK = CheckNodeUV( F, n, uv.ChangeCoord(), 2.*getFaceMaxTol( F )); // 2. from 22830
   }
-  else if(Pos->GetTypeOfPosition()==SMDS_TOP_EDGE)
+  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 retrieve value from this pcurve
-    const SMDS_EdgePosition* epos =
-      static_cast<const SMDS_EdgePosition*>( Pos );
-    int edgeID = n->getshapeId();
-    TopoDS_Edge E = TopoDS::Edge(GetMeshDS()->IndexToShape(edgeID));
+    // node has position on EDGE => it is needed to find
+    // corresponding EDGE from FACE, get pcurve for this
+    // EDGE and retrieve value from this pcurve
+    const SMDS_EdgePosition* epos = static_cast<const SMDS_EdgePosition*>( Pos );
+    const int              edgeID = n->getshapeId();
+    const 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);
-    bool validU = ( f < u && u < l );
-    if ( validU )
-      uv = C2d->Value( u );
-    else
-      uv.SetCoord( Precision::Infinite(),0.);
+    Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface( E, F, f, l );
+    bool validU = ( !C2d.IsNull() && ( 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 );
+      uvOK = CheckNodeUV( F, n, uv.ChangeCoord(), 2.*getFaceMaxTol( F ),/*force=*/ !validU );
 
-    // for a node on a seam edge select one of UVs on 2 pcurves
-    if ( n2 && IsSeamShape( edgeID ) )
+    // 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, check ));
+      uv = getUVOnSeam( uv, GetNodeUV( F, n2, 0, check ));
     }
     else
     { // adjust uv to period
@@ -611,23 +624,22 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face&   F,
       if ( isUPeriodic || isVPeriodic ) {
         Standard_Real UF,UL,VF,VL;
         S->Bounds(UF,UL,VF,VL);
-        if ( isUPeriodic )
-          newUV.SetX( uv.X() + ShapeAnalysis::AdjustToPeriod(uv.X(),UF,UL));
-        if ( isVPeriodic )
-          newUV.SetY( uv.Y() + ShapeAnalysis::AdjustToPeriod(uv.Y(),VF,VL));
-      }
-      if ( n2 )
-      {
-        gp_Pnt2d uv2 = GetNodeUV( F, n2, 0, check );
-        if ( isUPeriodic && Abs( uv.X()-uv2.X() ) < Abs( newUV.X()-uv2.X() ))
-          newUV.SetX( uv.X() );
-        if ( isVPeriodic && Abs( uv.Y()-uv2.Y() ) < Abs( newUV.Y()-uv2.Y() ))
-          newUV.SetY( uv.Y() );
+        if ( isUPeriodic ) newUV.SetX( uv.X() + ShapeAnalysis::AdjustToPeriod(uv.X(),UF,UL));
+        if ( isVPeriodic ) newUV.SetY( uv.Y() + ShapeAnalysis::AdjustToPeriod(uv.Y(),VF,VL));
+
+        if ( n2 )
+        {
+          gp_Pnt2d uv2 = GetNodeUV( F, n2, 0, check );
+          if ( isUPeriodic && Abs( uv.X()-uv2.X() ) < Abs( newUV.X()-uv2.X() ))
+            newUV.SetX( uv.X() );
+          if ( isVPeriodic && Abs( uv.Y()-uv2.Y() ) < Abs( newUV.Y()-uv2.Y() ))
+            newUV.SetY( uv.Y() );
+        }
       }
       uv = newUV;
     }
   }
-  else if(Pos->GetTypeOfPosition()==SMDS_TOP_VERTEX)
+  else if ( Pos->GetTypeOfPosition() == SMDS_TOP_VERTEX )
   {
     if ( int vertexID = n->getshapeId() ) {
       const TopoDS_Vertex& V = TopoDS::Vertex(GetMeshDS()->IndexToShape(vertexID));
@@ -637,16 +649,16 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face&   F,
       }
       catch (Standard_Failure& exc) {
       }
-      if ( !uvOK ) {
-        for ( TopExp_Explorer vert(F,TopAbs_VERTEX); !uvOK && vert.More(); vert.Next() )
-          uvOK = ( V == vert.Current() );
-        if ( !uvOK ) {
+      if ( !uvOK )
+      {
+        if ( !IsSubShape( V, F ))
+        {
           MESSAGE ( "SMESH_MesherHelper::GetNodeUV(); Vertex " << vertexID
                     << " not in face " << GetMeshDS()->ShapeToIndex( F ) );
           // get UV of a vertex closest to the node
           double dist = 1e100;
           gp_Pnt pn = XYZ( n );
-          for ( TopExp_Explorer vert(F,TopAbs_VERTEX); !uvOK && vert.More(); vert.Next() ) {
+          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 );
@@ -657,7 +669,8 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face&   F,
             }
           }
         }
-        else {
+        else
+        {
           uvOK = false;
           TopTools_ListIteratorOfListOfShape it( myMesh->GetAncestors( V ));
           for ( ; it.More(); it.Next() ) {
@@ -666,25 +679,45 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face&   F,
               double f,l;
               Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(edge, F, f, l);
               if ( !C2d.IsNull() ) {
-                double u = ( V == TopExp::FirstVertex( edge ) ) ?  f : l;
+                double u = ( V == IthVertex( 0, edge )) ?  f : l;
                 uv = C2d->Value( u );
                 uvOK = true;
                 break;
               }
             }
           }
+          if ( !uvOK && V.Orientation() == TopAbs_INTERNAL )
+          {
+            Handle(ShapeAnalysis_Surface) projector = GetSurface( F );
+            if ( n2 ) uv = GetNodeUV( F, n2 );
+            if ( Precision::IsInfinite( uv.X() ))
+              uv = projector->NextValueOfUV( uv, BRep_Tool::Pnt( V ), BRep_Tool::Tolerance( F ));
+            else
+              uv = projector->ValueOfUV( BRep_Tool::Pnt( V ), BRep_Tool::Tolerance( F ));
+            uvOK = ( projector->Gap() < getFaceMaxTol( F ));
+          }
         }
       }
-      if ( n2 && IsSeamShape( vertexID ) )
-        uv = GetUVOnSeam( uv, GetNodeUV( F, n2, 0 ));
+      if ( n2 && IsSeamShape( vertexID ))
+      {
+        bool isSeam = ( myShape.IsSame( F ));
+        if ( !isSeam ) {
+          SMESH_MesherHelper h( *myMesh );
+          h.SetSubShape( F );
+          isSeam = IsSeamShape( vertexID );
+        }
+
+        if ( isSeam )
+          uv = getUVOnSeam( uv, GetNodeUV( F, n2, 0 ));
+      }
     }
   }
   else
   {
-    uvOK = CheckNodeUV( F, n, uv.ChangeCoord(), 10*MaxTolerance( F ));
+    uvOK = CheckNodeUV( F, n, uv.ChangeCoord(), 2.*getFaceMaxTol( F ));
   }
 
-  if ( check )
+  if ( check && !uvOK )
     *check = uvOK;
 
   return uv.XY();
@@ -703,9 +736,11 @@ bool SMESH_MesherHelper::CheckNodeUV(const TopoDS_Face&   F,
                                      double               distXYZ[4]) const
 {
   int  shapeID = n->getshapeId();
-  bool infinit = ( Precision::IsInfinite( uv.X() ) || Precision::IsInfinite( uv.Y() ));
-  bool zero    = ( uv.X() == 0. && uv.Y() == 0. );
-  if ( force || toCheckPosOnShape( shapeID ) || infinit || zero )
+  bool infinit;
+  if (( infinit = ( Precision::IsInfinite( uv.X() ) || Precision::IsInfinite( uv.Y() ))) ||
+      ( force ) ||
+      ( uv.X() == 0. && uv.Y() == 0. ) ||
+      ( toCheckPosOnShape( shapeID )))
   {
     // check that uv is correct
     TopLoc_Location loc;
@@ -750,7 +785,7 @@ bool SMESH_MesherHelper::CheckNodeUV(const TopoDS_Face&   F,
         const_cast<SMDS_MeshNode*>(n)->SetPosition
           ( SMDS_PositionPtr( new SMDS_FacePosition( U, V )));
     }
-    else if ( uv.Modulus() > numeric_limits<double>::min() )
+    else if ( myShape.IsSame(F) && uv.Modulus() > numeric_limits<double>::min() )
     {
       setPosOnShapeValidity( shapeID, true );
     }
@@ -783,6 +818,24 @@ GeomAPI_ProjectPointOnSurf& SMESH_MesherHelper::GetProjector(const TopoDS_Face&
   return *( i_proj->second );
 }
 
+//=======================================================================
+//function : GetSurface
+//purpose  : Return a cached ShapeAnalysis_Surface of a FACE
+//=======================================================================
+
+Handle(ShapeAnalysis_Surface) SMESH_MesherHelper::GetSurface(const TopoDS_Face& F ) const
+{
+  Handle(Geom_Surface) surface = BRep_Tool::Surface( F );
+  int faceID = GetMeshDS()->ShapeToIndex( F );
+  TID2Surface::iterator i_surf = myFace2Surface.find( faceID );
+  if ( i_surf == myFace2Surface.end() && faceID )
+  {
+    Handle(ShapeAnalysis_Surface) surf( new ShapeAnalysis_Surface( surface ));
+    i_surf = myFace2Surface.insert( make_pair( faceID, surf )).first;
+  }
+  return i_surf->second;
+}
+
 namespace
 {
   gp_XY AverageUV(const gp_XY& uv1, const gp_XY& uv2) { return ( uv1 + uv2 ) / 2.; }
@@ -791,18 +844,20 @@ namespace
 }
 
 //=======================================================================
-//function : applyIn2D
+//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.
 //=======================================================================
 
-gp_XY SMESH_MesherHelper::applyIn2D(const Handle(Geom_Surface)& surface,
-                                    const gp_XY&                uv1,
-                                    const gp_XY&                uv2,
-                                    xyFunPtr                    fun,
-                                    const bool                  resultInPeriod)
+gp_XY SMESH_MesherHelper::ApplyIn2D(Handle(Geom_Surface) surface,
+                                    const gp_XY&         uv1,
+                                    const gp_XY&         uv2,
+                                    xyFunPtr             fun,
+                                    const bool           resultInPeriod)
 {
+  if ( surface->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface )))
+    surface = Handle(Geom_RectangularTrimmedSurface)::DownCast( surface )->BasisSurface();
   Standard_Boolean isUPeriodic = surface.IsNull() ? false : surface->IsUPeriodic();
   Standard_Boolean isVPeriodic = surface.IsNull() ? false : surface->IsVPeriodic();
   if ( !isUPeriodic && !isVPeriodic )
@@ -830,6 +885,31 @@ gp_XY SMESH_MesherHelper::applyIn2D(const Handle(Geom_Surface)& surface,
 
   return res;
 }
+
+//=======================================================================
+//function : AdjustByPeriod
+//purpose  : Move node positions on a FACE within surface period
+//=======================================================================
+
+void SMESH_MesherHelper::AdjustByPeriod( const TopoDS_Face& face, gp_XY uv[], const int nbUV )
+{
+  SMESH_MesherHelper h( *myMesh ), *ph = face.IsSame( myShape ) ? this : &h;
+  ph->SetSubShape( face );
+
+  for ( int iCoo = U_periodic; iCoo <= V_periodic; ++iCoo )
+    if ( ph->GetPeriodicIndex() & iCoo )
+    {
+      const double period = ( ph->myPar2[iCoo-1] - ph->myPar1[iCoo-1] );
+      const double xRef = uv[0].Coord( iCoo );
+      for ( int i = 1; i < nbUV; ++i )
+      {
+        double x = uv[i].Coord( iCoo );
+        double dx = ShapeAnalysis::AdjustByPeriod( x, xRef, period );
+        uv[i].SetCoord( iCoo, x + dx );
+      }
+    }
+}
+
 //=======================================================================
 //function : GetMiddleUV
 //purpose  : Return middle UV taking in account surface period
@@ -840,13 +920,13 @@ gp_XY SMESH_MesherHelper::GetMiddleUV(const Handle(Geom_Surface)& surface,
                                       const gp_XY&                p2)
 {
   // NOTE:
-  // the proper place of getting basic surface seems to be in applyIn2D()
+  // 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();
+  // 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 );
+  return ApplyIn2D( surface, p1, p2, & AverageUV );
 }
 
 //=======================================================================
@@ -939,9 +1019,11 @@ bool SMESH_MesherHelper::CheckNodeU(const TopoDS_Edge&   E,
                                     double               distXYZ[4]) const
 {
   int  shapeID = n->getshapeId();
-  bool infinit = Precision::IsInfinite( u );
-  bool zero    = ( u == 0. );
-  if ( force || infinit || zero || toCheckPosOnShape( shapeID ))
+  bool infinit;
+  if (( infinit = Precision::IsInfinite( u )) ||
+      ( force ) ||
+      ( u == 0. ) ||
+      ( toCheckPosOnShape( shapeID )))
   {
     TopLoc_Location loc; double f,l;
     Handle(Geom_Curve) curve = BRep_Tool::Curve( E,loc,f,l );
@@ -1037,15 +1119,22 @@ bool SMESH_MesherHelper::CheckNodeU(const TopoDS_Edge&   E,
 //=======================================================================
 //function : GetMediumPos
 //purpose  : Return index and type of the shape  (EDGE or FACE only) to
-//          set a medium node on
+//           set a medium node on
 //param    : useCurSubShape - if true, returns the shape set via SetSubShape()
 //           if any
+//param    : expectedSupport - shape type corresponding to element being created,
+//                             e.g TopAbs_EDGE if SMDSAbs_Edge is created
+//                             basing on \a n1 and \a n2
+// Calling GetMediumPos() with useCurSubShape=true is OK only for the
+// case where the lower dim mesh is already constructed and converted to quadratic,
+// else, nodes on EDGEs are assigned to FACE, for example.
 //=======================================================================
 
 std::pair<int, TopAbs_ShapeEnum>
 SMESH_MesherHelper::GetMediumPos(const SMDS_MeshNode* n1,
                                  const SMDS_MeshNode* n2,
-                                 const bool           useCurSubShape)
+                                 const bool           useCurSubShape,
+                                 TopAbs_ShapeEnum     expectedSupport)
 {
   if ( useCurSubShape && !myShape.IsNull() )
     return std::make_pair( myShapeID, myShape.ShapeType() );
@@ -1064,17 +1153,19 @@ SMESH_MesherHelper::GetMediumPos(const SMDS_MeshNode* n1,
     shapeID = n2->getshapeId();
     shape = GetSubShapeByNode( n1, GetMeshDS() );
   }
-  else
+  else // 2 different shapes
   {
     const SMDS_TypeOfPosition Pos1 = n1->GetPosition()->GetTypeOfPosition();
     const SMDS_TypeOfPosition Pos2 = n2->GetPosition()->GetTypeOfPosition();
 
     if ( Pos1 == SMDS_TOP_3DSPACE || Pos2 == SMDS_TOP_3DSPACE )
     {
+      // in SOLID
     }
     else if ( Pos1 == SMDS_TOP_FACE || Pos2 == SMDS_TOP_FACE )
     {
-      if ( Pos1 != SMDS_TOP_FACE || Pos2 != SMDS_TOP_FACE )
+      // in FACE or SOLID
+      if ( Pos1 != SMDS_TOP_FACE || Pos2 != SMDS_TOP_FACE ) // not 2 FACEs
       {
         if ( Pos1 != SMDS_TOP_FACE ) std::swap( n1,n2 );
         TopoDS_Shape F = GetSubShapeByNode( n1, GetMeshDS() );
@@ -1099,7 +1190,7 @@ SMESH_MesherHelper::GetMediumPos(const SMDS_MeshNode* n1,
       shape = GetCommonAncestor( V1, V2, *myMesh, TopAbs_EDGE );
       if ( shape.IsNull() ) shape = GetCommonAncestor( V1, V2, *myMesh, TopAbs_FACE );
     }
-    else // VERTEX and EDGE
+    else // on VERTEX and EDGE
     {
       if ( Pos1 != SMDS_TOP_VERTEX ) std::swap( n1,n2 );
       TopoDS_Shape V = GetSubShapeByNode( n1, GetMeshDS() );
@@ -1115,7 +1206,41 @@ SMESH_MesherHelper::GetMediumPos(const SMDS_MeshNode* n1,
   {
     if ( shapeID < 1 )
       shapeID = GetMeshDS()->ShapeToIndex( shape );
-    shapeType = shape.ShapeType();
+    shapeType = shape.ShapeType(); // EDGE or FACE
+
+    if ( expectedSupport < shapeType &&
+         expectedSupport != TopAbs_SHAPE &&
+         !myShape.IsNull() &&
+         myShape.ShapeType() == expectedSupport )
+    {
+      // e.g. a side of triangle connects nodes on the same EDGE but does not
+      // lie on this EDGE (an arc with a coarse mesh)
+      // =>  shapeType == TopAbs_EDGE, expectedSupport == TopAbs_FACE;
+      // hope that myShape is a right shape, return it if the found shape
+      // has converted elements of corresponding dim (segments in our example)
+      int nbConvertedElems = 0;
+      SMDSAbs_ElementType type = ( shapeType == TopAbs_FACE ? SMDSAbs_Face : SMDSAbs_Edge );
+      for ( int iN = 0; iN < 2; ++iN )
+      {
+        const SMDS_MeshNode* n = iN ? n2 : n1;
+        SMDS_ElemIteratorPtr it = n->GetInverseElementIterator( type );
+        while ( it->more() )
+        {
+          const SMDS_MeshElement* elem = it->next();
+          if ( elem->getshapeId() == shapeID &&
+               elem->IsQuadratic() )
+          {
+            ++nbConvertedElems;
+            break;
+          }
+        }
+      }
+      if ( nbConvertedElems == 2 )
+      {
+        shapeType = myShape.ShapeType();
+        shapeID   = myShapeID;
+      }
+    }
   }
   return make_pair( shapeID, shapeType );
 }
@@ -1186,11 +1311,11 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetCentralNode(const SMDS_MeshNode* n1,
       }
       else
       {
-        PShapeIteratorPtr it = GetAncestors(shape, *GetMesh(), TopAbs_FACE );
+        PShapeIteratorPtr it = GetAncestors( shape, *GetMesh(), TopAbs_FACE );
         while ( const TopoDS_Shape* face = it->next() )
         {
           faceID = meshDS->ShapeToIndex( *face );
-          itMapWithIdFace = faceId2nbNodes.insert( std::make_pair( faceID, 0 ) ).first;
+          itMapWithIdFace = faceId2nbNodes.insert( std::make_pair( faceID, 0 )).first;
           itMapWithIdFace->second++;
         }
       }
@@ -1199,14 +1324,24 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetCentralNode(const SMDS_MeshNode* n1,
   if ( solidID < 1 && !faceId2nbNodes.empty() ) // SOLID not found
   {
     // find ID of the FACE the four corner nodes belong to
-    itMapWithIdFace = faceId2nbNodes.begin();
-    for ( ; itMapWithIdFace != faceId2nbNodes.end(); ++itMapWithIdFace)
+    itMapWithIdFace = faceId2nbNodes.find( myShapeID ); // IPAL52698
+    if ( itMapWithIdFace != faceId2nbNodes.end() &&
+         itMapWithIdFace->second == 4 )
+    {
+      shapeType = TopAbs_FACE;
+      faceID = myShapeID;
+    }
+    else
     {
-      if ( itMapWithIdFace->second == 4 ) 
+      itMapWithIdFace = faceId2nbNodes.begin();
+      for ( ; itMapWithIdFace != faceId2nbNodes.end(); ++itMapWithIdFace)
       {
-        shapeType = TopAbs_FACE;
-        faceID = (*itMapWithIdFace).first;
-        break;
+        if ( itMapWithIdFace->second == 4 )
+        {
+          shapeType = TopAbs_FACE;
+          faceID = (*itMapWithIdFace).first;
+          break;
+        }
       }
     }
   }
@@ -1224,14 +1359,34 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetCentralNode(const SMDS_MeshNode* n1,
   bool toCheck = true;
   if ( !F.IsNull() && !force3d )
   {
-    uvAvg = calcTFI (0.5, 0.5,
-                     GetNodeUV(F,n1,n3,&toCheck), GetNodeUV(F,n2,n4,&toCheck),
-                     GetNodeUV(F,n3,n1,&toCheck), GetNodeUV(F,n4,n2,&toCheck), 
-                     GetNodeUV(F,n12,n3), GetNodeUV(F,n23,n4),
-                     GetNodeUV(F,n34,n2), GetNodeUV(F,n41,n2));
-    TopLoc_Location loc;
-    Handle( Geom_Surface ) S = BRep_Tool::Surface( F, loc );
-    P = S->Value( uvAvg.X(), uvAvg.Y() ).Transformed( loc );
+    Handle(ShapeAnalysis_Surface) surface = GetSurface( F );
+    if ( HasDegeneratedEdges() || surface->HasSingularities( 1e-7 ))
+    {
+      gp_Pnt center = calcTFI (0.5, 0.5, // IPAL0052863
+                               SMESH_TNodeXYZ(n1),  SMESH_TNodeXYZ(n2),
+                               SMESH_TNodeXYZ(n3),  SMESH_TNodeXYZ(n4),
+                               SMESH_TNodeXYZ(n12), SMESH_TNodeXYZ(n23),
+                               SMESH_TNodeXYZ(n34), SMESH_TNodeXYZ(n41));
+      gp_Pnt2d uv12 = GetNodeUV( F, n12, n3, &toCheck );
+      uvAvg = surface->NextValueOfUV( uv12, center, BRep_Tool::Tolerance( F )).XY();
+    }
+    else
+    {
+      gp_XY uv[8] = {
+        GetNodeUV( F,n1,  n3, &toCheck ),
+        GetNodeUV( F,n2,  n4, &toCheck ),
+        GetNodeUV( F,n3,  n1, &toCheck ),
+        GetNodeUV( F,n4,  n2, &toCheck ),
+        GetNodeUV( F,n12, n3 ),
+        GetNodeUV( F,n23, n4 ),
+        GetNodeUV( F,n34, n2 ),
+        GetNodeUV( F,n41, n2 )
+      };
+      AdjustByPeriod( F, uv, 8 ); // put uv[] within a period (IPAL52698)
+
+      uvAvg = calcTFI (0.5, 0.5, uv[0],uv[1],uv[2],uv[3], uv[4],uv[5],uv[6],uv[7] );
+    }
+    P = surface->Value( uvAvg );
     centralNode = meshDS->AddNode( P.X(), P.Y(), P.Z() );
     // if ( mySetElemOnShape ) node is not elem!
     meshDS->SetNodeOnFace( centralNode, faceID, uvAvg.X(), uvAvg.Y() );
@@ -1240,7 +1395,7 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetCentralNode(const SMDS_MeshNode* n1,
   {
     P = calcTFI (0.5, 0.5,
                  SMESH_TNodeXYZ(n1),  SMESH_TNodeXYZ(n2),
-                 SMESH_TNodeXYZ(n3),  SMESH_TNodeXYZ(n4), 
+                 SMESH_TNodeXYZ(n3),  SMESH_TNodeXYZ(n4),
                  SMESH_TNodeXYZ(n12), SMESH_TNodeXYZ(n23),
                  SMESH_TNodeXYZ(n34), SMESH_TNodeXYZ(n41));
     centralNode = meshDS->AddNode( P.X(), P.Y(), P.Z() );
@@ -1344,35 +1499,49 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetCentralNode(const SMDS_MeshNode* n1,
   if ( solidID < 1 && !faceId2nbNodes.empty() ) // SOLID not found
   {
     // find ID of the FACE the four corner nodes belong to
-    itMapWithIdFace = faceId2nbNodes.begin();
-    for ( ; itMapWithIdFace != faceId2nbNodes.end(); ++itMapWithIdFace)
+    itMapWithIdFace = faceId2nbNodes.find( myShapeID ); // IPAL52698
+    if ( itMapWithIdFace != faceId2nbNodes.end() &&
+         itMapWithIdFace->second == 4 )
+    {
+      shapeType = TopAbs_FACE;
+      faceID = myShapeID;
+    }
+    else
     {
-      if ( itMapWithIdFace->second == 3 ) 
+      itMapWithIdFace = faceId2nbNodes.begin();
+      for ( ; itMapWithIdFace != faceId2nbNodes.end(); ++itMapWithIdFace)
       {
-        shapeType = TopAbs_FACE;
-        faceID = (*itMapWithIdFace).first;
-        break;
+        if ( itMapWithIdFace->second == 3 )
+        {
+          shapeType = TopAbs_FACE;
+          faceID = (*itMapWithIdFace).first;
+          break;
+        }
       }
     }
   }
 
   TopoDS_Face F;
   gp_XY       uvAvg;
-  bool        badTria=false;
 
   if ( shapeType == TopAbs_FACE )
   {
     F = TopoDS::Face( meshDS->IndexToShape( faceID ));
-    bool check;
-    gp_XY uv1  = GetNodeUV( F, n1, n23, &check );
-    gp_XY uv2  = GetNodeUV( F, n2, n31, &check );
-    gp_XY uv3  = GetNodeUV( F, n3, n12, &check );
-    gp_XY uv12 = GetNodeUV( F, n12, n3, &check );
-    gp_XY uv23 = GetNodeUV( F, n23, n1, &check );
-    gp_XY uv31 = GetNodeUV( F, n31, n2, &check );
-    uvAvg = GetCenterUV( uv1,uv2,uv3, uv12,uv23,uv31, &badTria );
-    if ( badTria )
-      force3d = false;
+    bool checkOK = true, badTria = false;
+    gp_XY uv[6] = {
+      GetNodeUV( F, n1, n23, &checkOK ),
+      GetNodeUV( F, n2, n31, &checkOK ),
+      GetNodeUV( F, n3, n12, &checkOK ),
+      GetNodeUV( F, n12, n3, &checkOK ),
+      GetNodeUV( F, n23, n1, &checkOK ),
+      GetNodeUV( F, n31, n2, &checkOK )
+    };
+    AdjustByPeriod( F, uv, 6 ); // put uv[] within a period (IPAL52698)
+
+    uvAvg = GetCenterUV( uv[0],uv[1],uv[2], uv[3],uv[4],uv[5], &badTria );
+
+    if ( badTria || !checkOK )
+      force3d = true;
   }
 
   // Create a central node
@@ -1418,7 +1587,8 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetCentralNode(const SMDS_MeshNode* n1,
 
 const SMDS_MeshNode* SMESH_MesherHelper::GetMediumNode(const SMDS_MeshNode* n1,
                                                        const SMDS_MeshNode* n2,
-                                                       bool                 force3d)
+                                                       bool                 force3d,
+                                                       TopAbs_ShapeEnum     expectedSupport)
 {
   // Find existing node
 
@@ -1441,18 +1611,38 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetMediumNode(const SMDS_MeshNode* n1,
   int faceID = -1, edgeID = -1;
   TopoDS_Edge E; double u [2];
   TopoDS_Face F; gp_XY  uv[2];
-  bool uvOK[2] = { false, false };
+  bool uvOK[2] = { true, true };
+  const bool useCurSubShape = ( !myShape.IsNull() && myShape.ShapeType() == TopAbs_EDGE );
 
-  pair<int, TopAbs_ShapeEnum> pos = GetMediumPos( n1, n2, mySetElemOnShape );
-  // calling GetMediumPos() with useCurSubShape=mySetElemOnShape is OK only for the
-  // case where the lower dim mesh is already constructed, else, nodes on EDGEs are
-  // assigned to FACE, for example.
+  pair<int, TopAbs_ShapeEnum> pos = GetMediumPos( n1, n2, useCurSubShape, expectedSupport );
 
   // 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]);
+    if (( !force3d ) &&
+        ( HasDegeneratedEdges() || GetSurface( F )->HasSingularities( 1e-7 )))
+    {
+      // IPAL52850 (degen VERTEX not at singularity)
+      // project middle point to a surface
+      SMESH_TNodeXYZ p1( n1 ), p2( n2 );
+      gp_Pnt pMid = 0.5 * ( p1 + p2 );
+      Handle(ShapeAnalysis_Surface) projector = GetSurface( F );
+      gp_Pnt2d uvMid;
+      if ( uvOK[0] )
+        uvMid = projector->NextValueOfUV( uv[0], pMid, BRep_Tool::Tolerance( F ));
+      else
+        uvMid = projector->ValueOfUV( pMid, getFaceMaxTol( F ));
+      if ( projector->Gap() * projector->Gap() < ( p1 - p2 ).SquareModulus() / 4 )
+      {
+        gp_Pnt pProj = projector->Value( uvMid );
+        n12  = meshDS->AddNode( pProj.X(), pProj.Y(), pProj.Z() );
+        meshDS->SetNodeOnFace( n12, faceID, uvMid.X(), uvMid.Y() );
+        myTLinkNodeMap.insert( make_pair ( link, n12 ));
+        return n12;
+      }
+    }
     uv[1] = GetNodeUV(F,n2,n1, force3d ? 0 : &uvOK[1]);
   }
   else if ( pos.second == TopAbs_EDGE )
@@ -1765,9 +1955,9 @@ SMDS_MeshFace* SMESH_MesherHelper::AddFace(const SMDS_MeshNode* n1,
       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);
+    const SMDS_MeshNode* n12 = GetMediumNode( n1, n2, force3d, TopAbs_FACE );
+    const SMDS_MeshNode* n23 = GetMediumNode( n2, n3, force3d, TopAbs_FACE );
+    const SMDS_MeshNode* n31 = GetMediumNode( n3, n1, force3d, TopAbs_FACE );
     if(myCreateBiQuadratic)
     {
      const SMDS_MeshNode* nCenter = GetCentralNode(n1, n2, n3, n12, n23, n31, force3d);
@@ -1831,10 +2021,10 @@ SMDS_MeshFace* SMESH_MesherHelper::AddFace(const SMDS_MeshNode* n1,
       elem = meshDS->AddFace(n1, n2, n3, n4);
   }
   else {
-    const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
-    const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,force3d);
-    const SMDS_MeshNode* n34 = GetMediumNode(n3,n4,force3d);
-    const SMDS_MeshNode* n41 = GetMediumNode(n4,n1,force3d);
+    const SMDS_MeshNode* n12 = GetMediumNode( n1, n2, force3d, TopAbs_FACE );
+    const SMDS_MeshNode* n23 = GetMediumNode( n2, n3, force3d, TopAbs_FACE );
+    const SMDS_MeshNode* n34 = GetMediumNode( n3, n4, force3d, TopAbs_FACE );
+    const SMDS_MeshNode* n41 = GetMediumNode( n4, n1, force3d, TopAbs_FACE );
     if(myCreateBiQuadratic)
     {
      const SMDS_MeshNode* nCenter = GetCentralNode(n1, n2, n3, n4, n12, n23, n34, n41, force3d);
@@ -1869,26 +2059,28 @@ SMDS_MeshFace* SMESH_MesherHelper::AddPolygonalFace (const vector<const SMDS_Mes
   SMESHDS_Mesh * meshDS = GetMeshDS();
   SMDS_MeshFace* elem = 0;
 
-  if(!myCreateQuadratic) {
+  if(!myCreateQuadratic)
+  {
     if(id)
       elem = meshDS->AddPolygonalFaceWithID(nodes, id);
     else
       elem = meshDS->AddPolygonalFace(nodes);
   }
-  else {
-    vector<const SMDS_MeshNode*> newNodes;
-    for ( int i = 0; i < nodes.size(); ++i )
+  else
+  {
+    vector<const SMDS_MeshNode*> newNodes( nodes.size() * 2 );
+    newNodes = nodes;
+    for ( size_t 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 );
+      const SMDS_MeshNode* n12 = GetMediumNode( n1, n2, force3d, TopAbs_FACE );
       newNodes.push_back( n12 );
     }
     if(id)
-      elem = meshDS->AddPolygonalFaceWithID(newNodes, id);
+      elem = meshDS->AddQuadPolygonalFaceWithID(newNodes, id);
     else
-      elem = meshDS->AddPolygonalFace(newNodes);
+      elem = meshDS->AddQuadPolygonalFace(newNodes);
   }
   if ( mySetElemOnShape && myShapeID > 0 )
     meshDS->SetMeshElementOnShape( elem, myShapeID );
@@ -1919,20 +2111,20 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1,
       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* n12 = GetMediumNode( n1, n2, force3d, TopAbs_SOLID );
+    const SMDS_MeshNode* n23 = GetMediumNode( n2, n3, force3d, TopAbs_SOLID );
+    const SMDS_MeshNode* n31 = GetMediumNode( n3, n1, force3d, TopAbs_SOLID );
 
-    const SMDS_MeshNode* n45 = GetMediumNode(n4,n5,force3d);
-    const SMDS_MeshNode* n56 = GetMediumNode(n5,n6,force3d);
-    const SMDS_MeshNode* n64 = GetMediumNode(n6,n4,force3d);
+    const SMDS_MeshNode* n45 = GetMediumNode( n4, n5, force3d, TopAbs_SOLID );
+    const SMDS_MeshNode* n56 = GetMediumNode( n5, n6, force3d, TopAbs_SOLID );
+    const SMDS_MeshNode* n64 = GetMediumNode( n6, n4, force3d, TopAbs_SOLID );
 
-    const SMDS_MeshNode* n14 = GetMediumNode(n1,n4,force3d);
-    const SMDS_MeshNode* n25 = GetMediumNode(n2,n5,force3d);
-    const SMDS_MeshNode* n36 = GetMediumNode(n3,n6,force3d);
+    const SMDS_MeshNode* n14 = GetMediumNode( n1, n4, force3d, TopAbs_SOLID );
+    const SMDS_MeshNode* n25 = GetMediumNode( n2, n5, force3d, TopAbs_SOLID );
+    const SMDS_MeshNode* n36 = GetMediumNode( n3, n6, force3d, TopAbs_SOLID );
 
     if(id)
-      elem = meshDS->AddVolumeWithID(n1, n2, n3, n4, n5, n6, 
+      elem = meshDS->AddVolumeWithID(n1, n2, n3, n4, n5, n6,
                                      n12, n23, n31, n45, n56, n64, n14, n25, n36, id);
     else
       elem = meshDS->AddVolume(n1, n2, n3, n4, n5, n6,
@@ -1953,7 +2145,7 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1,
                                                const SMDS_MeshNode* n2,
                                                const SMDS_MeshNode* n3,
                                                const SMDS_MeshNode* n4,
-                                               const int id, 
+                                               const int id,
                                                const bool force3d)
 {
   SMESHDS_Mesh * meshDS = GetMeshDS();
@@ -1965,13 +2157,13 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1,
       elem = meshDS->AddVolume(n1, n2, n3, n4);
   }
   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* n12 = GetMediumNode( n1, n2, force3d, TopAbs_SOLID );
+    const SMDS_MeshNode* n23 = GetMediumNode( n2, n3, force3d, TopAbs_SOLID );
+    const SMDS_MeshNode* n31 = GetMediumNode( n3, n1, force3d, TopAbs_SOLID );
 
-    const SMDS_MeshNode* n14 = GetMediumNode(n1,n4,force3d);
-    const SMDS_MeshNode* n24 = GetMediumNode(n2,n4,force3d);
-    const SMDS_MeshNode* n34 = GetMediumNode(n3,n4,force3d);
+    const SMDS_MeshNode* n14 = GetMediumNode( n1, n4, force3d, TopAbs_SOLID );
+    const SMDS_MeshNode* n24 = GetMediumNode( n2, n4, force3d, TopAbs_SOLID );
+    const SMDS_MeshNode* n34 = GetMediumNode( n3, n4, force3d, TopAbs_SOLID );
 
     if(id)
       elem = meshDS->AddVolumeWithID(n1, n2, n3, n4, n12, n23, n31, n14, n24, n34, id);
@@ -1994,7 +2186,7 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1,
                                                const SMDS_MeshNode* n3,
                                                const SMDS_MeshNode* n4,
                                                const SMDS_MeshNode* n5,
-                                               const int id, 
+                                               const int id,
                                                const bool force3d)
 {
   SMDS_MeshVolume* elem = 0;
@@ -2005,15 +2197,15 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1,
       elem = GetMeshDS()->AddVolume(n1, n2, n3, n4, n5);
   }
   else {
-    const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
-    const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,force3d);
-    const SMDS_MeshNode* n34 = GetMediumNode(n3,n4,force3d);
-    const SMDS_MeshNode* n41 = GetMediumNode(n4,n1,force3d);
+    const SMDS_MeshNode* n12 = GetMediumNode( n1, n2, force3d, TopAbs_SOLID );
+    const SMDS_MeshNode* n23 = GetMediumNode( n2, n3, force3d, TopAbs_SOLID );
+    const SMDS_MeshNode* n34 = GetMediumNode( n3, n4, force3d, TopAbs_SOLID );
+    const SMDS_MeshNode* n41 = GetMediumNode( n4, n1, force3d, TopAbs_SOLID );
 
-    const SMDS_MeshNode* n15 = GetMediumNode(n1,n5,force3d);
-    const SMDS_MeshNode* n25 = GetMediumNode(n2,n5,force3d);
-    const SMDS_MeshNode* n35 = GetMediumNode(n3,n5,force3d);
-    const SMDS_MeshNode* n45 = GetMediumNode(n4,n5,force3d);
+    const SMDS_MeshNode* n15 = GetMediumNode( n1, n5, force3d, TopAbs_SOLID );
+    const SMDS_MeshNode* n25 = GetMediumNode( n2, n5, force3d, TopAbs_SOLID );
+    const SMDS_MeshNode* n35 = GetMediumNode( n3, n5, force3d, TopAbs_SOLID );
+    const SMDS_MeshNode* n45 = GetMediumNode( n4, n5, force3d, TopAbs_SOLID );
 
     if(id)
       elem = GetMeshDS()->AddVolumeWithID ( n1,  n2,  n3,  n4,  n5,
@@ -2033,7 +2225,7 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1,
 
 //=======================================================================
 //function : AddVolume
-//purpose  : Creates bi-quadratic, quadratic or linear hexahedron
+//purpose  : Creates tri-quadratic, quadratic or linear hexahedron
 //=======================================================================
 
 SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1,
@@ -2056,28 +2248,28 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1,
       elem = meshDS->AddVolume(n1, n2, n3, n4, n5, n6, n7, n8);
   }
   else {
-    const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
-    const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,force3d);
-    const SMDS_MeshNode* n34 = GetMediumNode(n3,n4,force3d);
-    const SMDS_MeshNode* n41 = GetMediumNode(n4,n1,force3d);
-
-    const SMDS_MeshNode* n56 = GetMediumNode(n5,n6,force3d);
-    const SMDS_MeshNode* n67 = GetMediumNode(n6,n7,force3d);
-    const SMDS_MeshNode* n78 = GetMediumNode(n7,n8,force3d);
-    const SMDS_MeshNode* n85 = GetMediumNode(n8,n5,force3d);
-
-    const SMDS_MeshNode* n15 = GetMediumNode(n1,n5,force3d);
-    const SMDS_MeshNode* n26 = GetMediumNode(n2,n6,force3d);
-    const SMDS_MeshNode* n37 = GetMediumNode(n3,n7,force3d);
-    const SMDS_MeshNode* n48 = GetMediumNode(n4,n8,force3d);
-    if(myCreateBiQuadratic)
+    const SMDS_MeshNode* n12 = GetMediumNode( n1, n2, force3d, TopAbs_SOLID );
+    const SMDS_MeshNode* n23 = GetMediumNode( n2, n3, force3d, TopAbs_SOLID );
+    const SMDS_MeshNode* n34 = GetMediumNode( n3, n4, force3d, TopAbs_SOLID );
+    const SMDS_MeshNode* n41 = GetMediumNode( n4, n1, force3d, TopAbs_SOLID );
+
+    const SMDS_MeshNode* n56 = GetMediumNode( n5, n6, force3d, TopAbs_SOLID );
+    const SMDS_MeshNode* n67 = GetMediumNode( n6, n7, force3d, TopAbs_SOLID );
+    const SMDS_MeshNode* n78 = GetMediumNode( n7, n8, force3d, TopAbs_SOLID );
+    const SMDS_MeshNode* n85 = GetMediumNode( n8, n5, force3d, TopAbs_SOLID );
+
+    const SMDS_MeshNode* n15 = GetMediumNode( n1, n5, force3d, TopAbs_SOLID );
+    const SMDS_MeshNode* n26 = GetMediumNode( n2, n6, force3d, TopAbs_SOLID );
+    const SMDS_MeshNode* n37 = GetMediumNode( n3, n7, force3d, TopAbs_SOLID );
+    const SMDS_MeshNode* n48 = GetMediumNode( n4, n8, force3d, TopAbs_SOLID );
+    if ( myCreateBiQuadratic )
     {
-      const SMDS_MeshNode* n1234 = GetCentralNode(n1,n2,n3,n4,n12,n23,n34,n41,force3d);
-      const SMDS_MeshNode* n1256 = GetCentralNode(n1,n2,n5,n6,n12,n26,n56,n15,force3d);
-      const SMDS_MeshNode* n2367 = GetCentralNode(n2,n3,n6,n7,n23,n37,n67,n26,force3d);
-      const SMDS_MeshNode* n3478 = GetCentralNode(n3,n4,n7,n8,n34,n48,n78,n37,force3d);
-      const SMDS_MeshNode* n1458 = GetCentralNode(n1,n4,n5,n8,n41,n48,n15,n85,force3d);
-      const SMDS_MeshNode* n5678 = GetCentralNode(n5,n6,n7,n8,n56,n67,n78,n85,force3d);
+      const SMDS_MeshNode* n1234 = GetCentralNode( n1,n2,n3,n4,n12,n23,n34,n41,force3d );
+      const SMDS_MeshNode* n1256 = GetCentralNode( n1,n2,n5,n6,n12,n26,n56,n15,force3d );
+      const SMDS_MeshNode* n2367 = GetCentralNode( n2,n3,n6,n7,n23,n37,n67,n26,force3d );
+      const SMDS_MeshNode* n3478 = GetCentralNode( n3,n4,n7,n8,n34,n48,n78,n37,force3d );
+      const SMDS_MeshNode* n1458 = GetCentralNode( n1,n4,n5,n8,n41,n48,n15,n85,force3d );
+      const SMDS_MeshNode* n5678 = GetCentralNode( n5,n6,n7,n8,n56,n67,n78,n85,force3d );
 
       vector<gp_XYZ> pointsOnShapes( SMESH_Block::ID_Shell );
 
@@ -2098,16 +2290,16 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1,
       pointsOnShapes[ SMESH_Block::ID_Ex11 ] = SMESH_TNodeXYZ( n78 );
       pointsOnShapes[ SMESH_Block::ID_E0y1 ] = SMESH_TNodeXYZ( n12 );
       pointsOnShapes[ SMESH_Block::ID_E1y1 ] = SMESH_TNodeXYZ( n56 );
-      pointsOnShapes[ SMESH_Block::ID_E00z ] = SMESH_TNodeXYZ( n41 );    
-      pointsOnShapes[ SMESH_Block::ID_E10z ] = SMESH_TNodeXYZ( n85 );    
-      pointsOnShapes[ SMESH_Block::ID_E01z ] = SMESH_TNodeXYZ( n23 );    
+      pointsOnShapes[ SMESH_Block::ID_E00z ] = SMESH_TNodeXYZ( n41 );
+      pointsOnShapes[ SMESH_Block::ID_E10z ] = SMESH_TNodeXYZ( n85 );
+      pointsOnShapes[ SMESH_Block::ID_E01z ] = SMESH_TNodeXYZ( n23 );
       pointsOnShapes[ SMESH_Block::ID_E11z ] = SMESH_TNodeXYZ( n67 );
 
       pointsOnShapes[ SMESH_Block::ID_Fxy0 ] = SMESH_TNodeXYZ( n3478 );
       pointsOnShapes[ SMESH_Block::ID_Fxy1 ] = SMESH_TNodeXYZ( n1256 );
-      pointsOnShapes[ SMESH_Block::ID_Fx0z ] = SMESH_TNodeXYZ( n1458 );   
-      pointsOnShapes[ SMESH_Block::ID_Fx1z ] = SMESH_TNodeXYZ( n2367 );   
-      pointsOnShapes[ SMESH_Block::ID_F0yz ] = SMESH_TNodeXYZ( n1234 );    
+      pointsOnShapes[ SMESH_Block::ID_Fx0z ] = SMESH_TNodeXYZ( n1458 );
+      pointsOnShapes[ SMESH_Block::ID_Fx1z ] = SMESH_TNodeXYZ( n2367 );
+      pointsOnShapes[ SMESH_Block::ID_F0yz ] = SMESH_TNodeXYZ( n1234 );
       pointsOnShapes[ SMESH_Block::ID_F1yz ] = SMESH_TNodeXYZ( n5678 );
 
       gp_XYZ centerCube(0.5, 0.5, 0.5);
@@ -2117,27 +2309,27 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1,
         meshDS->AddNode( nCenterElem.X(), nCenterElem.Y(), nCenterElem.Z() );
       meshDS->SetNodeInVolume( nCenter, myShapeID );
 
-     if(id)
+      if(id)
         elem = meshDS->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);
+                                       n12, n23, n34, n41, n56, n67,
+                                       n78, n85, n15, n26, n37, n48,
+                                       n1234, n1256, n2367, n3478, n1458, n5678, nCenter, id);
       else
         elem = meshDS->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);
+                                 n12, n23, n34, n41, n56, n67,
+                                 n78, n85, n15, n26, n37, n48,
+                                 n1234, n1256, n2367, n3478, n1458, n5678, nCenter);
     }
     else
     {
       if(id)
         elem = meshDS->AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8,
-                                      n12, n23, n34, n41, n56, n67,
-                                      n78, n85, n15, n26, n37, n48, id);
+                                       n12, n23, n34, n41, n56, n67,
+                                       n78, n85, n15, n26, n37, n48, id);
       else
         elem = meshDS->AddVolume(n1, n2, n3, n4, n5, n6, n7, n8,
-                                n12, n23, n34, n41, n56, n67,
-                                n78, n85, n15, n26, n37, n48);
+                                 n12, n23, n34, n41, n56, n67,
+                                 n78, n85, n15, n26, n37, n48);
     }
   }
   if ( mySetElemOnShape && myShapeID > 0 )
@@ -2201,7 +2393,7 @@ SMESH_MesherHelper::AddPolyhedralVolume (const std::vector<const SMDS_MeshNode*>
   {
     vector<const SMDS_MeshNode*> newNodes;
     vector<int> newQuantities;
-    for ( int iFace=0, iN=0; iFace < quantities.size(); ++iFace)
+    for ( size_t iFace = 0, iN = 0; iFace < quantities.size(); ++iFace )
     {
       int nbNodesInFace = quantities[iFace];
       newQuantities.push_back(0);
@@ -2210,12 +2402,12 @@ SMESH_MesherHelper::AddPolyhedralVolume (const std::vector<const SMDS_MeshNode*>
         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 )
+        // if ( n1->GetPosition()->GetTypeOfPosition() != SMDS_TOP_3DSPACE &&
+        //      n2->GetPosition()->GetTypeOfPosition() != SMDS_TOP_3DSPACE )
         {
-          const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
+          const SMDS_MeshNode* n12 = GetMediumNode( n1, n2, force3d, TopAbs_SOLID );
           newNodes.push_back( n12 );
           newQuantities.back()++;
         }
@@ -2340,10 +2532,38 @@ bool SMESH_MesherHelper::LoadNodeColumns(TParam2ColumnMap &            theParam2
     for ( int iE = 0; edge != theBaseSide.end(); ++edge, ++iE )
     {
       map< double, const SMDS_MeshNode*> sortedBaseNN;
-      SMESH_Algo::GetSortedNodesOnEdge( theMesh, *edge,/*noMedium=*/true, sortedBaseNN);
+      SMESH_Algo::GetSortedNodesOnEdge( theMesh, *edge,/*noMedium=*/true, sortedBaseNN );
+
+      map< double, const SMDS_MeshNode*>::iterator u_n;
+      // pb with mesh_Projection_2D_00/A1 fixed by adding expectedSupport arg to GetMediumPos()
+      // so the following solution is commented (hope forever :)
+      //
+      // SMESH_Algo::GetSortedNodesOnEdge( theMesh, *edge,/*noMedium=*/true, sortedBaseNN,
+      // // SMDSAbs_Edge here is needed to be coherent with
+      // // StdMeshers_FaceSide used by Quadrangle to get nodes
+      // // on EDGE; else pb in mesh_Projection_2D_00/A1 where a
+      // // medium node on EDGE is medium in a triangle but not
+      // // in a segment
+      // SMDSAbs_Edge );
+      // if ( faceSubMesh->GetElements()->next()->IsQuadratic() )
+      //   // filter off nodes medium in faces on theFace (same pb with mesh_Projection_2D_00/A1)
+      //   for ( u_n = sortedBaseNN.begin(); u_n != sortedBaseNN.end() ;     )
+      //   {
+      //     const SMDS_MeshNode* node = u_n->second;
+      //     SMDS_ElemIteratorPtr faceIt = node->GetInverseElementIterator( SMDSAbs_Face );
+      //     if ( faceIt->more() && node ) {
+      //       const SMDS_MeshElement* face = faceIt->next();
+      //       if ( faceSubMesh->Contains( face ) && face->IsMediumNode( node ))
+      //         node = 0;
+      //     }
+      //     if ( !node )
+      //       sortedBaseNN.erase( u_n++ );
+      //     else
+      //       ++u_n;
+      //   }
       if ( sortedBaseNN.empty() ) continue;
 
-      map< double, const SMDS_MeshNode*>::iterator u_n = sortedBaseNN.begin();
+      u_n = sortedBaseNN.begin();
       if ( theProxyMesh ) // from sortedBaseNN remove nodes not shared by faces of faceSubMesh
       {
         const SMDS_MeshNode* n1 = (++sortedBaseNN.begin())->second;
@@ -2386,8 +2606,8 @@ bool SMESH_MesherHelper::LoadNodeColumns(TParam2ColumnMap &            theParam2
   }
 
   // nb rows of nodes
-  int prevNbRows     = theParam2ColumnMap.begin()->second.size(); // current, at least 1 here
-  int expectedNbRows = faceSubMesh->NbElements() / ( theParam2ColumnMap.size()-1 ); // to be added
+  size_t prevNbRows     = theParam2ColumnMap.begin()->second.size(); // current, at least 1 here
+  size_t expectNbRows = faceSubMesh->NbElements() / ( theParam2ColumnMap.size()-1 ); // to be added
 
   // fill theParam2ColumnMap column by column by passing from nodes on
   // theBaseEdge up via mesh faces on theFace
@@ -2400,10 +2620,10 @@ bool SMESH_MesherHelper::LoadNodeColumns(TParam2ColumnMap &            theParam2
   {
     vector<const SMDS_MeshNode*>& nCol1 = par_nVec_1->second;
     vector<const SMDS_MeshNode*>& nCol2 = par_nVec_2->second;
-    nCol1.resize( prevNbRows + expectedNbRows );
-    nCol2.resize( prevNbRows + expectedNbRows );
+    nCol1.resize( prevNbRows + expectNbRows );
+    nCol2.resize( prevNbRows + expectNbRows );
 
-    int i1, i2, foundNbRows = 0;
+    int i1, i2; size_t foundNbRows = 0;
     const SMDS_MeshNode *n1 = nCol1[ prevNbRows-1 ];
     const SMDS_MeshNode *n2 = nCol2[ prevNbRows-1 ];
     // find face sharing node n1 and n2 and belonging to faceSubMesh
@@ -2415,7 +2635,7 @@ bool SMESH_MesherHelper::LoadNodeColumns(TParam2ColumnMap &            theParam2
         int nbNodes = face->NbCornerNodes();
         if ( nbNodes != 4 )
           return false;
-        if ( foundNbRows + 1 > expectedNbRows )
+        if ( foundNbRows + 1 > expectNbRows )
           return false;
         n1 = face->GetNode( (i2+2) % 4 ); // opposite corner of quadrangle face
         n2 = face->GetNode( (i1+2) % 4 );
@@ -2425,12 +2645,12 @@ bool SMESH_MesherHelper::LoadNodeColumns(TParam2ColumnMap &            theParam2
       }
       avoidSet.insert( face );
     }
-    if ( foundNbRows != expectedNbRows )
+    if ((size_t) foundNbRows != expectNbRows )
       return false;
     avoidSet.clear();
   }
   return ( theParam2ColumnMap.size() > 1 &&
-           theParam2ColumnMap.begin()->second.size() == prevNbRows + expectedNbRows );
+           theParam2ColumnMap.begin()->second.size() == prevNbRows + expectNbRows );
 }
 
 namespace
@@ -2488,7 +2708,7 @@ bool SMESH_MesherHelper::IsStructured( SMESH_subMesh* faceSM )
   faceAnalyser.SetSubShape( faceSM->GetSubShape() );
 
   // rotate edges to get the first node being at corner
-  // (in principle it's not necessary but so far none SALOME algo can make
+  // (in principle it's not necessary because so far none SALOME algo can make
   //  such a structured mesh that all corner nodes are not on VERTEXes)
   bool isCorner     = false;
   int nbRemainEdges = nbEdgesInWires.front();
@@ -2650,38 +2870,80 @@ bool SMESH_MesherHelper::IsReversedSubMesh (const TopoDS_Face& theFace)
   if ( !aSubMeshDSFace )
     return isReversed;
 
-  // find an element with a good normal
-  gp_Vec Ne;
-  bool normalOK = false;
-  gp_XY uv;
+  // find an element on a bounday of theFace
   SMDS_ElemIteratorPtr iteratorElem = aSubMeshDSFace->GetElements();
-  while ( !normalOK && iteratorElem->more() ) // loop on elements on theFace
+  const SMDS_MeshNode* nn[2];
+  while ( iteratorElem->more() ) // loop on elements on theFace
   {
     const SMDS_MeshElement* elem = iteratorElem->next();
-    if ( elem && elem->NbCornerNodes() > 2 )
+    if ( ! elem ) continue;
+
+    // look for 2 nodes on EDGE
+    int nbNodes = elem->NbCornerNodes();
+    nn[0] = elem->GetNode( nbNodes-1 );
+    for ( int iN = 0; iN < nbNodes; ++iN )
     {
-      SMESH_TNodeXYZ nPnt[3];
-      SMDS_ElemIteratorPtr nodesIt = elem->nodesIterator();
-      int iNodeOnFace = 0, iPosDim = SMDS_TOP_VERTEX;
-      for ( int iN = 0; nodesIt->more() && iN < 3; ++iN) // loop on nodes
+      nn[1] = elem->GetNode( iN );
+      if ( nn[0]->GetPosition()->GetDim() < 2 &&
+           nn[1]->GetPosition()->GetDim() < 2 )
       {
-        nPnt[ iN ] = nodesIt->next();
-        if ( nPnt[ iN ]._node->GetPosition()->GetTypeOfPosition() > iPosDim )
+        TopoDS_Shape s0 = GetSubShapeByNode( nn[0], GetMeshDS() );
+        TopoDS_Shape s1 = GetSubShapeByNode( nn[1], GetMeshDS() );
+        TopoDS_Shape  E = GetCommonAncestor( s0, s1, *myMesh, TopAbs_EDGE );
+        if ( !E.IsNull() && !s0.IsSame( s1 ))
         {
-          iNodeOnFace = iN;
-          iPosDim = nPnt[ iN ]._node->GetPosition()->GetTypeOfPosition();
+          // is E seam edge?
+          int nb = 0;
+          for ( TopExp_Explorer exp( theFace, TopAbs_EDGE ); exp.More(); exp.Next() )
+            if ( E.IsSame( exp.Current() )) {
+              ++nb;
+              E = exp.Current(); // to know orientation
+            }
+          if ( nb == 1 )
+          {
+            bool ok = true;
+            double u0 = GetNodeU( TopoDS::Edge( E ), nn[0], nn[1], &ok );
+            double u1 = GetNodeU( TopoDS::Edge( E ), nn[1], nn[0], &ok );
+            if ( ok )
+            {
+              isReversed = ( u0 > u1 );
+              if ( E.Orientation() == TopAbs_REVERSED )
+                isReversed = !isReversed;
+              return isReversed;
+            }
+          }
         }
       }
-      // compute normal
-      gp_Vec v01( nPnt[0], nPnt[1] ), v02( nPnt[0], nPnt[2] );
-      if ( v01.SquareMagnitude() > RealSmall() &&
-           v02.SquareMagnitude() > RealSmall() )
+      nn[0] = nn[1];
+    }
+  }
+
+  // find an element with a good normal
+  gp_Vec Ne;
+  bool normalOK = false;
+  gp_XY uv;
+  iteratorElem = aSubMeshDSFace->GetElements();
+  while ( !normalOK && iteratorElem->more() ) // loop on elements on theFace
+  {
+    const SMDS_MeshElement* elem = iteratorElem->next();
+    if ( ! SMESH_MeshAlgos::FaceNormal( elem, const_cast<gp_XYZ&>( Ne.XYZ() ), /*normalized=*/0 ))
+      continue;
+    normalOK = true;
+
+    // get UV of a node inside theFACE
+    SMDS_ElemIteratorPtr nodesIt = elem->nodesIterator();
+    const SMDS_MeshNode* nInFace = 0;
+    int iPosDim = SMDS_TOP_VERTEX;
+    while ( nodesIt->more() ) // loop on nodes
+    {
+      const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nodesIt->next() );
+      if ( n->GetPosition()->GetTypeOfPosition() >= iPosDim )
       {
-        Ne = v01 ^ v02;
-        if (( normalOK = ( Ne.SquareMagnitude() > RealSmall() )))
-          uv = GetNodeUV( theFace, nPnt[iNodeOnFace]._node, 0, &normalOK );
+        nInFace = n;
+        iPosDim = n->GetPosition()->GetTypeOfPosition();
       }
     }
+    uv = GetNodeUV( theFace, nInFace, 0, &normalOK );
   }
   if ( !normalOK )
     return isReversed;
@@ -2692,11 +2954,8 @@ bool SMESH_MesherHelper::IsReversedSubMesh (const TopoDS_Face& theFace)
   // if ( surf.IsNull() || surf->Continuity() < GeomAbs_C1 )
   // some surfaces not detected as GeomAbs_C1 are nevertheless correct for meshing
   if ( surf.IsNull() || surf->Continuity() < GeomAbs_C0 )
-    {
-      if (!surf.IsNull())
-        MESSAGE("surf->Continuity() < GeomAbs_C1 " << (surf->Continuity() < GeomAbs_C1));
-      return isReversed;
-    }
+    return isReversed;
+
   gp_Vec d1u, d1v; gp_Pnt p;
   surf->D1( uv.X(), uv.Y(), p, d1u, d1v );
   gp_Vec Nf = (d1u ^ d1v).Transformed( loc );
@@ -2848,6 +3107,24 @@ double SMESH_MesherHelper::MaxTolerance( const TopoDS_Shape& shape )
   return tol;
 }
 
+//================================================================================
+/*!
+ * \brief Return MaxTolerance( face ), probably cached
+ */
+//================================================================================
+
+double SMESH_MesherHelper::getFaceMaxTol( const TopoDS_Shape& face ) const
+{
+  int faceID = GetMeshDS()->ShapeToIndex( face );
+
+  SMESH_MesherHelper* me = const_cast< SMESH_MesherHelper* >( this );
+  double & tol = me->myFaceMaxTol.insert( make_pair( faceID, -1. )).first->second;
+  if ( tol < 0 )
+    tol = MaxTolerance( face );
+
+  return tol;
+}
+
 //================================================================================
 /*!
  * \brief Return an angle between two EDGEs sharing a common VERTEX with reference
@@ -2995,6 +3272,28 @@ TopAbs_ShapeEnum SMESH_MesherHelper::GetGroupType(const TopoDS_Shape& group,
   return TopAbs_SHAPE;
 }
 
+//================================================================================
+/*!
+ * \brief Returns a shape, to which a hypothesis used to mesh a given shape is assigned
+ *  \param [in] hyp - the hypothesis
+ *  \param [in] shape - the shape, for meshing which the \a hyp is used
+ *  \param [in] mesh - the mesh
+ *  \return TopoDS_Shape - the shape the \a hyp is assigned to
+ */
+//================================================================================
+
+TopoDS_Shape SMESH_MesherHelper::GetShapeOfHypothesis( const SMESHDS_Hypothesis * hyp,
+                                                       const TopoDS_Shape&        shape,
+                                                       SMESH_Mesh*                mesh)
+{
+  const SMESH_Hypothesis* h = static_cast<const SMESH_Hypothesis*>( hyp );
+  SMESH_HypoFilter hypFilter( SMESH_HypoFilter::Is( h ));
+
+  TopoDS_Shape shapeOfHyp;
+  mesh->GetHypothesis( shape, hypFilter, /*checkAncestors=*/true, &shapeOfHyp );
+  return shapeOfHyp;
+}
+
 //=======================================================================
 //function : IsQuadraticMesh
 //purpose  : Check mesh without geometry for: if all elements on this shape are quadratic,
@@ -3106,6 +3405,11 @@ TopoDS_Shape SMESH_MesherHelper::GetCommonAncestor(const TopoDS_Shape& shape1,
   TopoDS_Shape commonAnc;
   if ( !shape1.IsNull() && !shape2.IsNull() )
   {
+    if ( shape1.ShapeType() == ancestorType && IsSubShape( shape2, shape1 ))
+      return shape1;
+    if ( shape2.ShapeType() == ancestorType && IsSubShape( shape1, shape2 ))
+      return shape2;
+
     PShapeIteratorPtr ancIt = GetAncestors( shape1, mesh, ancestorType );
     while ( const TopoDS_Shape* anc = ancIt->next() )
       if ( IsSubShape( shape2, *anc ))
@@ -3146,30 +3450,32 @@ namespace { // Structures used by FixQuadraticElements()
     mutable vector<const QFace* > _faces;
     mutable gp_Vec                _nodeMove;
     mutable int                   _nbMoves;
+    mutable bool                  _is2dFixed; // is moved along surface or in 3D
 
     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();
+      _nodeMove = MediumPnt() - MiddlePnt();
+      _is2dFixed = ( MediumPos() != SMDS_TOP_FACE );
     }
     void SetContinuesFaces() const;
     const QFace* GetContinuesFace( const QFace* face ) const;
-    bool OnBoundary() 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
+    SMDS_TypeOfPosition  MediumPos() const
     { return _mediumNode->GetPosition()->GetTypeOfPosition(); }
-    SMDS_TypeOfPosition EndPos(bool isSecond) const
+    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; }
+    void Move(const gp_Vec& move, bool sum=false, bool is2dFixed=false) const
+    { _nodeMove += move; _nbMoves += sum ? (_nbMoves==0) : 1; _is2dFixed |= is2dFixed; }
     gp_XYZ Move() const { return _nodeMove.XYZ() / _nbMoves; }
     bool IsMoved() const { return (_nbMoves > 0 /*&& !IsStraight()*/); }
+    bool IsFixedOnSurface() const { return _is2dFixed; }
     bool IsStraight() const
     { return isStraightLink( (XYZ(node1())-XYZ(node2())).SquareModulus(),
                              _nodeMove.SquareMagnitude());
@@ -3247,11 +3553,11 @@ namespace { // Structures used by FixQuadraticElements()
     int NbVolumes() const { return !_volumes[0] ? 0 : !_volumes[1] ? 1 : 2; }
 
     void AddSelfToLinks() const {
-      for ( int i = 0; i < _sides.size(); ++i )
+      for ( size_t 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;
+      for (size_t 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;
@@ -3283,7 +3589,7 @@ namespace { // Structures used by FixQuadraticElements()
                               const SMDS_MeshNode* nodeToContain) const;
 
     const SMDS_MeshNode* GetNodeInFace() const {
-      for ( int iL = 0; iL < _sides.size(); ++iL )
+      for ( size_t iL = 0; iL < _sides.size(); ++iL )
         if ( _sides[iL]->MediumPos() == SMDS_TOP_FACE ) return _sides[iL]->_mediumNode;
       return 0;
     }
@@ -3336,7 +3642,7 @@ namespace { // Structures used by FixQuadraticElements()
     _sides = links;
     _sideIsAdded[0]=_sideIsAdded[1]=_sideIsAdded[2]=_sideIsAdded[3]=false;
     _normal.SetCoord(0,0,0);
-    for ( int i = 1; i < _sides.size(); ++i ) {
+    for ( size_t i = 1; i < _sides.size(); ++i ) {
       const QLink *l1 = _sides[i-1], *l2 = _sides[i];
       insert( l1->node1() ); insert( l1->node2() );
       // compute normal
@@ -3370,7 +3676,7 @@ namespace { // Structures used by FixQuadraticElements()
 
   bool QFace::GetLinkChain( int iSide, TChain& chain, SMDS_TypeOfPosition pos, int& error) const
   {
-    if ( iSide >= _sides.size() ) // wrong argument iSide
+    if ( iSide >= (int)_sides.size() ) // wrong argument iSide
       return false;
     if ( _sideIsAdded[ iSide ]) // already in chain
       return true;
@@ -3381,7 +3687,7 @@ namespace { // Structures used by FixQuadraticElements()
       list< const QFace* > faces( 1, this );
       while ( !faces.empty() ) {
         const QFace* face = faces.front();
-        for ( int i = 0; i < face->_sides.size(); ++i ) {
+        for ( size_t 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
@@ -3464,7 +3770,7 @@ namespace { // Structures used by FixQuadraticElements()
     typedef list< pair< const QFace*, TLinkInSet > > TFaceLinkList;
     TFaceLinkList adjacentFaces;
 
-    for ( int iL = 0; iL < _sides.size(); ++iL )
+    for ( size_t iL = 0; iL < _sides.size(); ++iL )
     {
       if ( avoidLink._qlink == _sides[iL] )
         continue;
@@ -3517,10 +3823,10 @@ namespace { // Structures used by FixQuadraticElements()
                                    const TChainLink&    avoidLink,
                                    const SMDS_MeshNode* nodeToContain) const
   {
-    for ( int i = 0; i < _sides.size(); ++i )
+    for ( size_t 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.find( _sides[i] );
     return links.end();
   }
 
@@ -3571,7 +3877,7 @@ namespace { // Structures used by FixQuadraticElements()
     if ( !theStep )
       return thePrevLen; // propagation limit reached
 
-    int iL; // index of theLink
+    size_t iL; // index of theLink
     for ( iL = 0; iL < _sides.size(); ++iL )
       if ( theLink._qlink == _sides[ iL ])
         break;
@@ -3648,7 +3954,7 @@ namespace { // Structures used by FixQuadraticElements()
       double r = thePrevLen / fullLen;
 
       gp_Vec move = linkNorm * refProj * ( 1 - r );
-      theLink->Move( move, true );
+      theLink->Move( move, /*sum=*/true );
 
       MSG(string(theStep,'.')<<" Move "<< theLink->_mediumNode->GetID()<<
           " by " << refProj * ( 1 - r ) << " following " <<
@@ -3711,7 +4017,7 @@ namespace { // Structures used by FixQuadraticElements()
     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 )
+    for ( size_t iF = 1; iFaceCont < 0 && iF < _faces.size(); ++iF )
     {
       // look for a face bounding none of volumes bound by _faces[0]
       bool sameVol = false;
@@ -3753,12 +4059,13 @@ namespace { // Structures used by FixQuadraticElements()
 
   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;
+    if ( _faces.size() <= 4 )
+      for ( size_t i = 0; i < _faces.size(); ++i ) {
+        if ( _faces[i] == face ) {
+          int iF = i < 2 ? 1-i : 5-i;
+          return iF < (int)_faces.size() ? _faces[iF] : 0;
+        }
       }
-    }
     return 0;
   }
   //================================================================================
@@ -3769,7 +4076,7 @@ namespace { // Structures used by FixQuadraticElements()
 
   bool QLink::OnBoundary() const
   {
-    for ( int i = 0; i < _faces.size(); ++i )
+    for ( size_t i = 0; i < _faces.size(); ++i )
       if (_faces[i] && _faces[i]->IsBoundary()) return true;
     return false;
   }
@@ -3838,7 +4145,7 @@ namespace { // Structures used by FixQuadraticElements()
       for ( ; bnd != bndEnd; ++bnd )
       {
         const QLink* bndLink = *bnd;
-        for ( int i = 0; i < bndLink->_faces.size(); ++i ) // loop on faces of bndLink
+        for ( size_t 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;
@@ -3905,7 +4212,7 @@ namespace { // Structures used by FixQuadraticElements()
   {
     // put links in the set and evalute number of result chains by number of boundary links
     TLinkSet linkSet;
-    int nbBndLinks = 0;
+    size_t nbBndLinks = 0;
     for ( TChain::iterator lnk = allLinks.begin(); lnk != allLinks.end(); ++lnk ) {
       linkSet.insert( *lnk );
       nbBndLinks += lnk->IsBoundary();
@@ -3954,7 +4261,7 @@ namespace { // Structures used by FixQuadraticElements()
 
       TLinkInSet botLink = startLink; // current horizontal link to go up from
       corner = startCorner; // current corner the botLink ends at
-      int iRow = 0;
+      size_t iRow = 0;
       while ( botLink != linksEnd ) // loop on rows
       {
         // add botLink to the columnChain
@@ -4051,7 +4358,7 @@ namespace { // Structures used by FixQuadraticElements()
     // 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 ) {
+    for ( size_t iRow = 0; iRow < rowChains.size(); ++iRow ) {
       // find the link (startLink) ending at startCorner
       corner = 0;
       for ( startLink = linkSet.begin(); startLink != linksEnd; ++startLink ) {
@@ -4143,6 +4450,7 @@ namespace { // Structures used by FixQuadraticElements()
           {
             continue;
           }
+        default:;
         }
         // get nodes shared by faces that may be distorted
         SMDS_NodeIteratorPtr nodeIt;
@@ -4193,7 +4501,7 @@ namespace { // Structures used by FixQuadraticElements()
                 continue;
               gp_XYZ edgeDir  = SMESH_TNodeXYZ( nOnEdge[0] ) - SMESH_TNodeXYZ( nOnEdge[1] );
               gp_XYZ edgeNorm = faceNorm ^ edgeDir;
-              n = theHelper.GetMediumNode( nOnEdge[0], nOnEdge[1], true );
+              n = theHelper.GetMediumNode( nOnEdge[0], nOnEdge[1], true ); // find n, not create 
               gp_XYZ pN0     = SMESH_TNodeXYZ( nOnEdge[0] );
               gp_XYZ pMedium = SMESH_TNodeXYZ( n );                   // on-edge node location
               gp_XYZ pFaceN  = SMESH_TNodeXYZ( nOnFace );             // on-face node location
@@ -4256,6 +4564,7 @@ namespace { // Structures used by FixQuadraticElements()
           {
             concaveFaces.push_back( face );
           }
+        default:;
         }
       }
       if ( concaveFaces.empty() )
@@ -4321,7 +4630,7 @@ namespace { // Structures used by FixQuadraticElements()
           while ( volIt->more() )
           {
             const SMDS_MeshElement* vol = volIt->next();
-            int nbN = vol->NbCornerNodes();
+            size_t                  nbN = vol->NbCornerNodes();
             if ( ( nbN != 4 && nbN != 5 )  ||
                  !solidSM->Contains( vol ) ||
                  !checkedVols.insert( vol ).second )
@@ -4606,6 +4915,8 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError,
   // 3. Compute displacement of medium nodes
   // ---------------------------------------
 
+  SMESH_MesherHelper faceHlp(*myMesh);
+
   // two loops on QFaces: the first is to treat boundary links, the second is for internal ones.
   TopLoc_Location loc;
   bool checkUV;
@@ -4637,7 +4948,7 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError,
         }
         else if ( error == ERR_TRI ) {  // chain contains continues triangles
           TSplitTriaResult res = splitTrianglesIntoChains( rawChain, chains, pos );
-          if ( res != _OK ) { // not quadrangles split into triangles
+          if ( res != _OK ) { // not 'quadrangles split into triangles' in chain
             fixTriaNearBoundary( rawChain, *this );
             break;
           }
@@ -4649,7 +4960,7 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError,
         else {
           continue;
         }
-        for ( int iC = 0; iC < chains.size(); ++iC )
+        for ( size_t iC = 0; iC < chains.size(); ++iC )
         {
           TChain& chain = chains[iC];
           if ( chain.empty() ) continue;
@@ -4665,12 +4976,14 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError,
           // mesure chain length and compute link position along the chain
           double chainLen = 0;
           vector< double > linkPos;
+          TChain savedChain; // backup
           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
+              if ( savedChain.empty() ) savedChain = chain;
               link1 = chain.erase( link1 );
               if ( link1 == chain.end() )
                 break;
@@ -4680,49 +4993,57 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError,
             linkPos.push_back( chainLen );
           }
           MSG("");
-          if ( linkPos.size() < 2 )
-            continue;
-
+          if ( linkPos.size() <= 2 && savedChain.size() > 2 ) {
+            //continue;
+            linkPos.clear();
+            chainLen = 0;
+            chain = savedChain;
+            for ( link1 = chain.begin(); link1 != chain.end(); ++link1 ) {
+              chainLen += 1;
+              linkPos.push_back( chainLen );
+            }
+          }
           gp_Vec move0 = chain.front()->_nodeMove;
           gp_Vec move1 = chain.back ()->_nodeMove;
 
           TopoDS_Face face;
           if ( !isInside )
           {
-            // compute node displacement of end links of chain in parametric space of face
+            // 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 );
+              faceHlp.SetSubShape( face );
               Handle(Geom_Surface) surf = BRep_Tool::Surface(face,loc);
-              bool isStraight[2];
+              //bool isStraight[2]; // commented for issue 0023118
               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);
+                gp_XY uvm  = faceHlp.GetNodeUV( face, link->_mediumNode, nodeOnFace, &checkUV );
+                gp_XY uv1  = faceHlp.GetNodeUV( face, link->node1(),     nodeOnFace, &checkUV );
+                gp_XY uv2  = faceHlp.GetNodeUV( face, link->node2(),     nodeOnFace, &checkUV );
+                gp_XY uv12 = faceHlp.GetMiddleUV( surf, uv1, uv2 );
                 // uvMove = uvm - uv12
-                gp_XY uvMove = applyIn2D(surf, uvm, uv12, gp_XY_Subtracted, /*inPeriod=*/false);
+                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
+                // 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);
+              gp_XY uvm  = faceHlp.GetNodeUV( face, linkOnFace->_mediumNode, 0, &checkUV );
+              gp_XY uv1  = faceHlp.GetNodeUV( face, linkOnFace->node1(), nodeOnFace, &checkUV );
+              gp_XY uv2  = faceHlp.GetNodeUV( face, linkOnFace->node2(), nodeOnFace, &checkUV );
+              gp_XY uv12 = faceHlp.GetMiddleUV( surf, uv1, uv2 );
               if (( uvm - uv12 ).SquareModulus() > 1e-10 )
               {
                 MSG("Already fixed - ignore");
@@ -4760,15 +5081,20 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError,
               // 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() );
+              try {
+                gp_Vec x = x01.Normalized() + x12.Normalized();
+                trsf.SetTransformation( gp_Ax3( gp::Origin(), link1->Normal(), x), gp_Ax3() );
+              } catch ( Standard_Failure ) {
+                trsf.Invert();
+              }
               move.Transform(trsf);
+              (*link1)->Move( move, /*sum=*/false, /*is2dFixed=*/false );
             }
             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_XY oldUV   = faceHlp.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) );
               if ( SMDS_FacePosition* nPos =
@@ -4778,8 +5104,8 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError,
               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);
+                gp_XY uv0 = faceHlp.GetNodeUV( face, (*link0)->_mediumNode, 0, &checkUV );
+                gp_XY uv2 = faceHlp.GetNodeUV( face, (*link2)->_mediumNode, 0, &checkUV );
                 MSG( "TOO LONG MOVE \t" <<
                      "uv0: "<<uv0.X()<<", "<<uv0.Y()<<" \t" <<
                      "uv2: "<<uv2.X()<<", "<<uv2.Y()<<" \t" <<
@@ -4787,8 +5113,8 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError,
                      "newUV: "<<newUV.X()<<", "<<newUV.Y()<<" \t");
               }
 #endif
+              (*link1)->Move( move, /*sum=*/false, /*is2dFixed=*/true );
             }
-            (*link1)->Move( move );
             MSG( "Move " << (*link1)->_mediumNode->GetID() << " following "
                  << chain.front()->_mediumNode->GetID() <<"-"
                  << chain.back ()->_mediumNode->GetID() <<
@@ -4807,11 +5133,28 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError,
   const bool toFixCentralNodes = ( myMesh->NbBiQuadQuadrangles() +
                                    myMesh->NbBiQuadTriangles() +
                                    myMesh->NbTriQuadraticHexas() );
+  double distXYZ[4];
+  faceHlp.ToFixNodeParameters( true );
 
   for ( pLink = links.begin(); pLink != links.end(); ++pLink ) {
     if ( pLink->IsMoved() )
     {
       gp_Pnt p = pLink->MiddlePnt() + pLink->Move();
+
+      // put on surface nodes on FACE but moved in 3D (23050)
+      if ( !pLink->IsFixedOnSurface() )
+      {
+        faceHlp.SetSubShape( pLink->_mediumNode->getshapeId() );
+        if ( faceHlp.GetSubShape().ShapeType() == TopAbs_FACE )
+        {
+          const_cast<SMDS_MeshNode*>( pLink->_mediumNode )->setXYZ( p.X(), p.Y(), p.Z());
+          p.Coord( distXYZ[1], distXYZ[2], distXYZ[3] );
+          gp_XY uv( Precision::Infinite(), 0 );
+          if ( faceHlp.CheckNodeUV( TopoDS::Face( faceHlp.GetSubShape() ), pLink->_mediumNode,
+                                    uv, /*tol=*/pLink->Move().Modulus(), /*force=*/true, distXYZ ))
+            p.SetCoord( distXYZ[1], distXYZ[2], distXYZ[3] );
+        }
+      }
       GetMeshDS()->MoveNode( pLink->_mediumNode, p.X(), p.Y(), p.Z());
 
       // collect bi-quadratic elements
@@ -4860,6 +5203,7 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError,
         if ( i > 3 && nodes[i]->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE )
           CheckNodeUV( F, nodes[i], uv[ i ], 2*tol, /*force=*/true );
       }
+      AdjustByPeriod( F, uv, 8 ); // put uv[] within a period (IPAL52698)
       // move the central node
       gp_XY uvCent = calcTFI (0.5, 0.5, uv[0],uv[1],uv[2],uv[3],uv[4],uv[5],uv[6],uv[7] );
       gp_Pnt p = surf->Value( uvCent.X(), uvCent.Y() ).Transformed( loc );
@@ -4885,17 +5229,30 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError,
       // nodes
       nodes.assign( tria->begin_nodes(), tria->end_nodes() );
       // UV
+      bool uvOK = true, badTria = false;
       for ( int i = 0; i < 6; ++i )
       {
-        uv[ i ] = GetNodeUV( F, nodes[i], nodes[(i+1)%3], &checkUV );
+        uv[ i ] = GetNodeUV( F, nodes[i], nodes[(i+1)%3], &uvOK );
         // as this method is used after mesh generation, UV of nodes is not
         // updated according to bending links, so we update 
         if ( nodes[i]->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE )
           CheckNodeUV( F, nodes[i], uv[ i ], 2*tol, /*force=*/true );
       }
+
       // move the central node
-      gp_XY uvCent = GetCenterUV( uv[0], uv[1], uv[2], uv[3], uv[4], uv[5] );
-      gp_Pnt p = surf->Value( uvCent.X(), uvCent.Y() ).Transformed( loc );
+      gp_Pnt p;
+      if ( !uvOK || badTria )
+      {
+        p = ( SMESH_TNodeXYZ( nodes[3] ) +
+              SMESH_TNodeXYZ( nodes[4] ) +
+              SMESH_TNodeXYZ( nodes[5] )) / 3;
+      }
+      else
+      {
+        AdjustByPeriod( F, uv, 6 ); // put uv[] within a period (IPAL52698)
+        gp_XY uvCent = GetCenterUV( uv[0], uv[1], uv[2], uv[3], uv[4], uv[5], &badTria );
+        p = surf->Value( uvCent.X(), uvCent.Y() ).Transformed( loc );
+      }
       GetMeshDS()->MoveNode( tria->GetNode(6), p.X(), p.Y(), p.Z() );
     }
   }
index 164861c3213fc54b76b6a1fc35c93489720944df..fdf863f033e94d0792d75204853661e5ee932545 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -34,6 +34,7 @@
 #include <SMDS_QuadraticEdge.hxx>
 
 #include <Geom_Surface.hxx>
+#include <ShapeAnalysis_Surface.hxx>
 #include <TopoDS_Face.hxx>
 #include <TopoDS_Shape.hxx>
 #include <gp_Pnt2d.hxx>
@@ -236,6 +237,10 @@ class SMESH_EXPORT SMESH_MesherHelper
   static TopAbs_ShapeEnum GetGroupType(const TopoDS_Shape& group,
                                        const bool          avoidCompound=false);
 
+  static TopoDS_Shape GetShapeOfHypothesis( const SMESHDS_Hypothesis * hyp,
+                                            const TopoDS_Shape&        shape,
+                                            SMESH_Mesh*                mesh);
+
 
 public:
   // ---------- PUBLIC INSTANCE METHODS ----------
@@ -243,7 +248,9 @@ public:
   // constructor
   SMESH_MesherHelper(SMESH_Mesh& theMesh);
 
-  SMESH_Mesh* GetMesh() const { return myMesh; }
+  SMESH_Gen*    GetGen() const { return GetMesh()->GetGen(); }
+    
+  SMESH_Mesh*   GetMesh() const { return myMesh; }
     
   SMESHDS_Mesh* GetMeshDS() const { return GetMesh()->GetMeshDS(); }
     
@@ -252,12 +259,9 @@ public:
    * quadratic elements will be created. Also fill myTLinkNodeMap
    */
   bool IsQuadraticSubMesh(const TopoDS_Shape& theShape);
-  /*!
-   * \brief Set order of elements to create without calling IsQuadraticSubMesh()
-   */
 
   /*!
-   * \brief Set myCreateQuadratic flag
+   * \brief Set order of elements to create without calling IsQuadraticSubMesh()
    */
   void SetIsQuadratic(const bool theBuildQuadratic)
   { myCreateQuadratic = theBuildQuadratic; }
@@ -482,10 +486,10 @@ public:
                            bool *       isBadTria=0);
   /*!
    * \brief Define a pointer to wrapper over a function of gp_XY class,
-   *       suitable to pass as xyFunPtr to applyIn2D().
+   *       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)
+   *       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 ); } \
@@ -496,18 +500,26 @@ public:
    *        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);
-                          
+  static gp_XY ApplyIn2D(Handle(Geom_Surface) surface,
+                         const gp_XY&         uv1,
+                         const gp_XY&         uv2,
+                         xyFunPtr             fun,
+                         const bool           resultInPeriod=true);
+
+  /*!
+   * \brief Move node positions on a FACE within surface period
+   *  \param [in] face - the FACE
+   *  \param [inout] uv - node positions to adjust
+   *  \param [in] nbUV - nb of \a uv
+   */
+  void AdjustByPeriod( const TopoDS_Face& face, gp_XY uv[], const int nbUV );
+
   /*!
    * \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
-    * SetSubShape()
+    \retval bool - return true if the face is periodic
+   *
+   * If F is Null, answer about subshape set through IsQuadraticSubMesh() or
+   * SetSubShape()
    */
   bool GetNodeUVneedInFaceNode(const TopoDS_Face& F = TopoDS_Face()) const;
 
@@ -517,13 +529,17 @@ public:
   GeomAPI_ProjectPointOnSurf& GetProjector(const TopoDS_Face& F,
                                            TopLoc_Location&   loc,
                                            double             tol=0 ) const; 
+  /*!
+   * \brief Return a cached ShapeAnalysis_Surface of a FACE
+   */
+  Handle(ShapeAnalysis_Surface) GetSurface(const TopoDS_Face& F ) const;
 
   /*!
    * \brief Check if shape is a degenerated edge or it's vertex
-    * \param subShape - edge or vertex index in SMESHDS
-    * \retval bool - true if subShape is a degenerated shape
-    *
-    * It works only if IsQuadraticSubMesh() or SetSubShape() has been called
+    \param subShape - edge or vertex index in SMESHDS
+    \retval bool - true if subShape is a degenerated shape
+   *
+   * It works only if IsQuadraticSubMesh() or SetSubShape() has been called
    */
   bool IsDegenShape(const int subShape) const
   { return myDegenShapeIds.find( subShape ) != myDegenShapeIds.end(); }
@@ -594,10 +610,14 @@ public:
    *  \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.
+   *  \param expectedSupport - shape type corresponding to element being created
+   *                           , e.g TopAbs_EDGE if SMDSAbs_Edge is created
+   *                           basing on \a n1 and \a n2
    */
   const SMDS_MeshNode* GetMediumNode(const SMDS_MeshNode* n1,
                                      const SMDS_MeshNode* n2,
-                                     const bool force3d);
+                                     const bool           force3d,
+                                     TopAbs_ShapeEnum     expectedSupport=TopAbs_SHAPE);
   /*!
    * \brief Return existing or create a new central node for a quardilateral
    *       quadratic face given its 8 nodes.
@@ -631,7 +651,8 @@ public:
    */
   std::pair<int, TopAbs_ShapeEnum> GetMediumPos(const SMDS_MeshNode* n1,
                                                 const SMDS_MeshNode* n2,
-                                                const bool           useCurSubShape=false);
+                                                const bool           useCurSubShape=false,
+                                                TopAbs_ShapeEnum     expectedSupport=TopAbs_SHAPE);
   /*!
    * \brief Add a link in my data structure
    */
@@ -671,11 +692,14 @@ public:
    *  \param uv2 - UV within a face
    *  \retval gp_Pnt2d - selected UV
    */
-  gp_Pnt2d GetUVOnSeam( const gp_Pnt2d& uv1, const gp_Pnt2d& uv2 ) const;
+  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);
+
+  double getFaceMaxTol( const TopoDS_Shape& face ) const;
+
  private:
 
   // Forbiden copy constructor
@@ -710,9 +734,13 @@ public:
   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;
+  std::map< int, double > myFaceMaxTol;
+
+  typedef std::map< int, Handle(ShapeAnalysis_Surface)> TID2Surface;
+  typedef std::map< int, GeomAPI_ProjectPointOnSurf* >  TID2ProjectorOnSurf;
   typedef std::map< int, GeomAPI_ProjectPointOnCurve* > TID2ProjectorOnCurve;
+  mutable TID2Surface  myFace2Surface;
+  TID2ProjectorOnSurf  myFace2Projector;
   TID2ProjectorOnCurve myEdge2Projector;
 
   TopoDS_Shape    myShape;
index 2264ba3d16503b8664ef57b2cf539d77bf44d631..1fe3af02f7c91675cfadbe257201ef60cd3f9ece 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -103,7 +103,7 @@ inline int getInt( const char * theSring )
   int val = strtol( theSring, &ptr, 10 );
   if ( ptr == theSring ||
       // there must not be neither '.' nor ',' nor 'E' ...
-      (*ptr != ' ' && *ptr != '\n' && *ptr != '\0'))
+      (*ptr != ' ' && *ptr != '\n' && *ptr != '\0' && *ptr != '\r'))
     return -1;
 
   return val;
@@ -540,7 +540,7 @@ static bool isMeshBoundToShape(SMESHDS_Mesh *     aMeshDS,
                                SMESHDS_SubMesh *  aFaceSubmesh,
                                const bool         isMainShape)
 {
-  if ( isMainShape ) {
+  if ( isMainShape && aFaceSubmesh ) {
     // check that all faces are bound to aFaceSubmesh
     if ( aMeshDS->NbFaces() != aFaceSubmesh->NbElements() )
       return false;
@@ -620,39 +620,26 @@ bool SMESH_Pattern::Load (SMESH_Mesh*        theMesh,
     // ---------------------------------------------------------------
 
     // get all faces
-    list< const SMDS_MeshElement* > faces;
-    if ( nbElems > 0 ) {
-      SMDS_ElemIteratorPtr fIt = fSubMesh->GetElements();
-      while ( fIt->more() ) {
-        const SMDS_MeshElement* f = fIt->next();
-        if ( f && f->GetType() == SMDSAbs_Face )
-          faces.push_back( f );
-      }
-    }
-    else {
-      SMDS_FaceIteratorPtr fIt = aMeshDS->facesIterator();
-      while ( fIt->more() )
-        faces.push_back( fIt->next() );
-    }
+    SMDS_ElemIteratorPtr fIt;
+    if ( nbElems > 0 )
+      fIt = fSubMesh->GetElements();
+    else
+      fIt = aMeshDS->elementsIterator( SMDSAbs_Face );
 
     // put nodes of all faces into the nodePointIDMap and fill myElemPointIDs
-    list< const SMDS_MeshElement* >::iterator fIt = faces.begin();
-    for ( ; fIt != faces.end(); ++fIt )
+    while ( fIt->more() )
     {
+      const SMDS_MeshElement* face = fIt->next();
       myElemPointIDs.push_back( TElemDef() );
       TElemDef& elemPoints = myElemPointIDs.back();
-      int nbNodes = (*fIt)->NbCornerNodes();
+      int nbNodes = face->NbCornerNodes();
       for ( int i = 0;i < nbNodes; ++i )
       {
-        const SMDS_MeshElement* node = (*fIt)->GetNode( i );
+        const SMDS_MeshElement* node = face->GetNode( i );
         TNodePointIDMap::iterator nIdIt = nodePointIDMap.insert( make_pair( node, -1 )).first;
         if ( nIdIt->second == -1 )
-        {
-          elemPoints.push_back( iPoint );
           nIdIt->second = iPoint++;
-        }
-        else
-          elemPoints.push_back( (*nIdIt).second );
+        elemPoints.push_back( (*nIdIt).second );
       }
     }
     myPoints.resize( iPoint );
@@ -716,12 +703,12 @@ bool SMESH_Pattern::Load (SMESH_Mesh*        theMesh,
     {
       if ( isClosed && ( iE == 0 || iE == *nbEinW ))
       {
-        // new wire begins; put EDGEs in eVec
+        // new wire begins; put wire EDGEs in eVec
         list<TopoDS_Edge>::iterator eEnd = elIt;
+        if ( iE == *nbEinW )
+          ++nbEinW;
         std::advance( eEnd, *nbEinW );
         eVec.assign( elIt, eEnd );
-        if ( iE > 0 )
-          ++nbEinW;
         iE = 0;
       }
       TopoDS_Edge & edge = *elIt;
@@ -733,7 +720,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh*        theMesh,
       TopoDS_Shape v1 = TopExp::FirstVertex( edge, true ); // always FORWARD
       TopoDS_Shape v2 = TopExp::LastVertex( edge, true ); // always REVERSED
       // to make adjacent edges share key-point, we make v2 FORWARD too
-      // (as we have different points for same shape with different orienation)
+      // (as we have different points for same shape with different orientation)
       v2.Reverse();
 
       // on closed face we must have REVERSED some of seam vertices
@@ -745,7 +732,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh*        theMesh,
             v2.Reverse();
           }
         }
-        else { // on CLOSED edge (i.e. having one vertex with different orienations)
+        else { // on CLOSED edge (i.e. having one vertex with different orientations)
           for ( int is2 = 0; is2 < 2; ++is2 ) {
             TopoDS_Shape & v = is2 ? v2 : v1;
             if ( helper.IsRealSeam( v ) ) {
@@ -805,7 +792,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh*        theMesh,
           double u = epos->GetUParameter();
           paramNodeMap.insert( make_pair( u, node ));
         }
-        if ( paramNodeMap.size() != eSubMesh->NbNodes() ) {
+        if ((int) paramNodeMap.size() != eSubMesh->NbNodes() ) {
           // wrong U on edge, project
           Extrema_ExtPC proj;
           BRepAdaptor_Curve aCurve( edge );
@@ -831,7 +818,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh*        theMesh,
           }
 
           //rnv : To fix the bug IPAL21999 Pattern Mapping - New - collapse of pattern mesh
-          if ( paramNodeMap.size() != eSubMesh->NbNodes() - nbMeduimNodes )
+          if ((int) paramNodeMap.size() != eSubMesh->NbNodes() - nbMeduimNodes )
             return setErrorCode(ERR_UNEXPECTED);
         }
 
@@ -1219,7 +1206,7 @@ struct TIsoNode {
   TIsoNode* myNext[4]; // order: (iDir=0,isForward=0), (1,0), (0,1), (1,1)
   TIsoNode* myBndNodes[4];     // order: (iDir=0,i=0), (1,0), (0,1), (1,1)
   TIsoNode(double initU, double initV):
-    myInitUV( initU, initV ), myUV( 1e100, 1e100 ), myIsMovable(true)
+    myIsMovable(true), myInitUV( initU, initV ), myUV( 1e100, 1e100 )
   { myNext[0] = myNext[1] = myNext[2] = myNext[3] = 0; }
   bool IsUVComputed() const
   { return myUV.X() != 1e100; }
@@ -2438,7 +2425,7 @@ bool SMESH_Pattern::Apply (const TopoDS_Face&   theFace,
   int nbVertices = loadVE( eList, myShapeIDMap );
   myShapeIDMap.Add( face );
 
-  if ( myShapeIDToPointsMap.size() != myShapeIDMap.Extent() ) {
+  if ((int) myShapeIDToPointsMap.size() != myShapeIDMap.Extent() ) {
     MESSAGE( myShapeIDToPointsMap.size() <<" != " << myShapeIDMap.Extent());
     return setErrorCode( ERR_APPLF_INTERNAL_EEROR );
   }
@@ -2514,9 +2501,9 @@ bool SMESH_Pattern::Apply (const TopoDS_Face&   theFace,
     while ( wlIt != wireList.end() )
     {
       list< TopoDS_Edge >& wire = (*wlIt);
-      int nbEdges = wire.size();
+      size_t nbEdges = wire.size();
       wlIt++;
-      if ( wlIt == wireList.end() || (*wlIt).size() != nbEdges ) // a unique size wire
+      if ( wlIt != wireList.end() && (*wlIt).size() != nbEdges ) // a unique size wire
       {
         // choose the best first edge of a wire
         setFirstEdge( wire, id1 );
@@ -2541,7 +2528,7 @@ bool SMESH_Pattern::Apply (const TopoDS_Face&   theFace,
     wlIt = wireList.begin();
     while ( wlIt != wireList.end() )
     {
-      int nbSameSize = 0, nbEdges = (*wlIt).size();
+      size_t nbSameSize = 0, nbEdges = (*wlIt).size();
       list< list< TopoDS_Edge > >::iterator wlIt2 = wlIt;
       wlIt2++;
       while ( wlIt2 != wireList.end() && (*wlIt2).size() == nbEdges ) { // a same size wire
@@ -2880,7 +2867,7 @@ bool SMESH_Pattern::Apply (SMESH_Mesh*          theMesh,
 
   // compute UV and XYZ of points on edges
 
-  for ( int i = 0; i < myOrderedNodes.size(); ++i, ++iSub )
+  for ( size_t i = 0; i < myOrderedNodes.size(); ++i, ++iSub )
   {
     gp_XY& uv1 = keyUV[ i ];
     gp_XY& uv2 = ( i+1 < keyUV.size() ) ? keyUV[ i+1 ] : keyUV[ 0 ];
@@ -3117,7 +3104,7 @@ bool SMESH_Pattern::Apply (std::set<const SMDS_MeshVolume*> & theVolumes,
 
   // to find point index
   map< TPoint*, int > pointIndex;
-  for ( int i = 0; i < myPoints.size(); i++ )
+  for ( size_t i = 0; i < myPoints.size(); i++ )
     pointIndex.insert( make_pair( & myPoints[ i ], i ));
 
   int ind1 = 0; // lowest point index for an element
@@ -3554,13 +3541,7 @@ void SMESH_Pattern::
   myPolyElems.reserve( myIdsOnBoundary.size() );
 
   // make a set of refined elements
-  TIDSortedElemSet avoidSet, elemSet;
-  std::vector<const SMDS_MeshElement*>::iterator itv =  myElements.begin();
-  for(; itv!=myElements.end(); itv++) {
-    const SMDS_MeshElement* el = (*itv);
-    avoidSet.insert( el );
-  }
-  //avoidSet.insert( myElements.begin(), myElements.end() );
+  TIDSortedElemSet elemSet, avoidSet( myElements.begin(), myElements.end() );
 
   map< TNodeSet, list< list< int > > >::iterator indListIt, nn_IdList;
 
@@ -4033,7 +4014,7 @@ bool SMESH_Pattern::MakeMesh(SMESH_Mesh* theMesh,
     for ( ; i_node != myXYZIdToNodeMap.end(); i_node++ ) {
       nodesVector[ i_node->first ] = i_node->second;
     }
-    for ( int i = 0; i < myXYZ.size(); ++i ) {
+    for ( size_t i = 0; i < myXYZ.size(); ++i ) {
       if ( !nodesVector[ i ] && isDefined( myXYZ[ i ] ) )
         nodesVector[ i ] = aMeshDS->AddNode (myXYZ[ i ].X(),
                                              myXYZ[ i ].Y(),
@@ -4203,7 +4184,7 @@ void SMESH_Pattern::createElements(SMESH_Mesh*                            theMes
     groups.resize( theElements.size() );
     const set<SMESHDS_GroupBase*>& allGroups = aMeshDS->GetGroups();
     set<SMESHDS_GroupBase*>::const_iterator grIt;
-    for ( int i = 0; i < theElements.size(); i++ )
+    for ( size_t i = 0; i < theElements.size(); i++ )
     {
       shapeIDs[ i ] = editor.FindShape( theElements[ i ] );
       for ( grIt = allGroups.begin(); grIt != allGroups.end(); grIt++ ) {
@@ -4245,7 +4226,7 @@ void SMESH_Pattern::createElements(SMESH_Mesh*                            theMes
     TElemDef::const_iterator id = elemNodeInd.begin();
     int nbNodes;
     for ( nbNodes = 0; id != elemNodeInd.end(); id++ ) {
-      if ( *id < theNodesVector.size() )
+      if ( *id < (int) theNodesVector.size() )
         nodes[ nbNodes++ ] = theNodesVector[ *id ];
       else
         nodes[ nbNodes++ ] = myXYZIdToNodeMap[ *id ];
@@ -4344,7 +4325,7 @@ void SMESH_Pattern::createElements(SMESH_Mesh*                            theMes
   }
   if ( onMeshElements ) {
     list< int > elemIDs;
-    for ( int i = 0; i < theElements.size(); i++ )
+    for ( size_t i = 0; i < theElements.size(); i++ )
     {
       subMesh = theMesh->GetSubMeshContaining( shapeIDs[ i ] );
       if ( subMesh )
@@ -4373,7 +4354,7 @@ bool SMESH_Pattern::isReversed(const SMDS_MeshNode* theFirstNode,
   gp_Pnt P[2];
   list<int>::const_iterator id = theIdsList.begin();
   for ( int i = 0; i < 2; ++i, ++id ) {
-    if ( *id < myXYZ.size() )
+    if ( *id < (int) myXYZ.size() )
       P[ i ] = myXYZ[ *id ];
     else {
       map< int, const SMDS_MeshNode*>::const_iterator i_n;
@@ -4448,7 +4429,7 @@ void SMESH_Pattern::arrangeBoundaries (list< list< TPoint* > >& boundaryList)
     }
 
     if ( outerBndPos != boundaryList.begin() )
-      boundaryList.splice( boundaryList.begin(), boundaryList, outerBndPos, ++outerBndPos );
+      boundaryList.splice( boundaryList.begin(), boundaryList, outerBndPos );
 
   } // if nbBoundaries > 1
 
@@ -4809,7 +4790,7 @@ bool SMESH_Pattern::setShapeToMesh(const TopoDS_Shape& theShape)
   // check nb of vertices
   TopTools_IndexedMapOfShape vMap;
   TopExp::MapShapes( theShape, TopAbs_VERTEX, vMap );
-  if ( vMap.Extent() + nbNodeOnSeamEdge != myKeyPointIDs.size() ) {
+  if ( vMap.Extent() + nbNodeOnSeamEdge != (int)myKeyPointIDs.size() ) {
     MESSAGE( myKeyPointIDs.size() + nbNodeOnSeamEdge << " != " << vMap.Extent() );
     return setErrorCode( ERR_APPL_BAD_NB_VERTICES );
   }
index 225e5abaa27b534c7557bde1e7bdaa479fb7e6fb..67c9093ea5c89eb1d71dee95604ea8719f30f22e 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index fd4f470b1484e3b1eb405df741420b9490d06d91..962ba92a56084ec932cda6c1eed5a8a704e3c038 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
@@ -130,7 +130,7 @@ const SMESHDS_SubMesh* SMESH_ProxyMesh::GetSubMesh(const TopoDS_Shape& shape) co
 {
   const SMESHDS_SubMesh* sm = 0;
 
-  int i = shapeIndex(shape);
+  size_t i = shapeIndex(shape);
   if ( i < _subMeshes.size() )
     sm = _subMeshes[i];
   if ( !sm )
@@ -148,7 +148,7 @@ const SMESHDS_SubMesh* SMESH_ProxyMesh::GetSubMesh(const TopoDS_Shape& shape) co
 const SMESH_ProxyMesh::SubMesh*
 SMESH_ProxyMesh::GetProxySubMesh(const TopoDS_Shape& shape) const
 {
-  int i = shapeIndex(shape);
+  size_t i = shapeIndex(shape);
   return i < _subMeshes.size() ? _subMeshes[i] : 0;
 }
 
index f0d86579e10c4c8e69c865555bbc8d8a3aa6560c..03d3f2b1bd5b3909a38cb6d6ed26519e1b4ba1f4 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index 257f960801d2aa873ae58807c0d337fe6c67933c..1094aed0dfddd34dbfa097b612289254b0574fb7 100755 (executable)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 0d4e2d120877f027f7f48970005a25a6a6963d3b..57a401df93e39f33c1a86c14bea38a286afd5db8 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -403,146 +403,48 @@ int SMESH_subMesh::computeCost() const
 
 //=============================================================================
 /*!
- *
- */
-//=============================================================================
-
-// 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;
-// }
-
-//=============================================================================
-/*!
- * Construct dependence on first level subMeshes. complex shapes (compsolid,
- * shell, wire) are not analysed the same way as simple shapes (solid, face,
- * edge).
- * For collection shapes (compsolid, shell, wire) prepare a list of submeshes
- * with possible multiples occurences. Multiples occurences corresponds to
- * internal frontiers within shapes of the collection and must not be keeped.
- * See FinalizeDependence.
+ * Returns all sub-meshes this one depend on
  */
 //=============================================================================
 
 const map < int, SMESH_subMesh * >& SMESH_subMesh::DependsOn()
 {
-  if (_dependenceAnalysed)
+  if ( _dependenceAnalysed || !_father->HasShapeToMesh() )
     return _mapDepend;
 
-  //MESSAGE("SMESH_subMesh::DependsOn");
-
   int type = _subShape.ShapeType();
-  //SCRUTE(type);
   switch (type)
   {
   case TopAbs_COMPOUND:
+  {
+    list< TopoDS_Shape > compounds( 1, _subShape );
+    list< TopoDS_Shape >::iterator comp = compounds.begin();
+    for ( ; comp != compounds.end(); ++comp )
     {
-      //MESSAGE("compound");
-      for (TopExp_Explorer exp(_subShape, TopAbs_SOLID); exp.More();exp.Next())
-      {
-        insertDependence(exp.Current());
-      }
-      for (TopExp_Explorer exp(_subShape, TopAbs_SHELL, TopAbs_SOLID); exp.More(); exp.Next())
-      {
-        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())
-      {
-        insertDependence(exp.Current());
-      }
-      for (TopExp_Explorer exp(_subShape, TopAbs_EDGE, TopAbs_FACE); exp.More();exp.Next())
-      {
-        insertDependence(exp.Current());
-      }
-      for (TopExp_Explorer exp(_subShape, TopAbs_VERTEX, TopAbs_EDGE); exp.More();exp.Next())
-      {
-        insertDependence(exp.Current());
-      }
-      break;
-    }
-  case TopAbs_COMPSOLID:
-    {
-      //MESSAGE("compsolid");
-      for (TopExp_Explorer exp(_subShape, TopAbs_SOLID); exp.More(); exp.Next())
-      {
-        insertDependence(exp.Current());
-      }
-      break;
-    }
-  case TopAbs_SHELL:
-    {
-      //MESSAGE("shell");
-      for (TopExp_Explorer exp(_subShape, TopAbs_FACE); exp.More(); exp.Next())
-      {
-        insertDependence(exp.Current());
-      }
-      break;
-    }
-  case TopAbs_WIRE:
-    {
-      //MESSAGE("wire");
-      for (TopExp_Explorer exp(_subShape, TopAbs_EDGE); exp.More(); exp.Next())
-      {
-        insertDependence(exp.Current());
-      }
-      break;
-    }
-  case TopAbs_SOLID:
-    {
-      //MESSAGE("solid");
-      if(_father->HasShapeToMesh()) {
-        for (TopExp_Explorer exp(_subShape, TopAbs_FACE); exp.More();exp.Next())
+      for ( TopoDS_Iterator sub( *comp ); sub.More(); sub.Next() )
+        switch ( sub.Value().ShapeType() )
         {
-          insertDependence(exp.Current());
+        case TopAbs_COMPOUND:  compounds.push_back( sub.Value() ); break;
+        case TopAbs_COMPSOLID: insertDependence( sub.Value(), TopAbs_SOLID ); break;
+        case TopAbs_SOLID:     insertDependence( sub.Value(), TopAbs_SOLID ); break;
+        case TopAbs_SHELL:     insertDependence( sub.Value(), TopAbs_FACE ); break;
+        case TopAbs_FACE:      insertDependence( sub.Value(), TopAbs_FACE ); break;
+        case TopAbs_WIRE:      insertDependence( sub.Value(), TopAbs_EDGE ); break;
+        case TopAbs_EDGE:      insertDependence( sub.Value(), TopAbs_EDGE ); break;
+        case TopAbs_VERTEX:    insertDependence( sub.Value(), TopAbs_VERTEX ); break;
+        default:;
         }
-      }
-      break;
-    }
-  case TopAbs_FACE:
-    {
-      //MESSAGE("face");
-      for (TopExp_Explorer exp(_subShape, TopAbs_EDGE); exp.More();exp.Next())
-      {
-        insertDependence(exp.Current());
-      }
-      break;
-    }
-  case TopAbs_EDGE:
-    {
-      //MESSAGE("edge");
-      for (TopExp_Explorer exp(_subShape, TopAbs_VERTEX); exp.More(); exp.Next())
-      {
-        insertDependence(exp.Current());
-      }
-      break;
-    }
-  case TopAbs_VERTEX:
-    {
-      break;
-    }
-  default:
-    {
-      break;
     }
   }
+  break;
+  case TopAbs_COMPSOLID: insertDependence( _subShape, TopAbs_SOLID ); break;
+  case TopAbs_SOLID:     insertDependence( _subShape, TopAbs_FACE ); break;
+  case TopAbs_SHELL:     insertDependence( _subShape, TopAbs_FACE ); break;
+  case TopAbs_FACE:      insertDependence( _subShape, TopAbs_EDGE ); break;
+  case TopAbs_WIRE:      insertDependence( _subShape, TopAbs_EDGE ); break;
+  case TopAbs_EDGE:      insertDependence( _subShape, TopAbs_VERTEX ); break;
+  default:;
+  }
   _dependenceAnalysed = true;
   return _mapDepend;
 }
@@ -553,32 +455,43 @@ const map < int, SMESH_subMesh * >& SMESH_subMesh::DependsOn()
  */
 //================================================================================
 
-namespace {
-  int dependsOnMapKey( const SMESH_subMesh* sm )
+namespace
+{
+  int dependsOnMapKey( TopAbs_ShapeEnum type, int shapeID )
   {
-    int type = sm->GetSubShape().ShapeType();
-    int ordType = 9 - type;               // 2 = Vertex, 8 = CompSolid
-    int cle = sm->GetId();
+    int ordType = 9 - int(type);               // 2 = Vertex, 8 = CompSolid
+    int     cle = shapeID;
     cle += 10000000 * ordType;    // sort map by ordType then index
     return cle;
   }
+  int dependsOnMapKey( const SMESH_subMesh* sm )
+  {
+    return dependsOnMapKey( sm->GetSubShape().ShapeType(), sm->GetId() );
+  }
 }
 
 //=============================================================================
 /*!
- * For simple Shapes (solid, face, edge): add subMesh into dependence list.
+ * Add sub-meshes on sub-shapes of a given type into the dependence map.
  */
 //=============================================================================
 
-void SMESH_subMesh::insertDependence(const TopoDS_Shape aSubShape)
+void SMESH_subMesh::insertDependence(const TopoDS_Shape aShape,
+                                     TopAbs_ShapeEnum   aSubType)
 {
-  SMESH_subMesh *aSubMesh = _father->GetSubMesh(aSubShape);
-  int cle = dependsOnMapKey( aSubMesh );
-  if ( _mapDepend.find( cle ) == _mapDepend.end())
+  TopExp_Explorer sub( aShape, aSubType );
+  for ( ; sub.More(); sub.Next() )
   {
-    _mapDepend[cle] = aSubMesh;
-    const map < int, SMESH_subMesh * > & subMap = aSubMesh->DependsOn();
-    _mapDepend.insert( subMap.begin(), subMap.end() );
+    SMESH_subMesh *aSubMesh = _father->GetSubMesh( sub.Current() );
+    if ( aSubMesh->GetId() == 0 )
+      continue;  // not a sub-shape of the shape to mesh
+    int cle = dependsOnMapKey( aSubMesh );
+    if ( _mapDepend.find( cle ) == _mapDepend.end())
+    {
+      _mapDepend[cle] = aSubMesh;
+      const map < int, SMESH_subMesh * > & subMap = aSubMesh->DependsOn();
+      _mapDepend.insert( subMap.begin(), subMap.end() );
+    }
   }
 }
 
@@ -593,6 +506,17 @@ bool SMESH_subMesh::DependsOn( const SMESH_subMesh* other ) const
   return other ? _mapDepend.count( dependsOnMapKey( other )) : false;
 }
 
+//================================================================================
+/*!
+ * \brief Return \c true if \a this sub-mesh depends on a \a shape
+ */
+//================================================================================
+
+bool SMESH_subMesh::DependsOn( const int shapeID ) const
+{
+  return DependsOn( _father->GetSubMeshContaining( shapeID ));
+}
+
 //=============================================================================
 /*!
  * Return a shape of \a this sub-mesh
@@ -690,6 +614,7 @@ SMESH_Hypothesis::Hypothesis_Status
   // le retour des evenement father n'indiquent pas que add ou remove fait
 
   SMESH_Hypothesis::Hypothesis_Status aux_ret, ret = SMESH_Hypothesis::HYP_OK;
+  if ( _Id == 0 ) return ret; // not a sub-shape of the shape to mesh
 
   SMESHDS_Mesh* meshDS =_father->GetMeshDS();
   SMESH_Algo*   algo   = 0;
@@ -979,7 +904,7 @@ SMESH_Hypothesis::Hypothesis_Status
         f.AndNot( SMESH_HypoFilter::Is( algo ));
         const SMESH_Hypothesis * prevAlgo = _father->GetHypothesis( this, f, true );
         if (prevAlgo &&
-            string(algo->GetName()) != string(prevAlgo->GetName()) )
+            string( algo->GetName()) != prevAlgo->GetName())
           modifiedHyp = true;
       }
       else
@@ -1096,8 +1021,8 @@ SMESH_Hypothesis::Hypothesis_Status
 
   // detect algorithm hiding
   //
-  if ( ret == SMESH_Hypothesis::HYP_OK &&
-       ( event == ADD_ALGO || event == ADD_FATHER_ALGO ) &&
+  if ( ret == SMESH_Hypothesis::HYP_OK && 
+       ( event == ADD_ALGO || event == ADD_FATHER_ALGO ) && algo && 
        algo->GetName() == anHyp->GetName() )
   {
     // is algo hidden?
@@ -1182,8 +1107,6 @@ bool SMESH_subMesh::IsConform(const SMESH_Algo* theAlgo)
        !theAlgo->OnlyUnaryInput() ) // all adjacent shapes will be meshed by this algo?
     return true;
 
-  SMESH_Gen* gen =_father->GetGen();
-
   // only local algo is to be checked
   //if ( gen->IsGlobalHypothesis( theAlgo, *_father ))
   if ( _subShape.ShapeType() == _father->GetMeshDS()->ShapeToMesh().ShapeType() )
@@ -1305,7 +1228,7 @@ void SMESH_subMesh::cleanDependsOn( SMESH_Algo* algoRequiringCleaning/*=0*/ )
       if ( !sm->IsEmpty() )
       {
         const bool sameShapeType = ( prevShapeType == sm->GetSubShape().ShapeType() );
-        bool keepSubMeshes = ( sameShapeType && toKeepPrevShapeType );
+        bool       keepSubMeshes = ( sameShapeType && toKeepPrevShapeType );
         if ( !sameShapeType )
         {
           // check if the algo allows presence of global algos of dimension the algo
@@ -1328,7 +1251,7 @@ void SMESH_subMesh::cleanDependsOn( SMESH_Algo* algoRequiringCleaning/*=0*/ )
         // remember all sub-meshes of sm
         if ( keepSubMeshes )
         {
-          SMESH_subMeshIteratorPtr smIt2 = getDependsOnIterator(false,true);
+          SMESH_subMeshIteratorPtr smIt2 = getDependsOnIterator(false);
           while ( smIt2->more() )
             smToKeep.insert( smIt2->next() );
         }
@@ -1353,48 +1276,32 @@ void SMESH_subMesh::cleanDependsOn( SMESH_Algo* algoRequiringCleaning/*=0*/ )
 
 void SMESH_subMesh::DumpAlgoState(bool isMain)
 {
-  // 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 = " << SMESH_Gen::GetShapeDim(_subShape) <<
-                " type of shape " << _subShape.ShapeType());
-        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);
+    }
+  }
+  MESSAGE("dim = " << SMESH_Gen::GetShapeDim(_subShape) <<
+          " type of shape " << _subShape.ShapeType());
+  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;
+  }
 }
 
 //================================================================================
@@ -1861,10 +1768,13 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
       removeSubMeshElementsAndNodes();
       break;
     case SUBMESH_COMPUTED:      // allow retry compute
-      if (_algoState == HYP_OK)
-        _computeState = READY_TO_COMPUTE;
-      else
-        _computeState = NOT_READY;
+      if ( IsEmpty() ) // 23061
+      {
+        if (_algoState == HYP_OK)
+          _computeState = READY_TO_COMPUTE;
+        else
+          _computeState = NOT_READY;
+      }
       break;
     case SUBMESH_RESTORED:
       ComputeSubMeshStateEngine( SUBMESH_RESTORED );
@@ -1924,12 +1834,12 @@ bool SMESH_subMesh::Evaluate(MapShapeNbElems& aResMap)
   SMESH_Hypothesis::Hypothesis_Status hyp_status;
 
   algo = GetAlgo();
-  if(algo && !aResMap.count(this) )
+  if( algo && !aResMap.count( this ))
   {
     ret = algo->CheckHypothesis((*_father), _subShape, hyp_status);
     if (!ret) return false;
 
-    if (_father->HasShapeToMesh() && algo->NeedDiscreteBoundary())
+    if (_father->HasShapeToMesh() && algo->NeedDiscreteBoundary() )
     {
       // check submeshes needed
       bool subMeshEvaluated = true;
@@ -1947,8 +1857,23 @@ bool SMESH_subMesh::Evaluate(MapShapeNbElems& aResMap)
         return false;
     }
     _computeError = SMESH_ComputeError::New(COMPERR_OK,"",algo);
-    ret = algo->Evaluate((*_father), _subShape, aResMap);
 
+    if ( IsMeshComputed() )
+    {
+      vector<int> & nbEntities = aResMap[ this ];
+      nbEntities.resize( SMDSEntity_Last, 0 );
+      if ( SMESHDS_SubMesh* sm = GetSubMeshDS() )
+      {
+        nbEntities[ SMDSEntity_Node ] = sm->NbNodes();
+        SMDS_ElemIteratorPtr   elemIt = sm->GetElements();
+        while ( elemIt->more() )
+          nbEntities[ elemIt->next()->GetEntityType() ]++;
+      }
+    }
+    else
+    {
+      ret = algo->Evaluate((*_father), _subShape, aResMap);
+    }
     aResMap.insert( make_pair( this,vector<int>(0)));
   }
 
@@ -2077,11 +2002,10 @@ void SMESH_subMesh::updateDependantsState(const compute_event theEvent)
   }
 }
 
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
+//=======================================================================
+//function : cleanDependants
+//purpose  : 
+//=======================================================================
 
 void SMESH_subMesh::cleanDependants()
 {
@@ -2102,11 +2026,10 @@ void SMESH_subMesh::cleanDependants()
   }
 }
 
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
+//=======================================================================
+//function : removeSubMeshElementsAndNodes
+//purpose  : 
+//=======================================================================
 
 void SMESH_subMesh::removeSubMeshElementsAndNodes()
 {
@@ -2467,9 +2390,8 @@ 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 ))
+    SMESH_Mesh* mesh = _father->FindMesh( d->myMeshID );
+    if ( !mesh || !mesh->GetSubMeshContaining( d->mySubMeshID ))
       continue;
     d->mySubMesh->DeleteEventListener( d->myListener );
   }
@@ -2555,7 +2477,7 @@ namespace {
   {
     _Iterator(SMDS_Iterator<SMESH_subMesh*>* subIt,
               SMESH_subMesh*                 prepend,
-              SMESH_subMesh*                 append): myIt(subIt),myAppend(append)
+              SMESH_subMesh*                 append): myAppend(append), myIt(subIt)
     {
       myCur = prepend ? prepend : myIt->more() ? myIt->next() : append;
       if ( myCur == append ) append = 0;
@@ -2657,16 +2579,18 @@ void SMESH_subMesh::ClearAncestors()
  */
 //================================================================================
 
-bool SMESH_subMesh::FindIntersection(const SMESH_subMesh* theOther,
+bool SMESH_subMesh::FindIntersection(const SMESH_subMesh*            theOther,
                                      std::set<const SMESH_subMesh*>& theSetOfCommon ) const
 {
-  int oldNb = theSetOfCommon.size();
+  size_t 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++ )
index 6d38841e0c7b71ba81b0c06daec33dd06fccee1b..24152268d2cf593e54c4cb9c5bba92b2ca39553b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -81,6 +81,7 @@ class SMESH_EXPORT SMESH_subMesh
 
   const std::map < int, SMESH_subMesh * >& DependsOn();
   bool DependsOn( const SMESH_subMesh* other ) const;
+  bool DependsOn( const int shapeID ) const;
   /*!
    * \brief Return iterator on the sub-meshes this one depends on. By default
    *        most simple sub-meshes go first.
@@ -280,7 +281,7 @@ public:
 
 protected:
   // ==================================================================
-  void insertDependence(const TopoDS_Shape aSubShape);
+  void insertDependence(const TopoDS_Shape aShape, TopAbs_ShapeEnum aSubType );
 
   void removeSubMeshElementsAndNodes();
   void updateDependantsState(const compute_event theEvent);
@@ -327,7 +328,7 @@ protected:
   int                   _Id;
 
   std::map < int, SMESH_subMesh * >_mapDepend;
-  bool                  _dependenceAnalysed;
+  bool                             _dependenceAnalysed;
   std::vector< SMESH_subMesh * >   _ancestors;
 
   SMESH_Algo *          _algo; // the algorithm found by last *StateEngine() call
index bccc5d073b129c7971cf15ad56db8683aad72a24..d5bfe5cfcaf90040ea0b9c5b00771347f23ae3c8 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index dc34dc2b5f5584a2e5749984550a215ae7c4418c..fe08e6124cb7136b5c13705d7a4029eeabd99e05 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2010-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2010-2015  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
index 24642b4f405e25ce551eb871e5a5f2bc18a99517..f0efeb624fee006e3d211e53d1dc9b8f89e8da2a 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2012-2015  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
index 25674a35298ccc732348ba295d1f3f903d59d934..1f7cd4f98fb2cdf71a9e3357a285804974eac0e1 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index d25d800d7e57cc5e669358e470d020371bdb4004..4c9cac3534e341d87df515339a2e1079962cc1db 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -90,7 +90,7 @@ namespace
     const SMESH::double_array& aCoords = theSeq[theId].coords;
     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
     CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
-    if(3*aNbElems != aCoords.length())
+    if(3*aNbElems != (CORBA::Long) aCoords.length())
       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],
@@ -112,7 +112,7 @@ namespace
   {
     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
     CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
-    if (2*aNbElems != anIndexes.length())
+    if (2*aNbElems != (CORBA::Long) anIndexes.length())
       EXCEPTION(runtime_error,"AddEdgeWithID - 2*aNbElems != aCoords.length()");
     CORBA::Long anIndexId = 0;
     for (; anElemId < aNbElems; anElemId++, anIndexId+=2)
@@ -135,9 +135,9 @@ namespace
     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() )
+    if (2*aNbElems != (CORBA::Long) anIndexes.length() )
       EXCEPTION(runtime_error,"AddEdgeWithID - 2*aNbElems != anIndexes.length()");
-    if (aNbElems != aDiameter.length())
+    if (aNbElems != (CORBA::Long) aDiameter.length())
       EXCEPTION(runtime_error,"AddEdgeWithID - aNbElems != aDiameter.length()");
     CORBA::Long anIndexId = 0;
     for (; anElemId < aNbElems; anElemId++, anIndexId+=2)
@@ -160,7 +160,7 @@ namespace
   {
     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
     CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
-    if(3*aNbElems != anIndexes.length())
+    if(3*aNbElems != (CORBA::Long) anIndexes.length())
       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],
@@ -181,7 +181,7 @@ namespace
   {
     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
     CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
-    if(4*aNbElems != anIndexes.length())
+    if(4*aNbElems != (CORBA::Long) anIndexes.length())
       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],
@@ -203,7 +203,7 @@ namespace
   {
     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
     CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
-    if(5*aNbElems != anIndexes.length())
+    if(5*aNbElems != (CORBA::Long) anIndexes.length())
       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],
@@ -244,6 +244,33 @@ namespace
   }
 
 
+  //=======================================================================
+  //function : AddQaudPolygonsWithID
+  //=======================================================================
+  inline void AddQuadPolygonsWithID(SMDS_Mesh* theMesh,
+                                    SMESH::log_array_var& theSeq,
+                                    CORBA::Long theId)
+  {
+    const SMESH::long_array& anIndexes = theSeq[theId].indexes;
+    CORBA::Long anIndexId = 0, aNbElems = theSeq[theId].number;
+
+    for (CORBA::Long anElemId = 0; anElemId < aNbElems; anElemId++) {
+      int aFaceId = anIndexes[anIndexId++];
+
+      int aNbNodes = anIndexes[anIndexId++];
+      std::vector<int> nodes_ids (aNbNodes);
+      for (int i = 0; i < aNbNodes; i++) {
+        nodes_ids[i] = anIndexes[anIndexId++];
+      }
+
+      SMDS_MeshElement* anElem = theMesh->AddQuadPolygonalFaceWithID(nodes_ids, aFaceId);
+      if (!anElem)
+        EXCEPTION(runtime_error, "SMDS_Mesh::FindElement - cannot AddQaudPolygonalFaceWithID for ID = "
+                  << anElemId);
+    }
+  }
+
+
   //=======================================================================
   //function : AddTetrasWithID
   //=======================================================================
@@ -253,7 +280,7 @@ namespace
   {
     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
     CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
-    if(5*aNbElems != anIndexes.length())
+    if(5*aNbElems != (CORBA::Long) anIndexes.length())
       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],
@@ -276,7 +303,7 @@ namespace
   {
     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
     CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
-    if(6*aNbElems != anIndexes.length())
+    if(6*aNbElems != (CORBA::Long) anIndexes.length())
       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],
@@ -300,7 +327,7 @@ namespace
   {
     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
     CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
-    if(7*aNbElems != anIndexes.length())
+    if(7*aNbElems != (CORBA::Long) anIndexes.length())
       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],
@@ -325,7 +352,7 @@ namespace
   {
     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
     CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
-    if(9*aNbElems != anIndexes.length())
+    if(9*aNbElems != (CORBA::Long) anIndexes.length())
       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],
@@ -351,7 +378,7 @@ namespace
   {
     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
     CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
-    if(13*aNbElems != anIndexes.length())
+    if(13*aNbElems != (CORBA::Long) 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],
@@ -416,7 +443,7 @@ namespace
   {
     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
     CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
-    if(4*aNbElems != anIndexes.length())
+    if(4*aNbElems != (CORBA::Long) anIndexes.length())
       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],
@@ -438,7 +465,7 @@ namespace
   {
     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
     CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
-    if(7*aNbElems != anIndexes.length())
+    if(7*aNbElems != (CORBA::Long) anIndexes.length())
       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],
@@ -463,7 +490,7 @@ namespace
   {
     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
     CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
-    if(9*aNbElems != anIndexes.length())
+    if(9*aNbElems != (CORBA::Long) anIndexes.length())
       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],
@@ -489,7 +516,7 @@ namespace
   {
     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
     CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
-    if(10*aNbElems != anIndexes.length())
+    if(10*aNbElems != (CORBA::Long) 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],
@@ -516,7 +543,7 @@ namespace
   {
     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
     CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
-    if(8*aNbElems != anIndexes.length())
+    if(8*aNbElems != (CORBA::Long) anIndexes.length())
       EXCEPTION(runtime_error,"AddBiQuadTriasWithID - 8*aNbElems != anIndexes.length()");
     for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=8){
       SMDS_MeshElement* anElem = theMesh->AddFaceWithID(anIndexes[anIndexId+1],
@@ -542,7 +569,7 @@ namespace
   {
     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
     CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
-    if(11*aNbElems != anIndexes.length())
+    if(11*aNbElems != (CORBA::Long) anIndexes.length())
       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],
@@ -571,7 +598,7 @@ namespace
   {
     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
     CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
-    if(14*aNbElems != anIndexes.length())
+    if(14*aNbElems != (CORBA::Long) anIndexes.length())
       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],
@@ -603,7 +630,7 @@ namespace
   {
     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
     CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
-    if(16*aNbElems != anIndexes.length())
+    if(16*aNbElems != (CORBA::Long) anIndexes.length())
       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],
@@ -637,7 +664,7 @@ namespace
   {
     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
     CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
-    if(21*aNbElems != anIndexes.length())
+    if(21*aNbElems != (CORBA::Long) anIndexes.length())
       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],
@@ -675,7 +702,7 @@ namespace
   {
     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
     CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
-    if(28*aNbElems != anIndexes.length())
+    if(28*aNbElems != (CORBA::Long) 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],
@@ -903,6 +930,7 @@ SMESH_Client::Update(bool theIsClear)
         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_QUADPOLYGON      : AddQuadPolygonsWithID( 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;
index 975885369f67b248c9d7ad95da063ad7a6385074..daa3e036d2b629ee5ff5508736b63579d9687e64 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index f5fb89fbe01208633349a398c5b428c15726b481..c3f1530592cb09796a0c50f54deba6822b5b118a 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2012-2015  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
index b3f05171f49d96e6975391416640651be7aad17e..b22079e6af166b84198e8a08d1352f743959a744 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -54,7 +54,7 @@ SMESHDS_Command::~SMESHDS_Command()
 //=======================================================================
 void SMESHDS_Command::AddNode(int NewNodeID, double x, double y, double z)
 {
-        if (!myType == SMESHDS_AddNode)
+        if ( myType != SMESHDS_AddNode)
         {
                 MESSAGE("SMESHDS_Command::AddNode : Bad Type");
                 return;
@@ -72,7 +72,7 @@ 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)
+        if ( myType != SMESHDS_MoveNode)
         {
                 MESSAGE("SMESHDS_Command::MoveNode : Bad Type");
                 return;
@@ -90,7 +90,7 @@ void SMESHDS_Command::MoveNode(int NodeID, double x, double y, double z)
 //=======================================================================
 void SMESHDS_Command::Add0DElement(int New0DElementID, int idnode)
 {
-  if (!myType == SMESHDS_Add0DElement)
+  if ( myType != SMESHDS_Add0DElement)
   {
     MESSAGE("SMESHDS_Command::Add0DElement : Bad Type");
     return;
@@ -106,7 +106,7 @@ void SMESHDS_Command::Add0DElement(int New0DElementID, int idnode)
 //=======================================================================
 void SMESHDS_Command::AddEdge(int NewEdgeID, int idnode1, int idnode2)
 {
-        if (!myType == SMESHDS_AddEdge)
+        if ( myType != SMESHDS_AddEdge)
         {
                 MESSAGE("SMESHDS_Command::AddEdge : Bad Type");
                 return;
@@ -124,7 +124,7 @@ void SMESHDS_Command::AddEdge(int NewEdgeID, int idnode1, int idnode2)
 void SMESHDS_Command::AddFace(int NewFaceID,
         int idnode1, int idnode2, int idnode3)
 {
-        if (!myType == SMESHDS_AddTriangle)
+        if ( myType != SMESHDS_AddTriangle)
         {
                 MESSAGE("SMESHDS_Command::AddFace : Bad Type");
                 return;
@@ -143,7 +143,7 @@ void SMESHDS_Command::AddFace(int NewFaceID,
 void SMESHDS_Command::AddFace(int NewFaceID,
         int idnode1, int idnode2, int idnode3, int idnode4)
 {
-        if (!myType == SMESHDS_AddQuadrangle)
+        if ( myType != SMESHDS_AddQuadrangle)
         {
                 MESSAGE("SMESHDS_Command::AddFace : Bad Type");
                 return;
@@ -163,7 +163,7 @@ void SMESHDS_Command::AddFace(int NewFaceID,
 void SMESHDS_Command::AddVolume(int NewVolID,
         int idnode1, int idnode2, int idnode3, int idnode4)
 {
-        if (!myType == SMESHDS_AddTetrahedron)
+        if ( myType != SMESHDS_AddTetrahedron)
         {
                 MESSAGE("SMESHDS_Command::AddVolume : Bad Type");
                 return;
@@ -183,7 +183,7 @@ void SMESHDS_Command::AddVolume(int NewVolID,
 void SMESHDS_Command::AddVolume(int NewVolID,
         int idnode1, int idnode2, int idnode3, int idnode4, int idnode5)
 {
-        if (!myType == SMESHDS_AddPyramid)
+        if ( myType != SMESHDS_AddPyramid)
         {
                 MESSAGE("SMESHDS_Command::AddVolume : Bad Type");
                 return;
@@ -205,7 +205,7 @@ void SMESHDS_Command::AddVolume(int NewVolID,
         int idnode1,
         int idnode2, int idnode3, int idnode4, int idnode5, int idnode6)
 {
-        if (!myType == SMESHDS_AddPrism)
+        if ( myType != SMESHDS_AddPrism)
         {
                 MESSAGE("SMESHDS_Command::AddVolume : Bad Type");
                 return;
@@ -230,7 +230,7 @@ void SMESHDS_Command::AddVolume(int NewVolID,
         int idnode3,
         int idnode4, int idnode5, int idnode6, int idnode7, int idnode8)
 {
-        if (!myType == SMESHDS_AddHexahedron)
+        if ( myType != SMESHDS_AddHexahedron)
         {
                 MESSAGE("SMESHDS_Command::AddVolume : Bad Type");
                 return;
@@ -280,7 +280,7 @@ void SMESHDS_Command::AddVolume(int NewVolID,
 void SMESHDS_Command::AddPolygonalFace (const int               ElementID,
                                         const std::vector<int>& nodes_ids)
 {
-  if (!myType == SMESHDS_AddPolygon) {
+  if ( myType != SMESHDS_AddPolygon) {
     MESSAGE("SMESHDS_Command::AddPolygonalFace : Bad Type");
     return;
   }
@@ -295,6 +295,28 @@ void SMESHDS_Command::AddPolygonalFace (const int               ElementID,
   myNumber++;
 }
 
+//=======================================================================
+//function : AddQuadPolygonalFace
+//purpose  :
+//=======================================================================
+void SMESHDS_Command::AddQuadPolygonalFace (const int               ElementID,
+                                            const std::vector<int>& nodes_ids)
+{
+  if ( myType != SMESHDS_AddQuadPolygon) {
+    MESSAGE("SMESHDS_Command::AddQuadraticPolygonalFace : Bad Type");
+    return;
+  }
+  myIntegers.push_back(ElementID);
+
+  int i, nbNodes = nodes_ids.size();
+  myIntegers.push_back(nbNodes);
+  for (i = 0; i < nbNodes; i++) {
+    myIntegers.push_back(nodes_ids[i]);
+  }
+
+  myNumber++;
+}
+
 //=======================================================================
 //function : AddPolyhedralVolume
 //purpose  : 
@@ -303,7 +325,7 @@ void SMESHDS_Command::AddPolyhedralVolume (const int               ElementID,
                                            const std::vector<int>& nodes_ids,
                                            const std::vector<int>& quantities)
 {
-  if (!myType == SMESHDS_AddPolyhedron) {
+  if ( myType != SMESHDS_AddPolyhedron) {
     MESSAGE("SMESHDS_Command::AddPolyhedralVolume : Bad Type");
     return;
   }
@@ -330,7 +352,7 @@ void SMESHDS_Command::AddPolyhedralVolume (const int               ElementID,
 //=======================================================================
 void SMESHDS_Command::RemoveNode(int NodeID)
 {
-        if (!myType == SMESHDS_RemoveNode)
+        if ( myType != SMESHDS_RemoveNode)
         {
                 MESSAGE("SMESHDS_Command::RemoveNode : Bad Type");
                 return;
@@ -345,7 +367,7 @@ void SMESHDS_Command::RemoveNode(int NodeID)
 //=======================================================================
 void SMESHDS_Command::RemoveElement(int ElementID)
 {
-        if (!myType == SMESHDS_RemoveElement)
+        if ( myType != SMESHDS_RemoveElement)
         {
                 MESSAGE("SMESHDS_Command::RemoveElement : Bad Type");
                 return;
@@ -361,7 +383,7 @@ void SMESHDS_Command::RemoveElement(int ElementID)
 
 void SMESHDS_Command::ChangeElementNodes(int ElementID, int nodes[], int nbnodes)
 {
-  if (!myType == SMESHDS_ChangeElementNodes)
+  if ( myType != SMESHDS_ChangeElementNodes)
   {
     MESSAGE("SMESHDS_Command::ChangeElementNodes : Bad Type");
     return;
@@ -411,7 +433,7 @@ void SMESHDS_Command::ChangePolyhedronNodes (const int               ElementID,
 
 void SMESHDS_Command::Renumber (const bool isNodes, const int startID, const int deltaID)
 {
-  if (!myType == SMESHDS_Renumber)
+  if ( myType != SMESHDS_Renumber)
   {
     MESSAGE("SMESHDS_Command::Renumber : Bad Type");
     return;
@@ -469,7 +491,7 @@ const list < double >&SMESHDS_Command::GetCoords()
 //=======================================================================
 void SMESHDS_Command::AddEdge(int NewEdgeID, int n1, int n2, int n12)
 {
-  if (!myType == SMESHDS_AddQuadEdge) {
+  if ( myType != SMESHDS_AddQuadEdge) {
     MESSAGE("SMESHDS_Command::AddEdge : Bad Type");
     return;
   }
@@ -488,7 +510,7 @@ void SMESHDS_Command::AddFace(int NewFaceID,
                               int n1, int n2, int n3,
                               int n12, int n23, int n31)
 {
-  if (!myType == SMESHDS_AddQuadTriangle) {
+  if ( myType != SMESHDS_AddQuadTriangle) {
     MESSAGE("SMESHDS_Command::AddFace : Bad Type");
     return;
   }
@@ -510,7 +532,7 @@ void SMESHDS_Command::AddFace(int NewFaceID,
                               int n1, int n2, int n3,
                               int n12, int n23, int n31, int nCenter)
 {
-  if (!myType == SMESHDS_AddBiQuadTriangle) {
+  if ( myType != SMESHDS_AddBiQuadTriangle) {
     MESSAGE("SMESHDS_Command::AddFace : Bad Type");
     return;
   }
@@ -533,7 +555,7 @@ void SMESHDS_Command::AddFace(int NewFaceID,
                               int n1, int n2, int n3, int n4,
                               int n12, int n23, int n34, int n41)
 {
-  if (!myType == SMESHDS_AddQuadQuadrangle) {
+  if ( myType != SMESHDS_AddQuadQuadrangle) {
     MESSAGE("SMESHDS_Command::AddFace : Bad Type");
     return;
   }
@@ -582,7 +604,7 @@ void SMESHDS_Command::AddVolume(int NewVolID, int n1, int n2, int n3, int n4,
                                 int n12, int n23, int n31,
                                 int n14, int n24, int n34)
 {
-  if (!myType == SMESHDS_AddQuadTetrahedron) {
+  if ( myType != SMESHDS_AddQuadTetrahedron) {
     MESSAGE("SMESHDS_Command::AddVolume : Bad Type");
     return;
   }
@@ -609,7 +631,7 @@ void SMESHDS_Command::AddVolume(int NewVolID, int n1, int n2,
                                 int n12, int n23, int n34, int n41,
                                 int n15, int n25, int n35, int n45)
 {
-  if (!myType == SMESHDS_AddQuadPyramid) {
+  if ( myType != SMESHDS_AddQuadPyramid) {
     MESSAGE("SMESHDS_Command::AddVolume : Bad Type");
     return;
   }
@@ -640,7 +662,7 @@ void SMESHDS_Command::AddVolume(int NewVolID, int n1, int n2,
                                 int n45, int n56, int n64,
                                 int n14, int n25, int n36)
 {
-  if (!myType == SMESHDS_AddQuadPentahedron) {
+  if ( myType != SMESHDS_AddQuadPentahedron) {
     MESSAGE("SMESHDS_Command::AddVolume : Bad Type");
     return;
   }
@@ -673,7 +695,7 @@ void SMESHDS_Command::AddVolume(int NewVolID, int n1, int n2, int n3,
                                 int n56, int n67, int n78, int n85,
                                 int n15, int n26, int n37, int n48)
 {
-  if (!myType == SMESHDS_AddQuadHexahedron) {
+  if ( myType != SMESHDS_AddQuadHexahedron) {
     MESSAGE("SMESHDS_Command::AddVolume : Bad Type");
     return;
   }
@@ -713,7 +735,7 @@ void SMESHDS_Command::AddVolume(int NewVolID, int n1, int n2, int n3,
                                 int n1234,int n1256,int n2367,int n3478,
                                 int n1458,int n5678,int nCenter)
 {
-  if (!myType == SMESHDS_AddQuadHexahedron) {
+  if ( myType != SMESHDS_AddQuadHexahedron) {
     MESSAGE("SMESHDS_Command::AddVolume : Bad Type");
     return;
   }
@@ -756,7 +778,7 @@ void SMESHDS_Command::AddVolume(int NewVolID, int n1, int n2, int n3,
 
 void SMESHDS_Command::AddBall(int NewBallID, int node, double diameter)
 {
-  if (!myType == SMESHDS_AddBall)
+  if ( myType != SMESHDS_AddBall)
   {
     MESSAGE("SMESHDS_Command::SMESHDS_AddBall : Bad Type");
     return;
index 7b5349b10c80e513db2ba2003977ad177acc7774..583cebe4a3a9e62b589c485257955862dd8afc56 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -57,6 +57,8 @@ class SMESHDS_EXPORT SMESHDS_Command
                        int idnode9, int idnode10, int idnode11, int idnode12);
         void AddPolygonalFace (const int               ElementID,
                                const std::vector<int>& nodes_ids);
+        void AddQuadPolygonalFace (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);
index e737f5f02c0905e7533df01b42ee3d3bb9d0b6ab..c355386e54d9f508cbaaff717bde02ef51a026b7 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -49,6 +49,7 @@ enum SMESHDS_CommandType {
   SMESHDS_AddQuadEdge,
   SMESHDS_AddQuadTriangle,
   SMESHDS_AddQuadQuadrangle,
+  SMESHDS_AddQuadPolygon,
   SMESHDS_AddQuadTetrahedron,
   SMESHDS_AddQuadPyramid,
   SMESHDS_AddQuadPentahedron,
index 21bb5a1e53a3dc5879e28e594a47ea78a212825c..3e083cd84d78709d8551779359898c846308fb46 100755 (executable)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 93fbc5ec0768e919dacffe3f66cfccc2faba5c50..98c9b494c8320440fe2ad5a8ab06c6ea8b08bd34 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -68,22 +68,22 @@ SMESHDS_Mesh * SMESHDS_Document::NewMesh(bool theIsEmbeddedMode, int MeshID)
 
 //=======================================================================
 //function : GetMesh
-//purpose  : 
+//purpose  :
 //=======================================================================
 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;
 }
 
 //=======================================================================
 //function : RemoveMesh
-//purpose  : 
+//purpose  :
 //=======================================================================
 void SMESHDS_Document::RemoveMesh(int MeshID)
 {
@@ -107,99 +107,99 @@ 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;
 }
 
 //=======================================================================
 //function : RemoveHypothesis
-//purpose  : 
+//purpose  :
 //=======================================================================
 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);
 }
 
 //=======================================================================
 //function : NbMeshes
-//purpose  : 
+//purpose  :
 //=======================================================================
 int SMESHDS_Document::NbMeshes()
 {
-        return myMeshes.size();
+  return myMeshes.size();
 }
 
 //=======================================================================
 //function : NbHypothesis
-//purpose  : 
+//purpose  :
 //=======================================================================
 int SMESHDS_Document::NbHypothesis()
 {
-        return myHypothesis.size();
+  return myHypothesis.size();
 }
 
 //=======================================================================
 //function : InitMeshesIterator
-//purpose  : 
+//purpose  :
 //=======================================================================
 void SMESHDS_Document::InitMeshesIterator()
 {
-        myMeshesIt=myMeshes.begin();
+  myMeshesIt=myMeshes.begin();
 }
 
 //=======================================================================
 //function : NextMesh
-//purpose  : 
+//purpose  :
 //=======================================================================
 SMESHDS_Mesh * SMESHDS_Document::NextMesh()
 {
-        SMESHDS_Mesh * toReturn=(*myMeshesIt).second;
-        myMeshesIt++;
-        return toReturn;
+  SMESHDS_Mesh * toReturn=(*myMeshesIt).second;
+  myMeshesIt++;
+  return toReturn;
 }
 
 //=======================================================================
 //function : MoreMesh
-//purpose  : 
+//purpose  :
 //=======================================================================
 bool SMESHDS_Document::MoreMesh()
 {
-        return myMeshesIt!=myMeshes.end();
+  return myMeshesIt!=myMeshes.end();
 }
 
 //=======================================================================
 //function : InitHypothesisIterator
-//purpose  : 
+//purpose  :
 //=======================================================================
 void SMESHDS_Document::InitHypothesisIterator()
 {
-        myHypothesisIt=myHypothesis.begin();
+  myHypothesisIt=myHypothesis.begin();
 }
 
 //=======================================================================
 //function : NextMesh
-//purpose  : 
+//purpose  :
 //=======================================================================
 SMESHDS_Hypothesis * SMESHDS_Document::NextHypothesis()
 {
-        SMESHDS_Hypothesis * toReturn=(*myHypothesisIt).second;
-        myHypothesisIt++;
-        return toReturn;
+  SMESHDS_Hypothesis * toReturn=(*myHypothesisIt).second;
+  myHypothesisIt++;
+  return toReturn;
 }
 
 //=======================================================================
 //function : MoreMesh
-//purpose  : 
+//purpose  :
 //=======================================================================
 bool SMESHDS_Document::MoreHypothesis()
 {
-        return myHypothesisIt!=myHypothesis.end();
+  return myHypothesisIt!=myHypothesis.end();
 }
index 86f68cddca8f1f4fcefc30edd71641bef5f1db39..9143fb36489eac43eef8287ca812b3cd9f7adf70 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index ce85efa339ff3c89dac055c4b8d4f42824a0b45c..6e30e008bbed413e832c4a03e955b62f00ab1a10 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -98,7 +98,17 @@ bool SMESHDS_Group::Contains (const SMDS_MeshElement* elem)
 
 bool SMESHDS_Group::Add (const int theID)
 {
-  const SMDS_MeshElement* aElem = findInMesh (theID);
+  return Add( findInMesh( theID ));
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+bool SMESHDS_Group::Add (const SMDS_MeshElement* aElem )
+{
   if (!aElem || myGroup.Contains(aElem))
     return false;
 
index c6998c99e856aebe1097d59d37f3bce32e240e6f..08ff29bacfb0283d9988597f0006c48dda814272 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -60,6 +60,8 @@ class SMESHDS_EXPORT SMESHDS_Group : public SMESHDS_GroupBase
 
   bool Add (const int theID);
 
+  bool Add (const SMDS_MeshElement* theElem );
+
   bool Remove (const int theID);
 
   void Clear();
index d1b0d6ecdf94e904038c545cf04e8b8d02e7fa2c..ef2f2de4a5c5e1c76b7900f9c6cc40f9d19093bb 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&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,6 +32,8 @@
 
 using namespace std;
 
+Quantity_Color SMESHDS_GroupBase::myDefaultColor = Quantity_Color( 0.0, 0.0, 0.0, Quantity_TOC_RGB );
+
 //=============================================================================
 /*!
  *  
@@ -44,7 +46,7 @@ SMESHDS_GroupBase::SMESHDS_GroupBase (const int                 theID,
        myID(theID), myMesh(theMesh), myType(theType), myStoreName(""),
        myCurIndex(0), myCurID(-1)
 {
-  myColor = Quantity_Color( 0.0, 0.0, 0.0, Quantity_TOC_RGB );
+  myColor = myDefaultColor;
 }
 
 //=============================================================================
index c00887858eef27098c7efda73cb8bcac012cdd09..305ecb8c08a2ec6d0713f6f3a3d77001ccdc56b7 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -85,6 +85,9 @@ class SMESHDS_EXPORT SMESHDS_GroupBase
 
   int GetColorGroup() const;
   
+  static void SetDefaultColor (const Quantity_Color& theColor)
+  { myDefaultColor = theColor;}
+
  protected:
   const SMDS_MeshElement* findInMesh (const int theID) const;
   void resetIterator();
@@ -105,6 +108,8 @@ class SMESHDS_EXPORT SMESHDS_GroupBase
   int                  myCurIndex;
   int                  myCurID;
   SMDS_ElemIteratorPtr myIterator;
+
+  static Quantity_Color myDefaultColor;
 };
 
 #endif
index e26bfa7e00157901fb64ad81be003aba4dd2b460..23c14e996ec36cf166c43e15970aa2f74599d0bc 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index b45e600ec1ccc60c29fa23a1fbe4413d267617fc..eaa67397b02353ca17b5652615cd8567a14c30f2 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 78fd1440ecc67d4151f85bb60e58458f09ab220a..6f68e8d22c9c142744e4c5bf5e028174762fa964 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index b29b1a5864866ab8eedcbc201ddd6e62e5c326d4..7807021395ef2ec4a11b4db0dd305cc0d4d67439 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 6e43761420178a48e273f7dfc0497630bcce3a51..930975074fc40a9675c9c17bda7d5b4a52bb0135 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 5e416504834d9582264fc45adfbd2bfa7422362a..26a66c3a276b44af08e0f30b8e7d04bb696eba59 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index ff1da64b0e784bb9bcca13e5743caedd89ff4b3a..a66f4482fe5a0f7c4523187dd12c57e5fa7c0815 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -213,7 +213,7 @@ void SMESHDS_Mesh::MoveNode(const SMDS_MeshNode *n, double x, double y, double z
 
 //=======================================================================
 //function : ChangeElementNodes
-//purpose  : 
+//purpose  : Changed nodes of an element provided that nb of nodes does not change
 //=======================================================================
 
 bool SMESHDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem,
@@ -708,9 +708,9 @@ SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID (const std::vector<int>& nod
   return anElem;
 }
 
-SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID
-                             (const std::vector<const SMDS_MeshNode*>& nodes,
-                              const int                                ID)
+SMDS_MeshFace*
+SMESHDS_Mesh::AddPolygonalFaceWithID (const std::vector<const SMDS_MeshNode*>& nodes,
+                                      const int                                ID)
 {
   SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
   if (anElem) {
@@ -724,8 +724,8 @@ SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID
   return anElem;
 }
 
-SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFace
-                             (const std::vector<const SMDS_MeshNode*>& nodes)
+SMDS_MeshFace*
+SMESHDS_Mesh::AddPolygonalFace (const std::vector<const SMDS_MeshNode*>& nodes)
 {
   SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFace(nodes);
   if (anElem) {
@@ -739,6 +739,53 @@ SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFace
   return anElem;
 }
 
+
+//=======================================================================
+//function : AddQuadPolygonalFace
+//purpose  : 
+//=======================================================================
+SMDS_MeshFace* SMESHDS_Mesh::AddQuadPolygonalFaceWithID (const std::vector<int>& nodes_ids,
+                                                         const int               ID)
+{
+  SMDS_MeshFace *anElem = SMDS_Mesh::AddQuadPolygonalFaceWithID(nodes_ids, ID);
+  if (anElem) {
+    myScript->AddQuadPolygonalFace(ID, nodes_ids);
+  }
+  return anElem;
+}
+
+SMDS_MeshFace*
+SMESHDS_Mesh::AddQuadPolygonalFaceWithID (const std::vector<const SMDS_MeshNode*>& nodes,
+                                          const int                                ID)
+{
+  SMDS_MeshFace *anElem = SMDS_Mesh::AddQuadPolygonalFaceWithID(nodes, ID);
+  if (anElem) {
+    int i, len = nodes.size();
+    std::vector<int> nodes_ids (len);
+    for (i = 0; i < len; i++) {
+      nodes_ids[i] = nodes[i]->GetID();
+    }
+    myScript->AddQuadPolygonalFace(ID, nodes_ids);
+  }
+  return anElem;
+}
+
+SMDS_MeshFace*
+SMESHDS_Mesh::AddQuadPolygonalFace (const std::vector<const SMDS_MeshNode*>& nodes)
+{
+  SMDS_MeshFace *anElem = SMDS_Mesh::AddQuadPolygonalFace(nodes);
+  if (anElem) {
+    int i, len = nodes.size();
+    std::vector<int> nodes_ids (len);
+    for (i = 0; i < len; i++) {
+      nodes_ids[i] = nodes[i]->GetID();
+    }
+    myScript->AddQuadPolygonalFace(anElem->GetID(), nodes_ids);
+  }
+  return anElem;
+}
+
+
 //=======================================================================
 //function : AddPolyhedralVolume
 //purpose  : 
@@ -918,7 +965,7 @@ void SMESHDS_Mesh::RemoveElement(const SMDS_MeshElement * elt)
     if ( elt->getshapeId() > 0 )
       subMesh = MeshElements( elt->getshapeId() );
 
-    RemoveFreeElement( elt, subMesh, true);
+    RemoveFreeElement( elt, subMesh, true );
     return;
   }
  
@@ -927,7 +974,7 @@ void SMESHDS_Mesh::RemoveElement(const SMDS_MeshElement * elt)
   list<const SMDS_MeshElement *> removedElems;
   list<const SMDS_MeshElement *> removedNodes;
 
-  SMDS_Mesh::RemoveElement(elt, removedElems, removedNodes, false);
+  SMDS_Mesh::RemoveElement(elt, removedElems, removedNodes, false );
   
   removeFromContainers( this, myGroups, removedElems, false );
 }
@@ -953,7 +1000,7 @@ void SMESHDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elt,
   myScript->RemoveElement(elt->GetID());
 
   // Rm from group
-  // Node can belong to several groups
+  // Element can belong to several groups
   if ( fromGroups && !myGroups.empty() ) {
     set<SMESHDS_GroupBase*>::iterator GrIt = myGroups.begin();
     for (; GrIt != myGroups.end(); GrIt++) {
@@ -965,10 +1012,12 @@ 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, /*deleted=*/false);
+  if ( !subMesh && elt->getshapeId() > 0 )
+    subMesh = MeshElements( elt->getshapeId() );
+  if ( subMesh )
+    subMesh->RemoveElement( elt, /*deleted=*/false );
 
-  SMDS_Mesh::RemoveFreeElement(elt);
+  SMDS_Mesh::RemoveFreeElement( elt );
 }
 
 //================================================================================
index e51df85d098d56f7c31578fc02615d4ed4b2f9a0..6ec2d3d9cabf5c1438c63fbcf0cb005cbcb8a79c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -511,6 +511,14 @@ public:
 
   virtual SMDS_MeshFace* AddPolygonalFace (const std::vector<const SMDS_MeshNode*>& nodes);
 
+  virtual SMDS_MeshFace* AddQuadPolygonalFaceWithID(const std::vector<int> & nodes_ids,
+                                                    const int                ID);
+
+  virtual SMDS_MeshFace* AddQuadPolygonalFaceWithID(const std::vector<const SMDS_MeshNode*> & nodes,
+                                                    const int                                 ID);
+
+  virtual SMDS_MeshFace* AddQuadPolygonalFace(const std::vector<const SMDS_MeshNode*> & nodes);
+
   virtual SMDS_MeshVolume* AddPolyhedralVolumeWithID
                            (const std::vector<int>& nodes_ids,
                             const std::vector<int>& quantities,
index 1c7c383981ece40cf9c5f6726b97b432aab5b9aa..e01109c3f254c9fc4909dc62614f43b74c32881e 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -255,6 +255,19 @@ void SMESHDS_Script::AddPolygonalFace (int NewFaceID, const std::vector<int>& no
   getCommand(SMESHDS_AddPolygon)->AddPolygonalFace(NewFaceID, nodes_ids);
 }
 
+//=======================================================================
+//function : AddQuadPolygonalFace
+//purpose  : 
+//=======================================================================
+void SMESHDS_Script::AddQuadPolygonalFace(int NewFaceID, const std::vector<int>& nodes_ids)
+{
+  if(myIsEmbeddedMode){
+    myIsModified = true;
+    return;
+  }
+  getCommand(SMESHDS_AddQuadPolygon)->AddQuadPolygonalFace(NewFaceID, nodes_ids);
+}
+
 //=======================================================================
 //function : AddPolyhedralVolume
 //purpose  : 
index ca71dd5d82b4502fcd4e319fb380edf69a0d52a7..3401ca6acd5cfc18d8bf07bc5693d77af02617cd 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -64,6 +64,8 @@ class SMESHDS_EXPORT SMESHDS_Script
 
         void AddPolygonalFace (const int               NewFaceID,
                                const std::vector<int>& nodes_ids);
+        void AddQuadPolygonalFace (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);
index 915ab0cdcb2278bb7ae32e840e9c6d3dd1ee62f5..32f89c9a62983ed7a61ef996cef37494967aec95 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -46,8 +46,6 @@ using namespace std;
 SMESHDS_SubMesh::SMESHDS_SubMesh(SMESHDS_Mesh *parent, int index)
 {
   myParent = parent;
-  myElements.clear();
-  myNodes.clear();
   myIndex = index;
   myUnusedIdNodes = 0;
   myUnusedIdElements = 0;
@@ -65,61 +63,54 @@ SMESHDS_SubMesh::~SMESHDS_SubMesh()
 
 //=======================================================================
 //function : AddElement
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 void SMESHDS_SubMesh::AddElement(const SMDS_MeshElement * ME)
 {
   if (!IsComplexSubmesh())
+  {
+    if ( ME->GetType() == SMDSAbs_Node )
+    {
+      AddNode( static_cast< const SMDS_MeshNode* >( ME ));
+      return;
+    }
+    int oldShapeId = ME->getshapeId();
+    if ( oldShapeId > 0 )
     {
-      if ( ME->GetType() == SMDSAbs_Node )
+      if (oldShapeId != myIndex)
       {
-        AddNode( static_cast< const SMDS_MeshNode* >( ME ));
-        return;
+        throw SALOME_Exception
+          (LOCALIZED("add element in subshape already belonging to a subshape"));
       }
-      int oldShapeId = ME->getshapeId();
-      if ( oldShapeId > 0 )
+      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 >= (int)myElements.size())
         {
-          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;
-                }
-            }
+          throw SALOME_Exception(LOCALIZED("out of bounds"));
         }
-
-      SMDS_MeshElement* elem = (SMDS_MeshElement*) (ME);
-      elem->setShapeId(myIndex);
-      elem->setIdInShape(myElements.size());
-      myElements.push_back(ME);
+        if (ME != myElements[idInSubShape])
+        {
+          throw SALOME_Exception(LOCALIZED("not the same element"));
+        }
+        return;
+      }
     }
+
+    SMDS_MeshElement* elem = (SMDS_MeshElement*) (ME);
+    elem->setShapeId(myIndex);
+    elem->setIdInShape(myElements.size());
+    myElements.push_back(ME);
+  }
 }
 
 //=======================================================================
 //function : RemoveElement
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 bool SMESHDS_SubMesh::RemoveElement(const SMDS_MeshElement * ME, bool isElemDeleted)
@@ -137,7 +128,7 @@ bool SMESHDS_SubMesh::RemoveElement(const SMDS_MeshElement * ME, bool isElemDele
     SMDS_MeshElement* elem = (SMDS_MeshElement*) (ME);
     elem->setShapeId(0);
     elem->setIdInShape(-1);
-    if ((idInSubShape >= 0) && (idInSubShape < myElements.size()))
+    if ((idInSubShape >= 0) && (idInSubShape < (int) myElements.size()))
     {
       myElements[idInSubShape] = 0; // this vector entry is no more used
       if ( ++myUnusedIdElements == (int) myElements.size() )
@@ -169,7 +160,7 @@ void SMESHDS_SubMesh::AddNode(const SMDS_MeshNode * N)
       if ( shapeId != myIndex )
         throw SALOME_Exception
           (LOCALIZED("a node being in sub-mesh is added to another sub-mesh"));
-      if ( idInSubShape >= myNodes.size() || myNodes[ idInSubShape ] != N )
+      if ( idInSubShape >= (int)myNodes.size() || myNodes[ idInSubShape ] != N )
         throw SALOME_Exception
           (LOCALIZED("a node with wrong idInSubShape is re-added to the same sub-mesh"));
       return; // already in
@@ -183,7 +174,7 @@ void SMESHDS_SubMesh::AddNode(const SMDS_MeshNode * N)
 
 //=======================================================================
 //function : RemoveNode
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 bool SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N, bool isNodeDeleted)
@@ -196,7 +187,7 @@ bool SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N, bool isNodeDeleted)
     SMDS_MeshNode* node = (SMDS_MeshNode*) (N);
     node->setShapeId(0);
     node->setIdInShape(-1);
-    if ((idInSubShape >= 0) && (idInSubShape < myNodes.size()))
+    if ((idInSubShape >= 0) && (idInSubShape < (int) myNodes.size()))
     {
       myNodes[idInSubShape] = 0; // this vector entry is no more used
       if ( ++myUnusedIdNodes == (int) myNodes.size() )
@@ -293,7 +284,7 @@ template<typename VALUE> class MyIterator : public SMDS_Iterator<VALUE>
 {
  public:
   MyIterator (const set<const SMESHDS_SubMesh*>& theSubMeshes)
-    : mySubIt( theSubMeshes.begin() ), mySubEnd( theSubMeshes.end() ), myMore(false)
+    : myMore(false), mySubIt( theSubMeshes.begin() ), mySubEnd( theSubMeshes.end() )
     {}
   bool more()
   {
@@ -385,29 +376,52 @@ bool SMESHDS_SubMesh::Contains(const SMDS_MeshElement * ME) const
   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;
-      return false;
-    }
+  if ( IsComplexSubmesh() )
+  {
+    set<const SMESHDS_SubMesh*>::const_iterator aSubIt = mySubMeshes.begin();
+    for (; aSubIt != mySubMeshes.end(); aSubIt++)
+      if ((*aSubIt)->Contains(ME))
+        return true;
+    return false;
+  }
 
   if (ME->GetType() == SMDSAbs_Node)
-    {
-      int idInShape = ME->getIdInShape();
-      if ((idInShape >= 0) && (idInShape < myNodes.size()))
-        if (myNodes[idInShape] == ME)
-          return true;
-    }
+  {
+    int idInShape = ME->getIdInShape();
+    if ((idInShape >= 0) && (idInShape < (int) 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;
-    }
+  {
+    int idInShape = ME->getIdInShape();
+    if ((idInShape >= 0) && (idInShape < (int) myElements.size()))
+      if (myElements[idInShape] == ME)
+        return true;
+  }
+  return false;
+}
+
+//=======================================================================
+//function : IsQuadratic
+//purpose  : Return true if my 1st element is quadratic
+//=======================================================================
+
+bool SMESHDS_SubMesh::IsQuadratic() const
+{
+  if ( IsComplexSubmesh() )
+  {
+    set<const SMESHDS_SubMesh*>::const_iterator aSubIt = mySubMeshes.begin();
+    for (; aSubIt != mySubMeshes.end(); aSubIt++)
+      if ((*aSubIt)->IsQuadratic())
+        return true;
+    return false;
+  }
+
+  for ( size_t i = 0; i < myElements.size(); ++i )
+    if ( myElements[i] )
+      return myElements[i]->IsQuadratic();
+
   return false;
 }
 
@@ -525,3 +539,23 @@ void SMESHDS_SubMesh::compactList()
     myUnusedIdNodes = 0;
   }
 }
+
+//=======================================================================
+//function : GetElement
+//purpose  : Return an element by its IdInShape
+//=======================================================================
+
+const SMDS_MeshElement* SMESHDS_SubMesh::GetElement( size_t idInShape ) const
+{
+  return ( !IsComplexSubmesh() && idInShape < myElements.size() ) ? myElements[idInShape] : 0;
+}
+
+//=======================================================================
+//function : GetElement
+//purpose  : Return a node by its IdInShape
+//=======================================================================
+
+const SMDS_MeshNode* SMESHDS_SubMesh::GetNode( size_t idInShape ) const
+{
+  return ( !IsComplexSubmesh() && idInShape < myNodes.size() ) ? myNodes[idInShape] : 0;
+}
index 2f28f0e9084df158d647ed93f23401f2bd9c9339..4eab3aa4470bf87057ffea6c53fee0d8a83f106b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -52,6 +52,8 @@ class SMESHDS_EXPORT SMESHDS_SubMesh
   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
+  virtual const SMDS_MeshElement* GetElement( size_t idInShape ) const;
+  virtual const SMDS_MeshNode*    GetNode   ( size_t idInShape ) const;
 
   // if IsComplexSubmesh()
   void AddSubMesh( const SMESHDS_SubMesh* theSubMesh );
@@ -67,19 +69,20 @@ class SMESHDS_EXPORT SMESHDS_SubMesh
   virtual int NbNodes() const;
   virtual SMDS_NodeIteratorPtr GetNodes() const;
   virtual bool Contains(const SMDS_MeshElement * ME) const;      // check if elem or node is in
+  virtual bool IsQuadratic() const;
 
   // clear the contents
   virtual void Clear();
-  int getSize();
+  int  getSize();
   void compactList();
 
-  SMESHDS_Mesh *GetParent()   { return myParent; }
-  int           GetID() const { return myIndex; }
+  SMESHDS_Mesh* GetParent() const { return const_cast< SMESHDS_Mesh*>( myParent ); }
+  int           GetID()     const { return myIndex; }
 
  private:
-  SMESHDS_Mesh * myParent;
+  SMESHDS_Mesh *                       myParent;
   std::vector<const SMDS_MeshElement*> myElements;
-  std::vector<const SMDS_MeshNode*> myNodes;
+  std::vector<const SMDS_MeshNode*>    myNodes;
 
   int myUnusedIdNodes;
   int myUnusedIdElements;
index 52c9eb2c4ba9ada3315e23332504da861587d579..289bde732ebf3f726de79134289c60d1dd568169 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -54,7 +54,7 @@ public:
     }
     else
     {
-      if ( myVec.size() <= id )
+      if ( (int)myVec.size() <= id )
         myVec.resize( id+1, (SUBMESH*) NULL );
       myVec[ id ] = sm;
     }
@@ -68,7 +68,7 @@ public:
     }
     else
     {
-      return (SUBMESH*) ( id >= myVec.size() ? NULL : myVec[ id ]);
+      return (SUBMESH*) ( id >= (int)myVec.size() ? NULL : myVec[ id ]);
     }
   }
   void DeleteAll()
index 4feb3959ea4193152d07ac4c42f72c96d4606b41..ee7c742f53879cf159d658df899c7b175a50ae38 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -24,7 +24,8 @@
 #define _SMESH_CONTROLS_HXX_
 
 // This file is named incosistently with others, i.e. not SMESHDS_Controls.hxx,
-// because it was moved from ../Controls/SMESH_Controls.hxx
+// because it was moved from ../Controls/SMESH_Controls.hxx.
+// It was moved here for the sake of SMESHDS_GroupOnFilter
 
 #include "SMDSAbs_ElementType.hxx"
 
@@ -47,7 +48,7 @@ namespace SMESH{
 
     /*
       Class       : Functor
-      Description : Root of all Functors
+      Description : Root of all Functors defined in ../Controls/SMESH_ControlsDef.hxx
     */
     class SMESHCONTROLS_EXPORT Functor
     {
index 193992f33fad59181b55bda8838af7400fbe3034..bbd85c6ec98acd3a1c76b9be96a7240475e40139 100755 (executable)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 9d9b8d831475fe98212d32bffe51d86b78c3c8b6..39ff8045ca16a92c2c80b6b09fdb7070efce65b4 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2012-2015  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
index 61cadf00cae80dc2cdbb045b3ef2232afae0aa50..033c5fb24882bf2d522b44a5c64981157ae283e4 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 773fc3d7627cfd4a83c016e6dd224541ae9951eb..6e0741c4b72ae1383a186e0ebe970827db58484b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 9cbe280aedc73e220a27c46a0c2d8bbaafb6a7c8..d104535dc2eea2b0a231aa2e69e2f77195f65886 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index a0e15e074920b96726cefdf9bb8eae1dabb0abff..be4fa41b10d4e1f713e44e852d6b8658b81cca0e 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index aaaafce7d0ea8ad66a15c4d535df8bf5456c1156..9398fe6499b4cf733f348e2475bf4c772e432975 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -59,7 +59,10 @@ namespace SMESH{
     GROUP_0D,
     GROUP_BALL,
     COMPONENT,
-    IDSOURCE
+    IDSOURCE,
+    IDSOURCE_EDGE, // IDSource including edges
+    IDSOURCE_FACE,
+    IDSOURCE_VOLUME
   };
 };
 #endif
index 9b1394da7707557d4c95b800c73ecd80ff551c5a..5f12c7faa9a794c7b6757d6d6193cd8136be1b1d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 
 #include "SMESH_TypeFilter.hxx"
 
+#include <LightApp_DataOwner.h>
 #include <SUIT_Session.h>
-
+#include <SalomeApp_Application.h>
 #include <SalomeApp_Study.h>
-#include <LightApp_DataOwner.h>
 
 #include <SALOMEconfig.h>
 #include CORBA_CLIENT_HEADER(SMESH_Gen)
@@ -39,6 +39,40 @@ SMESH_TypeFilter::~SMESH_TypeFilter()
 {
 }
 
+namespace
+{
+  //================================================================================
+  /*!
+   * \brief Returns true if \a obj is SMESH_IDSource including elements of a given \a type 
+   */
+  //================================================================================
+
+  bool isIDSourceOfType( _PTR(SObject) obj, SMESH::ElementType type )
+  {
+    bool Ok = false;
+    SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>
+      (SUIT_Session::session()->activeApplication());
+    _PTR(GenericAttribute) anAttr;
+    if ( obj->FindAttribute(anAttr, "AttributeIOR"))
+    {
+      _PTR(AttributeIOR) anIOR = anAttr;
+      std::string aVal = anIOR->Value();
+      if ( aVal.size() > 0 )
+      {
+        CORBA::Object_var corbaObj = app->orb()->string_to_object( aVal.c_str() );
+        SMESH::SMESH_IDSource_var ids = SMESH::SMESH_IDSource::_narrow( corbaObj );
+        if ( ! ids->_is_nil() )
+        {
+          SMESH::array_of_ElementType_var types = ids->GetTypes();
+          for ( int i = 0, nb = types->length(); i < nb && !Ok; ++i )
+            Ok = ( types[i] == type );
+        }
+      }
+    }
+    return Ok;
+  }
+}
+
 bool SMESH_TypeFilter::isOk (const SUIT_DataOwner* theDataOwner) const
 {
   bool Ok = false, extractReference = true;
@@ -215,6 +249,21 @@ bool SMESH_TypeFilter::isOk (const SUIT_DataOwner* theDataOwner) const
                  SMESH_TypeFilter(SMESH::GROUP)        .isOk( theDataOwner ));
           break;
         }
+      case SMESH::IDSOURCE_EDGE:
+        {
+          Ok = isIDSourceOfType( obj, SMESH::EDGE );
+          break;
+        }
+      case SMESH::IDSOURCE_FACE:
+        {
+          Ok = isIDSourceOfType( obj, SMESH::FACE );
+          break;
+        }
+      case SMESH::IDSOURCE_VOLUME:
+        {
+          Ok = isIDSourceOfType( obj, SMESH::VOLUME );
+          break;
+        }
     }
   }
   return Ok;
index e48d3d81bf72b96a28d9f9d1a7a813565e0b8adf..5eb318ca11f334b302008885233c6e3154c62296 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 59a99865b3a2313c63910c2cacd3cc2df138d383..c62f185e4593c49b09599e619c4fbcade64fefc7 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2012-2015  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
@@ -39,9 +39,7 @@ INCLUDE_DIRECTORIES(
   ${PROJECT_SOURCE_DIR}/src/SMESHFiltersSelection
   ${PROJECT_SOURCE_DIR}/src/SMDS
   ${PROJECT_SOURCE_DIR}/src/SMESHDS
-  ${PROJECT_SOURCE_DIR}/src/SMESH
   ${PROJECT_SOURCE_DIR}/src/SMESHUtils
-  ${PROJECT_SOURCE_DIR}/src/SMESH_I
   ${PROJECT_SOURCE_DIR}/src/Controls
   ${PROJECT_SOURCE_DIR}/src/SMESHClient
   ${PROJECT_SOURCE_DIR}/src/MEDWrapper/Base
@@ -143,6 +141,9 @@ SET(_moc_HEADERS
   SMESHGUI_Add0DElemsOnAllNodesDlg.h
   SMESHGUI_FieldSelectorWdg.h
   SMESHGUI_DisplayEntitiesDlg.h
+  SMESHGUI_SplitBiQuad.h
+  SMESHGUI_PreVisualObj.h
+  SMESHGUI_IdPreview.h
 )
 
 # header files / no moc processing
@@ -251,6 +252,9 @@ SET(_other_SOURCES
   SMESHGUI_FileValidator.cxx
   SMESHGUI_FieldSelectorWdg.cxx
   SMESHGUI_DisplayEntitiesDlg.cxx
+  SMESHGUI_SplitBiQuad.cxx
+  SMESHGUI_PreVisualObj.cxx
+  SMESHGUI_IdPreview.cxx
 )
 
 # sources / to compile
index 7908b4f49b94a457c3ef0b7829f41db3f0a9460e..d72312ddb456b4aac9d5d6f612c90f5775717c73 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -82,6 +82,7 @@
 #include "SMESHGUI_TranslationDlg.h"
 #include "SMESHGUI_TransparencyDlg.h"
 #include "SMESHGUI_DisplayEntitiesDlg.h"
+#include "SMESHGUI_SplitBiQuad.h"
 
 #include "SMESHGUI_FilterUtils.h"
 #include "SMESHGUI_GEOMGenUtils.h"
 
 #include <VTKViewer_Algorithm.h>
 
-#include <PyInterp_Interp.h>
-
 #include <SUIT_Desktop.h>
 #include <SUIT_FileDlg.h>
 #include <SUIT_MessageBox.h>
 #include <QApplication>
 #include <QMenu>
 #include <QTextStream>
+#include <QListView>
+#include <QTreeView>
 
 // BOOST includes
 #include <boost/shared_ptr.hpp>
 #include <SALOMEDSClient_StudyBuilder.hxx>
 #include <SALOMEDS_Study.hxx>
 #include <SALOMEDS_SObject.hxx>
+#include "utilities.h"
 
 // OCCT includes
 #include <Standard_ErrorHandler.hxx>
 #include <NCollection_DataMap.hxx>
+#include <NCollection_DoubleMap.hxx>
 
 #include <Basics_Utils.hxx>
 
@@ -197,6 +200,8 @@ namespace
 
   void SetDisplayEntity(int theCommandID);
 
+  int ActionToControl( int theID, bool theReversed = false );
+
   void Control( int theCommandID );
 
   // Definitions
@@ -423,17 +428,16 @@ namespace
     const bool isMED = ( theCommandID == SMESHOp::OpExportMED || theCommandID == SMESHOp::OpPopupExportMED );
     const bool isUNV = ( theCommandID == SMESHOp::OpExportUNV || theCommandID == SMESHOp::OpPopupExportUNV );
     const bool isSTL = ( theCommandID == SMESHOp::OpExportSTL || theCommandID == SMESHOp::OpPopupExportSTL );
-  #ifdef WITH_CGNS
+#ifdef WITH_CGNS
     const bool isCGNS= ( theCommandID == SMESHOp::OpExportCGNS || theCommandID == SMESHOp::OpPopupExportCGNS );
-  #else
+#else
     const bool isCGNS= false;
-  #endif
+#endif
     const bool isSAUV= ( theCommandID == SMESHOp::OpExportSAUV || theCommandID == SMESHOp::OpPopupExportSAUV );
     const bool isGMF = ( theCommandID == SMESHOp::OpExportGMF || theCommandID == SMESHOp::OpPopupExportGMF );
 
-    // actually, the following condition can't be met (added for insurance)
-    if( selected.Extent() == 0 ||
-        ( selected.Extent() > 1 && !isMED && !isSTL ))
+    const bool multiMeshSupported = ( isMED || isCGNS ); // file can hold several meshes
+    if ( selected.Extent() == 0 || ( selected.Extent() > 1 && !multiMeshSupported ))
       return;
 
     // get mesh object from selection and check duplication of their names
@@ -532,7 +536,6 @@ namespace
     {
       format = "CGNS";
       notSupportedElemTypes.push_back( SMESH::Entity_Ball );
-      notSupportedElemTypes.push_back( SMESH::Entity_BiQuad_Triangle );
     }
     else if ( isSAUV )
     {
@@ -543,6 +546,7 @@ namespace
       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_Quad_Polygon );
       notSupportedElemTypes.push_back( SMESH::Entity_Polyhedra );
     }
     else if ( isGMF )
@@ -714,6 +718,16 @@ namespace
       if ( !anInitialPath.isEmpty() )
         fd->setDirectory( anInitialPath );
       fd->selectFile(aMeshName);
+      
+      
+      QListView *lview = fd->findChild<QListView*>("listView");
+      if( lview ) {
+        lview->setMinimumHeight(200);
+      }
+      QTreeView *tview = fd->findChild<QTreeView*>("treeView");
+      if( tview ) {
+        tview->setMinimumHeight(200);
+      }
 
       SMESHGUI_FileValidator* fv = new SMESHGUI_FileValidator( fd );
       fd->setValidator( fv );
@@ -1162,7 +1176,7 @@ namespace
                   out << "# Control: " << functorToString( aFunctor ) << endl;
                   out << "#" << endl;
                   out.setFieldWidth( 10 );
-                  for ( int i = 0; i < qMin( nbEvents.size(), funValues.size()-1 ); i++ )
+                  for ( int i = 0; i < (int)qMin( nbEvents.size(), funValues.size()-1 ); i++ )
                     out << funValues[i] << "\t" << funValues[i+1] << "\t" << nbEvents[i] << endl;
                   f.close();
                 }
@@ -1174,7 +1188,7 @@ namespace
     }
   }
 
-  void ShowDistribution() {
+  void ShowElement(int theCommandID ) {
     LightApp_SelectionMgr* aSel = SMESHGUI::selectionMgr();
     SALOME_ListIO selected;
     if ( aSel )
@@ -1186,7 +1200,12 @@ namespace
         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());
+          if ( theCommandID == SMESHOp::OpShowDistribution ) {
+            aScalarBarActor->SetDistributionVisibility(!aScalarBarActor->GetDistributionVisibility());
+          }
+          else if ( theCommandID == SMESHOp::OpShowScalarBar ) {
+            aScalarBarActor->SetVisibility( !aScalarBarActor->GetVisibility());
+          }
         }
       }
     }
@@ -1310,7 +1329,7 @@ namespace
         QColor orientationColor, outlineColor, volumeColor;
         int deltaF = 0, deltaV = 0;
         int elem0dSize   = 1;
-        int ballSize     = 1;
+        //int ballSize     = 1;
         double ballScale = 1.0;
         int edgeWidth    = 1;
         int outlineWidth = 1;
@@ -1355,7 +1374,7 @@ namespace
             // balls: color, size
             anActor->GetBallColor( color[0], color[1], color[2] );
             ballColor.setRgbF( color[0], color[1], color[2] );
-            ballSize = qMax( (int)anActor->GetBallSize(), 1 ); // minimum allowed size is 1
+            //ballSize = qMax( (int)anActor->GetBallSize(), 1 ); // minimum allowed size is 1
             ballScale = qMax( (double)anActor->GetBallScale(), 1e-2 ); // minimum allowed scale is 1e-2
             // outlines: color
             anActor->GetOutlineColor( color[0], color[1], color[2] );
@@ -1412,7 +1431,7 @@ namespace
         dlg.setElem0dSize( elem0dSize );
         // balls: color, size
         dlg.setBallColor( ballColor );
-        dlg.setBallSize( ballSize );
+        //dlg.setBallSize( ballSize );
         dlg.setBallScale( ballScale );
         // orientation: color, scale, 3d flag
         dlg.setOrientationColor( orientationColor );
@@ -1439,7 +1458,7 @@ namespace
           elem0dColor      = dlg.elem0dColor();
           elem0dSize       = dlg.elem0dSize();
           ballColor        = dlg.ballColor();
-          ballSize         = dlg.ballSize();
+         // ballSize         = dlg.ballSize();
           ballScale        = dlg.ballScale();
           orientationColor = dlg.orientationColor();
           orientationScale = dlg.orientationSize() / 100.;
@@ -1483,7 +1502,7 @@ namespace
             anActor->Set0DSize( elem0dSize );
             // balls: color, size
             anActor->SetBallColor( ballColor.redF(), ballColor.greenF(), ballColor.blueF() );
-            anActor->SetBallSize( ballSize );
+            // anActor->SetBallSize( ballSize );
             anActor->SetBallScale( ballScale );
             // orientation: color, scale, 3d flag
             anActor->SetFacesOrientationColor( orientationColor.redF(), orientationColor.greenF(), orientationColor.blueF() );
@@ -1564,89 +1583,43 @@ namespace
     }
   }
 
+  int ActionToControl( int theID, bool theReversed )
+  {
+    NCollection_DoubleMap<int,int> ActionControl;
+    ActionControl.Bind( 0,                                SMESH_Actor::eNone );
+    ActionControl.Bind( SMESHOp::OpFreeNode,              SMESH_Actor::eFreeNodes );
+    ActionControl.Bind( SMESHOp::OpEqualNode,             SMESH_Actor::eCoincidentNodes );
+    ActionControl.Bind( SMESHOp::OpFreeEdge,              SMESH_Actor::eFreeEdges );
+    ActionControl.Bind( SMESHOp::OpFreeBorder,            SMESH_Actor::eFreeBorders );
+    ActionControl.Bind( SMESHOp::OpLength,                SMESH_Actor::eLength );
+    ActionControl.Bind( SMESHOp::OpConnection,            SMESH_Actor::eMultiConnection );
+    ActionControl.Bind( SMESHOp::OpEqualEdge,             SMESH_Actor::eCoincidentElems1D );
+    ActionControl.Bind( SMESHOp::OpFreeFace,              SMESH_Actor::eFreeFaces );
+    ActionControl.Bind( SMESHOp::OpBareBorderFace,        SMESH_Actor::eBareBorderFace );
+    ActionControl.Bind( SMESHOp::OpOverConstrainedFace,   SMESH_Actor::eOverConstrainedFace );
+    ActionControl.Bind( SMESHOp::OpLength2D,              SMESH_Actor::eLength2D );
+    ActionControl.Bind( SMESHOp::OpConnection2D,          SMESH_Actor::eMultiConnection2D );
+    ActionControl.Bind( SMESHOp::OpArea,                  SMESH_Actor::eArea );
+    ActionControl.Bind( SMESHOp::OpTaper,                 SMESH_Actor::eTaper );
+    ActionControl.Bind( SMESHOp::OpAspectRatio,           SMESH_Actor::eAspectRatio );
+    ActionControl.Bind( SMESHOp::OpMinimumAngle,          SMESH_Actor::eMinimumAngle );
+    ActionControl.Bind( SMESHOp::OpWarpingAngle,          SMESH_Actor::eWarping );
+    ActionControl.Bind( SMESHOp::OpSkew,                  SMESH_Actor::eSkew );
+    ActionControl.Bind( SMESHOp::OpMaxElementLength2D,    SMESH_Actor::eMaxElementLength2D );
+    ActionControl.Bind( SMESHOp::OpEqualFace,             SMESH_Actor::eCoincidentElems2D );
+    ActionControl.Bind( SMESHOp::OpAspectRatio3D,         SMESH_Actor::eAspectRatio3D );
+    ActionControl.Bind( SMESHOp::OpVolume,                SMESH_Actor::eVolume3D );
+    ActionControl.Bind( SMESHOp::OpMaxElementLength3D,    SMESH_Actor::eMaxElementLength3D );
+    ActionControl.Bind( SMESHOp::OpBareBorderVolume,      SMESH_Actor::eBareBorderVolume );
+    ActionControl.Bind( SMESHOp::OpOverConstrainedVolume, SMESH_Actor::eOverConstrainedVolume );
+    ActionControl.Bind( SMESHOp::OpEqualVolume,           SMESH_Actor::eCoincidentElems3D );
+
+    return theReversed ? ActionControl.Find2( theID ) : ActionControl.Find1( theID );
+  }
+
   void Control( int theCommandID )
   {
-    SMESH_Actor::eControl aControl = SMESH_Actor::eNone;
-    switch ( theCommandID ){
-    case SMESHOp::OpFreeNode:
-      aControl = SMESH_Actor::eFreeNodes;
-      break;
-    case SMESHOp::OpEqualNode:
-      aControl = SMESH_Actor::eCoincidentNodes;
-      break;
-    case SMESHOp::OpFreeEdge:
-      aControl = SMESH_Actor::eFreeEdges;
-      break;
-    case SMESHOp::OpFreeBorder:
-      aControl = SMESH_Actor::eFreeBorders;
-      break;
-    case SMESHOp::OpLength:
-      aControl = SMESH_Actor::eLength;
-      break;
-    case SMESHOp::OpConnection:
-      aControl = SMESH_Actor::eMultiConnection;
-      break;
-    case SMESHOp::OpEqualEdge:
-      aControl = SMESH_Actor::eCoincidentElems1D;
-      break;
-    case SMESHOp::OpFreeFace:
-      aControl = SMESH_Actor::eFreeFaces;
-      break;
-    case SMESHOp::OpBareBorderFace:
-      aControl = SMESH_Actor::eBareBorderFace;
-      break;
-    case SMESHOp::OpOverConstrainedFace:
-      aControl = SMESH_Actor::eOverConstrainedFace;
-      break;
-    case SMESHOp::OpLength2D:
-      aControl = SMESH_Actor::eLength2D;
-      break;
-    case SMESHOp::OpConnection2D:
-      aControl = SMESH_Actor::eMultiConnection2D;
-      break;
-    case SMESHOp::OpArea:
-      aControl = SMESH_Actor::eArea;
-      break;
-    case SMESHOp::OpTaper:
-      aControl = SMESH_Actor::eTaper;
-      break;
-    case SMESHOp::OpAspectRatio:
-      aControl = SMESH_Actor::eAspectRatio;
-      break;
-    case SMESHOp::OpMinimumAngle:
-      aControl = SMESH_Actor::eMinimumAngle;
-      break;
-    case SMESHOp::OpWarpingAngle:
-      aControl = SMESH_Actor::eWarping;
-      break;
-    case SMESHOp::OpSkew:
-      aControl = SMESH_Actor::eSkew;
-      break;
-    case SMESHOp::OpMaxElementLength2D:
-      aControl = SMESH_Actor::eMaxElementLength2D;
-      break;
-    case SMESHOp::OpEqualFace:
-      aControl = SMESH_Actor:: eCoincidentElems2D;
-      break;
-    case SMESHOp::OpAspectRatio3D:
-      aControl = SMESH_Actor::eAspectRatio3D;
-      break;
-    case SMESHOp::OpVolume:
-      aControl = SMESH_Actor::eVolume3D;
-      break;
-    case SMESHOp::OpMaxElementLength3D:
-      aControl = SMESH_Actor::eMaxElementLength3D;
-      break;
-    case SMESHOp::OpBareBorderVolume:
-      aControl = SMESH_Actor::eBareBorderVolume;
-      break;
-    case SMESHOp::OpOverConstrainedVolume:
-      aControl = SMESH_Actor::eOverConstrainedVolume;
-      break;
-    case SMESHOp::OpEqualVolume:
-      aControl = SMESH_Actor::eCoincidentElems3D;
-      break;
-    }
+    SMESH_Actor::eControl aControl = SMESH_Actor::eControl( ActionToControl( theCommandID ) );
     _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
     LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
     SALOME_ListIO selected;
@@ -1661,7 +1634,7 @@ namespace
         if(!anIO.IsNull()){
           _PTR(SObject) SO = aStudy->FindObjectID( It.Value()->getEntry() );
           if ( SO ) {
-            CORBA::Object_var aObject = SMESH::SObjectToObject( 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 );
@@ -1978,7 +1951,7 @@ SalomeApp_Module( "SMESH" )
     nbSeg = aResourceMgr->integerValue( "SMESH", "nb_segments_per_edge", 15 );
     myComponentSMESH->SetDefaultNbSegments( nbSeg );
 
-    const char* options[] = { "historical_python_dump", "forget_mesh_on_hyp_modif" };
+    const char* options[] = { "historical_python_dump", "forget_mesh_on_hyp_modif", "default_grp_color" };
     for ( size_t i = 0; i < sizeof(options)/sizeof(char*); ++i )
       if ( aResourceMgr->hasValue( "SMESH", options[i] ))
       {
@@ -2064,7 +2037,7 @@ bool SMESHGUI::automaticUpdate( SMESH::SMESH_IDSource_ptr theMesh,
   long nbEdges   = info[SMDSEntity_Edge] + info[SMDSEntity_Quad_Edge];
   long nbFaces   = info[SMDSEntity_Triangle]   + info[SMDSEntity_Quad_Triangle]   + info[SMDSEntity_BiQuad_Triangle] + 
                    info[SMDSEntity_Quadrangle] + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_BiQuad_Quadrangle] + 
-                   info[SMDSEntity_Polygon];
+                   info[SMDSEntity_Polygon] + info[SMDSEntity_Quad_Polygon];
   long nbVolumes = info[SMDSEntity_Tetra]   + info[SMDSEntity_Quad_Tetra] + 
                    info[SMDSEntity_Hexa]    + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_TriQuad_Hexa] + 
                    info[SMDSEntity_Pyramid] + info[SMDSEntity_Quad_Pyramid] + 
@@ -2247,6 +2220,26 @@ void SMESHGUI::EmitSignalVisibilityChanged()
   emit SignalVisibilityChanged();
 }
 
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+void SMESHGUI::EmitSignalCloseView()
+{
+  emit SignalCloseView();
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+void SMESHGUI::EmitSignalActivatedViewManager()
+{
+  emit SignalActivatedViewManager();
+}
+
 //=============================================================================
 /*!
  *
@@ -2451,8 +2444,9 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       if( aSel )
         aSel->selectedObjects( selected );
 
-      if( selected.Extent() ) {
-        Handle(SALOME_InteractiveObject) anIO = selected.First();
+      SALOME_ListIteratorOfListIO it(selected);
+      for( ; it.More(); it.Next()) {
+        Handle(SALOME_InteractiveObject) anIO = it.Value();
         if( anIO->hasEntry() ) {
           if( SMESH_Actor* anActor = SMESH::FindActorByEntry( anIO->getEntry() ) ) {
             anActor->SetControlMode( SMESH_Actor::eNone );
@@ -2462,6 +2456,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
           }
         }
       }
+      SMESH::UpdateView();
       break;
     }
   case SMESHOp::OpScalarBarProperties:
@@ -2469,6 +2464,12 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       SMESHGUI_Preferences_ScalarBarDlg::ScalarBarProperties( this );
       break;
     }
+  case SMESHOp::OpShowScalarBar:
+    {
+      // show/hide scalar bar
+      ::ShowElement(theCommandID);
+      break;
+    }
   case SMESHOp::OpSaveDistribution:
     {
       // dump control distribution data to the text file
@@ -2478,8 +2479,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
 
   case SMESHOp::OpShowDistribution:
     {
-      // show/ distribution
-      ::ShowDistribution();
+      // show/hide distribution
+      ::ShowElement(theCommandID);
       break;
     }
 
@@ -2583,8 +2584,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
     {
       SMESH::EDisplaing anAction;
       switch (theCommandID) {
-      case SMESHOp::OpHide: anAction = SMESH::eErase; break;
-      case SMESHOp::OpShow: anAction = SMESH::eDisplay; break;
+      case SMESHOp::OpHide:     anAction = SMESH::eErase; break;
+      case SMESHOp::OpShow:     anAction = SMESH::eDisplay; break;
       case SMESHOp::OpShowOnly: anAction = SMESH::eDisplayOnly; break;
       }
 
@@ -2593,7 +2594,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       if (aSel)
         aSel->selectedObjects( sel_objects );
 
-      if( theCommandID==SMESHOp::OpShowOnly )
+      if ( theCommandID==SMESHOp::OpShowOnly )
       {
         MESSAGE("anAction = SMESH::eDisplayOnly");
         startOperation( myEraseAll );
@@ -2607,20 +2608,17 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
 #endif
         if (vtkwnd) {
           SALOME_ListIteratorOfListIO It( to_process );
-          for ( ; It.More(); It.Next()) {
-            MESSAGE("---");
+          for ( ; It.More(); It.Next())
+          {
             Handle(SALOME_InteractiveObject) IOS = It.Value();
-            if (IOS->hasEntry()) {
-              MESSAGE("---");
-              if (!SMESH::UpdateView(anAction, IOS->getEntry())) {
+            if ( IOS->hasEntry() )
+            {
+              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;
-              }
             }
           }
         }
@@ -2812,6 +2810,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       }
       break;
     }
+  case SMESHOp::OpSplitBiQuadratic:
   case SMESHOp::OpConvertMeshToQuadratic:
   case SMESHOp::OpCreateBoundaryElements: // create 2D mesh from 3D
   case SMESHOp::OpReorientFaces:
@@ -3233,6 +3232,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case SMESHOp::OpBiQuadraticTriangle:
   case SMESHOp::OpQuadraticQuadrangle:
   case SMESHOp::OpBiQuadraticQuadrangle:
+  case SMESHOp::OpQuadraticPolygon:
   case SMESHOp::OpQuadraticTetrahedron:
   case SMESHOp::OpQuadraticPyramid:
   case SMESHOp::OpQuadraticPentahedron:
@@ -3245,15 +3245,16 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
         SMDSAbs_EntityType type = SMDSEntity_Last;
 
         switch (theCommandID) {
-        case SMESHOp::OpQuadraticEdge: type = SMDSEntity_Quad_Edge; break;
-        case SMESHOp::OpQuadraticTriangle: type = SMDSEntity_Quad_Triangle; break;
-        case SMESHOp::OpBiQuadraticTriangle: type = SMDSEntity_BiQuad_Triangle; break;
-        case SMESHOp::OpQuadraticQuadrangle: type = SMDSEntity_Quad_Quadrangle; break;
-        case SMESHOp::OpBiQuadraticQuadrangle: type = SMDSEntity_BiQuad_Quadrangle; break;
-        case SMESHOp::OpQuadraticTetrahedron: type = SMDSEntity_Quad_Tetra; break;
-        case SMESHOp::OpQuadraticPyramid: type = SMDSEntity_Quad_Pyramid; break;
-        case SMESHOp::OpQuadraticPentahedron: type = SMDSEntity_Quad_Penta; break;
-        case SMESHOp::OpQuadraticHexahedron: type = SMDSEntity_Quad_Hexa; break;
+        case SMESHOp::OpQuadraticEdge:          type = SMDSEntity_Quad_Edge; break;
+        case SMESHOp::OpQuadraticTriangle:      type = SMDSEntity_Quad_Triangle; break;
+        case SMESHOp::OpBiQuadraticTriangle:    type = SMDSEntity_BiQuad_Triangle; break;
+        case SMESHOp::OpQuadraticQuadrangle:    type = SMDSEntity_Quad_Quadrangle; break;
+        case SMESHOp::OpBiQuadraticQuadrangle:  type = SMDSEntity_BiQuad_Quadrangle; break;
+        case SMESHOp::OpQuadraticPolygon:       type = SMDSEntity_Quad_Polygon; break;
+        case SMESHOp::OpQuadraticTetrahedron:   type = SMDSEntity_Quad_Tetra; break;
+        case SMESHOp::OpQuadraticPyramid:       type = SMDSEntity_Quad_Pyramid; break;
+        case SMESHOp::OpQuadraticPentahedron:   type = SMDSEntity_Quad_Penta; break;
+        case SMESHOp::OpQuadraticHexahedron:    type = SMDSEntity_Quad_Hexa; break;
         case SMESHOp::OpTriQuadraticHexahedron: type = SMDSEntity_TriQuad_Hexa; break;
         default: break;
         }
@@ -3765,7 +3766,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   // ----- create actions --------------
 
   //createSMESHAction(  SMESHOp::OpImportDAT, "IMPORT_DAT", "", (Qt::CTRL+Qt::Key_B) );
-  createSMESHAction( SMESHOp::OpImportUNV, "IMPORT_UNV", "", (Qt::CTRL+Qt::Key_U) );
+  createSMESHAction( SMESHOp::OpImportUNV, "IMPORT_UNV", "", (Qt::CTRL+Qt::Key_I) );
   createSMESHAction( SMESHOp::OpImportMED, "IMPORT_MED", "", (Qt::CTRL+Qt::Key_M) );
   //createSMESHAction(  114, "NUM" );
   createSMESHAction( SMESHOp::OpImportSTL, "IMPORT_STL"  );
@@ -3802,8 +3803,8 @@ void SMESHGUI::initialize( CAM_Application* app )
   createSMESHAction( SMESHOp::OpCopyMesh,             "COPY_MESH",               "ICON_COPY_MESH" );
   createSMESHAction( SMESHOp::OpCompute,              "COMPUTE",                 "ICON_COMPUTE" );
   createSMESHAction( SMESHOp::OpPreCompute,           "PRECOMPUTE",              "ICON_PRECOMPUTE" );
-  createSMESHAction( SMESHOp::OpEvaluate,             "EVALUATE",                "ICON_COMPUTE" );
-  createSMESHAction( SMESHOp::OpMeshOrder,            "MESH_ORDER",              "ICON_COMPUTE" );
+  createSMESHAction( SMESHOp::OpEvaluate,             "EVALUATE",                "ICON_EVALUATE" );
+  createSMESHAction( SMESHOp::OpMeshOrder,            "MESH_ORDER",              "ICON_MESH_ORDER");
   createSMESHAction( SMESHOp::OpCreateGroup,          "CREATE_GROUP",            "ICON_CREATE_GROUP" );
   createSMESHAction( SMESHOp::OpCreateGeometryGroup,  "CREATE_GEO_GROUP",        "ICON_CREATE_GEO_GROUP" );
   createSMESHAction( SMESHOp::OpConstructGroup,       "CONSTRUCT_GROUP",         "ICON_CONSTRUCT_GROUP" );
@@ -3868,6 +3869,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   createSMESHAction( SMESHOp::OpBiQuadraticTriangle,    "BIQUADRATIC_TRIANGLE",    "ICON_DLG_BIQUADRATIC_TRIANGLE" );
   createSMESHAction( SMESHOp::OpQuadraticQuadrangle,    "QUADRATIC_QUADRANGLE",    "ICON_DLG_QUADRATIC_QUADRANGLE" );
   createSMESHAction( SMESHOp::OpBiQuadraticQuadrangle,  "BIQUADRATIC_QUADRANGLE",  "ICON_DLG_BIQUADRATIC_QUADRANGLE" );
+  createSMESHAction( SMESHOp::OpQuadraticPolygon,       "QUADRATIC_POLYGON",       "ICON_DLG_QUADRATIC_POLYGON" );
   createSMESHAction( SMESHOp::OpQuadraticTetrahedron,   "QUADRATIC_TETRAHEDRON",   "ICON_DLG_QUADRATIC_TETRAHEDRON" );
   createSMESHAction( SMESHOp::OpQuadraticPyramid,       "QUADRATIC_PYRAMID",       "ICON_DLG_QUADRATIC_PYRAMID" );
   createSMESHAction( SMESHOp::OpQuadraticPentahedron,   "QUADRATIC_PENTAHEDRON",   "ICON_DLG_QUADRATIC_PENTAHEDRON" );
@@ -3898,6 +3900,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   createSMESHAction( SMESHOp::OpUnionOfTriangles,       "UNION",           "ICON_UNIONTRI" );
   createSMESHAction( SMESHOp::OpCuttingOfQuadrangles,   "CUT",             "ICON_CUTQUAD" );
   createSMESHAction( SMESHOp::OpSplitVolumes,           "SPLIT_TO_TETRA",  "ICON_SPLIT_TO_TETRA" );
+  createSMESHAction( SMESHOp::OpSplitBiQuadratic,       "SPLIT_BIQUAD",    "ICON_SPLIT_BIQUAD" );
   createSMESHAction( SMESHOp::OpSmoothing,              "SMOOTH",          "ICON_DLG_SMOOTHING" );
   createSMESHAction( SMESHOp::OpExtrusion,              "EXTRUSION",       "ICON_EXTRUSION" );
   createSMESHAction( SMESHOp::OpExtrusionAlongAPath,    "EXTRUSION_ALONG", "ICON_EXTRUSION_ALONG" );
@@ -3908,6 +3911,7 @@ void SMESHGUI::initialize( CAM_Application* app )
 
   createSMESHAction( SMESHOp::OpReset,               "RESET" );
   createSMESHAction( SMESHOp::OpScalarBarProperties, "SCALAR_BAR_PROP" );
+  createSMESHAction( SMESHOp::OpShowScalarBar,       "SHOW_SCALAR_BAR","",0, true  );
   createSMESHAction( SMESHOp::OpSaveDistribution,    "SAVE_DISTRIBUTION" );
   createSMESHAction( SMESHOp::OpShowDistribution,    "SHOW_DISTRIBUTION","",0, true );
 #ifndef DISABLE_PLOT2DVIEWER
@@ -3981,12 +3985,14 @@ void SMESHGUI::initialize( CAM_Application* app )
 
   createMenu( separator(), fileId );
 
+  QMenu* nodeMenu = new QMenu(); QMenu* edgeMenu = new QMenu();
+  QMenu* faceMenu = new QMenu(); QMenu* volumeMenu = new QMenu();
   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 ),
+      nodeId   = createMenu( tr( "MEN_NODE_CTRL" ), ctrlId, -1, 10, -1, nodeMenu ),
+      edgeId   = createMenu( tr( "MEN_EDGE_CTRL" ), ctrlId, -1, 10, -1, edgeMenu ),
+      faceId   = createMenu( tr( "MEN_FACE_CTRL" ), ctrlId, -1, 10, -1, faceMenu ),
+      volumeId = createMenu( tr( "MEN_VOLUME_CTRL" ), ctrlId, -1, 10, -1, volumeMenu ),
       addId    = createMenu( tr( "MEN_ADD" ),    modifyId, 402 ),
       removeId = createMenu( tr( "MEN_REMOVE" ), modifyId, 403 ),
     //renumId  = createMenu( tr( "MEN_RENUM" ),  modifyId, 404 ),
@@ -4048,11 +4054,11 @@ void SMESHGUI::initialize( CAM_Application* app )
 
   createMenu( SMESHOp::OpFreeNode,              nodeId,   -1 );
   createMenu( SMESHOp::OpEqualNode,             nodeId,   -1 );
-  createMenu( SMESHOp::OpFreeEdge,              edgeId,   -1 );
   createMenu( SMESHOp::OpFreeBorder,            edgeId,   -1 );
   createMenu( SMESHOp::OpLength,                edgeId,   -1 );
   createMenu( SMESHOp::OpConnection,            edgeId,   -1 );
   createMenu( SMESHOp::OpEqualEdge,             edgeId,   -1 );
+  createMenu( SMESHOp::OpFreeEdge,              faceId,   -1 );
   createMenu( SMESHOp::OpFreeFace,              faceId,   -1 );
   createMenu( SMESHOp::OpBareBorderFace,        faceId,   -1 );
   createMenu( SMESHOp::OpOverConstrainedFace,   faceId,   -1 );
@@ -4097,6 +4103,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   createMenu( SMESHOp::OpBiQuadraticTriangle ,   addId, -1 );
   createMenu( SMESHOp::OpQuadraticQuadrangle,    addId, -1 );
   createMenu( SMESHOp::OpBiQuadraticQuadrangle,  addId, -1 );
+  createMenu( SMESHOp::OpQuadraticPolygon,       addId, -1 );
   createMenu( SMESHOp::OpQuadraticTetrahedron,   addId, -1 );
   createMenu( SMESHOp::OpQuadraticPyramid,       addId, -1 );
   createMenu( SMESHOp::OpQuadraticPentahedron,   addId, -1 );
@@ -4131,6 +4138,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   createMenu( SMESHOp::OpUnionOfTriangles,       modifyId, -1 );
   createMenu( SMESHOp::OpCuttingOfQuadrangles,   modifyId, -1 );
   createMenu( SMESHOp::OpSplitVolumes,           modifyId, -1 );
+  createMenu( SMESHOp::OpSplitBiQuadratic,       modifyId, -1 );
   createMenu( SMESHOp::OpSmoothing,              modifyId, -1 );
   createMenu( SMESHOp::OpExtrusion,              modifyId, -1 );
   createMenu( SMESHOp::OpExtrusionAlongAPath ,   modifyId, -1 );
@@ -4146,6 +4154,11 @@ void SMESHGUI::initialize( CAM_Application* app )
   createMenu( SMESHOp::OpPropertiesVolume, basicPropId, -1 );
   createMenu( SMESHOp::OpUpdate,           viewId,      -1 );
 
+  connect( nodeMenu, SIGNAL( aboutToShow() ), this, SLOT( onUpdateControlActions() ) );
+  connect( edgeMenu, SIGNAL( aboutToShow() ), this, SLOT( onUpdateControlActions() ) );
+  connect( faceMenu, SIGNAL( aboutToShow() ), this, SLOT( onUpdateControlActions() ) );
+  connect( volumeMenu, SIGNAL( aboutToShow() ), this, SLOT( onUpdateControlActions() ) );
+
   // ----- create toolbars --------------
   int meshTb       = createTool( tr( "TB_MESH" ),      QString( "SMESHMeshToolbar" ) ),
       info         = createTool( tr( "TB_INFO" ),      QString( "SMESHInformationToolbar" ) ),
@@ -4187,12 +4200,12 @@ void SMESHGUI::initialize( CAM_Application* app )
   createTool( SMESHOp::OpFreeNode,  ctrl0dTb );
   createTool( SMESHOp::OpEqualNode, ctrl0dTb );
 
-  createTool( SMESHOp::OpFreeEdge,   ctrl1dTb );
   createTool( SMESHOp::OpFreeBorder, ctrl1dTb );
   createTool( SMESHOp::OpLength,     ctrl1dTb );
   createTool( SMESHOp::OpConnection, ctrl1dTb );
   createTool( SMESHOp::OpEqualEdge,  ctrl1dTb );
 
+  createTool( SMESHOp::OpFreeEdge,            ctrl2dTb );
   createTool( SMESHOp::OpFreeFace,            ctrl2dTb );
   createTool( SMESHOp::OpBareBorderFace,      ctrl2dTb );
   createTool( SMESHOp::OpOverConstrainedFace, ctrl2dTb );
@@ -4234,6 +4247,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   createTool( SMESHOp::OpBiQuadraticTriangle,    addNonElemTb );
   createTool( SMESHOp::OpQuadraticQuadrangle,    addNonElemTb );
   createTool( SMESHOp::OpBiQuadraticQuadrangle,  addNonElemTb );
+  createTool( SMESHOp::OpQuadraticPolygon,       addNonElemTb );
   createTool( SMESHOp::OpQuadraticTetrahedron,   addNonElemTb );
   createTool( SMESHOp::OpQuadraticPyramid,       addNonElemTb );
   createTool( SMESHOp::OpQuadraticPentahedron,   addNonElemTb );
@@ -4265,6 +4279,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   createTool( SMESHOp::OpUnionOfTriangles,       modifyTb );
   createTool( SMESHOp::OpCuttingOfQuadrangles,   modifyTb );
   createTool( SMESHOp::OpSplitVolumes,           modifyTb );
+  createTool( SMESHOp::OpSplitBiQuadratic,       modifyTb );
   createTool( SMESHOp::OpSmoothing,              modifyTb );
   createTool( SMESHOp::OpExtrusion,              modifyTb );
   createTool( SMESHOp::OpExtrusionAlongAPath,    modifyTb );
@@ -4314,38 +4329,39 @@ void SMESHGUI::initialize( CAM_Application* app )
     hasElems0d("({'Elem0d'} in elemTypes)"),
     hasEdges("({'Edge'} in elemTypes)"),
     hasFaces("({'Face'} in elemTypes)"),
-    hasVolumes("({'Volume'} in elemTypes)");
+    hasVolumes("({'Volume'} in elemTypes)"),
+    hasFacesOrVolumes("(({'Face'} in elemTypes) || ({'Volume'} in elemTypes)) ");
 
   createPopupItem( SMESHOp::OpFileInformation,      OB, mesh, "&& selcount=1 && isImported" );
-  createPopupItem( SMESHOp::OpCreateSubMesh,        OB, mesh, "&& isComputable");
-  createPopupItem( SMESHOp::OpEditMeshOrSubMesh,    OB, mesh, "&& isComputable");
-  createPopupItem( SMESHOp::OpEditMeshOrSubMesh,    OB, subMesh, "&& isComputable" );
+  createPopupItem( SMESHOp::OpCreateSubMesh,        OB, mesh, "&& hasGeomReference");
+  createPopupItem( SMESHOp::OpEditMeshOrSubMesh,    OB, mesh );
+  createPopupItem( SMESHOp::OpEditMeshOrSubMesh,    OB, subMesh, "&& hasGeomReference" );
   createPopupItem( SMESHOp::OpEditGroup,            OB, group );
   createPopupItem( SMESHOp::OpEditGeomGroupAsGroup, OB, group, "&& groupType != 'Group'" );
 
   popupMgr()->insert( separator(), -1, 0 );
   createPopupItem( SMESHOp::OpCompute,                OB, mesh, "&& isComputable" );
-  createPopupItem( SMESHOp::OpPreCompute,             OB, mesh, "&& isComputable && isPreComputable" );
+  createPopupItem( SMESHOp::OpPreCompute,             OB, mesh, "&& isPreComputable" );
   createPopupItem( SMESHOp::OpEvaluate,               OB, mesh, "&& isComputable" );
-  createPopupItem( SMESHOp::OpMeshOrder,              OB, mesh, "&& isComputable" );
+  createPopupItem( SMESHOp::OpMeshOrder,              OB, mesh, "&& isComputable && hasGeomReference" );
   createPopupItem( SMESHOp::OpUpdate,                 OB, mesh_part );
   createPopupItem( SMESHOp::OpMeshInformation,        OB, mesh_part );
   createPopupItem( SMESHOp::OpFindElementByPoint,     OB, mesh_group );
   createPopupItem( SMESHOp::OpOverallMeshQuality,     OB, mesh_part );
   popupMgr()->insert( separator(), -1, 0 );
   createPopupItem( SMESHOp::OpCreateGroup,            OB, mesh );
-  createPopupItem( SMESHOp::OpCreateGeometryGroup,    OB, mesh );
+  createPopupItem( SMESHOp::OpCreateGeometryGroup,    OB, mesh, "&& hasGeomReference" );
   createPopupItem( SMESHOp::OpConstructGroup,         OB, subMesh );
   popupMgr()->insert( separator(), -1, 0 );
-  createPopupItem( SMESHOp::OpEditHypothesis,         OB, hypo);
+  createPopupItem( SMESHOp::OpEditHypothesis,         OB, hypo, "&& isEditableHyp");
   createPopupItem( SMESHOp::OpUnassign,               OB, hyp_alg );     // REMOVE HYPOTHESIS / ALGORITHMS
   popupMgr()->insert( separator(), -1, 0 );
-  createPopupItem( SMESHOp::OpClearMesh,              OB, mesh );
-  popupMgr()->insert( separator(), -1, 0 );
   createPopupItem( SMESHOp::OpConvertMeshToQuadratic, OB, mesh + " " + subMesh );  // convert to quadratic
   createPopupItem( SMESHOp::OpCreateBoundaryElements, OB, mesh + " " + group,      // create 2D mesh from 3D
                    "&& dim>=2");
   popupMgr()->insert( separator(), -1, 0 );
+  createPopupItem( SMESHOp::OpClearMesh,              OB, mesh );
+  popupMgr()->insert( separator(), -1, 0 );
 
   QString only_one_non_empty = QString( " && %1=1 && numberOfNodes>0" ).arg( dc );
   QString multiple_non_empty = QString( " && %1>0 && numberOfNodes>0" ).arg( dc );
@@ -4358,9 +4374,9 @@ void SMESHGUI::initialize( CAM_Application* app )
 #ifdef WITH_CGNS
   createPopupItem( SMESHOp::OpPopupExportCGNS, OB, mesh_group, multiple_non_empty, anId );
 #endif
-  createPopupItem( SMESHOp::OpPopupExportSAUV, OB, mesh_group, multiple_non_empty, anId );
-  createPopupItem( SMESHOp::OpPopupExportGMF,  OB, mesh_group, multiple_non_empty, anId );
-  createPopupItem( SMESHOp::OpPopupExportDAT,  OB, mesh_group, multiple_non_empty, anId );
+  createPopupItem( SMESHOp::OpPopupExportSAUV, OB, mesh_group, only_one_non_empty, anId );
+  createPopupItem( SMESHOp::OpPopupExportGMF,  OB, mesh_group, only_one_non_empty, anId );
+  createPopupItem( SMESHOp::OpPopupExportDAT,  OB, mesh_group, only_one_non_empty, anId );
   createPopupItem( SMESHOp::OpDelete,          OB, mesh_part + " " + hyp_alg );
   createPopupItem( SMESHOp::OpDeleteGroup,     OB, group );
   popupMgr()->insert( separator(), -1, 0 );
@@ -4525,12 +4541,8 @@ void SMESHGUI::initialize( CAM_Application* app )
 
   aSubId = popupMgr()->insert( tr( "MEN_EDGE_CTRL" ), anId, -1 ); // EDGE CONTROLS
 
-  popupMgr()->insert( action( SMESHOp::OpFreeEdge ), aSubId, -1 );
-  popupMgr()->setRule( action( SMESHOp::OpFreeEdge ), aMeshInVtkHasEdges, QtxPopupMgr::VisibleRule );
-  popupMgr()->setRule( action( SMESHOp::OpFreeEdge ), "controlMode = 'eFreeEdges'", QtxPopupMgr::ToggleRule );
-
   popupMgr()->insert( action( SMESHOp::OpFreeBorder ), aSubId, -1 );
-  popupMgr()->setRule( action( SMESHOp::OpFreeBorder ), aMeshInVtkHasEdges, QtxPopupMgr::VisibleRule );
+  popupMgr()->setRule( action( SMESHOp::OpFreeBorder ), aMeshInVTK + "&&" + hasEdges + "&&" + hasFacesOrVolumes, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( SMESHOp::OpFreeBorder ), "controlMode = 'eFreeBorders'", QtxPopupMgr::ToggleRule );
 
   popupMgr()->insert( action( SMESHOp::OpLength ), aSubId, -1 );
@@ -4546,6 +4558,10 @@ void SMESHGUI::initialize( CAM_Application* app )
 
   aSubId = popupMgr()->insert( tr( "MEN_FACE_CTRL" ), anId, -1 ); // FACE CONTROLS
 
+  popupMgr()->insert( action( SMESHOp::OpFreeEdge ), aSubId, -1 );
+  popupMgr()->setRule( action( SMESHOp::OpFreeEdge ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
+  popupMgr()->setRule( action( SMESHOp::OpFreeEdge ), "controlMode = 'eFreeEdges'", QtxPopupMgr::ToggleRule );
+
   popupMgr()->insert ( action( SMESHOp::OpFreeFace ), aSubId, -1 );
   popupMgr()->setRule( action( SMESHOp::OpFreeFace ), aMeshInVtkHasFaces /*aMeshInVtkHasVolumes*/,
                                        QtxPopupMgr::VisibleRule );
@@ -4626,6 +4642,9 @@ void SMESHGUI::initialize( CAM_Application* app )
 
   popupMgr()->insert( separator(), anId, -1 );
 
+  popupMgr()->insert( action( SMESHOp::OpShowScalarBar ), anId, -1 );
+  popupMgr()->setRule( action( SMESHOp::OpShowScalarBar ), aMeshInVTK + "&& controlMode <> 'eNone'", QtxPopupMgr::VisibleRule );
+  popupMgr()->setRule( action( SMESHOp::OpShowScalarBar ), aMeshInVTK + "&& controlMode <> 'eNone' && isScalarBarVisible", QtxPopupMgr::ToggleRule );
   popupMgr()->insert( action( SMESHOp::OpScalarBarProperties ), anId, -1 );
   popupMgr()->setRule( action( SMESHOp::OpScalarBarProperties ), aMeshInVTK + "&& controlMode <> 'eNone'", QtxPopupMgr::VisibleRule );
 
@@ -4638,7 +4657,7 @@ void SMESHGUI::initialize( CAM_Application* app )
 
   popupMgr()->insert( action( SMESHOp::OpShowDistribution ), aSubId, -1 );
   popupMgr()->setRule( action( SMESHOp::OpShowDistribution ), aMeshInVTK + "&& isNumFunctor", QtxPopupMgr::VisibleRule );
-  popupMgr()->setRule( action( SMESHOp::OpShowDistribution ), aMeshInVTK + "&& isNumFunctor && isDistributionVisible", QtxPopupMgr::ToggleRule);
+  popupMgr()->setRule( action( SMESHOp::OpShowDistribution ), aMeshInVTK + "&& isNumFunctor && isScalarBarVisible && isDistributionVisible", QtxPopupMgr::ToggleRule);
 
 #ifndef DISABLE_PLOT2DVIEWER
   popupMgr()->insert( action( SMESHOp::OpPlotDistribution ), aSubId, -1 );
@@ -4721,32 +4740,28 @@ bool SMESHGUI::activateModule( SUIT_Study* study )
 
   // import Python module that manages SMESH plugins (need to be here because SalomePyQt API uses active module)
   PyGILState_STATE gstate = PyGILState_Ensure();
-  PyObjWrapper pluginsmanager = PyImport_ImportModuleNoBlock((char*)"salome_pluginsmanager");
+  PyObject* pluginsmanager = PyImport_ImportModuleNoBlock((char*)"salome_pluginsmanager");
   if ( !pluginsmanager ) {
     PyErr_Print();
   }
   else {
-    PyObjWrapper result = PyObject_CallMethod( pluginsmanager, (char*)"initialize", (char*)"isss",1,"smesh",tr("MEN_MESH").toStdString().c_str(),tr("SMESH_PLUGINS_OTHER").toStdString().c_str());
+    PyObject* result = PyObject_CallMethod( pluginsmanager, (char*)"initialize", (char*)"isss",1,"smesh",tr("MEN_MESH").toUtf8().data(),tr("SMESH_PLUGINS_OTHER").toUtf8().data());
     if ( !result )
       PyErr_Print();
+    Py_XDECREF(result);
   }
   PyGILState_Release(gstate);
   // end of SMESH plugins loading
 
   // Reset actions accelerator keys
-  //action(SMESHOp::OpImportDAT)->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_B));
-  action(SMESHOp::OpImportUNV)->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_U));
-  action(SMESHOp::OpImportMED)->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_M));
-
   action(SMESHOp::OpDelete)->setEnabled(true); // Delete: Key_Delete
 
   //  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()) {
+  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.
@@ -4758,6 +4773,7 @@ bool SMESHGUI::activateModule( SUIT_Study* study )
       connectView( wnd );
   }
 
+  Py_XDECREF(pluginsmanager);
   return res;
 }
 
@@ -4769,10 +4785,6 @@ bool SMESHGUI::deactivateModule( SUIT_Study* study )
   EmitSignalCloseAllDialogs();
 
   // Unset actions accelerator keys
-  //action(SMESHOp::OpImportDAT)->setShortcut(QKeySequence());
-  action(SMESHOp::OpImportUNV)->setShortcut(QKeySequence());
-  action(SMESHOp::OpImportMED)->setShortcut(QKeySequence());
-
   action(SMESHOp::OpDelete)->setEnabled(false); // Delete: Key_Delete
 
   return SalomeApp_Module::deactivateModule( study );
@@ -4829,7 +4841,7 @@ void SMESHGUI::contextMenuPopup( const QString& client, QMenu* menu, QString& ti
     _PTR(Study) study = appStudy->studyDS();
     _PTR(SObject) obj = study->FindObjectID( io->getEntry() );
     if ( obj ) {
-      QString aName = QString( QString::fromUtf8(obj->GetName().c_str()) );
+      QString aName = QString( SMESH::fromUtf8(obj->GetName()) );
       while ( aName.at( aName.length() - 1 ) == ' ' ) // Remove extraspaces in Name of Popup
           aName.remove( (aName.length() - 1), 1 );
       title = aName;
@@ -4846,7 +4858,9 @@ void SMESHGUI::windows( QMap<int, int>& aMap ) const
 {
   aMap.insert( SalomeApp_Application::WT_ObjectBrowser, Qt::LeftDockWidgetArea );
   aMap.insert( SalomeApp_Application::WT_NoteBook, Qt::LeftDockWidgetArea );
+#ifndef DISABLE_PYCONSOLE
   aMap.insert( SalomeApp_Application::WT_PyConsole, Qt::BottomDockWidgetArea );
+#endif
 }
 
 void SMESHGUI::viewManagers( QStringList& list ) const
@@ -4864,6 +4878,7 @@ void SMESHGUI::onViewManagerActivated( SUIT_ViewManager* mgr )
       SUIT_ViewWindow *sf = aViews[i];
       connectView( sf );
     }
+    EmitSignalActivatedViewManager();
   }
 }
 
@@ -4886,7 +4901,7 @@ void SMESHGUI::ProcessEvents( vtkObject* theObject,
                               void* theCallData )
 {
   if( SMESHGUI* aSMESHGUI = reinterpret_cast<SMESHGUI*>( theClientData ) ) {
-    if( theObject && theEvent == SMESH::DeleteActorEvent ) {
+    if( theObject && (int) theEvent == SMESH::DeleteActorEvent ) {
       if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( theObject ) ) {
         SMESHGUI_ClippingPlaneInfoMap& aClippingPlaneInfoMap = aSMESHGUI->getClippingPlaneInfoMap();
         SMESHGUI_ClippingPlaneInfoMap::iterator anIter1 = aClippingPlaneInfoMap.begin();
@@ -4937,7 +4952,7 @@ void SMESHGUI::createPreferences()
   setPreferenceProperty( doubleNodesTol, "max", 1000000.0 );
   setPreferenceProperty( doubleNodesTol, "step", 0.0000001 );
 
-  int dispgroup = addPreference( tr( "PREF_DISPLAY_MODE" ), genTab );
+  int dispgroup = addPreference( tr( "PREF_DISPLAY_MODE_GROUP" ), genTab );
   setPreferenceProperty( dispgroup, "columns", 2 );
   int dispmode = addPreference( tr( "PREF_DISPLAY_MODE" ), dispgroup, LightApp_Preferences::Selector, "SMESH", "display_mode" );
   QStringList modes;
@@ -4953,7 +4968,7 @@ void SMESHGUI::createPreferences()
   setPreferenceProperty( dispmode, "strings", modes );
   setPreferenceProperty( dispmode, "indexes", indices );
 
-  int arcgroup = addPreference( tr( "QUADRATIC_REPRESENT_MODE" ), genTab );
+  int arcgroup = addPreference( tr( "QUADRATIC_REPRESENT_MODE_GROUP" ), genTab );
   setPreferenceProperty( arcgroup, "columns", 2 );
   int quadraticmode = addPreference( tr( "QUADRATIC_REPRESENT_MODE" ), arcgroup, LightApp_Preferences::Selector, "SMESH", "quadratic_mode" );
   QStringList quadraticModes;
@@ -5124,8 +5139,10 @@ void SMESHGUI::createPreferences()
 
   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 ballSize = addPreference(tr("PREF_BALL_SIZE"), elemGroup,
+                             LightApp_Preferences::IntSpin, "SMESH", "ball_elem_size"); */
+  double ballDiameter = addPreference(tr("PREF_BALL_DIAMETER"), elemGroup,
+                             LightApp_Preferences::DblSpin, "SMESH", "ball_elem_diameter");
   double ballScale = addPreference(tr("PREF_BALL_SCALE"), elemGroup,
                              LightApp_Preferences::DblSpin, "SMESH", "ball_elem_scale");
   int elemW  = addPreference(tr("PREF_WIDTH"), elemGroup,
@@ -5138,8 +5155,12 @@ void SMESHGUI::createPreferences()
   setPreferenceProperty( size0d, "min", 1 );
   setPreferenceProperty( size0d, "max", 10 );
 
-  setPreferenceProperty( ballSize, "min", 1 );
-  setPreferenceProperty( ballSize, "max", 10 );
+ // setPreferenceProperty( ballSize, "min", 1 );
+ // setPreferenceProperty( ballSize, "max", 10 );
+
+  setPreferenceProperty( ballDiameter, "min", 1e-7 );
+  setPreferenceProperty( ballDiameter, "max", 1e9 );
+  setPreferenceProperty( ballDiameter, "step", 0.1 );
 
   setPreferenceProperty( ballScale, "min", 1e-2 );
   setPreferenceProperty( ballScale, "max", 1e7 );
@@ -5284,79 +5305,92 @@ void SMESHGUI::createPreferences()
 
 void SMESHGUI::preferencesChanged( const QString& sect, const QString& name )
 {
-  if( sect=="SMESH" ) {
-    float sbX1,sbY1,sbW,sbH;
+  if ( sect=="SMESH" ) {
+    float sbX1 = 0.01, sbY1 = 0.01, sbW = 0.08, sbH = 0.08;
     float aTol = 1.00000009999999;
     std::string aWarning;
     SUIT_ResourceMgr* aResourceMgr = SMESH::GetResourceMgr(this);
-    if( name=="selection_object_color" || name=="selection_element_color" ||
-        name=="highlight_color" ||
-        name=="selection_precision_node" || name=="selection_precision_element" ||
-        name=="selection_precision_object")
+
+    if ( name== "selection_object_color" ||
+         name=="selection_element_color" ||
+         name==        "highlight_color" ||
+         name=="selection_precision_node"    ||
+         name=="selection_precision_element" ||
+         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){
+    }
+    else if (name == "scalar_bar_vertical_x" || name == "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);
+        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){
+    else if (name == "scalar_bar_vertical_y" || name == "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_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){
+    else if (name == "scalar_bar_horizontal_x" || name ==  "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;
+        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){
+    else if (name == "scalar_bar_horizontal_y" || name ==  "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;
+        sbH =0.08;
         aResourceMgr->setValue("SMESH", "scalar_bar_horizontal_y", sbY1);
         aResourceMgr->setValue("SMESH", "scalar_bar_horizontal_height",sbH);
       }
     }
-    else if ( name == "segmentation" ) {
+    else if ( name == "segmentation" )
+    {
       int nbSeg = aResourceMgr->integerValue( "SMESH", "segmentation", 10 );
       myComponentSMESH->SetBoundaryBoxSegmentation( nbSeg );
     }
-    else if ( name == "nb_segments_per_edge" ) {
+    else if ( name == "nb_segments_per_edge" )
+    {
       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") {
+    else if ( name == "historical_python_dump" || name == "forget_mesh_on_hyp_modif" || name == "default_grp_color" )
+    {
       QString val = aResourceMgr->stringValue( "SMESH", name );
       myComponentSMESH->SetOption( name.toLatin1().constData(), val.toLatin1().constData() );
     }
-    else if ( name == QString( "numbering_node_color" ) || name == QString( "numbering_node_font" ) ) {
-      SMESH::UpdateFontProp( this );    
+    else if ( name == "numbering_node_color" || name == "numbering_node_font" )
+    {
+      SMESH::UpdateFontProp( this );
     }
-    else if ( name == QString( "numbering_elem_color" ) || name == QString( "numbering_elem_font" ) ) {
+    else if ( name == "numbering_elem_color" || name == "numbering_elem_font" )
+    {
       SMESH::UpdateFontProp( this );
     }
 
-    if(aWarning.size() != 0){
+    if ( aWarning.size() != 0 ) {
       aWarning += "The default values are applied instead.";
       SUIT_MessageBox::warning(SMESHGUI::desktop(),
                                QObject::tr("SMESH_ERR_SCALARBAR_PARAMS"),
@@ -5428,6 +5462,9 @@ LightApp_Operation* SMESHGUI::createOperation( const int id ) const
   // to do : create operation here
   switch( id )
   {
+    case SMESHOp::OpSplitBiQuadratic:
+      op = new SMESHGUI_SplitBiQuadOp();
+    break;
     case SMESHOp::OpConvertMeshToQuadratic:
       op = new SMESHGUI_ConvToQuadOp();
     break;
@@ -5816,7 +5853,8 @@ void SMESHGUI::storeVisualParameters (int savePoint)
                   sizeStr << "elem0d";
                   sizeStr << QString::number((int)aSmeshActor->Get0DSize());
                   sizeStr << "ball";
-                  sizeStr << QString::number((int)aSmeshActor->GetBallSize());
+                  //sizeStr << QString::number((int)aSmeshActor->GetBallSize());
+                  sizeStr << QString::number((double)aSmeshActor->GetBallSize());
                   sizeStr << QString::number((double)aSmeshActor->GetBallScale());
                   sizeStr << "shrink";
                   sizeStr << QString::number(aSmeshActor->GetShrinkFactor());
@@ -6401,7 +6439,8 @@ void SMESHGUI::restoreVisualParameters (int savePoint)
               int lineWidth = -1;
               int outlineWidth = -1;
               int elem0dSize = -1;
-              int ballSize = -1;
+              //int ballSize = -1;
+              double ballDiameter = -1.0;
               double ballScale = -1.0;
               double shrinkSize = -1;
               double orientationSize = -1;
@@ -6434,10 +6473,12 @@ void SMESHGUI::restoreVisualParameters (int savePoint)
                   // - size - is a integer value specifying size
                   // - scale - is a double value specifying scale factor
                   if ( i+1 >= sizes.count() ) break;                       // format error
-                  int v1 = sizes[i+1].toInt( &bOk ); if ( !bOk ) break;    // format error
+                  //int v1 = sizes[i+1].toInt( &bOk ); if ( !bOk ) break;    // format error
+                  double v1 = sizes[i+1].toInt( &bOk ); if ( !bOk ) break;    // format error
                   if ( i+2 >= sizes.count() ) break;                       // format error
                   double v2 = sizes[i+2].toDouble( &bOk ); if ( !bOk ) break; // format error
-                  ballSize = v1;
+                  //ballSize = v1;
+                  ballDiameter = v1;
                   ballScale = v2;
                   i += 2;
                 }
@@ -6473,8 +6514,11 @@ void SMESHGUI::restoreVisualParameters (int savePoint)
               if ( elem0dSize > 0 )
                 aSmeshActor->Set0DSize( elem0dSize );
               // ball size
-              if ( ballSize > 0 )
-                aSmeshActor->SetBallSize( ballSize );
+              /*if ( ballSize > 0 )
+                aSmeshActor->SetBallSize( ballSize );*/
+              // ball diameter
+              if ( ballDiameter > 0 )
+                aSmeshActor->SetBallSize( ballDiameter );
               // ball scale
               if ( ballScale > 0.0 )
                 aSmeshActor->SetBallScale( ballScale );
@@ -6781,6 +6825,47 @@ void SMESHGUI::onHypothesisEdit( int result )
   updateObjBrowser( true );
 }
 
+/*!
+  \brief Actions after choosing menu of control modes
+  Updates control mode actions according to current selection
+*/
+void SMESHGUI::onUpdateControlActions()
+{
+  LightApp_SelectionMgr* aSel = SMESHGUI::selectionMgr();
+  SALOME_ListIO selected;
+  if ( aSel )
+    aSel->selectedObjects( selected );
+
+  SMESH_Actor::eControl aControl = SMESH_Actor::eNone;
+  if ( selected.Extent() ) {
+    if ( selected.First()->hasEntry() ) {
+      aControl = SMESH::FindActorByEntry( selected.First()->getEntry() )->GetControlMode();
+      SALOME_ListIteratorOfListIO it(selected);
+      for ( ; it.More(); it.Next() ) {
+        Handle(SALOME_InteractiveObject) anIO = it.Value();
+        if ( anIO->hasEntry() ) {
+          if ( SMESH_Actor* anActor = SMESH::FindActorByEntry( anIO->getEntry() ) ) {
+            if ( aControl != anActor->GetControlMode() ) {
+              aControl = SMESH_Actor::eNone;
+              break;
+            }
+          }
+        }
+      }
+    }
+  }
+
+  int anAction = ActionToControl( aControl, true );
+  if ( anAction)
+    action( anAction )->setChecked( true );
+  else {
+    QMenu* send = (QMenu*)sender();
+    QList<QAction*> actions = send->actions();
+    for ( int i = 0; i < actions.size(); i++ )
+      actions[i]->setChecked( false );
+  }
+}
+
 
 /*!
   \brief Signal handler closing(SUIT_ViewWindow*) of a view
@@ -6791,6 +6876,7 @@ void SMESHGUI::onViewClosed( SUIT_ViewWindow* pview ) {
   //Crear all Plot2d Viewers if need.
   SMESH::ClearPlot2Viewers(pview);
 #endif
+  EmitSignalCloseView();
 }
 
 void SMESHGUI::message( const QString& msg )
@@ -6809,7 +6895,7 @@ void SMESHGUI::message( const QString& msg )
       _PTR(SObject) obj = study->FindObjectID( entry.toLatin1().constData() );
       QString name;
       if ( obj )
-        name = QString::fromUtf8(obj->GetName().c_str());
+        name = SMESH::fromUtf8(obj->GetName());
       if ( name.isEmpty() )
         return;
       
index 9055fd200c3516e140e106cdeee4871800dd9f28..12d43fc6d37e9713e2efc733552477ea5f0c122f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -133,6 +133,8 @@ public :
   void                            EmitSignalStudyFrameChanged();
   void                            EmitSignalCloseAllDialogs();
   void                            EmitSignalVisibilityChanged();
+  void                            EmitSignalCloseView();
+  void                            EmitSignalActivatedViewManager();
 
   virtual void                    contextMenuPopup( const QString&, QMenu*, QString& );
   virtual void                    createPreferences();
@@ -169,12 +171,15 @@ private slots:
   void                            onOperationCommited( SUIT_Operation* );
   void                            onOperationAborted( SUIT_Operation* );
   void                            onHypothesisEdit( int result );
+  void                            onUpdateControlActions();
 
 signals:
   void                            SignalDeactivateActiveDialog();
   void                            SignalStudyFrameChanged();
   void                            SignalCloseAllDialogs();
   void                            SignalVisibilityChanged();
+  void                            SignalCloseView();
+  void                            SignalActivatedViewManager();
 
 protected:
   void                            createSMESHAction( const int,
index b053c60998ec2d5b549fb32633f3b75cb5b23029..8578dbf34df7ba4d870a17963d2d73c5b16e3354 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -223,6 +223,7 @@ SMESHGUI_Add0DElemsOnAllNodesOp::SMESHGUI_Add0DElemsOnAllNodesOp()
 
   connect( myDlg,              SIGNAL( selTypeChanged(int) ), SLOT( onSelTypeChange(int)));
   connect( myDlg->myFilterBtn, SIGNAL( clicked()),            SLOT( onSetFilter() ));
+  connect( myDlg->myGroupBox,  SIGNAL( clicked(bool)),        SLOT( updateButtons() ));
 }
 
 //================================================================================
@@ -270,6 +271,7 @@ void SMESHGUI_Add0DElemsOnAllNodesOp::selectionDone()
 
   myIO.Nullify();
   myDlg->setObjectText( 0, "");
+  updateButtons();
 
   SALOME_ListIO aList;
   selectionMgr()->selectedObjects( aList );
@@ -297,12 +299,14 @@ void SMESHGUI_Add0DElemsOnAllNodesOp::selectionDone()
   // fill the list of existing groups
   myDlg->myGroupListCmBox->clear();
   myDlg->myGroupListCmBox->addItem( QString() );
-  if ( !myIO.IsNull() && myIO->hasEntry()) {
-    _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
-    _PTR(SObject) meshSO = aStudy->FindObjectID( myIO->getEntry() );
+  if ( !myIO.IsNull() && myIO->hasEntry())
+  {
+    SMESH::SMESH_Mesh_var mesh = SMESH::GetMeshByIO( myIO );
+    _PTR(SObject)       meshSO = SMESH::ObjectToSObject( mesh );
     _PTR(SObject) group0DRoot;
-    if ( meshSO->FindSubObject( SMESH::Tag_0DElementsGroups, group0DRoot ))
+    if ( meshSO && meshSO->FindSubObject( SMESH::Tag_0DElementsGroups, group0DRoot ))
     {
+      _PTR(Study)              aStudy = SMESH::GetActiveStudyDocument();
       _PTR(ChildIterator) group0DIter = aStudy->NewChildIterator( group0DRoot );
       for ( ; group0DIter->More(); group0DIter->Next() )
       {
@@ -312,7 +316,42 @@ void SMESHGUI_Add0DElemsOnAllNodesOp::selectionDone()
           myDlg->myGroupListCmBox->addItem( groupName.c_str() );
       }
     }
+    // enable buttons
+    updateButtons();
+  }
+}
+
+//=======================================================================
+//function : updateButtons
+//purpose  : enable [Apply]
+//=======================================================================
+
+void SMESHGUI_Add0DElemsOnAllNodesOp::updateButtons()
+{
+  bool ok = false;
+
+  if (( !myIO.IsNull() && myIO->hasEntry() && !myDlg->objectText( 0 ).isEmpty() ) &&
+      ( !myDlg->myGroupBox->isChecked() || !myDlg->myGroupListCmBox->currentText().isEmpty() ))
+  {
+    SMESH::SMESH_Mesh_var mesh = SMESH::GetMeshByIO( myIO );
+    if ( !mesh->_is_nil() )
+    {
+      if ( myDlg->getSelectionType() == SEL_OBJECT )
+        ok = true;
+      else
+      {
+        QString        ids = myDlg->objectText( 0 );
+        QStringList idList = ids.split( " ", QString::SkipEmptyParts );
+        const bool  isElem = ( myDlg->getSelectionType() == SEL_ELEMENTS );
+        QStringList::iterator idIt = idList.begin();
+        for ( ; idIt != idList.end() && !ok; ++idIt )
+          ok = ( mesh->GetElementType( idIt->toLong(), isElem ) != SMESH::ALL );
+      }
+    }
   }
+
+  myDlg->button( QtxDialog::Apply )->setEnabled( ok );
+  myDlg->button( QtxDialog::OK    )->setEnabled( ok );
 }
 
 //================================================================================
@@ -353,7 +392,7 @@ bool SMESHGUI_Add0DElemsOnAllNodesOp::onApply()
     return false;
 
   // get a mesh
-  SMESH::SMESH_IDSource_wrap meshObject;
+  SMESH::IDSource_wrap meshObject;
   SMESH::SMESH_Mesh_var      mesh;
   if ( !myIO.IsNull() )
   {
@@ -458,6 +497,9 @@ void SMESHGUI_Add0DElemsOnAllNodesOp::onSelTypeChange(int selType)
     disconnect( myDlg, SIGNAL( objectChanged( int, const QStringList& )),
                 this,  SLOT  ( onTextChanged( int, const QStringList& )));
 
+  connect( myDlg->myGroupListCmBox, SIGNAL( editTextChanged(const QString & )),
+           this,                    SLOT(   updateButtons() ));
+
   selectionDone();
 }
 
@@ -495,3 +537,14 @@ void SMESHGUI_Add0DElemsOnAllNodesOp::onSetFilter()
 
   myFilterDlg->show();
 }
+
+//=======================================================================
+//function : onTextChanged
+//purpose  : SLOT called when the user types IDs
+//=======================================================================
+
+void SMESHGUI_Add0DElemsOnAllNodesOp::onTextChanged( int obj, const QStringList& text )
+{
+  SMESHGUI_SelectionOp::onTextChanged( obj, text );
+  updateButtons();
+}
index d887c14515047eb14bb5fae3881d402a6be655bc..805b9316ba90962bcb24809958b96e0a28c641b7 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -99,6 +99,8 @@ class SMESHGUI_EXPORT SMESHGUI_Add0DElemsOnAllNodesOp : public SMESHGUI_Selectio
   virtual bool                   onApply();
   void                           onSelTypeChange(int);
   void                           onSetFilter();
+  virtual void                   onTextChanged( int, const QStringList& );
+  void                           updateButtons();
 
  private:
   SMESHGUI_Add0DElemsOnAllNodesDlg* myDlg;
index cbc584da5a2d85f976b4b9ad0188877b800dee6c..a93494cc31eddf83720949befb879ed860283448 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -169,7 +169,8 @@ namespace SMESH
       // Preview for the balls
       vtkProperty* aBallProp = vtkProperty::New();
       aBallProp->SetColor(ffc.red() / 255. , ffc.green() / 255. , ffc.blue() / 255.);
-      double aBallElemSize = SMESH::GetFloat("SMESH:ball_elem_size",10);
+      //double aBallElemSize = SMESH::GetFloat("SMESH:ball_elem_size",10);
+      double aBallElemSize = SMESH::GetFloat("SMESH:ball_elem_diameter",1);
       aBallProp->SetPointSize(aBallElemSize);
 
       myBallPolyData = vtkPolyData::New();
@@ -213,12 +214,13 @@ namespace SMESH
       SetVisibility(true, theActor->GetFacesOriented(), false);
     }
 
-    void SetBallPosition(SMESH_Actor* theActor,TVTKIds& theIds, double theDiameter) {
+    void SetBallPosition(SMESH_Actor* theActor,TVTKIds& theIds, double theDiameter)
+    {
       vtkUnstructuredGrid *aGrid = theActor->GetUnstructuredGrid();
       myBallPolyData->Reset();
       myBallPolyData->DeleteCells();
       myBallPolyData->SetPoints(aGrid->GetPoints());
-      
+
       vtkDataArray* aScalars = vtkDataArray::CreateDataArray(VTK_DOUBLE);
       aScalars->SetNumberOfComponents(1);
       aScalars->SetNumberOfTuples(theIds.size());
@@ -234,7 +236,7 @@ namespace SMESH
         aScalars->SetTuple(anId,&d);
         anIds->Reset();
       }
-      
+
       anIds->Delete();
       myBallPolyData->Modified();
       SetVisibility (false, false, true);
@@ -427,7 +429,7 @@ SMESHGUI_AddMeshElementDlg::SMESHGUI_AddMeshElementDlg( SMESHGUI*          theMo
     GroupC1Layout->addWidget(DiameterSpinBox, 1, 1, 1, 2);
 
     DiameterSpinBox->RangeStepAndValidator( 1e-7, 1e+9, 0.1 );
-    DiameterSpinBox->SetValue( 1. );
+    DiameterSpinBox->SetValue( SMESH::GetFloat("SMESH:ball_elem_diameter", 1) );
     connect( DiameterSpinBox, SIGNAL( valueChanged ( double ) ), this, SLOT( onDiameterChanged( ) ) );
   }
   /* Add to group ************************************************/
@@ -514,10 +516,13 @@ void SMESHGUI_AddMeshElementDlg::Init()
   connect(SelectButtonC1A1,SIGNAL(clicked()),                     SLOT(SetEditCurrentArgument()));
   connect(LineEditC1A1,    SIGNAL(textChanged(const QString&)),   SLOT(onTextChange(const QString&)));
   connect(mySMESHGUI,      SIGNAL(SignalDeactivateActiveDialog()),SLOT(DeactivateActiveDialog()));
+
   connect(mySelectionMgr,  SIGNAL(currentSelectionChanged()),     SLOT(SelectionIntoArgument()));
   /* to close dialog if study frame change */
   connect(mySMESHGUI,      SIGNAL(SignalStudyFrameChanged()),     SLOT(reject()));
-  connect(mySMESHGUI,      SIGNAL(SignalCloseAllDialogs()),       SLOT(reject()));    
+  connect(mySMESHGUI,      SIGNAL(SignalCloseAllDialogs()),       SLOT(reject()));
+  connect(mySMESHGUI,      SIGNAL(SignalActivatedViewManager()),  SLOT(onOpenView()));
+  connect(mySMESHGUI,      SIGNAL(SignalCloseView()),             SLOT(onCloseView()));
 
   if (Reverse)
     connect(Reverse,       SIGNAL(stateChanged(int)),             SLOT(CheckBox(int)));
@@ -578,6 +583,13 @@ void SMESHGUI_AddMeshElementDlg::ClickOnApply()
                                                tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 );
           if ( res == 1 ) return;
         }
+        SMESH::SMESH_GroupOnFilter_var aFilterGroup = SMESH::SMESH_GroupOnFilter::_narrow( myGroups[idx-1] );
+        if ( !aFilterGroup->_is_nil() ) {
+          int res = SUIT_MessageBox::question( this, tr( "SMESH_WRN_WARNING" ),
+                                               tr( "MESH_FILTER_GRP_CHOSEN" ).arg( aGroupName ),
+                                               tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 );
+          if ( res == 1 ) return;
+        }
         aGroup = myGroups[idx-1];
       }
     }
@@ -586,16 +598,19 @@ void SMESHGUI_AddMeshElementDlg::ClickOnApply()
     SMESH::long_array_var anIdList = new SMESH::long_array;
     anIdList->length( 1 );
     anIdList[0] = -1;
-    const bool onlyNodesInMesh = ( myMesh->NbElements() == 0 );
+    //const bool onlyNodesInMesh = ( myMesh->NbElements() == 0 );
+    int nbElemsBefore = 0;
 
     switch (myElementType) {
     case SMDSAbs_0DElement:
+      nbElemsBefore = myMesh->Nb0DElements();
       anIdList->length( anArrayOfIndices->length() );
       for ( size_t i = 0; i < anArrayOfIndices->length(); ++i )
         anIdList[i] = aMeshEditor->Add0DElement(anArrayOfIndices[i]);
       break;
     case SMDSAbs_Ball:
       if ( myGeomType == SMDSEntity_Ball ) {
+        nbElemsBefore = myMesh->NbBalls();
         anIdList->length( anArrayOfIndices->length() );
         for ( size_t i = 0; i < anArrayOfIndices->length(); ++i )
           anIdList[i] = aMeshEditor->AddBall(anArrayOfIndices[i],
@@ -603,21 +618,24 @@ void SMESHGUI_AddMeshElementDlg::ClickOnApply()
       }
       break;
     case SMDSAbs_Edge:
+      nbElemsBefore = myMesh->NbEdges();
       anIdList[0] = aMeshEditor->AddEdge(anArrayOfIndices.inout()); break;
     case SMDSAbs_Face:
+      nbElemsBefore = myMesh->NbFaces();
       if ( myIsPoly )
         anIdList[0] = aMeshEditor->AddPolygonalFace(anArrayOfIndices.inout());
       else
         anIdList[0] = aMeshEditor->AddFace(anArrayOfIndices.inout());
       break;
     default:
+      nbElemsBefore = myMesh->NbVolumes();
       anIdList[0] = aMeshEditor->AddVolume(anArrayOfIndices.inout()); break;
     }
 
     if ( anIdList[0] > 0 && addToGroup && !aGroupName.isEmpty() ) {
       SMESH::SMESH_Group_var aGroupUsed;
       if ( aGroup->_is_nil() ) {
-        // create new group 
+        // create new group
         aGroupUsed = SMESH::AddGroup( myMesh, (SMESH::ElementType)myElementType, aGroupName );
         if ( !aGroupUsed->_is_nil() ) {
           myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroupUsed));
@@ -625,7 +643,8 @@ void SMESHGUI_AddMeshElementDlg::ClickOnApply()
         }
       }
       else {
-        SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGroup );
+        SMESH::SMESH_GroupOnGeom_var     aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGroup );
+        SMESH::SMESH_GroupOnFilter_var aFilterGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGroup );
         if ( !aGeomGroup->_is_nil() ) {
           aGroupUsed = myMesh->ConvertToStandalone( aGeomGroup );
           if ( !aGroupUsed->_is_nil() && idx > 0 ) {
@@ -633,6 +652,13 @@ void SMESHGUI_AddMeshElementDlg::ClickOnApply()
             SMESHGUI::GetSMESHGUI()->getApp()->updateObjectBrowser();
           }
         }
+        else if ( !aFilterGroup->_is_nil() ) {
+          aGroupUsed = myMesh->ConvertToStandalone( aFilterGroup );
+          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 );
       }
@@ -646,8 +672,24 @@ void SMESHGUI_AddMeshElementDlg::ClickOnApply()
     mySelectionMgr->setSelectedObjects( aList, false );
 
     mySimulation->SetVisibility(false);
-    if ( onlyNodesInMesh )
-      myActor->SetRepresentation( SMESH_Actor::eEdge ); // wireframe
+    // if ( onlyNodesInMesh )
+    //   myActor->SetRepresentation( SMESH_Actor::eEdge ); // wireframe
+    if ( nbElemsBefore == 0  )
+    {
+      // 1st element of the type has been added, update actor to show this entity
+      unsigned int aMode = myActor->GetEntityMode();
+      switch ( myElementType ) {
+      case SMDSAbs_Edge:
+        myActor->SetRepresentation(SMESH_Actor::eEdge);
+        myActor->SetEntityMode( aMode |= SMESH_Actor::eEdges ); break;
+      case SMDSAbs_Face:
+        myActor->SetRepresentation(SMESH_Actor::eSurface);
+        myActor->SetEntityMode( aMode |= SMESH_Actor::eFaces ); break;
+      case SMDSAbs_Volume:
+        myActor->SetRepresentation(SMESH_Actor::eSurface);
+        myActor->SetEntityMode( aMode |= SMESH_Actor::eVolumes ); break;
+      }
+    }
     SMESH::UpdateView();
 
     buttonOk->setEnabled(false);
@@ -941,9 +983,15 @@ void SMESHGUI_AddMeshElementDlg::ActivateThisDialog()
 //=================================================================================
 void SMESHGUI_AddMeshElementDlg::enterEvent (QEvent*)
 {
-  if (GroupConstructors->isEnabled())
-    return;
-  ActivateThisDialog();
+  if ( !GroupConstructors->isEnabled() ) {
+    SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
+    if ( aViewWindow && !mySelector && !mySimulation) {
+      mySelector = aViewWindow->GetSelector();
+      mySimulation = new SMESH::TElementSimulation(
+        dynamic_cast<SalomeApp_Application*>( mySMESHGUI->application() ) );
+    }
+    ActivateThisDialog();
+  }
 }
 
 //=================================================================================
@@ -978,7 +1026,7 @@ void SMESHGUI_AddMeshElementDlg::keyPressEvent( QKeyEvent* e )
 }
 
 //=================================================================================
-// function : isValid
+// function : onDiameterChanged()
 // purpose  :
 //=================================================================================
 void SMESHGUI_AddMeshElementDlg::onDiameterChanged(){
@@ -986,7 +1034,37 @@ void SMESHGUI_AddMeshElementDlg::onDiameterChanged(){
 }
 
 //=================================================================================
-// function : isValid
+// function : onOpenView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_AddMeshElementDlg::onOpenView()
+{
+  if ( mySelector && mySimulation ) {
+    mySimulation->SetVisibility(false);
+    SMESH::SetPointRepresentation(false);
+  }
+  else {
+    mySelector = SMESH::GetViewWindow( mySMESHGUI )->GetSelector();
+    mySimulation = new SMESH::TElementSimulation(
+      dynamic_cast<SalomeApp_Application*>( mySMESHGUI->application() ) );
+    ActivateThisDialog();
+  }
+}
+
+//=================================================================================
+// function : onCloseView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_AddMeshElementDlg::onCloseView()
+{
+  DeactivateActiveDialog();
+  mySelector = 0;
+  delete mySimulation;
+  mySimulation = 0;
+}
+
+//=================================================================================
+// function : isValid()
 // purpose  :
 //=================================================================================
 bool SMESHGUI_AddMeshElementDlg::isValid()
index af99005e2e41d816486518f92fc80c5fb435b2ac..9b19e3b064b984bb46385c5b78cf678cdd78689e 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -130,6 +130,8 @@ private slots:
   void                        ActivateThisDialog();
   void                        CheckBox( int );
   void                        onTextChange( const QString& );
+  void                        onOpenView();
+  void                        onCloseView();
 };
 
 #endif // SMESHGUI_ADDMESHELEMENTDLG_H
index 31a6214dc95fe7eb5bb8430e22af1aff7d0068a5..5cfddb9ce8850d6010519951a9d9cb24e90ef2fb 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 
 namespace
 {
+
+  // Define the sequences of ids
+  static int FirstEdgeIds[] = {0};
+  static int LastEdgeIds[] =  {1};
+
+  static int FirstTriangleIds[] = {0,1,2};
+  static int LastTriangleIds[] =  {1,2,0};
+
+  static int FirstQuadrangleIds[] = {0,1,2,3};
+  static int LastQuadrangleIds[] =  {1,2,3,0};
+
+  static int FirstTetrahedronIds[] = {0,1,2,3,3,3};
+  static int LastTetrahedronIds[] =  {1,2,0,0,1,2};
+
+  static int FirstPyramidIds[] = {0,1,2,3,4,4,4,4};
+  static int LastPyramidIds[] =  {1,2,3,0,0,1,2,3};
+
+  static int FirstPentahedronIds[] = {0,1,2,3,4,5,0,1,2};
+  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};
+
+  static vector<int> FirstPolygonIds;
+  static vector<int> LastPolygonIds;
+
   void ReverseConnectivity( std::vector<vtkIdType> & ids, SMDSAbs_EntityType type,
                             bool toReverse, // inverse element
                             bool toVtkOrder ) // smds connectivity to vtk one
   {
     if ( toReverse ) // first reverse smds order
     {
-      const std::vector<int>& index = SMDS_MeshCell::reverseSmdsOrder(type);
+      const std::vector<int>& index = SMDS_MeshCell::reverseSmdsOrder(type, ids.size());
       SMDS_MeshCell::applyInterlace( index, ids );
     }
     if ( toVtkOrder ) // from smds to vtk connectivity
@@ -113,7 +139,8 @@ namespace
 }
 namespace SMESH
 {
-  class TElementSimulationQuad {
+  class TElementSimulationQuad
+  {
     SalomeApp_Application* myApplication;
     SUIT_ViewWindow* myViewWindow;
     SVTK_ViewWindow* myVTKViewWindow;
@@ -148,7 +175,7 @@ namespace SMESH
       myPreviewActor->PickableOff();
       myPreviewActor->VisibilityOff();
       myPreviewActor->SetMapper(myMapper);
-      
+
       QColor ffc, bfc;
       int delta;
       vtkProperty* myProp = vtkProperty::New();
@@ -249,35 +276,12 @@ namespace SMESH
 
       myGrid->Delete();
 
-//       myProp->Delete();
-//       myBackProp->Delete();
+      //       myProp->Delete();
+      //       myBackProp->Delete();
     }
   };
 }
 
-
-// Define the sequences of ids
-static int FirstEdgeIds[] = {0};
-static int LastEdgeIds[] =  {1};
-
-static int FirstTriangleIds[] = {0,1,2};
-static int LastTriangleIds[] =  {1,2,0};
-
-static int FirstQuadrangleIds[] = {0,1,2,3};
-static int LastQuadrangleIds[] =  {1,2,3,0};
-
-static int FirstTetrahedronIds[] = {0,1,2,3,3,3};
-static int LastTetrahedronIds[] =  {1,2,0,0,1,2};
-
-static int FirstPyramidIds[] = {0,1,2,3,4,4,4,4};
-static int LastPyramidIds[] =  {1,2,3,0,0,1,2,3};
-
-static int FirstPentahedronIds[] = {0,1,2,3,4,5,0,1,2};
-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.
@@ -335,7 +339,6 @@ SMESHGUI_AddQuadraticElementDlg::SMESHGUI_AddQuadraticElementDlg( SMESHGUI* theM
     mySMESHGUI( theModule ),
     mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
     myGeomType( theType ),
-    //myType( theType ),
     myBusy( false )
 {
   setModal( false );
@@ -359,6 +362,9 @@ SMESHGUI_AddQuadraticElementDlg::SMESHGUI_AddQuadraticElementDlg( SMESHGUI* theM
   case SMDSEntity_Quad_Quadrangle:
     anElementName = QString("QUADRATIC_QUADRANGLE");
     break;
+  case SMDSEntity_Quad_Polygon:
+    anElementName = QString("QUADRATIC_POLYGON");
+    break;
   case SMDSEntity_BiQuad_Quadrangle:
     anElementName = QString("BIQUADRATIC_QUADRANGLE");
     break;
@@ -561,6 +567,11 @@ void SMESHGUI_AddQuadraticElementDlg::Init()
     myNbCenterNodes = 1;
     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_quadrangles
     break;
+  case SMDSEntity_Quad_Polygon:
+    aNumRows = 5;
+    myNbCorners = 0; // no limit
+    myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_polygons
+    break;
   case SMDSEntity_Quad_Tetra:
     aNumRows = 6;
     myNbCorners = 4;
@@ -650,6 +661,8 @@ void SMESHGUI_AddQuadraticElementDlg::Init()
   connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), SLOT(DeactivateActiveDialog()));
   connect(mySMESHGUI, SIGNAL (SignalStudyFrameChanged()), SLOT(reject()));
   connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), SLOT(reject()));
+  connect(mySMESHGUI, SIGNAL (SignalActivatedViewManager()), SLOT(onOpenView()));
+  connect(mySMESHGUI, SIGNAL (SignalCloseView()), SLOT(onCloseView()));
 
   myCurrentLineEdit = myCornerNodes;
 
@@ -687,6 +700,7 @@ bool SMESHGUI_AddQuadraticElementDlg::ClickOnApply()
     break;
   case SMDSEntity_Quad_Triangle:
   case SMDSEntity_Quad_Quadrangle:
+  case SMDSEntity_Quad_Polygon:
   case SMDSEntity_BiQuad_Triangle:
   case SMDSEntity_BiQuad_Quadrangle:
   case SMDSEntity_Quad_Tetra:
@@ -714,7 +728,7 @@ bool SMESHGUI_AddQuadraticElementDlg::ClickOnApply()
   if ( myReverseCB->isChecked())
     ReverseConnectivity( anIds, myGeomType, /*toReverse=*/true, /*toVtkOrder=*/false );
 
-  int aNumberOfIds =  anIds.size();
+  int aNumberOfIds = anIds.size();
   SMESH::long_array_var anArrayOfIdeces = new SMESH::long_array;
   anArrayOfIdeces->length( aNumberOfIds );
 
@@ -737,7 +751,14 @@ bool SMESHGUI_AddQuadraticElementDlg::ClickOnApply()
       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( "MESH_GEOM_GRP_CHOSEN" ).arg( aGroupName ),
+                                             tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 );
+        if ( res == 1 ) return false;
+      }
+      SMESH::SMESH_GroupOnFilter_var aFilterGroup = SMESH::SMESH_GroupOnFilter::_narrow( myGroups[idx-1] );
+      if ( !aFilterGroup->_is_nil() ) {
+        int res = SUIT_MessageBox::question( this, tr( "SMESH_WRN_WARNING" ),
+                                             tr( "MESH_FILTER_GRP_CHOSEN" ).arg( aGroupName ),
                                              tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 );
         if ( res == 1 ) return false;
       }
@@ -746,24 +767,31 @@ bool SMESHGUI_AddQuadraticElementDlg::ClickOnApply()
   }
 
   SMESH::ElementType anElementType;
-  long anElemId = -1;
+  long anElemId = -1, nbElemsBefore = 0;
   SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
   switch (myGeomType) {
   case SMDSEntity_Quad_Edge:
     anElementType = SMESH::EDGE;
+    nbElemsBefore = myMesh->NbEdges();
     anElemId = aMeshEditor->AddEdge(anArrayOfIdeces.inout()); break;
   case SMDSEntity_Quad_Triangle:
   case SMDSEntity_Quad_Quadrangle:
   case SMDSEntity_BiQuad_Triangle:
   case SMDSEntity_BiQuad_Quadrangle:
     anElementType = SMESH::FACE;
+    nbElemsBefore = myMesh->NbFaces();
     anElemId = aMeshEditor->AddFace(anArrayOfIdeces.inout()); break;
+  case SMDSEntity_Quad_Polygon:
+    anElementType = SMESH::FACE;
+    nbElemsBefore = myMesh->NbFaces();
+    anElemId = aMeshEditor->AddQuadPolygonalFace(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;
+    nbElemsBefore = myMesh->NbVolumes();
     anElemId = aMeshEditor->AddVolume(anArrayOfIdeces.inout()); break;
   default: break;
   }
@@ -779,7 +807,8 @@ bool SMESHGUI_AddQuadraticElementDlg::ClickOnApply()
       }
     }
     else {
-      SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGroup );
+      SMESH::SMESH_GroupOnGeom_var     aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGroup );
+      SMESH::SMESH_GroupOnFilter_var aFilterGroup = SMESH::SMESH_GroupOnFilter::_narrow( aGroup );
       if ( !aGeomGroup->_is_nil() ) {
         aGroupUsed = myMesh->ConvertToStandalone( aGeomGroup );
         if ( !aGroupUsed->_is_nil() && idx > 0 ) {
@@ -787,6 +816,13 @@ bool SMESHGUI_AddQuadraticElementDlg::ClickOnApply()
           SMESHGUI::GetSMESHGUI()->getApp()->updateObjectBrowser();
         }
       }
+      else if ( !aFilterGroup->_is_nil() ) {
+        aGroupUsed = myMesh->ConvertToStandalone( aFilterGroup );
+        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 );
     }
@@ -799,6 +835,23 @@ bool SMESHGUI_AddQuadraticElementDlg::ClickOnApply()
     }
   }
 
+  if ( nbElemsBefore == 0  )
+  {
+    // 1st element of the type has been added, update actor to show this entity
+    unsigned int aMode = myActor->GetEntityMode();
+    switch ( anElementType ) {
+    case SMESH::EDGE:
+      myActor->SetRepresentation(SMESH_Actor::eEdge);
+      myActor->SetEntityMode( aMode |= SMESH_Actor::eEdges ); break;
+    case SMESH::FACE:
+      myActor->SetRepresentation(SMESH_Actor::eSurface);
+      myActor->SetEntityMode( aMode |= SMESH_Actor::eFaces ); break;
+    case SMESH::VOLUME:
+      myActor->SetRepresentation(SMESH_Actor::eSurface);
+      myActor->SetEntityMode( aMode |= SMESH_Actor::eVolumes ); break;
+    }
+  }
+
   SALOME_ListIO aList; aList.Append( myActor->getIO() );
   mySelector->ClearIndex();
   mySelectionMgr->setSelectedObjects( aList, false );
@@ -844,6 +897,35 @@ void SMESHGUI_AddQuadraticElementDlg::reject()
   QDialog::reject();
 }
 
+//=================================================================================
+// function : onOpenView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_AddQuadraticElementDlg::onOpenView()
+{
+  if ( mySelector && mySimulation ) {
+    mySimulation->SetVisibility(false);
+    SMESH::SetPointRepresentation(false);
+  }
+  else {
+    mySelector = SMESH::GetViewWindow( mySMESHGUI )->GetSelector();
+    mySimulation = new SMESH::TElementSimulationQuad(
+      dynamic_cast<SalomeApp_Application*>( mySMESHGUI->application() ) );
+    ActivateThisDialog();
+  }
+}
+
+//=================================================================================
+// function : onCloseView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_AddQuadraticElementDlg::onCloseView()
+{
+  DeactivateActiveDialog();
+  mySelector = 0;
+  delete mySimulation;
+  mySimulation = 0;
+}
 //=================================================================================
 // function : ClickOnHelp()
 // purpose  :
@@ -976,6 +1058,7 @@ void SMESHGUI_AddQuadraticElementDlg::SelectionIntoArgument()
       anElementType = SMESH::EDGE; break;
     case SMDSEntity_Quad_Triangle:
     case SMDSEntity_Quad_Quadrangle:
+    case SMDSEntity_Quad_Polygon:
     case SMDSEntity_BiQuad_Triangle:
     case SMDSEntity_BiQuad_Quadrangle:
       anElementType = SMESH::FACE; break;
@@ -1157,12 +1240,17 @@ void SMESHGUI_AddQuadraticElementDlg::ActivateThisDialog()
 // function : enterEvent()
 // purpose  :
 //=================================================================================
-
 void SMESHGUI_AddQuadraticElementDlg::enterEvent (QEvent*)
 {
-  if (GroupConstructors->isEnabled())
-    return;
-  ActivateThisDialog();
+  if ( !GroupConstructors->isEnabled() ) {
+    SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
+    if ( aViewWindow && !mySelector && !mySimulation) {
+      mySelector = aViewWindow->GetSelector();
+      mySimulation = new SMESH::TElementSimulationQuad(
+        dynamic_cast<SalomeApp_Application*>( mySMESHGUI->application() ) );
+    }
+    ActivateThisDialog();
+  }
 }
 
 //=================================================================================
@@ -1233,6 +1321,44 @@ void SMESHGUI_AddQuadraticElementDlg::UpdateTable( bool theConersValidity )
 {
   QStringList aListCorners = myCornerNodes->text().split(" ", QString::SkipEmptyParts);
 
+  if ( myGeomType == SMDSEntity_Quad_Polygon )        // POLYGON
+  {
+    if ( aListCorners.count() < 3 )
+      theConersValidity = false;
+
+    if ( aListCorners.count() != myTable->rowCount() && theConersValidity )
+    {
+      // adjust nb of rows for the polygon
+      int oldNbRows = myTable->rowCount();
+      myTable->setRowCount( aListCorners.count() );
+      for ( int row = oldNbRows; row < myTable->rowCount(); row++ )
+      {
+        myTable->setItem( row, 0, new QTableWidgetItem( "" ) );
+        myTable->item( row, 0 )->setFlags(0);
+
+        IdEditItem* anEditItem = new IdEditItem( "" );
+        anEditItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled);
+        myTable->setItem(row, 1, anEditItem);
+
+        myTable->setItem( row, 2, new QTableWidgetItem( "" ) );
+        myTable->item( row, 2 )->setFlags(0);
+      }
+      myNbCorners = aListCorners.count();
+
+      // fill FirstPolygonIds and LastPolygonIds
+      FirstPolygonIds.resize( aListCorners.count() );
+      LastPolygonIds .resize( aListCorners.count() );
+      for ( int i = 0; i < aListCorners.count(); ++i )
+      {
+        FirstPolygonIds[i] = i;
+        LastPolygonIds [i] = i+1;
+      }
+      LastPolygonIds.back() = 0;
+
+      myNbCorners = aListCorners.count();
+    }
+  }
+
   if ( aListCorners.count() == myNbCorners && theConersValidity )
   {
     myTable->setEnabled( true );
@@ -1259,6 +1385,10 @@ void SMESHGUI_AddQuadraticElementDlg::UpdateTable( bool theConersValidity )
       aFirstColIds = FirstQuadrangleIds;
       aLastColIds  = LastQuadrangleIds;
       break;
+    case SMDSEntity_Quad_Polygon:
+      aFirstColIds = & FirstPolygonIds[0];
+      aLastColIds  = & LastPolygonIds[0];
+      break;
     case SMDSEntity_Quad_Tetra:
       aFirstColIds = FirstTetrahedronIds;
       aLastColIds  = LastTetrahedronIds;
index bc336e668722d1f6e07a1efedb054c4447eca7fb..7a36de47b8048c1cb06693acf0cfed35ba7e3c14 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -142,6 +142,8 @@ private slots:
   void                        SelectionIntoArgument();
   void                        DeactivateActiveDialog();
   void                        ActivateThisDialog();
+  void                        onOpenView();
+  void                        onCloseView();
 };
 
 #endif // SMESHGUI_ADDQUADRATICELEMENTDLG_H
index f25ed72cc0e5dd1e3eac755cccc95607fed77b13..ae1f5ad3f371312ded0de3e7b2193d2764268696 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -200,11 +200,11 @@ void SMESHGUI_BuildCompoundDlg::Init()
 {
   mySMESHGUI->SetActiveDialogBox((QDialog*)this);
 
-  myMesh = SMESH::SMESH_Mesh::_nil();
+  myMesh = SMESH::SMESH_IDSource::_nil();
 
-  myMeshFilter = new SMESH_TypeFilter (SMESH::MESH);
+  myMeshFilter = new SMESH_TypeFilter (SMESH::IDSOURCE);
 
-  myMeshArray = new SMESH::mesh_array();
+  myMeshArray = new SMESH::ListOfIDSources();
 
   // signals and slots connections
   connect(buttonOk,     SIGNAL(clicked()), this, SLOT(ClickOnOk()));
@@ -228,7 +228,7 @@ void SMESHGUI_BuildCompoundDlg::Init()
   ComboBoxUnion->addItem(tr("RENAME"));
   ComboBoxUnion->setCurrentIndex(0);
 
-  CheckBoxMerge->setChecked(false);
+  CheckBoxMerge->setChecked(true);
 
   TextLabelTol->setEnabled(CheckBoxMerge->isChecked());
   SpinBoxTol->SetValue(1e-05);
@@ -289,7 +289,7 @@ bool SMESHGUI_BuildCompoundDlg::ClickOnApply()
   if (!isValid())
     return false;
 
-  SMESH::SMESH_Mesh_var aCompoundMesh;
+  SMESH::SMESH_Mesh_var aMesh;
 
   if (!myMesh->_is_nil())
   {
@@ -300,22 +300,23 @@ bool SMESHGUI_BuildCompoundDlg::ClickOnApply()
     try {
       SUIT_OverrideCursor aWaitCursor;
 
-      myMeshArray[0]->SetParameters( aParameters.join(":").toLatin1().constData() );
+      aMesh = myMeshArray[0]->GetMesh();
+      aMesh->SetParameters( aParameters.join(":").toLatin1().constData() );
 
       SMESH::SMESH_Gen_var aSMESHGen = SMESHGUI::GetSMESHGen();
       // concatenate meshes
       if(CheckBoxCommon->isChecked())
-        aCompoundMesh = aSMESHGen->ConcatenateWithGroups(myMeshArray,
-                                                         !(ComboBoxUnion->currentIndex()),
-                                                         CheckBoxMerge->isChecked(),
-                                                         SpinBoxTol->GetValue());
+        aMesh = aSMESHGen->ConcatenateWithGroups(myMeshArray,
+                                                 !(ComboBoxUnion->currentIndex()),
+                                                 CheckBoxMerge->isChecked(),
+                                                 SpinBoxTol->GetValue());
       else
-        aCompoundMesh = aSMESHGen->Concatenate(myMeshArray,
-                                               !(ComboBoxUnion->currentIndex()),
-                                               CheckBoxMerge->isChecked(),
-                                               SpinBoxTol->GetValue());
+        aMesh = aSMESHGen->Concatenate(myMeshArray,
+                                       !(ComboBoxUnion->currentIndex()),
+                                       CheckBoxMerge->isChecked(),
+                                       SpinBoxTol->GetValue());
 
-      _PTR(SObject) aSO = SMESH::FindSObject( aCompoundMesh );
+      _PTR(SObject) aSO = SMESH::FindSObject( aMesh );
       if( aSO ) {
         SMESH::SetName( aSO, LineEditName->text() );
         anEntryList.append( aSO->GetID().c_str() );
@@ -332,9 +333,11 @@ bool SMESHGUI_BuildCompoundDlg::ClickOnApply()
       mySelectionMgr->clearSelected();
       SMESH::UpdateView();
 
-      _PTR(SObject) aSO = SMESH::FindSObject(aCompoundMesh.in());
-      if ( SMESH_Actor* anActor = SMESH::CreateActor(aSO->GetStudy(), aSO->GetID().c_str()) )
+      _PTR(SObject) aSO = SMESH::FindSObject(aMesh.in());
+      if ( SMESH_Actor* anActor = SMESH::CreateActor(aSO->GetStudy(), aSO->GetID().c_str()) ) {
         SMESH::DisplayActor(SMESH::GetActiveWindow(), anActor);
+        SMESH::UpdateView();
+      }
     }// end IPAL21468
 
     if( LightApp_Application* anApp =
@@ -410,12 +413,12 @@ void SMESHGUI_BuildCompoundDlg::SelectionIntoArgument()
     for (int i = 0; nbSel != 0; i++, nbSel--) {
       Handle(SALOME_InteractiveObject) IO = aList.First();
       aList.RemoveFirst();
-      myMesh = SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(IO);
+      myMesh = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>(IO);
       myMeshArray[i] = myMesh;
     }
   }
   else {
-    myMesh = SMESH::SMESH_Mesh::_nil();
+    myMesh = SMESH::SMESH_IDSource::_nil();
     aString = "";
   }
 
index a4fd91a49e55bb148bd166a41060b69b98849f2d..161d2183fd7191cc11d06abcb65b5f9c31714754 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -80,9 +80,9 @@ private:
   SMESHGUI*               mySMESHGUI;     /* Current SMESHGUI object */
   LightApp_SelectionMgr*  mySelectionMgr; /* User shape selection */
 
-  SMESH::SMESH_Mesh_var   myMesh;
-  SUIT_SelectionFilter*   myMeshFilter;
-  SMESH::mesh_array_var   myMeshArray;
+  SMESH::SMESH_IDSource_var  myMesh;
+  SUIT_SelectionFilter*      myMeshFilter;
+  SMESH::ListOfIDSources_var myMeshArray;
 
   // Widgets
   QGroupBox*              GroupConstructors;
index 5df21bca00fcd09f657a66f75d6294807f6406f8..1d68b74fa04a8a9f980913c3307a423ac37cc33b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index bab2458ed20826fac0629768a3c923f4bf2b7cdf..194f6b2f6bc8ae80b0324f8093c8b6d3583c4568 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 1bf5e5c8b975283865894de8afd4f48782407be9..a71b425d407fdd28f5e16f52de0ac45022aada07 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
 //
 #include "SMESHGUI_ComputeDlg.h"
 
+#include "SMDS_Mesh.hxx"
+#include "SMDS_SetIterator.hxx"
 #include "SMESHGUI.h"
 #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_MeshInfosBox.h"
 #include "SMESHGUI_MeshOrderDlg.h"
-
+#include "SMESHGUI_MeshOrderOp.h"
+#include "SMESHGUI_MeshUtils.h"
+#include "SMESHGUI_VTKUtils.h"
 #include "SMESH_Actor.h"
 #include "SMESH_ActorUtils.h"
 
-#include <SMDS_SetIterator.hxx>
-#include <SMDS_Mesh.hxx>
-
 // SALOME GEOM includes
 #include <GEOMBase.h>
 #include <GEOM_Actor.h>
 // SALOME GUI includes
 #include <LightApp_SelectionMgr.h>
 #include <LightApp_UpdateFlags.h>
+#include <QtxComboBox.h>
 #include <SALOME_ListIO.hxx>
-#include <SVTK_ViewWindow.h>
+#include <SUIT_Desktop.h>
+#include <SUIT_MessageBox.h>
+#include <SUIT_OverrideCursor.h>
+#include <SUIT_ResourceMgr.h>
+#include <SUIT_Session.h>
 #include <SVTK_ViewModel.h>
+#include <SVTK_ViewWindow.h>
 #include <SalomeApp_Application.h>
-#include <SUIT_ResourceMgr.h>
-#include <SUIT_OverrideCursor.h>
-#include <SUIT_MessageBox.h>
-#include <SUIT_Desktop.h>
-#include <QtxComboBox.h>
 
 // SALOME KERNEL includes
 #include <SALOMEDS_SObject.hxx>
 #include <SALOMEDSClient_SObject.hxx>
 #include <SALOMEDS_wrap.hxx>
+#include "utilities.h"
 
 #include CORBA_SERVER_HEADER(SMESH_Group)
 
 // OCCT includes
+#include <BRepBndLib.hxx>
+#include <BRepMesh_IncrementalMesh.hxx>
 #include <BRep_Tool.hxx>
+#include <Bnd_Box.hxx>
+#include <Poly_Triangulation.hxx>
 #include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
+#include <TopLoc_Location.hxx>
 #include <TopTools_IndexedMapOfShape.hxx>
 #include <TopoDS.hxx>
 
-#include <TopLoc_Location.hxx>
-#include <Poly_Triangulation.hxx>
-#include <Bnd_Box.hxx>
-#include <BRepBndLib.hxx>
-#include <BRepMesh_IncrementalMesh.hxx>
-
 #include <Standard_ErrorHandler.hxx>
 
 // Qt includes
@@ -488,7 +487,7 @@ namespace SMESH
 //=======================================================================
 
 SMESHGUI_ComputeDlg::SMESHGUI_ComputeDlg( QWidget* parent, bool ForEval )
- : SMESHGUI_Dialog( parent, false, true, Close/* | Help*/ )
+ : SMESHGUI_Dialog( parent, false, true, Close | Help )
 {
   QVBoxLayout* aDlgLay = new QVBoxLayout (mainFrame());
   aDlgLay->setMargin( 0 );
@@ -1222,6 +1221,7 @@ void SMESHGUI_BaseComputeOp::onPublishShape()
   GEOM::GEOM_Gen_var geomGen = SMESH::GetGEOMGen();
   SALOMEDS::Study_var study = SMESHGUI::GetSMESHGen()->GetCurrentStudy();
 
+  QStringList entryList;
   QList<int> rows;
   SMESH::getSelectedRows( table(), rows );
   int row;
@@ -1259,10 +1259,13 @@ void SMESHGUI_BaseComputeOp::onPublishShape()
         QString       shapeText = QString("%1 (%2)").arg( name.in() ).arg( entry.in() );
         table()->item( row, COL_SHAPE     )->setText( shapeText );
         table()->item( row, COL_PUBLISHED )->setText( entry.in() );
+        entryList.push_back( entry.in() );
       }
     }
   }
   getSMESHGUI()->getApp()->updateObjectBrowser();
+  getSMESHGUI()->getApp()->browseObjects( entryList, /*isApplyAndClose=*/true );
+
   currentCellChanged(); // to update buttons
 }
 
@@ -1479,6 +1482,7 @@ QTableWidget* SMESHGUI_BaseComputeOp::table()
 SMESHGUI_ComputeOp::SMESHGUI_ComputeOp()
  : SMESHGUI_BaseComputeOp()
 {
+  myHelpFileName = "constructing_meshes_page.html#compute_anchor";
 }
 
 
@@ -1542,13 +1546,12 @@ LightApp_Dialog* SMESHGUI_ComputeOp::dlg() const
 //================================================================================
 
 SMESHGUI_PrecomputeOp::SMESHGUI_PrecomputeOp()
- : SMESHGUI_BaseComputeOp(),
- myDlg( 0 ),
- myOrderMgr( 0 ),
- myActiveDlg( 0 ),
- myPreviewDisplayer( 0 )
 : SMESHGUI_BaseComputeOp(),
   myDlg( 0 ),
   myOrderMgr( 0 ),
   myActiveDlg( 0 ),
   myPreviewDisplayer( 0 )
 {
-  myHelpFileName = "constructing_meshes_page.html#preview_mesh_anchor";
 }
 
 //================================================================================
@@ -1589,6 +1592,8 @@ LightApp_Dialog* SMESHGUI_PrecomputeOp::dlg() const
 
 void SMESHGUI_PrecomputeOp::startOperation()
 {
+  myHelpFileName = "constructing_meshes_page.html#preview_anchor"; // other anchor onCompute()
+
   if ( !myDlg )
   {
     myDlg = new SMESHGUI_PrecomputeDlg( desktop() );
@@ -1723,13 +1728,14 @@ void SMESHGUI_PrecomputeOp::initDialog()
 void SMESHGUI_PrecomputeOp::getAssignedAlgos(_PTR(SObject) theMesh,
                                              QMap<int,int>& theModeMap)
 {
-  _PTR(SObject)          aHypRoot;
+  if ( !theMesh ) return;
+  _PTR(SObject)          aHypFolder;
   _PTR(GenericAttribute) anAttr;
   int aPart = SMESH::Tag_RefOnAppliedAlgorithms;
-  if ( theMesh && theMesh->FindSubObject( aPart, aHypRoot ) )
+  if ( theMesh->FindSubObject( aPart, aHypFolder ) )
   {
     _PTR(ChildIterator) anIter =
-      SMESH::GetActiveStudyDocument()->NewChildIterator( aHypRoot );
+      SMESH::GetActiveStudyDocument()->NewChildIterator( aHypFolder );
     for ( ; anIter->More(); anIter->Next() )
     {
       _PTR(SObject) anObj = anIter->Value();
@@ -1738,16 +1744,16 @@ void SMESHGUI_PrecomputeOp::getAssignedAlgos(_PTR(SObject) theMesh,
         anObj = aRefObj;
       else
         continue;
-      
+
       if ( anObj->FindAttribute( anAttr, "AttributeName" ) )
       {
         CORBA::Object_var aVar = _CAST(SObject,anObj)->GetObject();
         if ( CORBA::is_nil( aVar ) )
           continue;
-        
+
+        SMESH::SMESH_Algo_var algo;
         for( int dim = SMESH::DIM_1D; dim <= SMESH::DIM_3D; dim++ )
         {
-          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;
@@ -1755,7 +1761,56 @@ void SMESHGUI_PrecomputeOp::getAssignedAlgos(_PTR(SObject) theMesh,
           default: break;
           }
           if ( !algo->_is_nil() )
+          {
             theModeMap[ dim ] = 0;
+            if ( theModeMap.size() == 3 )
+              return;
+            break;
+          }
+        }
+      }
+    }
+  }
+
+  // check sub-meshes
+  for ( aPart = SMESH::Tag_SubMeshOnEdge; aPart <= SMESH::Tag_LastSubMesh; ++aPart )
+  {
+    if ( !theMesh->FindSubObject( aPart, aHypFolder ))
+      continue;
+
+    _PTR(ChildIterator) anIter =
+      SMESH::GetActiveStudyDocument()->NewChildIterator( aHypFolder );
+    for ( anIter->InitEx(true); anIter->More(); anIter->Next() )
+    {
+      _PTR(SObject) anObj = anIter->Value();
+      _PTR(SObject) aRefObj;
+      if ( anObj->ReferencedObject( aRefObj ) )
+        anObj = aRefObj;
+      else
+        continue;
+
+      if ( anObj->FindAttribute( anAttr, "AttributeName" ))
+      {
+        CORBA::Object_var aVar = _CAST(SObject,anObj)->GetObject();
+        if ( CORBA::is_nil( aVar ) )
+          continue;
+
+        SMESH::SMESH_Algo_var algo;
+        for( int dim = SMESH::DIM_1D; dim <= SMESH::DIM_3D; dim++ )
+        {
+          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() )
+          {
+            theModeMap[ dim ] = 0;
+            if ( theModeMap.size() == 3 )
+              return;
+            break;
+          }
         }
       }
     }
@@ -1775,6 +1830,7 @@ void SMESHGUI_PrecomputeOp::onCompute()
     myOrderMgr->SetMeshOrder();
   myMapShapeId.clear();
   myActiveDlg = computeDlg();
+  myHelpFileName = "constructing_meshes_page.html#compute_anchor";
   computeMesh();
 }
 
@@ -1805,7 +1861,7 @@ void SMESHGUI_PrecomputeOp::onCancel()
       // remove all submeshes for collected shapes
       QMap<int,int>::const_iterator it = myMapShapeId.constBegin();
       for ( ; it != myMapShapeId.constEnd(); ++it )
-        myMesh->ClearSubMesh( *it );
+        myMesh->ClearSubMesh( it.key() );
       isRestoreOrder = true;
     }
   }
@@ -1847,19 +1903,19 @@ void SMESHGUI_PrecomputeOp::onPreview()
   if (myOrderMgr && myOrderMgr->IsOrderChanged())
     myOrderMgr->SetMeshOrder();
 
-  // Compute preview of mesh, 
+  // Compute preview of mesh,
   // i.e. compute mesh till indicated dimension
   int dim = myDlg->getPreviewMode();
-  
+
   SMESH::MemoryReserve aMemoryReserve;
-  
+
   SMESH::compute_error_array_var aCompErrors;
   QString                        aHypErrors;
 
   bool computeFailed = true, memoryLack = false;
 
   SMESHGUI_ComputeDlg* aCompDlg = computeDlg();
-    aCompDlg->myMeshName->setText( aMeshSObj->GetName().c_str() );
+  aCompDlg->myMeshName->setText( aMeshSObj->GetName().c_str() );
 
   SMESHGUI* gui = getSMESHGUI();
   SMESH::SMESH_Gen_var gen = gui->GetSMESHGen();
@@ -1959,6 +2015,7 @@ SMESHGUI_PrecomputeDlg::SMESHGUI_PrecomputeDlg( QWidget* parent )
 
   setButtonText( OK, tr( "COMPUTE" ) );
   QFrame* main = mainFrame();
+  main->setMinimumWidth( 300 );
 
   QVBoxLayout* layout = new QVBoxLayout( main );
 
@@ -2042,6 +2099,7 @@ SMESHGUI_MeshOrderBox* SMESHGUI_PrecomputeDlg::getMeshOrderBox() const
 SMESHGUI_EvaluateOp::SMESHGUI_EvaluateOp()
  : SMESHGUI_BaseComputeOp()
 {
+  myHelpFileName = "constructing_meshes_page.html#evaluate_anchor";
 }
 
 
index ad1bd8f985245931be0bfccaa75a2c516498083a..0c0b7ff317f0b979cb863d35cb2e21dd36c3986e 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index 59855bb494c0266f13a2df482356ba0ef5180d95..6ceca1063f786ecf07462f4cdb83f6aabc0199dc 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index d3b461fe598be27c4e83ff0b3afefd78a0af4a3d..80c848ad95d59cc7b60eb8fcbf4a66b00b7f0a19 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 70b7493cbcbe65f005424027f3a96c6157f0da58..cc60fc47115f115e3ee26bedcf2be90059df158f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -105,7 +105,7 @@ void SMESHGUI_ConvToQuadOp::startOperation()
 
   SMESHGUI_SelectionOp::startOperation();
 
-  myDlg->SetMediumNdsOnGeom( false );
+  myDlg->SetMediumNdsOnGeom( true );
   myDlg->activateObject( 0 );
   myDlg->ShowWarning( false );
   myDlg->show();
@@ -346,6 +346,7 @@ SMESHGUI_ConvToQuadOp::DestinationMesh( const SMESH::SMESH_IDSource_var& idSourc
                    nbElemOfType[SMDSEntity_Quad_Tetra     ] ||
                    nbElemOfType[SMDSEntity_Quad_Hexa      ] ||
                    nbElemOfType[SMDSEntity_Quad_Pyramid   ] ||
+                   nbElemOfType[SMDSEntity_Quad_Polygon   ] ||
                    nbElemOfType[SMDSEntity_Quad_Penta     ] );
 
   bool hasLin  = ( nbElemOfType[SMDSEntity_Edge      ] ||
@@ -354,6 +355,7 @@ SMESHGUI_ConvToQuadOp::DestinationMesh( const SMESH::SMESH_IDSource_var& idSourc
                    nbElemOfType[SMDSEntity_Tetra     ] ||
                    nbElemOfType[SMDSEntity_Hexa      ] ||
                    nbElemOfType[SMDSEntity_Pyramid   ] ||
+                   nbElemOfType[SMDSEntity_Polygon   ] ||
                    nbElemOfType[SMDSEntity_Penta     ] );
 
   int tgtType = 0;
index 023789c6675f95423c6183a4585e05b9d3b061c9..e700c8f090a6b96bc91f60d746d95ff6bf9f1781 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 8a02ddd031d6b44c85f5609a63947c15c7e73f11..35611dfe5a004b715b44c329b90647a09ee02190 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -109,8 +109,8 @@ SMESHGUI_CopyMeshDlg::SMESHGUI_CopyMeshDlg( SMESHGUI* theModule )
   : QDialog( SMESH::GetDesktop( theModule ) ),
     mySMESHGUI( theModule ),
     mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
-    myFilterDlg(0),
     mySelectedObject(SMESH::SMESH_IDSource::_nil()),
+    myFilterDlg(0),
     myIsApplyAndClose( false )
 {
   QPixmap image (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_COPY_MESH")));
@@ -234,6 +234,10 @@ SMESHGUI_CopyMeshDlg::SMESHGUI_CopyMeshDlg( SMESHGUI* theModule )
           this,           SLOT   (SelectionIntoArgument()));
   connect(mySMESHGUI,     SIGNAL (SignalCloseAllDialogs()),/* to close dialog if study change */
           this,           SLOT   (reject()));
+  connect(mySMESHGUI,     SIGNAL (SignalActivatedViewManager()),
+          this,           SLOT   (onOpenView()));
+  connect(mySMESHGUI,     SIGNAL (SignalCloseView()),
+          this,           SLOT   (onCloseView()));
 
   connect(myLineEditElements, SIGNAL(textChanged(const QString&)),
           this,               SLOT  (onTextChange(const QString&)));
@@ -309,7 +313,8 @@ bool SMESHGUI_CopyMeshDlg::ClickOnApply()
   try
   {
     SUIT_OverrideCursor aWaitCursor;
-    SMESH::SMESH_IDSource_wrap aPartToCopy;
+
+    SMESH::IDSource_wrap aPartToCopy;
     if ( myIdSourceCheck->isChecked())
     {
       aPartToCopy = mySelectedObject;
@@ -380,6 +385,31 @@ void SMESHGUI_CopyMeshDlg::reject()
   QDialog::reject();
 }
 
+//=================================================================================
+// function : onOpenView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_CopyMeshDlg::onOpenView()
+{
+  if ( mySelector ) {
+    SMESH::SetPointRepresentation(false);
+  }
+  else {
+    mySelector = SMESH::GetViewWindow( mySMESHGUI )->GetSelector();
+    ActivateThisDialog();
+  }
+}
+
+//=================================================================================
+// function : onCloseView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_CopyMeshDlg::onCloseView()
+{
+  DeactivateActiveDialog();
+  mySelector = 0;
+}
+
 //=================================================================================
 // function : ClickOnHelp()
 // purpose  :
@@ -464,6 +494,9 @@ void SMESHGUI_CopyMeshDlg::onTextChange (const QString& theNewText)
 void SMESHGUI_CopyMeshDlg::SelectionIntoArgument()
 {
   if (myBusy) return;
+  if (myFilterDlg && myFilterDlg->isVisible()) return; // filter dlg active
+  if (!GroupButtons->isEnabled()) return;              // inactive
+
   BusyLocker lock( myBusy );
 
   // clear
@@ -601,16 +634,21 @@ void SMESHGUI_CopyMeshDlg::ActivateThisDialog()
   SelectionIntoArgument();
 }
 
+
 //=================================================================================
 // function : enterEvent()
 // purpose  :
 //=================================================================================
 void SMESHGUI_CopyMeshDlg::enterEvent (QEvent*)
 {
-  if (!ConstructorsBox->isEnabled())
+  if ( !ConstructorsBox->isEnabled() ) {
+    SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
+    if ( aViewWindow && !mySelector ) {
+      mySelector = aViewWindow->GetSelector();
+    }
     ActivateThisDialog();
+  }
 }
-
 //=================================================================================
 // function : keyPressEvent()
 // purpose  :
@@ -642,6 +680,15 @@ void SMESHGUI_CopyMeshDlg::setFilters()
   if ( !myFilterDlg )
     myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, SMESH::ALL );
 
+  QList<int> types;
+  if ( myMesh->NbEdges()     ) types << SMESH::EDGE;
+  if ( myMesh->NbFaces()     ) types << SMESH::FACE;
+  if ( myMesh->NbVolumes()   ) types << SMESH::VOLUME;
+  if ( myMesh->NbBalls()     ) types << SMESH::BALL;
+  if ( myMesh->Nb0DElements()) types << SMESH::ELEM0D;
+  if ( types.count() > 1 )     types << SMESH::ALL;
+
+  myFilterDlg->Init( types );
   myFilterDlg->SetSelection();
   myFilterDlg->SetMesh( myMesh );
   myFilterDlg->SetSourceWg( myLineEditElements );
index a81a37669c1887a931600c5ae084fd616a62b699..54347e18ad4e8f8caf1af04946c4c4846f0ddfaf 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -125,6 +125,8 @@ private slots:
   void                   onTextChange( const QString& );
   void                   onSelectIdSource( bool );
   void                   setFilters();
+  void                   onOpenView();
+  void                   onCloseView();
 };
 
 #endif // SMESHGUI_CopyMeshDLG_H
index 34771755d5ca05bc1724e060442c09f4ea933f83..47c2f8eecbd27236c838df8a9d1da1b3c0f61d13 100755 (executable)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -105,9 +105,6 @@ SMESHGUI_CreatePatternDlg::SMESHGUI_CreatePatternDlg( SMESHGUI*   theModule,
 
   aDlgLay->setStretchFactor( aMainFrame, 1 );
 
-  if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ) )
-    mySelector = aViewWindow->GetSelector();
-
   myHelpFileName = "pattern_mapping_page.html";
 
   Init( theType );
@@ -572,7 +569,7 @@ void SMESHGUI_CreatePatternDlg::onSelectionDone()
 {
   try {
     SALOME_ListIO aList;
-    mySelectionMgr->selectedObjects( aList, SVTK_Viewer::Type() );
+    mySelectionMgr->selectedObjects( aList );
     if ( aList.Extent() != 1 )
       return;
 
index 515c230d10df5517cfcc0969a077d9eb2ec1d5ca..840f09cfb062bdcca875a27733d02050aa7d1930 100755 (executable)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -115,7 +115,6 @@ private:
   QCheckBox*               myProjectChk;
 
   SMESHGUI*                mySMESHGUI;
-  SVTK_Selector*           mySelector;
   LightApp_SelectionMgr*   mySelectionMgr;
   int                      myType;
 
index 73fac9a8451add34f314b5100eb126f264774504..bdbb2d95da478b1c3b6f1a179cdec60f7013fe8e 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -49,6 +49,8 @@
 #include <SalomeApp_Application.h>
 #include <LightApp_SelectionMgr.h>
 
+#include "utilities.h"
+
 #include <SVTK_ViewWindow.h>
 
 // OCCT includes
@@ -351,8 +353,9 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::Init()
   connect( mySelectionMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( SelectionIntoArgument() ) );
   connect( Preview, SIGNAL(toggled(bool)), this, SLOT(ClickOnPreview(bool)));
   /* to close dialog if study change */
-  connect( mySMESHGUI, SIGNAL ( SignalCloseAllDialogs() ), this, SLOT( reject() ) );
-  
+  connect( mySMESHGUI, SIGNAL ( SignalCloseAllDialogs() ),      this, SLOT( reject() ) );
+  connect( mySMESHGUI, SIGNAL ( SignalActivatedViewManager() ), this, SLOT( onOpenView() ) );
+  connect( mySMESHGUI, SIGNAL ( SignalCloseView() ),            this, SLOT( onCloseView() ) );
   ConstructorsClicked(0);
   SelectionIntoArgument();
 }
@@ -611,6 +614,36 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::reject()
   QDialog::reject();
 }
 
+//=================================================================================
+// function : onOpenView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_CreatePolyhedralVolumeDlg::onOpenView()
+{
+  if ( mySelector && mySimulation ) {
+    mySimulation->SetVisibility(false);
+    SMESH::SetPointRepresentation(false);
+  }
+  else {
+    mySelector = SMESH::GetViewWindow( mySMESHGUI )->GetSelector();
+    mySimulation = new SMESH::TPolySimulation(
+      dynamic_cast<SalomeApp_Application*>( mySMESHGUI->application() ) );
+    ActivateThisDialog();
+  }
+}
+
+//=================================================================================
+// function : onCloseView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_CreatePolyhedralVolumeDlg::onCloseView()
+{
+  DeactivateActiveDialog();
+  mySelector = 0;
+  delete mySimulation;
+  mySimulation = 0;
+}
+
 //=================================================================================
 // function : ClickOnHelp()
 // purpose  :
@@ -1025,16 +1058,21 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::ActivateThisDialog()
   SelectionIntoArgument();
 }
 
-
 //=================================================================================
 // function : enterEvent()
 // purpose  :
 //=================================================================================
-void SMESHGUI_CreatePolyhedralVolumeDlg::enterEvent(QEvent* e)
+void SMESHGUI_CreatePolyhedralVolumeDlg::enterEvent (QEvent*)
 {
-  if ( ConstructorsBox->isEnabled() )
-    return;  
-  ActivateThisDialog();
+  if ( !ConstructorsBox->isEnabled() ) {
+    SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
+    if ( aViewWindow && !mySelector && !mySimulation) {
+      mySelector = aViewWindow->GetSelector();
+      mySimulation = new SMESH::TPolySimulation(
+        dynamic_cast<SalomeApp_Application*>( mySMESHGUI->application() ) );
+    }
+    ActivateThisDialog();
+  }
 }
 
 //=================================================================================
index 4f6de47b981acb7ebf9f628558a66d61d2ea8920..85343ee0f2d845436f8f092b5095950a09dc1f1f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -138,6 +138,8 @@ private slots:
   void                     ActivateThisDialog();
   void                     onTextChange( const QString& );
   void                     onListSelectionChanged();
+  void                     onOpenView();
+  void                     onCloseView();
 };
 
 #endif // SMESHGUI_CREATEPOLYHEDRALVOLUMEDLG_H
index f106c0b6661e64c4096e30e03dd1163f565b014c..dd1f1e684c4a52f963bf42545cd36782074804fe 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -73,8 +73,8 @@
 //=================================================================================
 SMESHGUI_DeleteGroupDlg::SMESHGUI_DeleteGroupDlg (SMESHGUI* theModule):
   QDialog(SMESH::GetDesktop(theModule)),
-  mySelectionMgr(SMESH::GetSelectionMgr(theModule)),
-  mySMESHGUI(theModule)
+  mySMESHGUI(theModule),
+  mySelectionMgr(SMESH::GetSelectionMgr(theModule))
 {
   setModal(false);
   setWindowTitle(tr("CAPTION"));
index e9f3f2ade945e0df3254450c9d5a35804cf9210c..fb4a1ad28fc5880156045abd4fd070f3327398a1 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index a5fcf31c59cc9a4a266bb14e3e5f13fd5ef9f47a..59e54c651d11227cde2cce379b48d1f0b3d77206 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 582af42437beecf71f9d2aa94cb93c94da959d1f..979551a3aeebc7f8a63d5bbcd1edb57d421ff33f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 1e0a288d515874f16923cc44aada6ae37c901270..c26925804953a9f0d089bafc9ac2d9b5a49f5602 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2014-2015  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
 #include "SMESHGUI_DisplayEntitiesDlg.h"
 
 #include "SMESHGUI.h"
+#include "SMESHGUI_MeshUtils.h"
 #include "SMESHGUI_Utils.h"
 #include "SMESHGUI_VTKUtils.h"
-#include "SMESHGUI_MeshUtils.h"
 
-#include <QLabel>
-#include <QGroupBox>
-#include <QGridLayout>
-#include <QVBoxLayout>
-#include <QCheckBox>
-
-#include <SUIT_Session.h>
-#include <SUIT_MessageBox.h>
-#include <SUIT_ResourceMgr.h>
 #include <LightApp_Application.h>
 #include <LightApp_SelectionMgr.h>
 #include <SALOME_ListIO.hxx>
+#include <SUIT_MessageBox.h>
+#include <SUIT_OverrideCursor.h>
+#include <SUIT_ResourceMgr.h>
+#include <SUIT_Session.h>
+
+#include <QCheckBox>
+#include <QGridLayout>
+#include <QGroupBox>
+#include <QLabel>
+#include <QVBoxLayout>
 
 const int MARGIN  = 9;
 const int SPACING = 6;
@@ -176,7 +177,7 @@ SMESHGUI_DisplayEntitiesDlg::~SMESHGUI_DisplayEntitiesDlg()
 }
 
 void SMESHGUI_DisplayEntitiesDlg::InverseEntityMode(unsigned int& theOutputMode,
-                                                   unsigned int theMode)
+                                                    unsigned int theMode)
 {
   bool anIsNotPresent = ~theOutputMode & theMode;
   if(anIsNotPresent)
@@ -193,7 +194,7 @@ void SMESHGUI_DisplayEntitiesDlg::onChangeEntityMode( bool isChecked )
   QCheckBox* aSender = (QCheckBox*)sender();
   if ( myNbCheckedButtons == 1 && !isChecked ) {
     SUIT_MessageBox::warning(this, tr("SMESH_WRN_WARNING"),
-                            tr("WRN_AT_LEAST_ONE"));
+                             tr("WRN_AT_LEAST_ONE"));
     disconnect( aSender, SIGNAL(toggled(bool)), this, SLOT(onChangeEntityMode(bool)) );
     aSender->setChecked( true );
     connect( aSender, SIGNAL(toggled(bool)), this, SLOT(onChangeEntityMode(bool)) );
@@ -228,11 +229,13 @@ void SMESHGUI_DisplayEntitiesDlg::onHelp()
 */
 void SMESHGUI_DisplayEntitiesDlg::onOk()
 {
+  SUIT_OverrideCursor wc;
+
   const char* entry = myIObject->getEntry();
   
   if ( !myActor ) {
     myActor = SMESH::CreateActor(SMESH::GetActiveStudyDocument(), 
-                                entry, true);
+                                 entry, true);
   }
 
   if( myEntityMode != myActor->GetEntityMode() ) {
index 4b36a6b254805a26de3363d1b4e0fb5a5c87c5a8..0f98bda2d4fe70dbd89d2c7f3debc1cd2401299a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2014-2015  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
@@ -39,7 +39,7 @@ public:
 
 private:
   void InverseEntityMode( unsigned int& theOutputMode,
-                         unsigned int theMode );
+                          unsigned int theMode );
 
 private slots:
   void              onOk();
index 4c672d2b54415b750a73191ef21c5c4201c7aeb8..95c44a602b5c84b3e04a1fc4707062c806746651 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 446bedce14cea7acc36349f2662e4c75fa8cc8df..65de4e8b058e9afb6bc363012b8bd63adb7e73fc 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 57428add241d7cb5f2e65714425fc341cc34bb3f..91b45ece436aeafe2e89a462a8e884a4ea97c3a3 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -602,7 +602,7 @@ void SMESHGUI_DuplicateNodesDlg::onSelectionChanged()
         break;
       case 3:
         ok = ( aGroupType == SMESH::VOLUME || 
-              aGroupType == SMESH::FACE );
+               aGroupType == SMESH::FACE );
         break;
       }
     }
index 5bf5247d292f9e606bbe6e4a60a2944321b5a6ae..04570a42a3fd1073e80582a5578e61ef7b1d0d23 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 8c2d0ef51f2fecd701ea4d4d802207f4bd03afcc..2779ce68917e4d004fd4017040187263bb5373eb 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 #include "SMESHGUI_ExtrusionAlongPathDlg.h"
 
 #include "SMESHGUI.h"
-#include "SMESHGUI_Utils.h"
-#include "SMESHGUI_VTKUtils.h"
-#include "SMESHGUI_MeshUtils.h"
-#include "SMESHGUI_SpinBox.h"
-#include "SMESHGUI_IdValidator.h"
+#include "SMESHGUI_ExtrusionDlg.h" // for SMESHGUI_3TypesSelector
 #include "SMESHGUI_FilterDlg.h"
+#include "SMESHGUI_IdValidator.h"
 #include "SMESHGUI_MeshEditPreview.h"
+#include "SMESHGUI_MeshUtils.h"
+#include "SMESHGUI_SpinBox.h"
+#include "SMESHGUI_Utils.h"
+#include "SMESHGUI_VTKUtils.h"
 
 #include <SMESH_Actor.h>
 #include <SMESH_TypeFilter.hxx>
 #include <SUIT_Desktop.h>
 #include <SUIT_MessageBox.h>
 #include <SUIT_Session.h>
-
 #include <LightApp_Application.h>
 #include <LightApp_SelectionMgr.h>
-
 #include <SVTK_ViewWindow.h>
 
 // OCCT includes
@@ -111,18 +110,13 @@ private:
 //=================================================================================
 SMESHGUI_ExtrusionAlongPathDlg::SMESHGUI_ExtrusionAlongPathDlg( SMESHGUI* theModule )
   : SMESHGUI_PreviewDlg( theModule ),
-    mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
-    myFilterDlg( 0 )
+    mySelectionMgr( SMESH::GetSelectionMgr( theModule ) )
 {
   SUIT_ResourceMgr* mgr = SMESH::GetResourceMgr( mySMESHGUI );
-  QPixmap edgeImage   ( mgr->loadPixmap("SMESH", tr("ICON_DLG_EDGE")));
-  QPixmap faceImage   ( mgr->loadPixmap("SMESH", tr("ICON_DLG_TRIANGLE")));
   QPixmap selectImage ( mgr->loadPixmap("SMESH", tr("ICON_SELECT")));
   QPixmap addImage    ( mgr->loadPixmap("SMESH", tr("ICON_APPEND")));
   QPixmap removeImage ( mgr->loadPixmap("SMESH", tr("ICON_REMOVE")));
 
-  myType = -1;
-
   setModal( false );
   setAttribute( Qt::WA_DeleteOnClose, true );
   setWindowTitle(tr("EXTRUSION_ALONG_PATH"));
@@ -132,48 +126,17 @@ SMESHGUI_ExtrusionAlongPathDlg::SMESHGUI_ExtrusionAlongPathDlg( SMESHGUI* theMod
   topLayout->setSpacing(SPACING);
   topLayout->setMargin(MARGIN);
 
-  /***************************************************************/
-  // Elements type group box (1d / 2d elements)
-  ConstructorsBox = new QGroupBox(tr("SMESH_EXTRUSION"), this);
-  GroupConstructors = new QButtonGroup(this);
-  QHBoxLayout* ConstructorsBoxLayout = new QHBoxLayout(ConstructorsBox);
-  ConstructorsBoxLayout->setSpacing(SPACING); ConstructorsBoxLayout->setMargin(MARGIN);
-
-  Elements1dRB = new QRadioButton(ConstructorsBox);
-  Elements1dRB->setIcon(edgeImage);
-  Elements2dRB = new QRadioButton(ConstructorsBox);
-  Elements2dRB->setIcon(faceImage);
-  Elements1dRB->setChecked(true);
-
-  // layouting
-  ConstructorsBoxLayout->addWidget(Elements1dRB);
-  ConstructorsBoxLayout->addWidget(Elements2dRB);
-  GroupConstructors->addButton(Elements1dRB,  0);
-  GroupConstructors->addButton(Elements2dRB, 1);
-
   /***************************************************************/
   // Arguments group box
-  GroupArguments = new QGroupBox(tr("EXTRUSION_1D"), this);
+  GroupArguments = new QGroupBox(tr("SMESH_EXTRUSION"), this);
   QGridLayout* GroupArgumentsLayout = new QGridLayout(GroupArguments);
   GroupArgumentsLayout->setSpacing(SPACING); GroupArgumentsLayout->setMargin(MARGIN);
 
   myIdValidator = new SMESHGUI_IdValidator(this);
 
   // Controls for elements selection
-  ElementsLab = new QLabel(tr("SMESH_ID_ELEMENTS"), GroupArguments);
-
-  SelectElementsButton = new QToolButton(GroupArguments);
-  SelectElementsButton->setIcon(selectImage);
-
-  ElementsLineEdit = new QLineEdit(GroupArguments);
-  ElementsLineEdit->setValidator(myIdValidator);
-  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);
-
+  SelectorWdg = new SMESHGUI_3TypesSelector( GroupArguments );
+  
   // Controls for path selection
   PathGrp = new QGroupBox(tr("SMESH_PATH"), GroupArguments);
   QGridLayout* PathGrpLayout = new QGridLayout(PathGrp);
@@ -182,8 +145,9 @@ SMESHGUI_ExtrusionAlongPathDlg::SMESHGUI_ExtrusionAlongPathDlg( SMESHGUI* theMod
   // Controls for path mesh selection
   QLabel* PathMeshLab = new QLabel(tr("SMESH_PATH_MESH"), PathGrp);
 
-  SelectPathMeshButton = new QToolButton(PathGrp);
+  SelectPathMeshButton = new QPushButton(PathGrp);
   SelectPathMeshButton->setIcon(selectImage);
+  SelectPathMeshButton->setCheckable(true);
 
   PathMeshLineEdit = new QLineEdit(PathGrp);
   PathMeshLineEdit->setReadOnly(true);
@@ -191,8 +155,9 @@ SMESHGUI_ExtrusionAlongPathDlg::SMESHGUI_ExtrusionAlongPathDlg( SMESHGUI* theMod
   // Controls for path starting point selection
   QLabel* StartPointLab = new QLabel(tr("SMESH_PATH_START"), PathGrp);
 
-  SelectStartPointButton = new QToolButton(PathGrp);
+  SelectStartPointButton = new QPushButton(PathGrp);
   SelectStartPointButton->setIcon(selectImage);
+  SelectStartPointButton->setCheckable(true);
 
   StartPointLineEdit = new QLineEdit(PathGrp);
   StartPointLineEdit->setValidator(new QIntValidator(this));
@@ -211,8 +176,13 @@ SMESHGUI_ExtrusionAlongPathDlg::SMESHGUI_ExtrusionAlongPathDlg( SMESHGUI* theMod
   QHBoxLayout* BasePointGrpLayout = new QHBoxLayout(BasePointGrp);
   BasePointGrpLayout->setSpacing(SPACING); BasePointGrpLayout->setMargin(MARGIN);
 
-  SelectBasePointButton = new QToolButton(BasePointGrp);
+  SelectBasePointButton = new QPushButton(BasePointGrp);
   SelectBasePointButton->setIcon(selectImage);
+  SelectBasePointButton->setCheckable(true);
+
+  SelectorWdg->GetButtonGroup()->addButton( SelectPathMeshButton );
+  SelectorWdg->GetButtonGroup()->addButton( SelectStartPointButton );
+  SelectorWdg->GetButtonGroup()->addButton( SelectBasePointButton );
 
   QLabel* XLab  = new QLabel(tr("SMESH_X"), BasePointGrp);
   XSpin = new SMESHGUI_SpinBox(BasePointGrp);
@@ -266,16 +236,12 @@ SMESHGUI_ExtrusionAlongPathDlg::SMESHGUI_ExtrusionAlongPathDlg( SMESHGUI* theMod
   myPreviewCheckBox = new QCheckBox(tr("PREVIEW"), GroupArguments);
 
   // layouting
-  GroupArgumentsLayout->addWidget(ElementsLab,          0, 0);
-  GroupArgumentsLayout->addWidget(SelectElementsButton, 0, 1);
-  GroupArgumentsLayout->addWidget(ElementsLineEdit,     0, 2);
-  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(myPreviewCheckBox,    5, 0, 1, 4);
-  GroupArgumentsLayout->addWidget(MakeGroupsCheck,      6, 0, 1, 4);
+  GroupArgumentsLayout->addWidget(SelectorWdg,          0, 0);
+  GroupArgumentsLayout->addWidget(PathGrp,              1, 0);
+  GroupArgumentsLayout->addWidget(BasePointGrp,         2, 0);
+  GroupArgumentsLayout->addWidget(AnglesGrp,            3, 0);
+  GroupArgumentsLayout->addWidget(myPreviewCheckBox,    4, 0);
+  GroupArgumentsLayout->addWidget(MakeGroupsCheck,      5, 0);
 
   /***************************************************************/
   // common buttons group box
@@ -287,7 +253,7 @@ SMESHGUI_ExtrusionAlongPathDlg::SMESHGUI_ExtrusionAlongPathDlg( SMESHGUI* theMod
   OkButton->setAutoDefault(true);
   OkButton->setDefault(true);
 
-  ApplyButton = new QPushButton(tr("SMESH_BUT_APPLY"), GroupButtons);
+  ApplyButton = new QPushButton(tr("SMESH_BUT_APPLY"), GroupButtons); 
   ApplyButton->setAutoDefault(true);
 
   CloseButton = new QPushButton(tr("SMESH_BUT_CLOSE"), GroupButtons);
@@ -307,7 +273,6 @@ SMESHGUI_ExtrusionAlongPathDlg::SMESHGUI_ExtrusionAlongPathDlg( SMESHGUI* theMod
 
   /***************************************************************/
   // layouting
-  topLayout->addWidget(ConstructorsBox);
   topLayout->addWidget(GroupArguments);
   topLayout->addWidget(GroupButtons);
 
@@ -322,16 +287,6 @@ SMESHGUI_ExtrusionAlongPathDlg::SMESHGUI_ExtrusionAlongPathDlg( SMESHGUI* theMod
 
   mySMESHGUI->SetActiveDialogBox(this);
 
-  // Costruction of the logical filter for the elements: mesh/sub-mesh/group
-  SMESH_TypeFilter* aMeshOrSubMeshFilter = new SMESH_TypeFilter (SMESH::MESHorSUBMESH);
-  SMESH_TypeFilter* aSmeshGroupFilter    = new SMESH_TypeFilter (SMESH::GROUP);
-
-  QList<SUIT_SelectionFilter*> aListOfFilters;
-  if (aMeshOrSubMeshFilter) aListOfFilters.append(aMeshOrSubMeshFilter);
-  if (aSmeshGroupFilter)    aListOfFilters.append(aSmeshGroupFilter);
-
-  myElementsFilter = new SMESH_LogicalFilter (aListOfFilters, SMESH_LogicalFilter::LO_OR);
-  //myPathMeshFilter = new SMESH_TypeFilter (SMESH::MESH);
   myPathMeshFilter = new SMESH_TypeFilter(SMESH::MESHorSUBMESH);
 
   myHelpFileName = "extrusion_along_path_page.html";
@@ -348,42 +303,40 @@ SMESHGUI_ExtrusionAlongPathDlg::SMESHGUI_ExtrusionAlongPathDlg( SMESHGUI* theMod
   connect(AddAngleButton,    SIGNAL(clicked()), this, SLOT(OnAngleAdded()));
   connect(RemoveAngleButton, SIGNAL(clicked()), this, SLOT(OnAngleRemoved()));
 
-  connect(GroupConstructors, SIGNAL(buttonClicked(int)), SLOT(ConstructorsClicked(int)));
-
-  connect(SelectElementsButton,   SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
   connect(SelectPathMeshButton,   SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
   connect(SelectStartPointButton, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
   connect(SelectBasePointButton,  SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
   connect(BasePointGrp,       SIGNAL(toggled(bool)), this, SLOT(SetEditCurrentArgument()));
 
-  connect(mySMESHGUI,  SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog()));
-  connect(mySelectionMgr, SIGNAL(currentSelectionChanged()),      this, SLOT(SelectionIntoArgument()));
-  connect(mySMESHGUI,  SIGNAL(SignalCloseAllDialogs()),        this, SLOT(reject()));
+  connect(mySMESHGUI,  SIGNAL(SignalCloseAllDialogs()),        SLOT(reject()));
+  connect(mySMESHGUI,  SIGNAL(SignalActivatedViewManager()),   SLOT(onOpenView()));
+  connect(mySMESHGUI,  SIGNAL(SignalCloseView()),              SLOT(onCloseView()));
+  connect(mySMESHGUI,  SIGNAL(SignalDeactivateActiveDialog()), SLOT(DeactivateActiveDialog()));
+  connect(mySelectionMgr, SIGNAL(currentSelectionChanged()),   SLOT(SelectionIntoArgument()));
+  connect(SelectorWdg,    SIGNAL(selectionChanged()), this,    SLOT(toDisplaySimulation()));
+  connect(SelectorWdg,    SIGNAL(selectionChanged()), this,    SLOT(CheckIsEnable()));
 
-  connect(ElementsLineEdit, SIGNAL(textChanged(const QString&)),
-          SLOT(onTextChange(const QString&)));
   connect(StartPointLineEdit, SIGNAL(textChanged(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(AddAngleButton,    SIGNAL(clicked()), this, SLOT(toDisplaySimulation()));
   connect(RemoveAngleButton, SIGNAL(clicked()), this, SLOT(toDisplaySimulation()));
-  connect(LinearAnglesCheck, SIGNAL(toggled(bool)), SLOT(onSelectMesh()));
+  //connect(LinearAnglesCheck, SIGNAL(toggled(bool)), SLOT(onSelectMesh()));
 
 
   //To Connect preview check box
   connectPreviewControl();
 
-  AnglesList->installEventFilter(this);
-  ElementsLineEdit->installEventFilter(this);
+  AnglesList        ->installEventFilter(this);
   StartPointLineEdit->installEventFilter(this);
-  XSpin->editor()->installEventFilter(this);
-  YSpin->editor()->installEventFilter(this);
-  ZSpin->editor()->installEventFilter(this);
+  XSpin->editor()   ->installEventFilter(this);
+  YSpin->editor()   ->installEventFilter(this);
+  ZSpin->editor()   ->installEventFilter(this);
+
+  CheckIsEnable();
 }
 
 //=================================================================================
@@ -393,10 +346,6 @@ SMESHGUI_ExtrusionAlongPathDlg::SMESHGUI_ExtrusionAlongPathDlg( SMESHGUI* theMod
 SMESHGUI_ExtrusionAlongPathDlg::~SMESHGUI_ExtrusionAlongPathDlg()
 {
   // no need to delete child widgets, Qt does it all for us
-  if ( myFilterDlg != 0 ) {
-    myFilterDlg->setParent( 0 );
-    delete myFilterDlg;
-  }
 }
 
 //=================================================================================
@@ -408,12 +357,9 @@ void SMESHGUI_ExtrusionAlongPathDlg::Init (bool ResetControls)
   myBusy = false;
   myEditCurrentArgument = 0;
 
-  myMesh      = SMESH::SMESH_Mesh::_nil();
-  myIDSource  = SMESH::SMESH_IDSource::_nil();
-  myMeshActor = 0;
-  myPath  = SMESH::SMESH_IDSource::_nil();
+  myPath = SMESH::SMESH_IDSource::_nil();
 
-  ElementsLineEdit->clear();
+  SelectorWdg->Clear();
   PathMeshLineEdit->clear();
   StartPointLineEdit->clear();
 
@@ -423,9 +369,6 @@ void SMESHGUI_ExtrusionAlongPathDlg::Init (bool ResetControls)
     ZSpin->SetValue(0.0);
 
     AngleSpin->SetValue(45);
-    MeshCheck->setChecked(false);
-    ConstructorsClicked(0);
-    onSelectMesh();
     myPreviewCheckBox->setChecked(false);
     onDisplaySimulation(false);
   }
@@ -433,53 +376,16 @@ void SMESHGUI_ExtrusionAlongPathDlg::Init (bool ResetControls)
 }
 
 //=================================================================================
-// function : ConstructorsClicked()
-// purpose  : Called when user changes type of elements (1d / 2d)
+// function : CheckIsEnable()
+// purpose  : Check whether the Ok and Apply buttons should be enabled or not
 //=================================================================================
-void SMESHGUI_ExtrusionAlongPathDlg::ConstructorsClicked (int type)
-{
-  if (myType == type) return;
 
-  disconnect(mySelectionMgr, 0, this, 0);
+void SMESHGUI_ExtrusionAlongPathDlg::CheckIsEnable()
+{  
+  bool anIsEnable = SelectorWdg->IsAnythingSelected() && isValuesValid();
 
-  hidePreview();
-
-  if (type == 0)
-    GroupArguments->setTitle(tr("EXTRUSION_1D"));
-  else if (type == 1)
-    GroupArguments->setTitle(tr("EXTRUSION_2D"));
-
-  // clear elements ID list
-  if (!MeshCheck->isChecked()) {
-    ElementsLineEdit->clear();
-  }
-  // set selection mode if necessary
-  if (myEditCurrentArgument == ElementsLineEdit) {
-    mySelectionMgr->clearSelected();
-    mySelectionMgr->clearFilters();
-    SMESH::SetPickable();
-
-    SMESH::SetPointRepresentation(false);
-    if (MeshCheck->isChecked()) {
-      if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-        aViewWindow->SetSelectionMode(ActorSelection);
-      mySelectionMgr->installFilter(myElementsFilter);
-    } else {
-      if (type == 0)
-        {
-          if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-            aViewWindow->SetSelectionMode(EdgeSelection);
-        }
-      if (type == 1)
-        {
-          if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-            aViewWindow->SetSelectionMode(FaceSelection);
-        }
-    }
-  }
-  connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
-
-  myType = type;
+  OkButton->setEnabled(anIsEnable);
+  ApplyButton->setEnabled(anIsEnable);
 }
 
 //=================================================================================
@@ -491,17 +397,12 @@ 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 ||*/ myPath->_is_nil() )
+  if ( !SelectorWdg->IsAnythingSelected() || myPath->_is_nil() )
     return false;
 
   if (!isValid())
     return false;
 
-  SMESH::long_array_var anElementsId = getSelectedElements();
-
   if (StartPointLineEdit->text().trimmed().isEmpty()) {
     return false;
   }
@@ -517,7 +418,7 @@ bool SMESHGUI_ExtrusionAlongPathDlg::ClickOnApply()
   //get angles
   SMESH::double_array_var anAngles = getAngles();
   
-  for (int i = 0; i < myAnglesList.count(); i++) 
+  for (int i = 0; i < myAnglesList.count(); i++)
     aParameters << AnglesList->item(i)->text();
 
 
@@ -528,38 +429,43 @@ bool SMESHGUI_ExtrusionAlongPathDlg::ClickOnApply()
     aBasePoint.y = YSpin->GetValue();
     aBasePoint.z = ZSpin->GetValue();
   }
-
   aParameters << XSpin->text();
   aParameters << YSpin->text();
   aParameters << ZSpin->text();
 
+  bool meshHadNewTypeBefore = true;
+  int  maxSelType = 0;
+  const bool makeGroups = ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() );
+
   try {
     SUIT_OverrideCursor wc;
 
-    SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
-    SMESH::SMESH_MeshEditor::Extrusion_Error retVal;
+    SMESH::SMESH_Mesh_var mesh = SelectorWdg->GetMesh();
 
-    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 {
-      SMESH::ListOfGroups_var groups = 
-        aMeshEditor->ExtrusionAlongPathObjX(myIDSource, myPath, aNodeStart, AnglesGrp->isChecked(),
-                                          anAngles, LinearAnglesCheck->isChecked(),
-                                          BasePointGrp->isChecked(), aBasePoint,
-                                          NeedGroups, ElemType, retVal);
-    }
+    mesh->SetParameters( aParameters.join(":").toLatin1().constData() );
+
+    SMESH::ListOfIDSources_var nodes = new SMESH::ListOfIDSources();
+    SMESH::ListOfIDSources_var edges = new SMESH::ListOfIDSources();
+    SMESH::ListOfIDSources_var faces = new SMESH::ListOfIDSources();
+    maxSelType = SelectorWdg->GetSelected( nodes, edges, faces );
 
+    // is it necessary to switch on the next Display Mode?
+    SMESH::ElementType newType = (SMESH::ElementType)( maxSelType + 1 );
+    SMESH::array_of_ElementType_var oldTypes = mesh->GetTypes();
+    meshHadNewTypeBefore = false;
+    for ( size_t i = 0; i < oldTypes->length() && !meshHadNewTypeBefore; ++i )
+      meshHadNewTypeBefore = ( oldTypes[i] >= newType );
+
+    SMESH::SMESH_MeshEditor_var aMeshEditor = mesh->GetMeshEditor();
+    SMESH::SMESH_MeshEditor::Extrusion_Error retVal;
+
+    SMESH::ListOfGroups_var groups =
+      aMeshEditor->ExtrusionAlongPathObjects( nodes, edges, faces, myPath,
+                                              GEOM::GEOM_Object::_nil(),
+                                              aNodeStart, AnglesGrp->isChecked(),
+                                              anAngles, LinearAnglesCheck->isChecked(),
+                                              BasePointGrp->isChecked(), aBasePoint,
+                                              makeGroups, retVal );
 
     wc.suspend();
     switch (retVal) {
@@ -600,17 +506,31 @@ bool SMESHGUI_ExtrusionAlongPathDlg::ClickOnApply()
     return false;
   }
 
-  //mySelectionMgr->clearSelected();
-  if ( myMeshActor )
-    SMESH::Update( myMeshActor->getIO(), myMeshActor->GetVisibility() );
-    
-  SMESHGUI::Modified();
-
-  if ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() )
+  SMESH_Actor* actor = SelectorWdg->GetActor();
+  if ( actor && !meshHadNewTypeBefore )
+  {
+    unsigned int aMode = actor->GetEntityMode();
+    switch ( maxSelType ) {
+    case SMESH::NODE: // extrude node -> edges
+      actor->SetRepresentation(SMESH_Actor::eEdge);
+      actor->SetEntityMode( aMode |= SMESH_Actor::eEdges ); break;
+    case SMESH::EDGE: // edge -> faces
+      actor->SetRepresentation(SMESH_Actor::eSurface);
+      actor->SetEntityMode( aMode |= SMESH_Actor::eFaces ); break;
+    case SMESH::FACE: // faces -> volumes
+      actor->SetRepresentation(SMESH_Actor::eSurface);
+      actor->SetEntityMode( aMode |= SMESH_Actor::eVolumes ); break;
+    }
+  }
+  if ( actor )
+    SMESH::Update( actor->getIO(), actor->GetVisibility() );
+  if ( makeGroups )
     mySMESHGUI->updateObjBrowser(true); // new groups may appear
-  //SMESH::UpdateView();
   Init(false);
-  ConstructorsClicked(GetConstructorId());
+  mySelectionMgr->clearSelected();
+  SelectorWdg->Clear();
+
+  SMESHGUI::Modified();
   return true;
 }
 
@@ -665,9 +585,35 @@ void SMESHGUI_ExtrusionAlongPathDlg::reject()
   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
     aViewWindow->SetSelectionMode(ActorSelection);
   mySMESHGUI->ResetState();
+
   QDialog::reject();
 }
 
+//=================================================================================
+// function : onOpenView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_ExtrusionAlongPathDlg::onOpenView()
+{
+  if ( mySelector ) {
+    SMESH::SetPointRepresentation(false);
+  }
+  else {
+    mySelector = SMESH::GetViewWindow( mySMESHGUI )->GetSelector();
+    ActivateThisDialog();
+  }
+}
+
+//=================================================================================
+// function : onCloseView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_ExtrusionAlongPathDlg::onCloseView()
+{
+  DeactivateActiveDialog();
+  mySelector = 0;
+}
+
 //=======================================================================
 // function : onTextChange()
 // purpose  :
@@ -682,54 +628,13 @@ void SMESHGUI_ExtrusionAlongPathDlg::onTextChange (const QString& theNewText)
   // set busy flag
   SetBusy sb (this);
 
-  if (send != StartPointLineEdit && send != ElementsLineEdit)
-    send = ElementsLineEdit;
-
-  if (send == ElementsLineEdit && myEditCurrentArgument == ElementsLineEdit) {
-    // hilight entered elements
-    SMDS_Mesh* aMesh = 0;
-    if (myMeshActor)
-      aMesh = myMeshActor->GetObject()->GetMesh();
-
-    if (aMesh) {
-      //mySelectionMgr->clearSelected();
-      //mySelectionMgr->AddIObject(myMeshActor->getIO());
-      SALOME_ListIO aList;
-      aList.Append(myMeshActor->getIO());
-      mySelectionMgr->setSelectedObjects(aList, false);
-
-      QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts);
-      bool bOk;
-      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());
-          }
-        }
-      }
-      mySelector->AddOrRemoveIndex(anIO, newIndices, false);
-      if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-        aViewWindow->highlight( anIO, true, true );
-    }
-  }
-  else if (send == StartPointLineEdit &&
-             myEditCurrentArgument == StartPointLineEdit) {
+  if (send == StartPointLineEdit &&
+      myEditCurrentArgument == StartPointLineEdit)
+  {
     if (!myPath->_is_nil()) {
       SMESH_Actor* aPathActor = SMESH::FindActorByObject(myPath);
-      SMDS_Mesh* aMesh = 0;
-      if (aPathActor)
-        aMesh = aPathActor->GetObject()->GetMesh();
+      SMDS_Mesh* aMesh = aPathActor ? aPathActor->GetObject()->GetMesh() : 0;
       if (aMesh) {
-        //mySelectionMgr->clearSelected();
-        //mySelectionMgr->AddIObject(aPathActor->getIO());
         SALOME_ListIO aList;
         aList.Append(aPathActor->getIO());
         mySelectionMgr->setSelectedObjects(aList, false);
@@ -739,7 +644,6 @@ void SMESHGUI_ExtrusionAlongPathDlg::onTextChange (const QString& theNewText)
         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 );
@@ -750,6 +654,8 @@ void SMESHGUI_ExtrusionAlongPathDlg::onTextChange (const QString& theNewText)
       }
     }
   }
+  CheckIsEnable();
+  onDisplaySimulation(true);
 }
 
 //=================================================================================
@@ -773,67 +679,29 @@ void SMESHGUI_ExtrusionAlongPathDlg::SelectionIntoArgument()
   // set busy flag
   SetBusy sb (this);
 
-  if (myEditCurrentArgument == ElementsLineEdit) {
-    // we are now selecting mesh elements (or whole mesh/submesh/group)
-    // reset
-    ElementsLineEdit->clear();
-    myMesh      = SMESH::SMESH_Mesh::_nil();
-    myIDSource  = SMESH::SMESH_IDSource::_nil();
-    myMeshActor = 0;
-
-    // try to get mesh from selection
-    Handle(SALOME_InteractiveObject) IO = aList.First();
-    myMesh = SMESH::GetMeshByIO(IO);
-    if (myMesh->_is_nil())
-      return;
-
-    // MakeGroups is available if there are groups
-    if ( myMesh->NbGroups() == 0 ) {
-      MakeGroupsCheck->setChecked(false);
-      MakeGroupsCheck->setEnabled(false);
-    } else {
-      MakeGroupsCheck->setEnabled(true);
-    }
-    // find actor
-    myMeshActor = SMESH::FindActorByObject(myMesh);
-    if (!myMeshActor && !MeshCheck->isChecked())
-      return;
-
-    if (MeshCheck->isChecked()) {
-      // If "Select whole mesh, submesh or group" check box is on ->
-      // get ID source and put it's name to the edit box
-      QString aString;
-      SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aString);
+  const bool isPathDef = ( SelectPathMeshButton->isChecked() ||
+                           SelectStartPointButton->isChecked() );
 
-      myIDSource = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>(IO);
-      ElementsLineEdit->setText(aString);
-    } else {
-      // If "Select whole mesh, submesh or group" check box is off ->
-      // try to get selected elements IDs
-      QString aString;
-      //int aNbUnits = SMESH::GetNameOfSelectedElements(mySelectionMgr, aString);
-      SMESH::GetNameOfSelectedElements(mySelector, IO, aString);
-      ElementsLineEdit->setText(aString);
-    }
-  }
-  else if (myEditCurrentArgument == PathMeshLineEdit) {
+  if (myEditCurrentArgument == PathMeshLineEdit && isPathDef)
+  {
     // we are now selecting path mesh
     // reset
     PathMeshLineEdit->clear();
     myPath = SMESH::SMESH_IDSource::_nil();
     StartPointLineEdit->clear();
-    
+
     // try to get mesh from selection
     Handle(SALOME_InteractiveObject) IO = aList.First();
     myPath = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>(IO);
     if( myPath->_is_nil() )
       return;
-    
+
     QString aString;
     SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aString);
     PathMeshLineEdit->setText(aString);
   }
-  else if (myEditCurrentArgument == StartPointLineEdit) {
+  else if (myEditCurrentArgument == StartPointLineEdit && isPathDef )
+  {
     // we are now selecting start point of path
     // reset
     StartPointLineEdit->clear();
@@ -848,13 +716,15 @@ void SMESHGUI_ExtrusionAlongPathDlg::SelectionIntoArgument()
     SMESH_Actor* aPathActor = SMESH::FindActorByObject(myPath);
     if ( !aPathActor )
       return;
-    
+
     QString aString;
     int aNbUnits = SMESH::GetNameOfSelectedElements(mySelector, aPathActor->getIO(), aString);
     if (aNbUnits == 1)
       StartPointLineEdit->setText(aString.trimmed());
-
-  } else if (myEditCurrentArgument == XSpin) {
+  }
+  else if ( myEditCurrentArgument == XSpin &&
+            SelectBasePointButton->isChecked() )
+  {
     // we are now selecting base point
     // reset is not performed here!
 
@@ -905,7 +775,13 @@ void SMESHGUI_ExtrusionAlongPathDlg::SelectionIntoArgument()
     YSpin->SetValue(n->Y());
     ZSpin->SetValue(n->Z());
   }
+  else
+  {
+    return;
+  }
+
   onDisplaySimulation(true);
+  CheckIsEnable();
 }
 
 //=================================================================================
@@ -914,11 +790,10 @@ void SMESHGUI_ExtrusionAlongPathDlg::SelectionIntoArgument()
 //=================================================================================
 void SMESHGUI_ExtrusionAlongPathDlg::SetEditCurrentArgument()
 {
-  QToolButton* send = (QToolButton*)sender();
+  QPushButton* send = (QPushButton*)sender();
   if ( sender() == BasePointGrp )
     send = SelectBasePointButton;
-  if (send != SelectElementsButton   &&
-      send != SelectPathMeshButton   &&
+  if (send != SelectPathMeshButton   &&
       send != SelectStartPointButton &&
       send != SelectBasePointButton)
     return;
@@ -929,53 +804,37 @@ void SMESHGUI_ExtrusionAlongPathDlg::SetEditCurrentArgument()
 // function : SetEditCurrentArgument()
 // purpose  :
 //=================================================================================
-void SMESHGUI_ExtrusionAlongPathDlg::SetEditCurrentArgument (QToolButton* button)
+void SMESHGUI_ExtrusionAlongPathDlg::SetEditCurrentArgument (QPushButton* button)
 {
   disconnect(mySelectionMgr, 0, this, 0);
   //  mySelectionMgr->clearSelected();
   mySelectionMgr->clearFilters();
   SMESH::SetPickable();
 
-  if (button == SelectElementsButton) {
-    myEditCurrentArgument = ElementsLineEdit;
-    SMESH::SetPointRepresentation(false);
-    if (MeshCheck->isChecked()) {
-      if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-        aViewWindow->SetSelectionMode(ActorSelection);
-      mySelectionMgr->installFilter(myElementsFilter);
-    } else {
-      if (Elements1dRB->isChecked())
-        {
-          if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-            aViewWindow->SetSelectionMode(EdgeSelection);
-        }
-      else if (Elements2dRB->isChecked())
-        {
-          if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-            aViewWindow->SetSelectionMode(FaceSelection);
-        }
-    }
-  } else if (button == SelectPathMeshButton) {
+  myEditCurrentArgument = 0;
+  if (button == SelectPathMeshButton)
+  {
     myEditCurrentArgument = PathMeshLineEdit;
     SMESH::SetPointRepresentation(false);
     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
       aViewWindow->SetSelectionMode(ActorSelection);
     mySelectionMgr->installFilter(myPathMeshFilter);
   }
-  else if (button == SelectStartPointButton) {
+  else if (button == SelectStartPointButton)
+  {
     myEditCurrentArgument = StartPointLineEdit;
-    //if (!myPathMesh->_is_nil()) {
     if (!myPath->_is_nil()) {
       SMESH_Actor* aPathActor = SMESH::FindActorByObject(myPath);
       if (aPathActor) {
-        SMESH::SetPointRepresentation(true);
+        aPathActor->SetPointRepresentation( true );
         if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
           aViewWindow->SetSelectionMode(NodeSelection);
         SMESH::SetPickable(aPathActor);
       }
     }
   }
-  else if (button == SelectBasePointButton) {
+  else if (button == SelectBasePointButton)
+  {
     myEditCurrentArgument = XSpin;
     SMESH::SetPointRepresentation(true);
     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
@@ -1005,10 +864,11 @@ void SMESHGUI_ExtrusionAlongPathDlg::SetEditCurrentArgument (QToolButton* button
 //=================================================================================
 void SMESHGUI_ExtrusionAlongPathDlg::DeactivateActiveDialog()
 {
-  if (ConstructorsBox->isEnabled()) {
-    ConstructorsBox->setEnabled(false);
+  if (GroupButtons->isEnabled())
+  {
     GroupArguments->setEnabled(false);
     GroupButtons->setEnabled(false);
+    SelectorWdg->setEnabled(false);
     mySMESHGUI->ResetState();
     mySMESHGUI->SetActiveDialogBox(0);
   }
@@ -1022,50 +882,27 @@ void SMESHGUI_ExtrusionAlongPathDlg::ActivateThisDialog()
 {
   // Emit a signal to deactivate the active dialog
   mySMESHGUI->EmitSignalDeactivateDialog();
-  ConstructorsBox->setEnabled(true);
   GroupArguments->setEnabled(true);
   GroupButtons->setEnabled(true);
+  SelectorWdg->setEnabled(true);
 
   mySMESHGUI->SetActiveDialogBox(this);
-
-  ConstructorsClicked(GetConstructorId());
   SelectionIntoArgument();
 }
 
 //=================================================================================
 // function : enterEvent()
-// purpose  : Mouse enter event
+// purpose  :
 //=================================================================================
 void SMESHGUI_ExtrusionAlongPathDlg::enterEvent (QEvent*)
 {
-  if (!ConstructorsBox->isEnabled())
+  if ( !GroupButtons->isEnabled() ) {
+    SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
+    if ( aViewWindow && !mySelector) {
+      mySelector = aViewWindow->GetSelector();
+    }
     ActivateThisDialog();
-}
-
-//=======================================================================
-// function : onSelectMesh()
-// purpose  :
-//=======================================================================
-void SMESHGUI_ExtrusionAlongPathDlg::onSelectMesh()
-{
-  bool toSelectMesh = MeshCheck->isChecked();
-
-  ElementsLineEdit->setReadOnly(toSelectMesh);
-  ElementsLineEdit->setValidator(toSelectMesh ? 0 : myIdValidator);
-  ElementsLab->setText(toSelectMesh ? tr("SMESH_NAME") : tr("SMESH_ID_ELEMENTS"));
-  ElementsLineEdit->clear();
-  myFilterBtn->setEnabled(!toSelectMesh);
-
-  SetEditCurrentArgument(SelectElementsButton);
-}
-
-//=================================================================================
-// function : GetConstructorId()
-// purpose  :
-//=================================================================================
-int SMESHGUI_ExtrusionAlongPathDlg::GetConstructorId()
-{
-  return GroupConstructors->checkedId();
+  }
 }
 
 //=======================================================================
@@ -1118,11 +955,7 @@ bool SMESHGUI_ExtrusionAlongPathDlg::eventFilter (QObject* object, QEvent* event
     }
   }
   else if (event->type() == QEvent::FocusIn) {
-    if (object == ElementsLineEdit) {
-      if (myEditCurrentArgument != ElementsLineEdit)
-        SetEditCurrentArgument(SelectElementsButton);
-    }
-    else if (object == StartPointLineEdit) {
+    if (object == StartPointLineEdit) {
       if (myEditCurrentArgument != StartPointLineEdit)
         SetEditCurrentArgument(SelectStartPointButton);
     }
@@ -1150,34 +983,6 @@ void SMESHGUI_ExtrusionAlongPathDlg::keyPressEvent( QKeyEvent* e )
   }
 }
 
-//=================================================================================
-// function : setFilters()
-// purpose  : SLOT. Called when "Filter" button pressed.
-//=================================================================================
-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;  
-    types.append( SMESH::EDGE );
-    types.append( SMESH::FACE );
-    myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, types );
-  }
-  myFilterDlg->Init( Elements1dRB->isChecked() ? SMESH::EDGE : SMESH::FACE );
-
-  myFilterDlg->SetSelection();
-  myFilterDlg->SetMesh( myMesh );
-  myFilterDlg->SetSourceWg( ElementsLineEdit );
-
-  myFilterDlg->show();
-}
-
 //=================================================================================
 // function : isValid
 // purpose  :
@@ -1224,40 +1029,51 @@ void SMESHGUI_ExtrusionAlongPathDlg::updateLinearAngles()
 // 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() )
+
+bool SMESHGUI_ExtrusionAlongPathDlg::isValuesValid()
+{ 
+  if ( 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) {
+  long aNodeStart = StartPointLineEdit->text().toLong(&bOk);
+  if ( !bOk || aNodeStart < 1 )
+    return false;
+
+  SMESH::SMESH_Mesh_var mesh = myPath->GetMesh();
+  if ( mesh->_is_nil() )
+    return false;
+
+  SMESH::ElementType type = mesh->GetElementType( aNodeStart, false );
+  if ( type != SMESH::NODE )
     return false;
-  }
 
+  if ( mesh->HasShapeToMesh() )
+  {
+    SMESH::NodePosition_var pos = mesh->GetNodePosition( aNodeStart );
+    if ( pos->shapeType != GEOM::VERTEX )
+      return false;
+  }
+  else
+  {
+    SMESH::long_array_var elems = mesh->GetNodeInverseElements( aNodeStart );
+    if ( elems->length() != 1 ||
+         mesh->GetElementType( elems[0], true ) != SMESH::EDGE )
+      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();
 
+void SMESHGUI_ExtrusionAlongPathDlg::onDisplaySimulation( bool toDisplayPreview )
+{
+  if ( myPreviewCheckBox->isChecked() && toDisplayPreview ) {
+    if ( SelectorWdg->IsAnythingSelected() && isValid() && isValuesValid())
+    {
       // get angles
       SMESH::double_array_var anAngles = getAngles();
       
@@ -1271,42 +1087,44 @@ void SMESHGUI_ExtrusionAlongPathDlg::onDisplaySimulation( bool toDisplayPreview
       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 = ( GetConstructorId() == 0 ) ? SMESH::EDGE : SMESH::FACE;
-          if( !MeshCheck->isChecked() ) {
-            aMeshEditor->ExtrusionAlongPathX(anElementsId, myPath, aNodeStart, AnglesGrp->isChecked(),
-                                             anAngles, LinearAnglesCheck->isChecked(),
-                                             BasePointGrp->isChecked(), aBasePoint,
-                                             NeedGroups, ElemType, retVal);
+          SMESH::SMESH_Mesh_var             mesh = SelectorWdg->GetMesh();
+          SMESH::SMESH_MeshEditor_var meshEditor = mesh->GetMeshEditPreviewer();
+
+          SMESH::ListOfIDSources_var nodes = new SMESH::ListOfIDSources();
+          SMESH::ListOfIDSources_var edges = new SMESH::ListOfIDSources();
+          SMESH::ListOfIDSources_var faces = new SMESH::ListOfIDSources();
+          SelectorWdg->GetSelected( nodes, edges, faces );
+          const bool makeGroups = false;
+
+          SMESH::ListOfGroups_var groups =
+            meshEditor->ExtrusionAlongPathObjects( nodes, edges, faces, myPath,
+                                                   GEOM::GEOM_Object::_nil(),
+                                                   aNodeStart, AnglesGrp->isChecked(),
+                                                   anAngles, LinearAnglesCheck->isChecked(),
+                                                   BasePointGrp->isChecked(), aBasePoint,
+                                                   makeGroups, retVal );
+
+          if( retVal == SMESH::SMESH_MeshEditor::EXTR_OK )
+          {
+            SMESH::MeshPreviewStruct_var aMeshPreviewStruct = meshEditor->GetPreviewData();
+            mySimulation->SetData( aMeshPreviewStruct._retn() );
           }
           else {
-            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 ) {
-            SMESH::MeshPreviewStruct_var aMeshPreviewStruct = aMeshEditor->GetPreviewData();
-            mySimulation->SetData(aMeshPreviewStruct._retn());
-          } else {
             hidePreview();
           }
-          
+
         } catch (...) {
           hidePreview();
         }
       } else {
         hidePreview();
       }
-      
+
     } else {
       hidePreview();
     }
@@ -1315,49 +1133,11 @@ void SMESHGUI_ExtrusionAlongPathDlg::onDisplaySimulation( bool toDisplayPreview
   }
 }
 
-
-//=================================================================================
-// 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 SMESHGUI_ExtrusionAlongPathDlg::getAngles()
+{
   SMESH::double_array_var anAngles = new SMESH::double_array;
-  if (AnglesGrp->isChecked()) {
+  if (AnglesGrp->isChecked())
+  {
     anAngles->length(myAnglesList.count());
     int j = 0;
     for (int i = 0; i < myAnglesList.count(); i++) {
index bedc111efa03cdcd1b1373ea4ce2e6f7a0d3ac63..0a5f150e2c3609fd9b7096c51c1c3074075a5e6f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -45,14 +45,15 @@ class QCheckBox;
 class QListWidget;
 class QPushButton;
 
+class LightApp_SelectionMgr;
 class SMESHGUI;
-class SMESH_Actor;
+class SMESHGUI_3TypesSelector;
+class SMESHGUI_FilterDlg;
 class SMESHGUI_IdValidator;
 class SMESHGUI_SpinBox;
-class SMESHGUI_FilterDlg;
-class SVTK_Selector;
-class LightApp_SelectionMgr;
+class SMESH_Actor;
 class SUIT_SelectionFilter;
+class SVTK_Selector;
 
 //=================================================================================
 // class    : SMESHGUI_ExtrusionAlongPathDlg
@@ -75,13 +76,11 @@ private:
   void                      Init( bool = true );
   void                      enterEvent( QEvent* );                           /* mouse enter the QWidget */
   void                      keyPressEvent( QKeyEvent* );
-  int                       GetConstructorId();
-  void                      SetEditCurrentArgument( QToolButton* );
+  void                      SetEditCurrentArgument( QPushButton* );
 
   bool                      isValid();
   bool                      isValuesValid();
   
-  SMESH::long_array_var     getSelectedElements();
   SMESH::double_array_var   getAngles();
 
   void                      updateLinearAngles();
@@ -89,38 +88,20 @@ private:
   SMESHGUI_IdValidator*     myIdValidator;
   LightApp_SelectionMgr*    mySelectionMgr;        /* User shape selection */
   SVTK_Selector*            mySelector;
-
   QWidget*                  myEditCurrentArgument; /* Current  argument */
 
   bool                      myBusy;
-  SMESH::SMESH_Mesh_var     myMesh;
-  SMESH_Actor*              myMeshActor;
-  SMESH::SMESH_IDSource_var myIDSource;
-  //SMESH::SMESH_Mesh_var     myPathMesh;
   SMESH::SMESH_IDSource_var myPath;
-  //GEOM::GEOM_Object_var     myPathShape;
-  SUIT_SelectionFilter*     myElementsFilter;
   SUIT_SelectionFilter*     myPathMeshFilter;
-  int                       myType;
   QList<double>             myAnglesList;
 
   // widgets
-  QGroupBox*                ConstructorsBox;
-  QButtonGroup*             GroupConstructors;
-  QRadioButton*             Elements1dRB;
-  QRadioButton*             Elements2dRB;
-
+  SMESHGUI_3TypesSelector*  SelectorWdg;
   QGroupBox*                GroupArguments;
-  QLabel*                   ElementsLab;
-  QToolButton*              SelectElementsButton;
-  QLineEdit*                ElementsLineEdit;
-  QCheckBox*                MeshCheck;
   QGroupBox*                PathGrp;
-  QToolButton*              SelectPathMeshButton;
+  QPushButton*              SelectPathMeshButton;
   QLineEdit*                PathMeshLineEdit;
-  //QToolButton*              SelectPathShapeButton;
-  //QLineEdit*                PathShapeLineEdit;
-  QToolButton*              SelectStartPointButton;
+  QPushButton*              SelectStartPointButton;
   QLineEdit*                StartPointLineEdit;
   QCheckBox*                LinearAnglesCheck;
   QGroupBox*                AnglesGrp;
@@ -129,7 +110,7 @@ private:
   QToolButton*              RemoveAngleButton;
   SMESHGUI_SpinBox*         AngleSpin;
   QGroupBox*                BasePointGrp;
-  QToolButton*              SelectBasePointButton;
+  QPushButton*              SelectBasePointButton;
   SMESHGUI_SpinBox*         XSpin;
   SMESHGUI_SpinBox*         YSpin;
   SMESHGUI_SpinBox*         ZSpin;
@@ -143,27 +124,24 @@ private:
 
   QString                   myHelpFileName;
 
-  QPushButton*              myFilterBtn;
-  SMESHGUI_FilterDlg*       myFilterDlg;
-   
 protected slots:
   void                      reject();
   virtual void              onDisplaySimulation( bool );
 
 private slots:
-  void                      ConstructorsClicked( int );
   void                      ClickOnOk();
   bool                      ClickOnApply();
   void                      ClickOnHelp();
+  void                      CheckIsEnable();
   void                      SetEditCurrentArgument();
   void                      SelectionIntoArgument();
   void                      DeactivateActiveDialog();
   void                      ActivateThisDialog();
   void                      onTextChange( const QString& );
-  void                      onSelectMesh();
   void                      OnAngleAdded();
   void                      OnAngleRemoved();
-  void                      setFilters();
+  void                      onOpenView();
+  void                      onCloseView();
 };
 
 #endif // SMESHGUI_EXTRUSIONALONGPATHDLG_H
index 798b6b9eb26a1e2edb676259381e3d83c348c509..38b36d060c79d521335a4a97d3f4fd98660e163b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 #define SPACING 6
 #define MARGIN  11
 
+namespace
+{
+  const char* getLabelText( int typeIndex, bool objSelection )
+  {
+    const char* typeLbl[3] = { "SMESH_ID_NODES", "SMESH_ID_EDGES", "SMESH_ID_FACES" };
+    const char* obj = "SMESH_OBJECTS";
+    return objSelection ? obj : typeLbl[ typeIndex ];
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Constructor
+ */
+//================================================================================
+
+SMESHGUI_3TypesSelector::SMESHGUI_3TypesSelector( QWidget * parent ):
+  QWidget( parent )
+{
+  SMESHGUI*  gui = SMESHGUI::GetSMESHGUI();
+  mySelectionMgr = SMESH::GetSelectionMgr( gui );
+  mySelector     = SMESH::GetViewWindow( gui )->GetSelector();
+  myFilterDlg    = 0;
+  myIdValidator  = new SMESHGUI_IdValidator(this);
+
+  QPixmap image( SMESH::GetResourceMgr( gui )->loadPixmap("SMESH", tr("ICON_SELECT")));
+
+  mySelectBtnGrp = new QButtonGroup( this );
+  mySelectBtnGrp->setExclusive( true );
+
+  QVBoxLayout* mainLayout = new QVBoxLayout( this );
+  mainLayout->setSpacing( SPACING );
+  mainLayout->setMargin( 0 );
+
+  const char* groupLbl[3] = { "SMESH_NODES", "SMESH_EDGES", "SMESH_FACES" };
+
+  for ( int i = 0; i < 3; ++i )
+  {
+    myGroups[i] = new QGroupBox( tr( groupLbl[i] ), this );
+    mainLayout->addWidget( myGroups[i] );
+    QGridLayout* layout = new QGridLayout( myGroups[i] );
+    layout->setSpacing( SPACING );
+    layout->setMargin( MARGIN );
+
+    QPushButton* selBtn = new QPushButton( myGroups[i] );
+    selBtn->setIcon( image );
+    selBtn->setCheckable( true );
+    mySelectBtnGrp->addButton( selBtn, i );
+    myLabel    [i] = new QLabel( myGroups[i] );
+    myLineEdit [i] = new QLineEdit( myGroups[i] );
+    myMeshChk  [i] = new QCheckBox( tr("SMESH_SELECT_WHOLE_MESH"), myGroups[i] );
+    myFilterBtn[i] = new QPushButton( tr( "SMESH_BUT_FILTER" ), myGroups[i] );
+
+    myLineEdit[i]->setMaxLength(-1);
+    myLabel   [i]->setText( tr( getLabelText( i, true )));
+
+    layout->addWidget(myLabel    [i], 0, 0);
+    layout->addWidget(selBtn,         0, 1);
+    layout->addWidget(myLineEdit [i], 0, 2, 1, 2);
+    layout->addWidget(myFilterBtn[i], 0, 4);
+    layout->addWidget(myMeshChk  [i], 1, 0, 1, 5);
+    layout->setColumnStretch( 2, 10 );
+
+    connect( myMeshChk  [i], SIGNAL(toggled(bool)),               SLOT(onSelectMesh(bool)));
+    connect( myFilterBtn[i], SIGNAL(clicked()),                   SLOT(setFilters()));
+    connect( myLineEdit [i], SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
+    myIDSource[i] = new SMESH::ListOfIDSources;
+  }
+  connect( mySelectBtnGrp, SIGNAL(buttonClicked (int)),           SLOT(onSelectType(int)));
+  connect(mySelectionMgr, SIGNAL( currentSelectionChanged()),     SLOT(selectionIntoArgument()));
+
+  // Costruction of the logical filter for the elements: mesh/sub-mesh/group
+  QList<SUIT_SelectionFilter*> aListOfFilters;
+  aListOfFilters.append(new SMESH_TypeFilter (SMESH::MESH));
+  aListOfFilters.append(new SMESH_TypeFilter (SMESH::SUBMESH_VERTEX));
+  aListOfFilters.append(new SMESH_TypeFilter (SMESH::GROUP_NODE));
+  myFilter[0] = 
+    new SMESH_LogicalFilter (aListOfFilters, SMESH_LogicalFilter::LO_OR, /*takeOwnership=*/true);
+  aListOfFilters.append(0);
+  aListOfFilters[0] = new SMESH_TypeFilter (SMESH::MESH);
+  aListOfFilters[1] = new SMESH_TypeFilter (SMESH::SUBMESH_EDGE);
+  aListOfFilters[2] = new SMESH_TypeFilter (SMESH::GROUP_EDGE);
+  aListOfFilters[3] = new SMESH_TypeFilter (SMESH::IDSOURCE_EDGE); // for sub-mesh on group of EDGEs
+  myFilter[1] = 
+    new SMESH_LogicalFilter (aListOfFilters, SMESH_LogicalFilter::LO_OR, /*takeOwnership=*/true);
+  aListOfFilters[0] = new SMESH_TypeFilter (SMESH::MESH);
+  aListOfFilters[1] = new SMESH_TypeFilter (SMESH::SUBMESH_FACE);
+  aListOfFilters[2] = new SMESH_TypeFilter (SMESH::GROUP_FACE);
+  aListOfFilters[3] = new SMESH_TypeFilter (SMESH::IDSOURCE_FACE); // for sub-mesh on group of FACEs
+  myFilter[2] = 
+    new SMESH_LogicalFilter (aListOfFilters, SMESH_LogicalFilter::LO_OR, /*takeOwnership=*/true);
+
+  myBusy = false;
+
+  myMeshChk[0]->setChecked( true );
+  myMeshChk[1]->setChecked( true );
+  myMeshChk[2]->setChecked( true );
+  mySelectBtnGrp->button(0)->click();
+}
+
+//================================================================================
+/*!
+ * \brief Destructor
+ */
+//================================================================================
+
+SMESHGUI_3TypesSelector::~SMESHGUI_3TypesSelector()
+{
+  myIDSource[0].out();
+  myIDSource[1].out();
+  myIDSource[2].out();
+
+  delete myFilter[0];
+  delete myFilter[1];
+  delete myFilter[2];
+
+  if ( myFilterDlg )
+  {
+    myFilterDlg->setParent( 0 );
+    delete myFilterDlg;
+    myFilterDlg = 0;
+  }
+  disconnect(mySelectionMgr, 0, this, 0);
+}
+
+//================================================================================
+/*!
+ * \brief Slot called when selection changes
+ */
+//================================================================================
+
+void SMESHGUI_3TypesSelector::selectionIntoArgument()
+{
+  if (myBusy) return;
+
+  // return if dialog box is inactive
+  if ( !isEnabled() )
+    return;
+
+  // get a current element type
+  int iType = mySelectBtnGrp->checkedId();
+  if ( iType < 0 || iType > 2 )
+    return;
+
+  QString aString = "";
+  int nbObjects = 0;
+
+  // clear
+  myBusy = true;
+  myLineEdit[ iType ]->setText(aString);
+  myIDSource[ iType ]->length (nbObjects);
+  myBusy = false;
+  if ( !myGroups[ iType ]->isEnabled() )
+    return;
+
+  SMESH::SetPointRepresentation(false);
+
+  SALOME_ListIO selected;
+  mySelectionMgr->selectedObjects( selected );
+
+  if ( myMeshChk[ iType ]->isChecked() ) // objects selection
+    myIDSource[ iType ]->length( selected.Extent() ); // reserve
+  myIDSource[ iType ]->length(0);
+
+  SALOME_ListIteratorOfListIO It( selected );
+  for ( ; It.More(); It.Next() )
+  {
+    Handle(SALOME_InteractiveObject) IO = It.Value();
+
+    // get selected mesh
+    SMESH::SMESH_Mesh_var mesh = SMESH::GetMeshByIO(IO);
+    if ( mesh->_is_nil() )
+      continue;
+    if ( !myMesh->_is_nil() &&
+         IsAnythingSelected() &&
+         myMesh->GetId() != mesh->GetId() )
+      continue; // other mesh
+    myMesh  = mesh;
+    myIO    = IO;
+    myActor = SMESH::FindActorByEntry( IO->getEntry() );
+
+    if ( myMeshChk[ iType ]->isChecked() ) // objects selection
+    {
+      SMESH::SMESH_IDSource_var idSrc = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>(IO);
+      if ( idSrc->_is_nil() )
+        continue;
+      mesh = SMESH::SMESH_Mesh::_narrow( idSrc );
+      if ( !mesh->_is_nil() ) // if a mesh is selected, stop iteration
+      {
+        nbObjects = 1;
+        myIDSource[ iType ]->length( nbObjects );
+        myIDSource[ iType ][ 0 ] = idSrc;
+        aString = IO->getName();
+        break;
+      }
+      else // several groups can be selected
+      {
+        myIDSource[ iType ]->length( nbObjects + 1 );
+        myIDSource[ iType ][ nbObjects++ ] = idSrc;
+        aString += " " + QString( IO->getName() ) + " ";
+      }
+    }
+    else // get indices of selected elements
+    {
+      TColStd_IndexedMapOfInteger aMapIndex;
+      mySelector->GetIndex(IO,aMapIndex);
+      int nbElements = aMapIndex.Extent();
+      if ( nbElements > 0 )
+      {
+        SMESH::long_array_var ids = new SMESH::long_array;
+        ids->length( nbElements );
+        for ( int i = 0; i < nbElements; ++i )
+          aString += QString(" %1").arg( ids[ i ] = aMapIndex( i+1 ));
+        addTmpIdSource( ids, iType, nbObjects++ );
+      }
+      break;
+    }
+  }
+
+  myIDSource[ iType ]->length( nbObjects );
+
+  myBusy = true;
+  myLineEdit[ iType ]->setText(aString);
+  myBusy = false;
+
+  emit selectionChanged();
+}
+
+//================================================================================
+/*!
+ * \brief Slot called when text changes in myLineEdit
+ */
+//================================================================================
+
+void SMESHGUI_3TypesSelector::onTextChange( const QString& theNewText )
+{
+  // return if busy
+  if (myBusy) return;
+
+  // get a current element type
+  int iType = 0;
+  QLineEdit* le = (QLineEdit*) sender();
+  for ( ; iType < 3; ++iType )
+    if ( myLineEdit[ iType ] == le )
+      break;
+  if ( iType < 0 || iType > 2 )
+    return;
+  if ( !myGroups[ iType ]->isEnabled() )
+    return;
+
+  myBusy = true;
+
+  // hilight entered elements/nodes
+
+  myIDSource[ iType ]->length( 0 );
+
+  if ( !myMesh->_is_nil() )
+  {
+    QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts);
+    if ( aListId.count() > 0 )
+    {
+      SMDS_Mesh* aMesh = myActor ? myActor->GetObject()->GetMesh() : 0;
+
+      SMESH::ElementType SMESHType = SMESH::ElementType ( iType+1 );
+      SMDSAbs_ElementType SMDSType = SMDSAbs_ElementType( iType+1 );
+      const bool isNode = ( SMDSType == SMDSAbs_Node );
+
+      SMESH::long_array_var ids = new SMESH::long_array;
+      ids->length( aListId.count() );
+      TColStd_MapOfInteger newIndices;
+      for (int i = 0; i < aListId.count(); i++) {
+        int id = aListId[ i ].toInt();
+        bool validId = false;
+        if ( id > 0 ) {
+          if ( aMesh ) {
+            const SMDS_MeshElement * e;
+            if ( isNode ) e = aMesh->FindNode( id );
+            else          e = aMesh->FindElement( id );
+            validId = ( e && e->GetType() == SMDSType );
+          } else {
+            validId = ( myMesh->GetElementType( id, !isNode ) == SMESHType );
+          }
+        }
+        if ( validId && newIndices.Add( id ))
+          ids[ newIndices.Extent()-1 ] = id;
+      }
+      if ( !newIndices.IsEmpty() ) {
+        ids->length( newIndices.Extent() );
+        addTmpIdSource( ids, iType, 0 );
+      }
+      mySelector->AddOrRemoveIndex(myIO, newIndices, false);
+      if ( SVTK_ViewWindow* aViewWindow = SMESH::GetCurrentVtkView() )
+        aViewWindow->highlight( myIO, true, true );
+    }
+  }
+
+  emit selectionChanged();
+
+  myBusy = false;
+}
+
+//================================================================================
+/*!
+ * \brief Creates from ids and stores a temporary IDSource
+ */
+//================================================================================
+
+void SMESHGUI_3TypesSelector::addTmpIdSource( SMESH::long_array_var& ids, int iType, int index )
+{
+  SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
+  SMESH::SMESH_IDSource_var idSrc =
+    aMeshEditor->MakeIDSource( ids, SMESH::ElementType( iType+1 ));
+
+  if ( (int) myIDSource[ iType ]->length() <= index )
+    myIDSource[ iType ]->length( index + 1 );
+  myIDSource[ iType ][ index ] = idSrc;
+
+  myTmpIDSourceList.push_back( idSrc );
+}
+
+//================================================================================
+/*!
+ * \brief Slot called when myMeshChk is checked
+ */
+//================================================================================
+
+void SMESHGUI_3TypesSelector::onSelectMesh( bool on )
+{
+  QCheckBox* send = (QCheckBox*)sender();
+  for ( int iType = 0; iType < 3; ++iType )
+    if ( send == myMeshChk[ iType ])
+    {
+      myLabel[ iType ]->setText( tr( getLabelText( iType, on )));
+      myFilterBtn[ iType ]->setEnabled( !on );
+      myIDSource [ iType ]->length(0);
+      myBusy = true; 
+      myLineEdit [ iType ]->setText("");
+      myBusy = false; 
+      myLineEdit [ iType ]->setReadOnly( on );
+      myLineEdit [ iType ]->setValidator( on ? 0 : myIdValidator );
+      mySelectBtnGrp->button(iType)->click();
+      break;
+    }
+    else
+    {
+      
+    }
+}
+
+//================================================================================
+/*!
+ * \brief Slot called when a selection button is clicked
+ */
+//================================================================================
+
+void SMESHGUI_3TypesSelector::onSelectType(int iType)
+{
+  if ( iType < 0 || iType > 2 )
+    return;
+
+  myIDSource[ iType ]->length(0);
+  myLineEdit[ iType ]->setText("");
+
+  disconnect(mySelectionMgr, 0, this, 0);
+  mySelectionMgr->clearFilters();
+
+  SVTK_ViewWindow* aViewWindow = SMESH::GetCurrentVtkView();
+  if ( myMeshChk[ iType ]->isChecked() )
+  {
+    if ( aViewWindow ) aViewWindow->SetSelectionMode(ActorSelection);
+    mySelectionMgr->installFilter( myFilter[ iType ]);
+  }
+  else if ( aViewWindow )
+  {
+    switch ( iType+1 ) {
+    case SMESH::NODE: aViewWindow->SetSelectionMode(NodeSelection); break;
+    case SMESH::EDGE: aViewWindow->SetSelectionMode(EdgeSelection); break;
+    case SMESH::FACE: aViewWindow->SetSelectionMode(FaceSelection); break;
+    }
+  }
+
+  myLineEdit[ iType ]->setFocus();
+
+  connect(mySelectionMgr, SIGNAL( currentSelectionChanged()), SLOT( selectionIntoArgument()));
+  selectionIntoArgument();
+}
+
+//================================================================================
+/*!
+ * \brief Slot called when "Set filter" is clicked
+ */
+//================================================================================
+
+void SMESHGUI_3TypesSelector::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( SMESHGUI::GetSMESHGUI(), types );
+  }
+
+  QPushButton* send = (QPushButton*)sender();
+  for ( int iType = 0; iType < 3; ++iType )
+    if ( send == myFilterBtn[ iType ])
+    {
+      mySelectBtnGrp->button(iType)->click();
+
+      myFilterDlg->Init( SMESH::ElementType( iType+1 ) );
+      myFilterDlg->SetSelection();
+      myFilterDlg->SetMesh( myMesh );
+      myFilterDlg->SetSourceWg( myLineEdit[ iType ]);
+      myFilterDlg->show();
+      break;
+    }
+}
+
+//================================================================================
+/*!
+ * \brief Clear selection
+ */
+//================================================================================
+
+void SMESHGUI_3TypesSelector::Clear()
+{
+  myBusy = true;
+  for ( int iType = 0; iType < 3; ++iType )
+  {
+    myIDSource[ iType ]->length(0);
+    myLineEdit[ iType ]->setText("");
+  }
+  myBusy = false;
+  selectionIntoArgument();
+}
+
+//================================================================================
+/*!
+ * \brief Enable/disable controls of a type
+ */
+//================================================================================
+
+void SMESHGUI_3TypesSelector::SetEnabled( bool enable, SMESH::ElementType type )
+{
+  myBusy = true; 
+  for ( int iType = 0; iType < 3; ++iType )
+    if ( iType+1 == type || type == SMESH::ALL )
+    {
+      myGroups[ iType ]->setEnabled( enable );
+      if ( !enable ) {
+        myIDSource[ iType ]->length(0);
+        myLineEdit[ iType ]->setText("");
+      }
+    }
+  myBusy = false;
+  selectionIntoArgument();
+}
+
+//================================================================================
+/*!
+ * \brief Checks if anything is selected
+ */
+//================================================================================
+
+bool SMESHGUI_3TypesSelector::IsAnythingSelected( SMESH::ElementType type )
+{
+  int nbSel = 0;
+
+  for ( int iType = 0; iType < 3; ++iType )
+    if ( iType+1 == type || type == SMESH::ALL )
+      nbSel += myIDSource[ iType ]->length();
+
+  return nbSel;
+}
+
+//================================================================================
+/*!
+ * \brief Returns selected elements and most complex type of selected elements
+ */
+//================================================================================
+
+SMESH::ElementType SMESHGUI_3TypesSelector::GetSelected( SMESH::ListOfIDSources & nodes,
+                                                         SMESH::ListOfIDSources & edges,
+                                                         SMESH::ListOfIDSources & faces )
+{
+  nodes = myIDSource[0];
+  edges = myIDSource[1];
+  faces = myIDSource[2];
+
+  if ( myIDSource[2]->length() > 0 ) return SMESH::FACE;
+  if ( myIDSource[1]->length() > 0 ) return SMESH::EDGE;
+  if ( myIDSource[0]->length() > 0 ) return SMESH::NODE;
+  return SMESH::ALL;
+}
+
 //=================================================================================
 // function : SMESHGUI_ExtrusionDlg()
 // purpose  : constructor
 //=================================================================================
+
 SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
   : SMESHGUI_PreviewDlg( theModule ),
-    mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
-    myEditCurrentArgument(0),
-    myFilterDlg( 0 ),
-    mySelectedObject(SMESH::SMESH_IDSource::_nil())
+    mySelectionMgr( SMESH::GetSelectionMgr( 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")));
+  QPixmap image (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT")));
 
   setModal( false );
   setAttribute( Qt::WA_DeleteOnClose, true );
@@ -110,78 +607,20 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
   SMESHGUI_ExtrusionDlgLayout->setMargin(MARGIN);
 
   /***************************************************************/
-  ConstructorsBox = new QGroupBox(tr("SMESH_EXTRUSION"), this);
-  GroupConstructors = new QButtonGroup(this);
-  QHBoxLayout* ConstructorsBoxLayout = new QHBoxLayout(ConstructorsBox);
-  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(RadioButton0, 0);
-  GroupConstructors->addButton(RadioButton1, 1);
-  GroupConstructors->addButton(RadioButton2, 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);
-
-  /***************************************************************/
-  GroupArguments = new QGroupBox(tr("EXTRUSION_0D"), this);
+  GroupArguments = new QGroupBox(tr("SMESH_EXTRUSION"), 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);
+  SelectorWdg = new SMESHGUI_3TypesSelector( GroupArguments );
 
-  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);
-
-  RadioButton3 = new QRadioButton(GroupArguments);
-  RadioButton3->setText( tr("SMESH_EXTRUSION_TO_DISTANCE") );
-  RadioButton4 = new QRadioButton(GroupArguments);
-  RadioButton4->setText( tr("SMESH_EXTRUSION_ALONG_VECTOR") );
+  ExtrMethod_RBut0 = new QRadioButton(GroupArguments);
+  ExtrMethod_RBut0->setText( tr("SMESH_EXTRUSION_TO_DISTANCE") );
+  ExtrMethod_RBut1 = new QRadioButton(GroupArguments);
+  ExtrMethod_RBut1->setText( tr("SMESH_EXTRUSION_ALONG_VECTOR") );
+  ExtrMethod_RBut2 = new QRadioButton(GroupArguments);
+  ExtrMethod_RBut2->setText( tr("SMESH_EXTRUSION_BY_NORMAL") );
 
   //Control for the Distance selection
   TextLabelDistance = new QLabel(tr("SMESH_DISTANCE"), GroupArguments);
@@ -200,7 +639,9 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
   TextLabelVector = new QLabel(tr("SMESH_VECTOR"), GroupArguments);
 
   SelectVectorButton = new QPushButton(GroupArguments);
-  SelectVectorButton->setIcon(image2);
+  SelectVectorButton->setIcon(image);
+  SelectVectorButton->setCheckable( true );
+  SelectorWdg->GetButtonGroup()->addButton( SelectVectorButton );
 
   TextLabelVx = new QLabel(tr("SMESH_DX"), GroupArguments);
   SpinBox_Vx = new SMESHGUI_SpinBox(GroupArguments);
@@ -221,83 +662,92 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
   // CheckBox for groups generation
   MakeGroupsCheck = new QCheckBox(tr("SMESH_MAKE_GROUPS"), GroupArguments);
 
+  // CheckBox for ByAverageNormal arg of ExtrusionByNormal()
+  ByAverageNormalCheck = new QCheckBox(tr("BY_AVERAGE_NORMAL"), GroupArguments);
+
+  // CheckBox for UseInputElemsOnly arg of ExtrusionByNormal()
+  UseInputElemsOnlyCheck = new QCheckBox(tr("USE_INPUT_ELEMS_ONLY"), 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(myFilterBtn,          0, 7);
-  GroupArgumentsLayout->addWidget(CheckBoxMesh,         1, 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);
+  GroupArgumentsLayout->addWidget(SelectorWdg,            0, 0, 1, 9);
+  GroupArgumentsLayout->addWidget(ExtrMethod_RBut0,       1, 0, 1, 3);
+  GroupArgumentsLayout->addWidget(ExtrMethod_RBut1,       1, 3, 1, 3);
+  GroupArgumentsLayout->addWidget(ExtrMethod_RBut2,       1, 6, 1, 3);
+  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(TextLabelDist,          4, 0);
+  GroupArgumentsLayout->addWidget(SpinBox_VDist,          4, 3);
+  GroupArgumentsLayout->addWidget(TextLabelNbSteps,       5, 0, 1, 3);
+  GroupArgumentsLayout->addWidget(SpinBox_NbSteps,        5, 3);
+  GroupArgumentsLayout->addWidget(ByAverageNormalCheck,   6, 0, 1, 4);
+  GroupArgumentsLayout->addWidget(UseInputElemsOnlyCheck, 6, 4, 1, 4);
+  GroupArgumentsLayout->addWidget(myPreviewCheckBox,      7, 0, 1, 8);
+  GroupArgumentsLayout->addWidget(MakeGroupsCheck,        8, 0, 1, 8);
+  GroupArgumentsLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding), 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_ExtrusionDlgLayout->addWidget(ConstructorsBox);
   SMESHGUI_ExtrusionDlgLayout->addWidget(GroupArguments);
   SMESHGUI_ExtrusionDlgLayout->addWidget(GroupButtons);
 
   /* Initialisations */
-  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_Vx->RangeStepAndValidator(COORD_MIN, COORD_MAX, 0.1, "length_precision");
+  SpinBox_Vy->RangeStepAndValidator(COORD_MIN, COORD_MAX, 0.1, "length_precision");
+  SpinBox_Vz->RangeStepAndValidator(COORD_MIN, COORD_MAX, 0.1, "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_NbSteps->setRange(1, 999999);
-  SpinBox_VDist->RangeStepAndValidator(0, COORD_MAX, 10.0, "length_precision");
+  SpinBox_VDist->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
 
-  RadioButton0->setChecked(true);
-  RadioButton3->setChecked(true);
+  ExtrMethod_RBut0->setChecked(true);
+  UseInputElemsOnlyCheck->setChecked(true);
   MakeGroupsCheck->setChecked(true);
 
   mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
 
   mySMESHGUI->SetActiveDialogBox(this);
 
-  // Costruction of the logical filter for the elements: mesh/sub-mesh/group
-  QList<SUIT_SelectionFilter*> aListOfFilters;
-  aListOfFilters.append(new SMESH_TypeFilter (SMESH::MESH));
-  aListOfFilters.append(new SMESH_TypeFilter (SMESH::SUBMESH_VERTEX));
-  aListOfFilters.append(new SMESH_TypeFilter (SMESH::GROUP_NODE));
-  myMeshOrSubMeshOrGroupFilter0D =
-    new SMESH_LogicalFilter (aListOfFilters, SMESH_LogicalFilter::LO_OR, /*takeOwnership=*/true);
-  aListOfFilters[0] = new SMESH_TypeFilter (SMESH::MESH);
-  aListOfFilters[1] = new SMESH_TypeFilter (SMESH::SUBMESH_EDGE);
-  aListOfFilters[2] = new SMESH_TypeFilter (SMESH::GROUP_EDGE);
-  myMeshOrSubMeshOrGroupFilter1D =
-    new SMESH_LogicalFilter (aListOfFilters, SMESH_LogicalFilter::LO_OR, /*takeOwnership=*/true);
-  aListOfFilters[0] = new SMESH_TypeFilter (SMESH::MESH);
-  aListOfFilters[1] = new SMESH_TypeFilter (SMESH::SUBMESH_FACE);
-  aListOfFilters[2] = new SMESH_TypeFilter (SMESH::GROUP_FACE);
-  myMeshOrSubMeshOrGroupFilter2D =
-    new SMESH_LogicalFilter (aListOfFilters, SMESH_LogicalFilter::LO_OR, /*takeOwnership=*/true);
-
   myHelpFileName = "extrusion_page.html";
 
   Init();
@@ -309,8 +759,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()));
+  connect(ExtrMethod_RBut0, SIGNAL(clicked()), this, SLOT(ClickOnRadio()));
+  connect(ExtrMethod_RBut1, SIGNAL(clicked()), this, SLOT(ClickOnRadio()));
+  connect(ExtrMethod_RBut2, SIGNAL(clicked()), this, SLOT(ClickOnRadio()));
 
   // to update state of the Ok & Apply buttons
   connect(SpinBox_Vx, SIGNAL(valueChanged(double)), SLOT(CheckIsEnable()));
@@ -320,33 +771,33 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
   connect(SpinBox_Dy, SIGNAL(valueChanged(double)), SLOT(CheckIsEnable()));
   connect(SpinBox_Dz, SIGNAL(valueChanged(double)), SLOT(CheckIsEnable()));
 
-  connect(GroupConstructors,    SIGNAL(buttonClicked(int)), SLOT(ConstructorsClicked(int)));
-  connect(SelectElementsButton, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
   connect(SelectVectorButton,   SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
-  connect(mySMESHGUI,           SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog()));
-  connect(mySelectionMgr,       SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
+  connect(mySMESHGUI,           SIGNAL(SignalDeactivateActiveDialog()), SLOT(DeactivateActiveDialog()));
+  connect(mySelectionMgr,       SIGNAL(currentSelectionChanged()), SLOT(toDisplaySimulation()));
+  connect(SelectorWdg,          SIGNAL(selectionChanged()), this, SLOT(toDisplaySimulation()));
+  connect(SelectorWdg,          SIGNAL(selectionChanged()), this, SLOT(CheckIsEnable()));
   /* to close dialog if study change */
-  connect(mySMESHGUI,           SIGNAL(SignalCloseAllDialogs()),   this, SLOT(reject()));
-  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()));
+  connect(mySMESHGUI,           SIGNAL(SignalCloseAllDialogs()),      this, SLOT(reject()));
+  connect(mySMESHGUI,           SIGNAL(SignalActivatedViewManager()), this, SLOT(onOpenView()));
+  connect(mySMESHGUI,           SIGNAL(SignalCloseView()),            this, SLOT(onCloseView()));
+
+  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()));
+  connect(ByAverageNormalCheck,   SIGNAL(toggled(bool)), this, SLOT(toDisplaySimulation()));
+  connect(UseInputElemsOnlyCheck, SIGNAL(toggled(bool)), this, SLOT(toDisplaySimulation()));
 
   //To Connect preview check box
   connectPreviewControl();
 
   /***************************************************************/
   
-  ConstructorsClicked(0);
   ClickOnRadio();
-  SelectionIntoArgument();
 }
 
 //=================================================================================
@@ -355,13 +806,6 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
 //=================================================================================
 SMESHGUI_ExtrusionDlg::~SMESHGUI_ExtrusionDlg()
 {
-  if ( myFilterDlg != 0 ) {
-    myFilterDlg->setParent( 0 );
-    delete myFilterDlg;
-  }
-  if ( myMeshOrSubMeshOrGroupFilter0D ) delete myMeshOrSubMeshOrGroupFilter0D;
-  if ( myMeshOrSubMeshOrGroupFilter1D ) delete myMeshOrSubMeshOrGroupFilter1D;
-  if ( myMeshOrSubMeshOrGroupFilter2D ) delete myMeshOrSubMeshOrGroupFilter2D;
 }
 
 //=================================================================================
@@ -370,16 +814,8 @@ SMESHGUI_ExtrusionDlg::~SMESHGUI_ExtrusionDlg()
 //=================================================================================
 void SMESHGUI_ExtrusionDlg::Init (bool ResetControls)
 {
-  myBusy = false;
-  myIDs.clear();
-
-  LineEditElements->clear();
-  myNbOkElements = 0;
-
-  myActor = 0;
-  myMesh = SMESH::SMESH_Mesh::_nil();
-
-  if (ResetControls) {
+  if (ResetControls)
+  {
     SpinBox_NbSteps->setValue(1);
     SpinBox_VDist->setValue(10);
     SpinBox_Dx->SetValue(0);
@@ -389,12 +825,10 @@ void SMESHGUI_ExtrusionDlg::Init (bool ResetControls)
     SpinBox_Vy->SetValue(0);
     SpinBox_Vz->SetValue(0);
 
-    CheckBoxMesh->setChecked(false);
-    onSelectMesh(false);
     myPreviewCheckBox->setChecked(false);
     onDisplaySimulation(false);
   }
-
+  SelectorWdg->Clear();
   CheckIsEnable();
 }
 
@@ -404,7 +838,7 @@ void SMESHGUI_ExtrusionDlg::Init (bool ResetControls)
 //=================================================================================
 void SMESHGUI_ExtrusionDlg::CheckIsEnable()
 {  
-  bool anIsEnable = myNbOkElements > 0 && isValuesValid();
+  bool anIsEnable = SelectorWdg->IsAnythingSelected() && isValuesValid();
 
   buttonOk->setEnabled(anIsEnable);
   buttonApply->setEnabled(anIsEnable);
@@ -414,92 +848,42 @@ void SMESHGUI_ExtrusionDlg::CheckIsEnable()
 // function : isValuesValid()
 // purpose  : Return true in case if values entered into dialog are valid
 //=================================================================================
-bool SMESHGUI_ExtrusionDlg::isValuesValid() {
+bool SMESHGUI_ExtrusionDlg::isValuesValid()
+{
   double aX, aY, aZ, aModule = 0;
-  if ( RadioButton3->isChecked() ) {
+  if ( ExtrMethod_RBut0->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() ) {
+  }
+  else if ( ExtrMethod_RBut1->isChecked() )
+  {
     aX = SpinBox_Vx->GetValue();
     aY = SpinBox_Vy->GetValue();
     aZ = SpinBox_Vz->GetValue();
     aModule = sqrt(aX*aX + aY*aY + aZ*aZ);
+    double aVDist = (double)SpinBox_VDist->value();
+    aModule *= aVDist;
+  }
+  else if ( ExtrMethod_RBut2->isChecked() )
+  {
+    aModule = Abs((double)SpinBox_VDist->value());
   }
+  
   return aModule > 1.0E-38;
 }
 
 //=================================================================================
-// function : ConstructorsClicked()
+// function : ClickOnRadio()
 // purpose  : Radio button management
 //=================================================================================
-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_0D"));
-      if (!CheckBoxMesh->isChecked())
-      {
-        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())
-      {
-        LineEditElements->clear();
-        myIDs.clear();
-        if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-          aViewWindow->SetSelectionMode(FaceSelection);
-      }
-      break;
-    }
-  }
-
-  myEditCurrentArgument = (QWidget*)LineEditElements;
-  LineEditElements->setFocus();
-
-  if (CheckBoxMesh->isChecked())
-    onSelectMesh(true);
-
-  myEditCurrentArgument->hide();
-  myEditCurrentArgument->show();
-
-  connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
-}
 
-//=================================================================================
-// function : ConstructorsClicked()
-// purpose  : Radio button management
-//=================================================================================
 void SMESHGUI_ExtrusionDlg::ClickOnRadio()
 {
-  if ( RadioButton3->isChecked() ) {
+  if ( ExtrMethod_RBut0->isChecked() )
+  {
     TextLabelDistance->show();
     TextLabelDx->show();
     SpinBox_Dx->show();
@@ -515,29 +899,72 @@ void SMESHGUI_ExtrusionDlg::ClickOnRadio()
     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();
+    TextLabelDist->hide();
+    SpinBox_VDist->hide();
+    SelectVectorButton->hide();
+
+    ByAverageNormalCheck->hide();
+    UseInputElemsOnlyCheck->hide();
+
+    SelectorWdg->SetEnabled( true, SMESH::ALL );
+  }
+  else if ( ExtrMethod_RBut1->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();
+
+    ByAverageNormalCheck->hide();
+    UseInputElemsOnlyCheck->hide();
+
+    SelectorWdg->SetEnabled( true, SMESH::ALL );
+  }
+  else if ( ExtrMethod_RBut2->isChecked() )
+  {
+    TextLabelDistance->hide();
+    TextLabelDx->hide();
+    SpinBox_Dx->hide();
+    TextLabelDy->hide();
+    SpinBox_Dy->hide();
+    TextLabelDz->hide();
+    SpinBox_Dz->hide();
+
+    TextLabelVector->hide();
+    TextLabelVx->hide();
+    SpinBox_Vx->hide();
+    TextLabelVy->hide();
+    SpinBox_Vy->hide();
+    TextLabelVz->hide();
+    SpinBox_Vz->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();
+    SelectVectorButton->hide();
+
+    ByAverageNormalCheck->show();
+    UseInputElemsOnlyCheck->show();
+
+    SelectorWdg->SetEnabled( false, SMESH::NODE );
+    SelectorWdg->SetEnabled( false, SMESH::EDGE );
   }
+
+  CheckIsEnable();
+
   onDisplaySimulation(true);
   // AdjustSize
   qApp->processEvents();
@@ -549,6 +976,7 @@ void SMESHGUI_ExtrusionDlg::ClickOnRadio()
 // function : ClickOnApply()
 // purpose  : Called when user presses <Apply> button
 //=================================================================================
+
 bool SMESHGUI_ExtrusionDlg::ClickOnApply()
 {
   if (mySMESHGUI->isActiveStudyLocked())
@@ -557,103 +985,105 @@ bool SMESHGUI_ExtrusionDlg::ClickOnApply()
   if (!isValid())
     return false;
 
-  if (myNbOkElements) {
-
+  if ( SelectorWdg->IsAnythingSelected() )
+  {
     SMESH::DirStruct aVector;
     getExtrusionVector(aVector);
     
     QStringList aParameters;
-    if ( RadioButton3->isChecked() ) {
+    if ( ExtrMethod_RBut0->isChecked() )
+    {
       aParameters << SpinBox_Dx->text();
       aParameters << SpinBox_Dy->text();
       aParameters << SpinBox_Dz->text();
-    } else if ( RadioButton4->isChecked() ) {
+    }
+    else if ( ExtrMethod_RBut1->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();
     }
+    else if ( ExtrMethod_RBut2->isChecked() )
+    {
+      aParameters << SpinBox_VDist->text();
+    }
 
     long aNbSteps = (long)SpinBox_NbSteps->value();
 
     aParameters << SpinBox_NbSteps->text();
 
+    bool meshHadNewTypeBefore = true;
+    int  maxSelType = 0;
+    const bool makeGroups = ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() );
+
     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() ) 
-          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);
-        }
 
+      SMESH::SMESH_Mesh_var mesh = SelectorWdg->GetMesh();
+
+      SMESH::ListOfIDSources_var nodes = new SMESH::ListOfIDSources();
+      SMESH::ListOfIDSources_var edges = new SMESH::ListOfIDSources();
+      SMESH::ListOfIDSources_var faces = new SMESH::ListOfIDSources();
+      maxSelType = SelectorWdg->GetSelected( nodes, edges, faces );
+
+      // is it necessary to switch on the next Display Mode?
+      SMESH::ElementType newType = (SMESH::ElementType)( maxSelType + 1 );
+      SMESH::array_of_ElementType_var oldTypes = mesh->GetTypes();
+      meshHadNewTypeBefore = false;
+      for ( size_t i = 0; i < oldTypes->length() && !meshHadNewTypeBefore; ++i )
+        meshHadNewTypeBefore = ( oldTypes[i] >= newType );
+
+      SMESH::SMESH_MeshEditor_var meshEditor = mesh->GetMeshEditor();
+      SMESH::ListOfGroups_var groups;
+
+      mesh->SetParameters( aParameters.join(":").toLatin1().constData() );
+
+      if ( ExtrMethod_RBut2->isVisible() &&
+           ExtrMethod_RBut2->isChecked() ) // Extrusion by normal
+      {
+        double stepSize          = (double) SpinBox_VDist->value();
+        long   nbSteps           = (long) SpinBox_NbSteps->value();
+        bool   useInputElemsOnly = UseInputElemsOnlyCheck->isChecked();
+        bool   byAverageNormal   = ByAverageNormalCheck->isChecked();
+        int    dim               = (maxSelType == SMESH::FACE) ? 2 : 1;
+
+        groups = meshEditor->ExtrusionByNormal( faces, stepSize, nbSteps, useInputElemsOnly,
+                                                byAverageNormal, makeGroups, dim );
       }
-      else {
-        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);
+      else
+      {
+        groups = meshEditor->ExtrusionSweepObjects( nodes, edges, faces,
+                                                    aVector, aNbSteps, makeGroups );
       }
 
     } catch (...) {
     }
 
-    SMESH::Update(myIO, SMESH::eDisplay);
-    if ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() )
+    SMESH_Actor* actor = SelectorWdg->GetActor();
+    if ( actor && !meshHadNewTypeBefore )
+    {
+      unsigned int aMode = actor->GetEntityMode();
+      switch ( maxSelType ) {
+      case SMESH::NODE: // extrude node -> edges
+        actor->SetRepresentation(SMESH_Actor::eEdge);
+        actor->SetEntityMode( aMode |= SMESH_Actor::eEdges ); break;
+      case SMESH::EDGE: // edge -> faces
+        actor->SetRepresentation(SMESH_Actor::eSurface);
+        actor->SetEntityMode( aMode |= SMESH_Actor::eFaces ); break;
+      case SMESH::FACE: // faces -> volumes
+        actor->SetRepresentation(SMESH_Actor::eSurface);
+        actor->SetEntityMode( aMode |= SMESH_Actor::eVolumes ); break;
+      }
+    }
+    if ( actor )
+      SMESH::Update( actor->getIO(), actor->GetVisibility() );
+    if ( makeGroups )
       mySMESHGUI->updateObjBrowser(true); // new groups may appear
     Init(false);
-    ConstructorsClicked(GetConstructorId());
     mySelectionMgr->clearSelected();
-    mySelectedObject = SMESH::SMESH_IDSource::_nil();
-    SelectionIntoArgument();
+    SelectorWdg->Clear();
 
     SMESHGUI::Modified();
   }
@@ -691,6 +1121,31 @@ void SMESHGUI_ExtrusionDlg::reject()
   QDialog::reject();
 }
 
+//=================================================================================
+// function : onOpenView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_ExtrusionDlg::onOpenView()
+{
+  if ( mySelector ) {
+    SMESH::SetPointRepresentation(false);
+  }
+  else {
+    mySelector = SMESH::GetViewWindow( mySMESHGUI )->GetSelector();
+    ActivateThisDialog();
+  }
+}
+
+//=================================================================================
+// function : onCloseView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_ExtrusionDlg::onCloseView()
+{
+  DeactivateActiveDialog();
+  mySelector = 0;
+}
+
 //=================================================================================
 // function : ClickOnHelp()
 // purpose  :
@@ -715,185 +1170,35 @@ void SMESHGUI_ExtrusionDlg::ClickOnHelp()
   }
 }
 
-//=================================================================================
-// function : onTextChange()
-// purpose  :
-//=================================================================================
-void SMESHGUI_ExtrusionDlg::onTextChange (const QString& theNewText)
-{
-  QLineEdit* send = (QLineEdit*)sender();
-
-  // return if busy
-  if (myBusy) return;
-
-  // set busy flag
-  myBusy = true;
-
-  if (send == LineEditElements)
-    myNbOkElements = 0;
-
-  // hilight entered elements/nodes
-
-  if (!myIO.IsNull()) {
-    QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts);
-
-    if (send == LineEditElements)
-    {
-      SMDS_Mesh* aMesh = myActor ? myActor->GetObject()->GetMesh() : 0;
-      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;
-      for (int i = 0; i < aListId.count(); i++) {
-        int id = aListId[ i ].toInt();
-        bool validId = false;
-        if ( id > 0 ) {
-          if ( aMesh ) {
-            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 );
-          }
-        }
-        if ( validId && newIndices.Add( id ))
-          myElementsId[ newIndices.Extent()-1 ] = id;
-      }
-      myElementsId->length( myNbOkElements = newIndices.Extent() );
-      mySelector->AddOrRemoveIndex(myIO, newIndices, false);
-      if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-        aViewWindow->highlight( myIO, true, true );
-    }
-  }
-
-  CheckIsEnable();
-
-  onDisplaySimulation(true);
-
-  myBusy = false;
-}
-
 //=================================================================================
 // function : SelectionIntoArgument()
-// purpose  : Called when selection as changed or other case
+// purpose  : Called when selection has changed or other case
 //=================================================================================
 void SMESHGUI_ExtrusionDlg::SelectionIntoArgument()
 {
-  if (myBusy) return;
-
   // return if dialog box is inactive
   if (!GroupButtons->isEnabled())
     return;
 
-  // clear
-  if(myEditCurrentArgument != (QWidget*)SpinBox_Vx) {
-    myActor = 0;
-    Handle(SALOME_InteractiveObject) resIO = myIO;
-    myIO.Nullify();
-  }
-
-  QString aString = "";
-  // set busy flag
-  if(myEditCurrentArgument == (QWidget*)LineEditElements) {
-    myBusy = true;
-    LineEditElements->setText(aString);
-    myNbOkElements = 0;
-    myBusy = false;
-  }
-  // get selected mesh
-  SALOME_ListIO aList;
-  mySelectionMgr->selectedObjects(aList);
-  int nbSel = SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aString);
-  if (nbSel != 1)
-    return;
-
-  Handle(SALOME_InteractiveObject) IO = aList.First();
-
-  if(myEditCurrentArgument != (QWidget*)SpinBox_Vx) {
-    myMesh = SMESH::GetMeshByIO(IO);
-    if (myMesh->_is_nil())
+  if ( SelectVectorButton->isChecked() )
+  {
+    SALOME_ListIO aList;
+    mySelectionMgr->selectedObjects(aList);
+    if ( aList.IsEmpty() || aList.Extent() > 1 )
       return;
-    myIO = IO;
-    myActor = SMESH::FindActorByObject(myMesh);
-  }
-
-  if (myEditCurrentArgument == (QWidget*)LineEditElements) {    
-    int aNbElements = 0;
-
-    // MakeGroups is available if there are groups
-    if ( myMesh->NbGroups() == 0 ) {
-      MakeGroupsCheck->setChecked(false);
-      MakeGroupsCheck->setEnabled(false);
-    } else {
-      MakeGroupsCheck->setEnabled(true);
-    }
-
-    if (CheckBoxMesh->isChecked()) {
-      SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aString);
-
-      if (!SMESH::IObjectToInterface<SMESH::SMESH_IDSource>(IO)->_is_nil())
-        mySelectedObject = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>(IO);
-      else
-        return;
-    } else {
-      // get indices of selected elements
-      TColStd_IndexedMapOfInteger aMapIndex;
-      mySelector->GetIndex(IO,aMapIndex);
-      aNbElements = aMapIndex.Extent();
-
-      if (aNbElements < 1)
-        return;
-
-      myElementsId = new SMESH::long_array;
-      myElementsId->length( aNbElements );
-      aString = "";
-      for ( int i = 0; i < aNbElements; ++i )
-        aString += QString(" %1").arg( myElementsId[ i ] = aMapIndex( i+1 ) );
-    }
 
-    myNbOkElements = true;
-
-    myBusy = true;
-    ((QLineEdit*)myEditCurrentArgument)->setText(aString);
-    myBusy = false;
-  }
-  else if(myEditCurrentArgument == (QWidget*)SpinBox_Vx){
+    Handle(SALOME_InteractiveObject) IO = aList.First();
     TColStd_IndexedMapOfInteger aMapIndex;
     mySelector->GetIndex(IO,aMapIndex);
-    int aNbElements = aMapIndex.Extent();
-    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)
+    if ( aMapIndex.Extent() != 1 )
+      return;
+    SMESH_Actor* anActor = SMESH::FindActorByEntry( IO->getEntry() );
+    SMDS_Mesh*     aMesh = anActor ? anActor->GetObject()->GetMesh() : 0;
+    if ( !aMesh )
       return;
-    
-    const SMDS_MeshFace* face = dynamic_cast<const SMDS_MeshFace*>(aMesh->FindElement(aMapIndex(aNbElements)));
 
+    const SMDS_MeshFace* face =
+      dynamic_cast<const SMDS_MeshFace*>(aMesh->FindElement(aMapIndex(1)));
     if (!face)
       return;
 
@@ -901,12 +1206,9 @@ void SMESHGUI_ExtrusionDlg::SelectionIntoArgument()
     SpinBox_Vx->SetValue(aNormale.X());
     SpinBox_Vy->SetValue(aNormale.Y());
     SpinBox_Vz->SetValue(aNormale.Z());
-    
   }
-  
+
   onDisplaySimulation(true);
-  
-  // OK
   CheckIsEnable();
 }
 
@@ -922,50 +1224,12 @@ void SMESHGUI_ExtrusionDlg::SetEditCurrentArgument()
   mySelectionMgr->clearSelected();
   mySelectionMgr->clearFilters();
 
-  if (send == SelectElementsButton) {
-    myEditCurrentArgument = (QWidget*)LineEditElements;
-    if (CheckBoxMesh->isChecked())
-    {
-      if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-        aViewWindow->SetSelectionMode(ActorSelection);
-      switch( GetConstructorId() ) {
-      case 0: mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter0D); break;
-      case 1: mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter1D); break;
-      case 2: mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter2D); break;
-      }
-    }
-    else
-    {
-      int aConstructorId = GetConstructorId();
-      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){
-    myEditCurrentArgument = (QWidget*)SpinBox_Vx;
+  if (send == SelectVectorButton)
+  {
     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
       aViewWindow->SetSelectionMode(FaceSelection);
   }
   
-  myEditCurrentArgument->setFocus();
   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
   SelectionIntoArgument();
 }
@@ -976,10 +1240,11 @@ void SMESHGUI_ExtrusionDlg::SetEditCurrentArgument()
 //=================================================================================
 void SMESHGUI_ExtrusionDlg::DeactivateActiveDialog()
 {
-  if (ConstructorsBox->isEnabled()) {
-    ConstructorsBox->setEnabled(false);
+  if (GroupButtons->isEnabled())
+  {
     GroupArguments->setEnabled(false);
     GroupButtons->setEnabled(false);
+    SelectorWdg->setEnabled(false);
     mySMESHGUI->ResetState();
     mySMESHGUI->SetActiveDialogBox(0);
   }
@@ -993,101 +1258,26 @@ void SMESHGUI_ExtrusionDlg::ActivateThisDialog()
 {
   // Emit a signal to deactivate the active dialog
   mySMESHGUI->EmitSignalDeactivateDialog();
-  ConstructorsBox->setEnabled(true);
   GroupArguments->setEnabled(true);
   GroupButtons->setEnabled(true);
+  SelectorWdg->setEnabled(true);
 
   mySMESHGUI->SetActiveDialogBox(this);
-
-  ConstructorsClicked(GetConstructorId());
-  SelectionIntoArgument();
 }
 
 //=================================================================================
 // function : enterEvent()
-// purpose  : Mouse enter event
-//=================================================================================
-void SMESHGUI_ExtrusionDlg::enterEvent (QEvent*)
-{
-  if (!ConstructorsBox->isEnabled())
-    ActivateThisDialog();
-}
-
-//=================================================================================
-// function : onSelectMesh()
 // purpose  :
 //=================================================================================
-void SMESHGUI_ExtrusionDlg::onSelectMesh (bool toSelectMesh)
+void SMESHGUI_ExtrusionDlg::enterEvent (QEvent*)
 {
-  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;
-  }
-
-  mySelectionMgr->clearFilters();
-
-  if (toSelectMesh)
-  {
-    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-      aViewWindow->SetSelectionMode(ActorSelection);
-    switch( GetConstructorId() ) {
-    case 0: mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter0D); break;
-    case 1: mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter1D); break;
-    case 2: mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter2D); break;
-    }
-    LineEditElements->setReadOnly(true);
-    LineEditElements->setValidator(0);
-  }
-  else
-  {
-    int aConstructorId = GetConstructorId();
-    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;
-        }
+  if ( !GroupButtons->isEnabled() ) {
+    SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
+    if ( aViewWindow && !mySelector) {
+      mySelector = aViewWindow->GetSelector();
     }
-    LineEditElements->setReadOnly(false);
-    LineEditElements->setValidator(myIdValidator);
-    onTextChange(LineEditElements->text());
+    ActivateThisDialog();
   }
-
-  SelectionIntoArgument();
-
-  if (!toSelectMesh)
-    LineEditElements->setText( myIDs );
-}
-
-//=================================================================================
-// function : GetConstructorId()
-// purpose  :
-//=================================================================================
-int SMESHGUI_ExtrusionDlg::GetConstructorId()
-{
-  return GroupConstructors->checkedId();
 }
 
 //=================================================================================
@@ -1106,52 +1296,6 @@ void SMESHGUI_ExtrusionDlg::keyPressEvent( QKeyEvent* e )
   }
 }
 
-//=================================================================================
-// function : setFilters()
-// purpose  : SLOT. Called when "Filter" button pressed.
-//=================================================================================
-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 );
-  }
-  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 );
-  myFilterDlg->SetSourceWg( LineEditElements );
-
-  myFilterDlg->show();
-}
-
 //=================================================================================
 // function : isValid
 // purpose  :
@@ -1160,11 +1304,11 @@ bool SMESHGUI_ExtrusionDlg::isValid()
 {
   QString msg;
   bool ok = true;
-  if ( RadioButton3->isChecked() ) {
+  if ( ExtrMethod_RBut0->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() ) {
+  } else if ( ExtrMethod_RBut1->isChecked() ) {
     ok = SpinBox_Vx->isValid( msg, true ) && ok;
     ok = SpinBox_Vy->isValid( msg, true ) && ok;
     ok = SpinBox_Vz->isValid( msg, true ) && ok;
@@ -1186,46 +1330,51 @@ bool SMESHGUI_ExtrusionDlg::isValid()
 // function : onDisplaySimulation
 // purpose  : Show/Hide preview
 //=================================================================================
-void SMESHGUI_ExtrusionDlg::onDisplaySimulation( bool toDisplayPreview ) {
+void SMESHGUI_ExtrusionDlg::onDisplaySimulation( bool toDisplayPreview )
+{
   if (myPreviewCheckBox->isChecked() && toDisplayPreview) {
-    if (myNbOkElements && isValid() && isValuesValid()) {
+    if ( SelectorWdg->IsAnythingSelected() && isValid() && isValuesValid())
+    {
       //Get input vector
       SMESH::DirStruct aVector;
       getExtrusionVector(aVector);
 
-      //Get Number of the steps 
+      //Get Number of the steps
       long aNbSteps = (long)SpinBox_NbSteps->value();
-      
-      try {
+      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;
-              }
-          }
+
+        SMESH::SMESH_Mesh_var             mesh = SelectorWdg->GetMesh();
+        SMESH::SMESH_MeshEditor_var meshEditor = mesh->GetMeshEditPreviewer();
+        SMESH::ListOfGroups_var         groups;
+
+        SMESH::ListOfIDSources_var nodes = new SMESH::ListOfIDSources();
+        SMESH::ListOfIDSources_var edges = new SMESH::ListOfIDSources();
+        SMESH::ListOfIDSources_var faces = new SMESH::ListOfIDSources();
+        const int  maxSelType = SelectorWdg->GetSelected( nodes, edges, faces );
+        const bool makeGroups = false;
+
+        if ( ExtrMethod_RBut2->isVisible() &&
+             ExtrMethod_RBut2->isChecked() ) // Extrusion by normal
+        {
+          double stepSize          = (double) SpinBox_VDist->value();
+          long   nbSteps           = (long) SpinBox_NbSteps->value();
+          bool   useInputElemsOnly = UseInputElemsOnlyCheck->isChecked();
+          bool   byAverageNormal   = ByAverageNormalCheck->isChecked();
+          int    dim               = (maxSelType == SMESH::FACE) ? 2 : 1;
+
+          groups = meshEditor->ExtrusionByNormal( faces, stepSize, nbSteps, useInputElemsOnly,
+                                                  byAverageNormal, makeGroups, dim );
         }
         else
-          if(GetConstructorId() == 0)
-            aMeshEditor->ExtrusionSweep0D(myElementsId.inout(), aVector, aNbSteps);
-          else
-            aMeshEditor->ExtrusionSweep(myElementsId.inout(), aVector, aNbSteps);
-        
-        SMESH::MeshPreviewStruct_var aMeshPreviewStruct = aMeshEditor->GetPreviewData();
+        {
+          groups = meshEditor->ExtrusionSweepObjects( nodes, edges, faces,
+                                                      aVector, aNbSteps, makeGroups );
+        }
+        SMESH::MeshPreviewStruct_var aMeshPreviewStruct = meshEditor->GetPreviewData();
         mySimulation->SetData(aMeshPreviewStruct._retn());
+
       } catch (...) {
         hidePreview();
       }
@@ -1241,20 +1390,22 @@ void SMESHGUI_ExtrusionDlg::onDisplaySimulation( bool toDisplayPreview ) {
 // function : getExtrusionVector()
 // purpose  : get direction of the extrusion
 //=================================================================================
-void SMESHGUI_ExtrusionDlg::getExtrusionVector(SMESH::DirStruct& aVector) {
-  if ( RadioButton3->isChecked() ) {
+void SMESHGUI_ExtrusionDlg::getExtrusionVector(SMESH::DirStruct& aVector)
+{
+  if ( ExtrMethod_RBut0->isChecked() )
+  {
     aVector.PS.x = SpinBox_Dx->GetValue();
     aVector.PS.y = SpinBox_Dy->GetValue();
-    aVector.PS.z = SpinBox_Dz->GetValue();      
-  } else if ( RadioButton4->isChecked() ) {
+    aVector.PS.z = SpinBox_Dz->GetValue();
+  }
+  else if ( ExtrMethod_RBut1->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 c3acc56d0c3f57e3c2e3cefef9befe2aadeed81b..64173209f852b3ce76e2734ce5c4b5afa220ec3f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -30,6 +30,7 @@
 // SMESH includes
 #include "SMESH_SMESHGUI.hxx"
 #include "SMESHGUI_PreviewDlg.h"
+#include "SMESHGUI_Utils.h"
 
 // SALOME GUI includes
 #include <SALOME_InteractiveObject.hxx>
@@ -37,6 +38,7 @@
 // IDL includes
 #include <SALOMEconfig.h>
 #include CORBA_SERVER_HEADER(SMESH_Mesh)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
 
 class QButtonGroup;
 class QRadioButton;
@@ -56,15 +58,80 @@ class LightApp_SelectionMgr;
 class SUIT_SelectionFilter;
 class SalomeApp_IntSpinBox;
 
+//=================================================================================
+// class    : SMESHGUI_ExtrusionDlg
+// purpose  : A widget used to select both nodes, edges and faces for
+//            Extrusion and Revolution operations
+//=================================================================================
+
+class SMESHGUI_EXPORT SMESHGUI_3TypesSelector : public QWidget
+{
+  Q_OBJECT
+
+    public:
+
+  SMESHGUI_3TypesSelector( QWidget * parent = 0 );
+  ~SMESHGUI_3TypesSelector();
+
+  void Clear();
+  void SetEnabled( bool enable, SMESH::ElementType type );
+  bool IsAnythingSelected( SMESH::ElementType type = SMESH::ALL );
+  SMESH::ElementType GetSelected( SMESH::ListOfIDSources & nodes,
+                                  SMESH::ListOfIDSources & edges,
+                                  SMESH::ListOfIDSources & faces );
+  SMESH::SMESH_Mesh_var GetMesh() { return myMesh; }
+  SMESH_Actor*         GetActor() { return myActor; }
+  Handle(SALOME_InteractiveObject) GetIO() { return myIO; }
+  QButtonGroup* GetButtonGroup()  { return mySelectBtnGrp; }
+
+ signals:
+
+  void selectionChanged();
+
+ private slots:
+
+  void                            selectionIntoArgument();
+  void                            onTextChange( const QString& );
+  void                            onSelectMesh( bool on );
+  void                            setFilters();
+  void                            onSelectType( int iType );
+
+ private:
+
+  void                             addTmpIdSource( SMESH::long_array_var& ids,
+                                                   int iType, int index);
+
+  QGroupBox*                       myGroups   [3];
+  QLabel*                          myLabel    [3];
+  QLineEdit*                       myLineEdit [3];
+  QCheckBox*                       myMeshChk  [3];
+  QPushButton*                     myFilterBtn[3];
+  QButtonGroup*                    mySelectBtnGrp;
+  SMESHGUI_FilterDlg*              myFilterDlg;
+  SUIT_SelectionFilter*            myFilter   [3];
+  SMESHGUI_IdValidator*            myIdValidator;
+
+  bool                             myBusy;
+  SMESH::SMESH_Mesh_var            myMesh;
+  SMESH_Actor*                     myActor;
+  Handle(SALOME_InteractiveObject) myIO;
+  SMESH::ListOfIDSources_var       myIDSource[3];
+  QList<SMESH::IDSource_wrap>      myTmpIDSourceList;
+
+  LightApp_SelectionMgr*           mySelectionMgr;
+  SVTK_Selector*                   mySelector;
+};
+
 //=================================================================================
 // class    : SMESHGUI_ExtrusionDlg
 // purpose  :
 //=================================================================================
+
 class SMESHGUI_EXPORT SMESHGUI_ExtrusionDlg : public SMESHGUI_PreviewDlg
 {
   Q_OBJECT
 
-public:
+    public:
   SMESHGUI_ExtrusionDlg( SMESHGUI* );
   ~SMESHGUI_ExtrusionDlg();
 
@@ -74,42 +141,22 @@ private:
   void                             keyPressEvent( QKeyEvent* );
   int                              GetConstructorId();
   void                             getExtrusionVector(SMESH::DirStruct& aVector);
+  void                             extrusionByNormal(SMESH::SMESH_MeshEditor_ptr meshEditor,
+                                                     const bool                  makeGroups=false);
   
   bool                             isValid();
   bool                             isValuesValid();
   
-  SMESHGUI_IdValidator*            myIdValidator;
   LightApp_SelectionMgr*           mySelectionMgr;        /* User shape selection */
-  QWidget*                         myEditCurrentArgument; /* Current  argument editor */
-  int                              myNbOkElements;        /* to check when elements are defined */
   SVTK_Selector*                   mySelector;
 
-  SMESH::SMESH_IDSource_var        mySelectedObject;
-
-  bool                             myBusy;
-  SMESH::SMESH_Mesh_var            myMesh;
-  SMESH::long_array_var            myElementsId;
-  SMESH_Actor*                     myActor;
-  Handle(SALOME_InteractiveObject) myIO;
-  SUIT_SelectionFilter*            myMeshOrSubMeshOrGroupFilter0D;
-  SUIT_SelectionFilter*            myMeshOrSubMeshOrGroupFilter1D;
-  SUIT_SelectionFilter*            myMeshOrSubMeshOrGroupFilter2D;
-
   // widgets
-  QGroupBox*                       ConstructorsBox;
-  QButtonGroup*                    GroupConstructors;
-  QRadioButton*                    RadioButton0;
-  QRadioButton*                    RadioButton1;
-  QRadioButton*                    RadioButton2;
-  QRadioButton*                    RadioButton3;
-  QRadioButton*                    RadioButton4;
+  SMESHGUI_3TypesSelector*         SelectorWdg;
+  QRadioButton*                    ExtrMethod_RBut0;
+  QRadioButton*                    ExtrMethod_RBut1;
+  QRadioButton*                    ExtrMethod_RBut2;
 
   QGroupBox*                       GroupArguments;
-  QGroupBox*                       GroupDimensions;
-  QLabel*                          TextLabelElements;
-  QPushButton*                     SelectElementsButton;
-  QLineEdit*                       LineEditElements;
-  QCheckBox*                       CheckBoxMesh;
   QLabel*                          TextLabelVector;
   QLabel*                          TextLabelDistance;
   QPushButton*                     SelectVectorButton;
@@ -129,6 +176,8 @@ private:
   SMESHGUI_SpinBox*                SpinBox_VDist;
   QLabel*                          TextLabelNbSteps;
   SalomeApp_IntSpinBox*            SpinBox_NbSteps;
+  QCheckBox*                       ByAverageNormalCheck;
+  QCheckBox*                       UseInputElemsOnlyCheck;
   QCheckBox*                       MakeGroupsCheck;
 
   QGroupBox*                       GroupButtons;
@@ -140,15 +189,11 @@ private:
   QString                          myHelpFileName;
   QString                          myIDs;
 
-  QPushButton*                     myFilterBtn;
-  SMESHGUI_FilterDlg*              myFilterDlg;
-
 protected slots:
   virtual void                    onDisplaySimulation( bool );
   virtual void                    reject();
    
 private slots:
-  void                            ConstructorsClicked( int );
   void                            CheckIsEnable();
   void                            ClickOnOk();
   bool                            ClickOnApply();
@@ -158,9 +203,9 @@ private slots:
   void                            SelectionIntoArgument();
   void                            DeactivateActiveDialog();
   void                            ActivateThisDialog();
-  void                            onTextChange( const QString& );
-  void                            onSelectMesh( bool );
-  void                            setFilters();
+  void                            onOpenView();
+  void                            onCloseView();
+
 };
 
 #endif // SMESHGUI_EXTRUSIONDLG_H
index d178095075d11f92202c7828c63323a7521e8cbc..9b72ae2f4f5b6feb2b121997b1847ef4f5d63163 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -170,7 +170,7 @@ bool SMESHGUI_FieldSelectorWdg::GetSelectedFeilds()
 {
   int nbSelected = 0;
   if ( myTree->isEnabled() )
-    for ( size_t i = 0; i < myTree->topLevelItemCount(); ++i )
+    for ( int i = 0; i < myTree->topLevelItemCount(); ++i )
     {
       QTreeWidgetItem* meshItem = myTree->topLevelItem( i );
       int iM = meshItem->data( 0, Qt::UserRole ).toInt();
@@ -202,7 +202,7 @@ bool SMESHGUI_FieldSelectorWdg::GetSelectedFeilds()
     }
   else
   {
-    for ( size_t iF = 0; iF < myFields->count(); ++iF )
+    for ( int iF = 0; iF < myFields->count(); ++iF )
     {
       GEOM::ListOfFields& fields = (*myFields)[ iF ].first.inout();
       fields.length( 0 );
index feaa8341514caeece262bda3e0847b382e10a1db..be27e775f91344cb5cf279d34dcacedf31934a14 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 587b43042e827f5bb7cc7cd1119959f77abf5ca7..08734d4445f8b93e8f9571782a3e09d35ababdf4 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index afbf6e9c1ff0bc217ccd77955464cfcaf88ec39a..b9bd0903238b15c0aacdae9d1391fb8a796c5558 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index 7e7eeed5072697dfb89a216e13d131a433b05c27..ecf7658e68f1b19b8e3770473da994fa7c2103d4 100755 (executable)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index ad76aae449582c29e08a9b8d7eb54a931fc4e7cf..6ac58d946dc07ae9baa2096b6e39226644a89537 100755 (executable)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index a6daed8fc8d89f0186cb4767e585adb6e7c49af4..da70e5aefefb454057b6ba19fc0be8c2e6c0c5ee 100755 (executable)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index ab68a6b1b7421c3d0e80e994431e192a787dae7b..39e3f96b919f0c581040e32fe266c29481e013de 100755 (executable)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 8db0a78141b2dac70528ed0d9926c16e7c5537e5..04732d8f6fff5539617f7e477d8063fb2ada1305 100755 (executable)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 
 #include <LightApp_Application.h>
 #include <LightApp_SelectionMgr.h>
-#include <SalomeApp_Tools.h>
-#include <SalomeApp_Study.h>
-#include <SalomeApp_IntSpinBox.h>
+#include <SalomeApp_Application.h>
 #include <SalomeApp_DoubleSpinBox.h>
+#include <SalomeApp_IntSpinBox.h>
+#include <SalomeApp_Study.h>
+#include <SalomeApp_Tools.h>
 
 #include <SALOME_ListIO.hxx>
 
@@ -869,8 +870,8 @@ SMESHGUI_FilterTable::SMESHGUI_FilterTable( SMESHGUI* theModule,
                                             QWidget* parent,
                                             const int type )
 : QWidget( parent ),
-  myIsLocked( false ),
-  mySMESHGUI( theModule )
+  mySMESHGUI( theModule ),
+  myIsLocked( false )
 {
   myEntityType = -1;
 
@@ -887,8 +888,8 @@ SMESHGUI_FilterTable::SMESHGUI_FilterTable( SMESHGUI* theModule,
                                             QWidget* parent,
                                             const QList<int>& types )
 : QWidget( parent ),
-  myIsLocked( false ),
-  mySMESHGUI( theModule )
+  mySMESHGUI( theModule ),
+  myIsLocked( false )
 {
   myEntityType = -1;
   Init(types);
@@ -1011,6 +1012,7 @@ void SMESHGUI_FilterTable::Init (const QList<int>& theTypes)
         Table* aTable = createTable(mySwitchTableGrp, *typeIt);
         myTables[ *typeIt ] = aTable;
         ((QVBoxLayout*)mySwitchTableGrp->layout())->addWidget(myTables[ *typeIt ]);
+        myEntityType = -1;
       }
     }
   }
@@ -1134,6 +1136,7 @@ bool SMESHGUI_FilterTable::IsValid (const bool theMess, const int theEntityType)
         errMsg = tr( "GROUPCOLOR_ERROR" );
     }
     else if (aCriterion == SMESH::FT_RangeOfIds ||
+             aCriterion == SMESH::FT_BelongToMeshGroup ||
              aCriterion == SMESH::FT_BelongToGeom ||
              aCriterion == SMESH::FT_BelongToPlane ||
              aCriterion == SMESH::FT_BelongToCylinder ||
@@ -1152,7 +1155,7 @@ bool SMESHGUI_FilterTable::IsValid (const bool theMess, const int theEntityType)
       bool aRes = false;
       bool isSignalsBlocked = aTable->signalsBlocked();
       aTable->blockSignals(true);
-      double  aThreshold = (int)aTable->text(i, 2).toDouble(&aRes);
+      /*double  aThreshold =*/ aTable->text(i, 2).toDouble( &aRes );
       aTable->blockSignals(isSignalsBlocked);
 
       if (!aRes && aTable->isEditable(i, 2))
@@ -1283,6 +1286,7 @@ void SMESHGUI_FilterTable::GetCriterion (const int                 theRow,
     }
   }
   else if ( aCriterionType != SMESH::FT_RangeOfIds &&
+            aCriterionType != SMESH::FT_BelongToMeshGroup &&
             aCriterionType != SMESH::FT_BelongToGeom &&
             aCriterionType != SMESH::FT_BelongToPlane &&
             aCriterionType != SMESH::FT_BelongToCylinder &&
@@ -1382,6 +1386,7 @@ void SMESHGUI_FilterTable::SetCriterion (const int                       theRow,
     }
   }
   else if (theCriterion.Type != SMESH::FT_RangeOfIds &&
+           theCriterion.Type != SMESH::FT_BelongToMeshGroup &&
            theCriterion.Type != SMESH::FT_BelongToGeom &&
            theCriterion.Type != SMESH::FT_BelongToPlane &&
            theCriterion.Type != SMESH::FT_BelongToCylinder &&
@@ -1398,6 +1403,7 @@ void SMESHGUI_FilterTable::SetCriterion (const int                       theRow,
            theCriterion.Type != SMESH::FT_OverConstrainedVolume &&
            theCriterion.Type != SMESH::FT_LinearOrQuadratic)
   {
+    // Numberic criterion
     aTable->item( theRow, 2 )->setText(QString("%1").arg(theCriterion.Threshold, 0, 'g', 15));
   }
   else
@@ -1554,19 +1560,29 @@ 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_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 ||
+  bool isDbl = ( aCriterion == SMESH::FT_AspectRatio        ||
+                 aCriterion == SMESH::FT_AspectRatio3D      ||
+                 aCriterion == SMESH::FT_Warping            ||
+                 aCriterion == SMESH::FT_MinimumAngle       ||
+                 aCriterion == SMESH::FT_Taper              ||
+                 aCriterion == SMESH::FT_Skew               ||
+                 aCriterion == SMESH::FT_Area               ||
+                 aCriterion == SMESH::FT_Volume3D           ||
+                 aCriterion == SMESH::FT_MaxElementLength2D ||
+                 aCriterion == SMESH::FT_MaxElementLength3D ||
+                 aCriterion == SMESH::FT_Length             ||
+                 aCriterion == SMESH::FT_Length2D           ||
+                 aCriterion == SMESH::FT_BallDiameter );
+
+  bool toEnable = (( isDbl && ((ComboItem*)aTable->item(aRow, 1))->value() == SMESH::FT_EqualTo) ||
+                   aCriterion == SMESH::FT_BelongToPlane                                         ||
+                   aCriterion == SMESH::FT_BelongToCylinder                                      ||
+                   aCriterion == SMESH::FT_BelongToGenSurface                                    ||
+                   aCriterion == SMESH::FT_BelongToGeom                                          ||
+                   aCriterion == SMESH::FT_LyingOnGeom                                           ||
+                   aCriterion == SMESH::FT_CoplanarFaces                                         ||
                    aCriterion == SMESH::FT_EqualNodes);
-  
+
   if (!myAddWidgets.contains(anItem))
   {
     myAddWidgets[ anItem ] = new AdditionalWidget(myWgStack);
@@ -1725,7 +1741,7 @@ static QList<int> entityTypes( const int theType )
     typeIds.append( SMDSEntity_Quad_Quadrangle );
     typeIds.append( SMDSEntity_BiQuad_Quadrangle );
     typeIds.append( SMDSEntity_Polygon );
-    //typeIds.append( SMDSEntity_Quad_Polygon );
+    typeIds.append( SMDSEntity_Quad_Polygon );
     break;
   case SMESH::VOLUME:
     typeIds.append( SMDSEntity_Tetra );
@@ -1813,13 +1829,15 @@ void SMESHGUI_FilterTable::onCriterionChanged (const int row, const int col, con
   case SMESH::FT_Length:
   case SMESH::FT_Length2D: anIsDoubleCriterion = true; break;
 
+  case SMESH::FT_BelongToMeshGroup: break;
+
   case SMESH::FT_BelongToGeom:
   case SMESH::FT_BelongToPlane:
   case SMESH::FT_BelongToCylinder:
   case SMESH::FT_BelongToGenSurface:
-  case SMESH::FT_LyingOnGeom: nbCompareSigns = 1; isThresholdEditable = true; break;
+  case SMESH::FT_LyingOnGeom: nbCompareSigns = 0; isThresholdEditable = true; break;
 
-  case SMESH::FT_RangeOfIds: nbCompareSigns = 1; isThresholdEditable = true; break;
+  case SMESH::FT_RangeOfIds: nbCompareSigns = 0; isThresholdEditable = true; break;
 
   case SMESH::FT_BadOrientedVolume:
   case SMESH::FT_BareBorderVolume:
@@ -2162,6 +2180,7 @@ const QMap<int, QString>& SMESHGUI_FilterTable::getCriteria (const int theType)
     if (aCriteria.isEmpty())
     {
       aCriteria[ SMESH::FT_RangeOfIds         ] = tr("RANGE_OF_IDS");
+      aCriteria[ SMESH::FT_BelongToMeshGroup  ] = tr("BELONG_TO_MESH_GROUP");
       aCriteria[ SMESH::FT_BelongToGeom       ] = tr("BELONG_TO_GEOM");
       aCriteria[ SMESH::FT_BelongToPlane      ] = tr("BELONG_TO_PLANE");
       aCriteria[ SMESH::FT_BelongToCylinder   ] = tr("BELONG_TO_CYLINDER");
@@ -2183,6 +2202,7 @@ const QMap<int, QString>& SMESHGUI_FilterTable::getCriteria (const int theType)
       aCriteria[ SMESH::FT_MultiConnection    ] = tr("MULTI_BORDERS");
       aCriteria[ SMESH::FT_Length             ] = tr("LENGTH");
       aCriteria[ SMESH::FT_RangeOfIds         ] = tr("RANGE_OF_IDS");
+      aCriteria[ SMESH::FT_BelongToMeshGroup  ] = tr("BELONG_TO_MESH_GROUP");
       aCriteria[ SMESH::FT_BelongToGeom       ] = tr("BELONG_TO_GEOM");
       aCriteria[ SMESH::FT_BelongToPlane      ] = tr("BELONG_TO_PLANE");
       aCriteria[ SMESH::FT_BelongToCylinder   ] = tr("BELONG_TO_CYLINDER");
@@ -2211,6 +2231,7 @@ const QMap<int, QString>& SMESHGUI_FilterTable::getCriteria (const int theType)
       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_BelongToMeshGroup  ] = tr("BELONG_TO_MESH_GROUP");
       aCriteria[ SMESH::FT_BelongToGeom       ] = tr("BELONG_TO_GEOM");
       aCriteria[ SMESH::FT_BelongToPlane      ] = tr("BELONG_TO_PLANE");
       aCriteria[ SMESH::FT_BelongToCylinder   ] = tr("BELONG_TO_CYLINDER");
@@ -2238,6 +2259,7 @@ const QMap<int, QString>& SMESHGUI_FilterTable::getCriteria (const int theType)
     {
       aCriteria[ SMESH::FT_AspectRatio3D        ] = tr("ASPECT_RATIO_3D");
       aCriteria[ SMESH::FT_RangeOfIds           ] = tr("RANGE_OF_IDS");
+      aCriteria[ SMESH::FT_BelongToMeshGroup    ] = tr("BELONG_TO_MESH_GROUP");
       aCriteria[ SMESH::FT_BelongToGeom         ] = tr("BELONG_TO_GEOM");
       aCriteria[ SMESH::FT_LyingOnGeom          ] = tr("LYING_ON_GEOM");
       aCriteria[ SMESH::FT_BadOrientedVolume    ] = tr("BAD_ORIENTED_VOLUME");
@@ -2260,6 +2282,7 @@ const QMap<int, QString>& SMESHGUI_FilterTable::getCriteria (const int theType)
     if (aCriteria.isEmpty())
     {
       aCriteria[ SMESH::FT_RangeOfIds         ] = tr("RANGE_OF_IDS");
+      aCriteria[ SMESH::FT_BelongToMeshGroup  ] = tr("BELONG_TO_MESH_GROUP");
       aCriteria[ SMESH::FT_BelongToGeom       ] = tr("BELONG_TO_GEOM");
       aCriteria[ SMESH::FT_BelongToPlane      ] = tr("BELONG_TO_PLANE");
       aCriteria[ SMESH::FT_BelongToCylinder   ] = tr("BELONG_TO_CYLINDER");
@@ -2276,6 +2299,7 @@ const QMap<int, QString>& SMESHGUI_FilterTable::getCriteria (const int theType)
     {
       aCriteria[ SMESH::FT_BallDiameter       ] = tr("BALL_DIAMETER");
       aCriteria[ SMESH::FT_RangeOfIds         ] = tr("RANGE_OF_IDS");
+      aCriteria[ SMESH::FT_BelongToMeshGroup  ] = tr("BELONG_TO_MESH_GROUP");
       aCriteria[ SMESH::FT_BelongToGeom       ] = tr("BELONG_TO_GEOM");
       aCriteria[ SMESH::FT_BelongToPlane      ] = tr("BELONG_TO_PLANE");
       aCriteria[ SMESH::FT_BelongToCylinder   ] = tr("BELONG_TO_CYLINDER");
@@ -2291,6 +2315,7 @@ const QMap<int, QString>& SMESHGUI_FilterTable::getCriteria (const int theType)
     if (aCriteria.isEmpty())
     {
       aCriteria[ SMESH::FT_RangeOfIds         ] = tr("RANGE_OF_IDS");
+      aCriteria[ SMESH::FT_BelongToMeshGroup  ] = tr("BELONG_TO_MESH_GROUP");
       aCriteria[ SMESH::FT_BelongToGeom       ] = tr("BELONG_TO_GEOM");
       aCriteria[ SMESH::FT_BelongToPlane      ] = tr("BELONG_TO_PLANE");
       aCriteria[ SMESH::FT_BelongToCylinder   ] = tr("BELONG_TO_CYLINDER");
@@ -2306,6 +2331,7 @@ const QMap<int, QString>& SMESHGUI_FilterTable::getCriteria (const int theType)
     if (aCriteria.isEmpty())
     {
       aCriteria[ SMESH::FT_RangeOfIds         ] = tr("RANGE_OF_IDS");
+      aCriteria[ SMESH::FT_BelongToMeshGroup  ] = tr("BELONG_TO_MESH_GROUP");
       aCriteria[ SMESH::FT_BelongToGeom       ] = tr("BELONG_TO_GEOM");
       aCriteria[ SMESH::FT_LyingOnGeom        ] = tr("LYING_ON_GEOM");
       aCriteria[ SMESH::FT_LinearOrQuadratic  ] = tr("LINEAR");
@@ -2866,9 +2892,15 @@ void SMESHGUI_FilterDlg::Init (const int type, const bool setInViewer)
 //=======================================================================
 void SMESHGUI_FilterDlg::Init (const QList<int>& theTypes, const bool setInViewer)
 {
+  if ( theTypes.empty() )
+  {
+    Init( SMESH::ALL, setInViewer );
+    return;
+  }
   mySourceWg  = 0;
   myTypes     = theTypes;
   myMesh      = SMESH::SMESH_Mesh::_nil();
+  myGroup     = SMESH::SMESH_GroupOnFilter::_nil();
   myIObjects.Clear();
   myIsSelectionChanged = false;
   myToRestoreSelMode = false;
@@ -2899,6 +2931,8 @@ void SMESHGUI_FilterDlg::Init (const QList<int>& theTypes, const bool setInViewe
 
   connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), SLOT(onDeactivate()));
   connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), SLOT(reject()));
+  connect(mySMESHGUI, SIGNAL(SignalActivatedViewManager()), SLOT(onOpenView()));
+  connect(mySMESHGUI, SIGNAL(SignalCloseView()), SLOT(onCloseView()));
   
   updateMainButtons();
   updateSelection();
@@ -2984,6 +3018,29 @@ void SMESHGUI_FilterDlg::reject()
   QDialog::reject();
 }
 
+//=================================================================================
+// function : onOpenView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_FilterDlg::onOpenView()
+{
+  if ( mySelector ) {
+    SMESH::SetPointRepresentation(false);
+  }
+  else {
+    mySelector = SMESH::GetViewWindow( mySMESHGUI )->GetSelector();
+  }
+}
+
+//=================================================================================
+// function : onCloseView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_FilterDlg::onCloseView()
+{
+  mySelector = 0;
+}
+
 //=================================================================================
 // function : onHelp()
 // purpose  :
@@ -3147,8 +3204,7 @@ bool SMESHGUI_FilterDlg::isValid() const
       if (aType == SMESH::FT_BelongToCylinder ||
           aType == SMESH::FT_BelongToPlane    ||
           aType == SMESH::FT_BelongToGenSurface ) {
-        CORBA::Object_var anObject = SMESH::SObjectToObject(aList[ 0 ]);
-        //GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow(aList[ 0 ]->GetObject());
+        CORBA::Object_var     anObject = SMESH::SObjectToObject(aList[ 0 ]);
         GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow(anObject);
         if (!aGeomObj->_is_nil()) {
           TopoDS_Shape aFace;
@@ -3252,6 +3308,15 @@ void SMESHGUI_FilterDlg::SetMesh (SMESH::SMESH_Mesh_var theMesh)
   myButtons[BTN_Apply]->setEnabled(isEnable);
 }
 
+//=======================================================================
+// name    : SMESHGUI_FilterDlg::SetGroup
+// Purpose : Set a group being edited
+//=======================================================================
+void SMESHGUI_FilterDlg::SetGroup(SMESH::SMESH_GroupOnFilter_var group)
+{
+  myGroup = group;
+}
+
 //=======================================================================
 // name    : SMESHGUI_FilterDlg::SetSelection
 // Purpose : Get filtered ids
@@ -3299,13 +3364,21 @@ bool SMESHGUI_FilterDlg::onApply()
     insertFilterInViewer();
 
     if (!myFilter[ aCurrType ]->GetPredicate()->_is_nil()) {
-      QList<int> aResultIds;
-      filterSource(aCurrType, aResultIds);
-      // select in viewer
-      selectInViewer(aCurrType, aResultIds);
+      //
+      bool toFilter = (( getActor() ) ||
+                       ( myInitSourceWgOnApply && mySourceWg ) ||
+                       ( mySourceGrp->checkedId() == Dialog && mySourceWg ));
+      if ( toFilter ) {
+        QList<int> aResultIds;
+        filterSource(aCurrType, aResultIds);
+        // select in viewer
+        selectInViewer(aCurrType, aResultIds);
+        // set ids to the dialog
+        if ( myInitSourceWgOnApply || mySourceGrp->checkedId() == Dialog )
+          setIdsToWg(mySourceWg, aResultIds);
+      }
     }
 
-
     myInsertState[ aCurrType ] = mySetInViewer->isChecked();
     myApplyToState[ aCurrType ] = mySourceGrp->checkedId();
   }
@@ -3343,7 +3416,7 @@ bool SMESHGUI_FilterDlg::createFilter (const int theType)
   if ( mgr && mgr->booleanValue( "SMESH", "use_precision", false ) )
     aPrecision = mgr->integerValue( "SMESH", "controls_precision", aPrecision );
 
-  for (CORBA::ULong i = 0; i < n; i++) {
+  for ( int i = 0; i < n; i++) {
     SMESH::Filter::Criterion aCriterion = createCriterion();
     myTable->GetCriterion(i, aCriterion);
     aCriterion.Precision = aPrecision;
@@ -3478,9 +3551,6 @@ void SMESHGUI_FilterDlg::filterSource (const int theType,
       if (aPred->IsSatisfy(*anIter))
         theResIds.append(*anIter);
   }
-  // set ids to the dialog
-  if (myInitSourceWgOnApply || aSourceId == Dialog)
-    setIdsToWg(mySourceWg, theResIds);
 }
 
 //=======================================================================
@@ -3552,6 +3622,35 @@ void SMESHGUI_FilterDlg::filterSelectionSource (const int theType,
       theResIds.append(aResIter.Key());
 }
 
+//=======================================================================
+//function : getActor
+//purpose  : Returns an actor to show filtered entities
+//=======================================================================
+
+SMESH_Actor* SMESHGUI_FilterDlg::getActor()
+{
+  SMESH_Actor* meshActor = SMESH::FindActorByObject( myMesh );
+  if ( meshActor && meshActor->GetVisibility() )
+    return meshActor;
+
+  SALOME_DataMapIteratorOfDataMapOfIOMapOfInteger anIter(myIObjects);
+  for ( ; anIter.More(); anIter.Next())
+  {
+    Handle(SALOME_InteractiveObject) io = anIter.Key();
+    if ( io->hasEntry() )
+    {
+      SMESH_Actor* actor = SMESH::FindActorByEntry( io->getEntry() );
+      if ( !actor )
+        continue;
+      if ( actor->GetVisibility() )
+        return actor;
+      if ( !meshActor )
+        meshActor = actor;
+    }
+  }
+  return meshActor;
+}
+
 //=======================================================================
 // name    : SMESHGUI_FilterDlg::selectInViewer
 // Purpose : Select given entities in viewer
@@ -3574,8 +3673,8 @@ void SMESHGUI_FilterDlg::selectInViewer (const int theType, const QList<int>& th
   }
 
   // Clear selection
-  SMESH_Actor* anActor = SMESH::FindActorByObject(myMesh);
-  if (!anActor || !anActor->hasIO())
+  SMESH_Actor* anActor = getActor();
+  if ( !anActor || !anActor->hasIO() )
     return;
 
   Handle(SALOME_InteractiveObject) anIO = anActor->getIO();
@@ -3654,10 +3753,10 @@ void SMESHGUI_FilterDlg::onSelectionDone()
 
   const int type = myTable->GetCriterionType(aRow);
   QList<int> types; 
-  types << SMESH::FT_BelongToGeom     << SMESH::FT_BelongToPlane 
-        << SMESH::FT_BelongToCylinder << SMESH::FT_BelongToGenSurface
-        << SMESH::FT_LyingOnGeom      << SMESH::FT_CoplanarFaces
-        << SMESH::FT_ConnectedElements;
+  types << SMESH::FT_BelongToGeom      << SMESH::FT_BelongToPlane 
+        << SMESH::FT_BelongToCylinder  << SMESH::FT_BelongToGenSurface
+        << SMESH::FT_LyingOnGeom       << SMESH::FT_CoplanarFaces
+        << SMESH::FT_ConnectedElements << SMESH::FT_BelongToMeshGroup;
   if ( !types.contains( type ))
     return;
 
@@ -3689,13 +3788,31 @@ void SMESHGUI_FilterDlg::onSelectionDone()
       }
       break;
     }
+  case SMESH::FT_BelongToMeshGroup: // get a group Name and Entry
+    {
+      SMESH::SMESH_GroupBase_var grp = SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(anIO);
+      if ( !grp->_is_nil() )
+      {
+        if ( !myMesh->_is_nil() )
+        {
+          SMESH::SMESH_Mesh_var mesh = grp->GetMesh();
+          if ( ! myMesh->_is_equivalent( mesh ))
+            return;
+        }
+        if ( !myGroup->_is_nil() && myGroup->IsInDependency( grp ))
+          return; // avoid cyclic dependencies between Groups on Filter
+
+        myTable->SetThreshold(aRow, SMESH::toQStr( grp->GetName() ));
+        myTable->SetID       (aRow, anIO->getEntry() );
+      }
+    }
   default: // get a GEOM object
     {
       GEOM::GEOM_Object_var anObj = SMESH::IObjectToInterface<GEOM::GEOM_Object>(anIO);
       if (!anObj->_is_nil())
       {
         myTable->SetThreshold(aRow, GEOMBase::GetName(anObj));
-        myTable->SetID(aRow, anIO->getEntry());
+        myTable->SetID       (aRow, anIO->getEntry());
       }
     }
   }
@@ -3780,6 +3897,23 @@ void SMESHGUI_FilterDlg::updateSelection()
     myIsSelectionChanged = true;
 
   }
+  else if ( aCriterionType == SMESH::FT_BelongToMeshGroup )
+  {
+    SMESH_TypeFilter* typeFilter = 0;
+    switch ( myTable->GetType() )
+    {
+    case SMESH::NODE   : typeFilter = new SMESH_TypeFilter( SMESH::GROUP_NODE   ); break;
+    case SMESH::ELEM0D : typeFilter = new SMESH_TypeFilter( SMESH::GROUP_0D     ); break;
+    case SMESH::BALL   : typeFilter = new SMESH_TypeFilter( SMESH::GROUP_BALL   ); break;
+    case SMESH::EDGE   : typeFilter = new SMESH_TypeFilter( SMESH::GROUP_EDGE   ); break;
+    case SMESH::FACE   : typeFilter = new SMESH_TypeFilter( SMESH::GROUP_FACE   ); break;
+    case SMESH::VOLUME : typeFilter = new SMESH_TypeFilter( SMESH::GROUP_VOLUME ); break;
+    case SMESH::ALL    : typeFilter = new SMESH_TypeFilter( SMESH::GROUP        ); break;
+    default            : typeFilter = 0;
+    }
+    if ( typeFilter )
+      mySelectionMgr->installFilter( typeFilter );
+  }
   else if ( aCriterionType == SMESH::FT_ConnectedElements )
   {
     QList<SUIT_SelectionFilter*> fList;
index da3358a8a88053192a93671e9f648bf725780325..2bff4ba6f2f1a2d83ed6cc26ca4950b2845d342d 100755 (executable)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 #include CORBA_SERVER_HEADER(SMESH_Filter)
 #include CORBA_SERVER_HEADER(SMESH_Mesh)
 
-class QFrame;
+class LightApp_SelectionMgr;
 class QButtonGroup;
 class QCheckBox;
+class QFrame;
 class QGroupBox;
 class QPushButton;
+class QStackedWidget;
 class QTableWidget;
 class QTableWidgetItem;
-class QStackedWidget;
-class LightApp_SelectionMgr;
 class SMESHGUI;
 class SMESHGUI_FilterLibraryDlg;
+class SMESH_Actor;
 class SVTK_Selector;
 
 /*!
@@ -228,6 +229,7 @@ public:
 
   void                      SetSelection();
   void                      SetMesh (SMESH::SMESH_Mesh_var);
+  void                      SetGroup (SMESH::SMESH_GroupOnFilter_var);
   void                      SetSourceWg( QWidget*, const bool initOnApply = true );
   void                      SetEnabled( bool setInViewer, bool diffSources );
 
@@ -254,6 +256,8 @@ private slots:
   void                      onCriterionChanged( const int, const int );
   void                      onThresholdChanged( const int, const int );
   void                      onCurrentChanged( int, int );
+  void                      onOpenView();
+  void                      onCloseView();
 
 private:
 
@@ -279,6 +283,7 @@ private:
   void                      setIdsToWg( QWidget*, const QList<int>& );
   Selection_Mode            getSelMode( const int ) const;
   void                      updateSelection();
+  SMESH_Actor*              getActor();
 
 private:
   // widgets
@@ -297,6 +302,7 @@ private:
   LightApp_SelectionMgr*    mySelectionMgr;
   SVTK_Selector*            mySelector;
   SMESH::SMESH_Mesh_var     myMesh;
+  SMESH::SMESH_GroupOnFilter_var myGroup;
   bool                      myInitSourceWgOnApply;
   bool                      myInsertEnabled;
   bool                      myDiffSourcesEnabled;
index ee16256859428f94085d8cd6ac260c724a84a8c8..c4b0465de691d71a1e70b2dec1ff5abfa3b64e97 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -1205,11 +1205,11 @@ void SMESHGUI_FilterLibraryDlg::onSelectionDone()
     return;
 
   const int type = myTable->GetCriterionType(aRow);
-  QList<int> types; 
-  types << SMESH::FT_BelongToGeom     << SMESH::FT_BelongToPlane 
-        << SMESH::FT_BelongToCylinder << SMESH::FT_BelongToGenSurface
-        << SMESH::FT_LyingOnGeom      << SMESH::FT_CoplanarFaces
-        << SMESH::FT_ConnectedElements;
+  QList<int> types;
+  types << SMESH::FT_BelongToGeom      << SMESH::FT_BelongToPlane 
+        << SMESH::FT_BelongToCylinder  << SMESH::FT_BelongToGenSurface
+        << SMESH::FT_LyingOnGeom       << SMESH::FT_CoplanarFaces
+        << SMESH::FT_ConnectedElements << SMESH::FT_BelongToMeshGroup;
   if ( !types.contains( type ))
     return;
 
@@ -1241,6 +1241,10 @@ void SMESHGUI_FilterLibraryDlg::onSelectionDone()
       }
       break;
     }
+  case SMESH::FT_BelongToMeshGroup: // get a group name and IOR
+    {
+      myTable->SetThreshold(aRow, anIO->getName() );
+    }
   default: // get a GEOM object
     {
       GEOM::GEOM_Object_var anObj = SMESH::IObjectToInterface<GEOM::GEOM_Object>(anIO);
index cc5d1f7ce6b32f9ef4fadde6c456c26b95556992..8ef9e319160905146365800246cf697a8f8b5ec2 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index c0b4acb233b5228d576280ecbf861a9ca5d2156a..777db56d560780333165556b38339baf51196782 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 86bd1d72d1d80894c6227854d5500ee5d764a29c..3e9dbb731bf4405f6fc76aa0f8325112bf2a51e3 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 12dad3e0fcc1d0f99f1bbbf8005aaa222b4dc73d..5b3f1ef2792624efc96755eb3ccadec633f4e6ab 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
@@ -101,7 +101,7 @@ void SMESHGUI_FindElemByPointDlg::setTypes(SMESH::array_of_ElementType_var & typ
   myElemTypeCombo->blockSignals(true);
   myElemTypeCombo->clear();
   int nbTypes = 0, hasNodes = 0;
-  for ( int i = 0; i < types->length(); ++i )
+  for ( int i = 0; i < (int) types->length(); ++i )
   {
     switch ( types[i] ) {
     case SMESH::NODE:
@@ -238,6 +238,7 @@ SMESHGUI_FindElemByPointOp::SMESHGUI_FindElemByPointOp()
   :SMESHGUI_SelectionOp()
 {
   mySimulation = 0;
+  mySMESHGUI = 0;
   myDlg = new SMESHGUI_FindElemByPointDlg;
   myHelpFileName = "find_element_by_point_page.html";
 
@@ -279,7 +280,10 @@ void SMESHGUI_FindElemByPointOp::startOperation()
 {
   // init simulation with a current View
   if ( mySimulation ) delete mySimulation;
-  mySimulation = new SMESHGUI_MeshEditPreview(SMESH::GetViewWindow( getSMESHGUI() ));
+  mySMESHGUI = getSMESHGUI();
+  mySimulation = new SMESHGUI_MeshEditPreview(SMESH::GetViewWindow( mySMESHGUI ) );
+  connect(mySMESHGUI, SIGNAL (SignalActivatedViewManager()), this, SLOT(onOpenView()));
+  connect(mySMESHGUI, SIGNAL (SignalCloseView()), this, SLOT(onCloseView()));
   vtkProperty* aProp = vtkProperty::New();
   aProp->SetRepresentationToWireframe();
   aProp->SetColor(250, 0, 250);
@@ -309,10 +313,37 @@ void SMESHGUI_FindElemByPointOp::stopOperation()
     delete mySimulation;
     mySimulation = 0;
   }
+  disconnect(mySMESHGUI, SIGNAL (SignalActivatedViewManager()), this, SLOT(onOpenView()));
+  disconnect(mySMESHGUI, SIGNAL (SignalCloseView()), this, SLOT(onCloseView()));
   selectionMgr()->removeFilter( myFilter );
   SMESHGUI_SelectionOp::stopOperation();
 }
 
+//=================================================================================
+/*!
+ * \brief SLOT called when the viewer opened
+ */
+//=================================================================================
+void SMESHGUI_FindElemByPointOp::onOpenView()
+{
+  if ( mySimulation ) {
+    mySimulation->SetVisibility(false);
+  }
+  else {
+    mySimulation = new SMESHGUI_MeshEditPreview(SMESH::GetViewWindow( mySMESHGUI ));
+  }
+}
+
+//=================================================================================
+/*!
+ * \brief SLOT called when the viewer closed
+ */
+//=================================================================================
+void SMESHGUI_FindElemByPointOp::onCloseView()
+{
+  delete mySimulation;
+  mySimulation = 0;
+}
 //================================================================================
 /*!
  * \brief hilight found selected elements
@@ -418,7 +449,7 @@ void SMESHGUI_FindElemByPointOp::onFind()
                                                myDlg->myZ->GetValue(),
                                                SMESH::ElementType( myDlg->myElemTypeCombo->currentId()));
     myDlg->myFoundList->clear();
-    for ( int i = 0; i < foundIds->length(); ++i )
+    for ( int i = 0; i < (int) foundIds->length(); ++i )
       myDlg->myFoundList->addItem( QString::number( foundIds[i] ));
 
     if ( foundIds->length() > 0 )
@@ -503,7 +534,8 @@ void SMESHGUI_FindElemByPointOp::redisplayPreview()
   myPreview->nodesXYZ[0].x = myDlg->myX->GetValue();
   myPreview->nodesXYZ[0].y = myDlg->myY->GetValue();
   myPreview->nodesXYZ[0].z = myDlg->myZ->GetValue();
-
+  if (!mySimulation)
+    mySimulation = new SMESHGUI_MeshEditPreview(SMESH::GetViewWindow( mySMESHGUI ));
   mySimulation->SetData(&myPreview.in());
 }
 
index 568ae629559129134a70c0221cca6d5d8d3fda10..a3418e8ec5d0b5b0dcda3d238b9d501d5f022986 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
@@ -68,11 +68,14 @@ private slots:
   void                           onElemSelected();
   void                           onElemTypeChange(int);
   void                           redisplayPreview();
+  void                           onOpenView();
+  void                           onCloseView();
 
 private:
   SMESHGUI_FindElemByPointDlg*     myDlg;
 
   SUIT_SelectionFilter*            myFilter;
+  SMESHGUI*                        mySMESHGUI;
   SMESHGUI_MeshEditPreview*        mySimulation; // to show point coordinates
   SMESH::SMESH_IDSource_var        myMeshOrPart;
   SMESH::MeshPreviewStruct_var     myPreview;
index 5453a6a1b758608d71a50e4b0eca7221532432ff..c029e1ebfdae7e1d82c943b18bd5411de541c2e6 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 0aa10bd7a9bb493a9a431f867eefffab9dca2190..3fb5987ececa41c635ac8de4a21b95c50f7d1b04 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 7cad3307110b7808401bd9b28896cb2b1f68aa45..c2575f14e533e0d8430a9fd72916ad07d5119ec8 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -128,8 +128,8 @@ SMESHGUI_GroupDlg::SMESHGUI_GroupDlg( SMESHGUI* theModule,
     mySelector( SMESH::GetViewWindow( theModule )->GetSelector() ),
     myIsBusy( false ),
     myNameChanged( false ),
-    myIsApplyAndClose( false ),
-    myNbChangesOfContents(0)
+    myNbChangesOfContents(0),
+    myIsApplyAndClose( false )
 {
   initDialog( true );
   if ( !theMesh->_is_nil() )
@@ -462,7 +462,8 @@ void SMESHGUI_GroupDlg::initDialog( bool create)
   connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()),        this, SLOT(reject()));
   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()),  this, SLOT(onObjectSelectionChanged()));
   connect(mySMESHGUI, SIGNAL(SignalVisibilityChanged()),      this, SLOT(onVisibilityChanged()));
-
+  connect(mySMESHGUI, SIGNAL(SignalActivatedViewManager()),   this, SLOT(onOpenView()));
+  connect(mySMESHGUI, SIGNAL(SignalCloseView()),              this, SLOT(onCloseView()));
   rb1->setChecked(true); // VSR !!!
   onGrpTypeChanged(0); // VSR!!!
 
@@ -519,7 +520,7 @@ QString SMESHGUI_GroupDlg::GetDefaultName(const QString& theOperation)
   bool isUnique = false;
   while (!isUnique) {
     aName = theOperation + "_" + QString::number(++aNumber);
-    isUnique = (aSet.count(aName.toUtf8().data()) == 0);
+    isUnique = (aSet.count(std::string(SMESH::toUtf8(aName))) == 0);
   }
 
   return aName;
@@ -535,7 +536,7 @@ void  SMESHGUI_GroupDlg::setDefaultName() const
   do
   {
     aResName = aPrefix + QString::number( i++ );
-    anObj = aStudy->FindObject( aResName.toUtf8().data() );
+    anObj = aStudy->FindObject( SMESH::toUtf8(aResName) );
   }
   while ( anObj );
   myName->setText(aResName); 
@@ -594,14 +595,14 @@ void SMESHGUI_GroupDlg::init (SMESH::SMESH_GroupBase_ptr theGroup,
 
   myNameChanged = true;
   myName->blockSignals(true);
-  myName->setText(QString::fromUtf8(theGroup->GetName()));
+  myName->setText(SMESH::fromUtf8(theGroup->GetName()));
   myName->blockSignals(false);
   myName->home(false);
 
   SALOMEDS::Color aColor = theGroup->GetColor();
   setGroupColor( aColor );
 
-  myMeshGroupLine->setText(QString::fromUtf8(theGroup->GetName()));
+  myMeshGroupLine->setText(SMESH::fromUtf8(theGroup->GetName()));
 
   int aType = 0;
   switch(theGroup->GetType()) {
@@ -611,6 +612,8 @@ void SMESHGUI_GroupDlg::init (SMESH::SMESH_GroupBase_ptr theGroup,
   case SMESH::EDGE:   aType = grpEdgeSelection;   break;
   case SMESH::FACE:   aType = grpFaceSelection;   break;
   case SMESH::VOLUME: aType = grpVolumeSelection; break;
+  case SMESH::ALL:
+  case SMESH::NB_ELEMENT_TYPES: break;
   }
   myTypeGroup->button(aType)->setChecked(true);
 
@@ -686,7 +689,7 @@ void SMESHGUI_GroupDlg::init (SMESH::SMESH_GroupBase_ptr theGroup,
   {
     myNameChanged = true;
     myName->blockSignals(true);
-    myName->setText(QString::fromUtf8(theGroup->GetName()));
+    myName->setText(SMESH::fromUtf8(theGroup->GetName()));
     myName->blockSignals(false);
   }
 
@@ -730,6 +733,17 @@ void SMESHGUI_GroupDlg::updateButtons()
     }
   }
 
+  bool meshHasGeom = ( myMesh->_is_nil() || myMesh->HasShapeToMesh() );
+  if ( myGrpTypeId != 1 )
+  {
+    myGrpTypeGroup->button(1)->setEnabled( meshHasGeom );
+  }
+  else
+  {
+    myGeomGroupBtn->setEnabled( meshHasGeom );
+    myGeomGroupLine->setEnabled( meshHasGeom );
+  }
+
   myOKBtn->setEnabled(enable);
   myApplyBtn->setEnabled(enable);
 }
@@ -1041,7 +1055,7 @@ bool SMESHGUI_GroupDlg::onApply()
 
       if (myGeomObjects->length() == 1) {
         myGroupOnGeom = myMesh->CreateGroupFromGEOM(aType,
-                                                    myName->text().toUtf8().data(),
+                                                    SMESH::toUtf8(myName->text()),
                                                     myGeomObjects[0]);
       }
       else {
@@ -1063,7 +1077,7 @@ bool SMESHGUI_GroupDlg::onApply()
         // check and add all selected GEOM objects: they must be
         // a sub-shapes of the main GEOM and must be of one type
         TopAbs_ShapeEnum aGroupType = TopAbs_SHAPE;
-        for ( int i =0; i < myGeomObjects->length(); i++) {
+        for ( int i =0; i < (int)myGeomObjects->length(); i++) {
           TopAbs_ShapeEnum aSubShapeType = (TopAbs_ShapeEnum)myGeomObjects[i]->GetShapeType();
           if (i == 0)
             aGroupType = aSubShapeType;
@@ -1083,11 +1097,11 @@ bool SMESHGUI_GroupDlg::onApply()
           aNewGeomGroupName += myName->text();
           SALOMEDS::SObject_var aNewGroupSO =
             geomGen->AddInStudy(aSMESHGen->GetCurrentStudy(), aGroupVar,
-                                aNewGeomGroupName.toUtf8().data(), aMeshShape);
+                                SMESH::toUtf8(aNewGeomGroupName), aMeshShape);
         }
 
         myGroupOnGeom = myMesh->CreateGroupFromGEOM(aType,
-                                                    myName->text().toUtf8().data(),
+                                                    SMESH::toUtf8(myName->text()),
                                                     aGroupVar);
       }
       resultGroup = SMESH::SMESH_GroupBase::_narrow( myGroupOnGeom );
@@ -1110,7 +1124,7 @@ bool SMESHGUI_GroupDlg::onApply()
         return false;
 
       myGroupOnFilter = myMesh->CreateGroupFromFilter(aType,
-                                                      myName->text().toUtf8().data(),
+                                                      SMESH::toUtf8(myName->text()),
                                                       myFilter);
 
       resultGroup = SMESH::SMESH_GroupBase::_narrow( myGroupOnFilter );
@@ -1135,6 +1149,8 @@ bool SMESHGUI_GroupDlg::onApply()
     if( aMeshGroupSO )
       anEntryList.append( aMeshGroupSO->GetID().c_str() );
 
+    resultGroup->SetName(SMESH::toUtf8(myName->text().trimmed()));
+
     if ( isCreation )
     {
       SMESH::setFileType ( aMeshGroupSO, "COULEURGROUP" );
@@ -1151,8 +1167,6 @@ bool SMESHGUI_GroupDlg::onApply()
     }
     else
     {
-      resultGroup->SetName(myName->text().toUtf8().data());
-
       if ( aMeshGroupSO )
       {
         if ( SMESH_Actor *anActor = SMESH::FindActorByEntry(aMeshGroupSO->GetID().c_str()))
@@ -1166,7 +1180,7 @@ bool SMESHGUI_GroupDlg::onApply()
             if ( !anActor ) return false;
             myActorsList.append( anActor );
           }
-          anActor->setName(myName->text().toUtf8().data());
+          anActor->setName(SMESH::toUtf8(myName->text()));
           QColor c;
           int delta;
           switch ( myTypeId ) {
@@ -1186,7 +1200,10 @@ bool SMESHGUI_GroupDlg::onApply()
           }
           // update a visible group accoding to a changed contents
           if ( !isConversion && anActor->GetVisibility() )
+          {
             SMESH::Update( anIO, true );
+            SMESH::RepaintCurrentView();
+          }
         }
       }
     }
@@ -1315,6 +1332,10 @@ void SMESHGUI_GroupDlg::onObjectSelectionChanged()
         // any visible actor of group or submesh of myMesh
         SetAppropriateActor();
 
+        setDefaultGroupColor();
+        if (myName->text().isEmpty())
+          setDefaultName();
+
         aString = aList.First()->getName();
         myMeshGroupLine->setText(aString);
         myMeshGroupLine->home( false );
@@ -1751,10 +1772,10 @@ void SMESHGUI_GroupDlg::setFilters()
   myFilterDlg->SetEnabled( /*setInViewer=*/isStandalone,
                            /*diffSources=*/isStandalone );
   myFilterDlg->SetMesh( myMesh );
+  myFilterDlg->SetGroup( myGroupOnFilter );
   myFilterDlg->SetSelection();
   myFilterDlg->SetSourceWg( myElements, false );
 
-
   myFilterDlg->show();
 }
 
@@ -1790,6 +1811,10 @@ void SMESHGUI_GroupDlg::onFilterAccepted()
         mesh = myGroupOnFilter->GetMesh();
     }
     myFilter->SetMesh( mesh );
+
+    // highlight ids if selection changed in the Viewer (IPAL52924)
+    myCurrentLineEdit = 0;
+    onObjectSelectionChanged();
   }
 
   updateButtons();
@@ -1808,6 +1833,8 @@ void SMESHGUI_GroupDlg::onAdd()
 
   if (aNbSel == 0 || myActorsList.count() == 0 || myMesh->_is_nil()) return;
 
+  SUIT_OverrideCursor wc;
+
   myIsBusy = true;
   int sizeBefore = myElements->count();
 
@@ -2118,15 +2145,13 @@ void SMESHGUI_GroupDlg::onRemove()
       }
     }
     else if (myCurrentLineEdit == myGroupLine) {
-      Standard_Boolean aRes;
-      //SALOME_ListIteratorOfListIO anIt (mySelectionMgr->StoredIObjects());
       SALOME_ListIO aList;
       mySelectionMgr->selectedObjects( aList );
 
       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()) {
+        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();
@@ -2230,6 +2255,32 @@ void SMESHGUI_GroupDlg::reject()
   if ( myFilterDlg ) myFilterDlg->UnRegisterFilters();
 }
 
+//=================================================================================
+// function : onOpenView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_GroupDlg::onOpenView()
+{
+  if ( mySelector ) {
+    SMESH::SetPointRepresentation(false);
+  }
+  else {
+    mySelector = SMESH::GetViewWindow( mySMESHGUI )->GetSelector();
+    mySMESHGUI->EmitSignalDeactivateDialog();
+    setEnabled(true);
+  }
+}
+
+//=================================================================================
+// function : onCloseView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_GroupDlg::onCloseView()
+{
+  onDeactivate();
+  mySelector = 0;
+}
+
 //=================================================================================
 // function : onHelp()
 // purpose  :
@@ -2238,18 +2289,20 @@ void SMESHGUI_GroupDlg::onHelp()
 {
   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
   if (app)
-    app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString( "" ), myHelpFileName);
-  else {
-    QString platform;
+  {
+    app->onHelpContextModule
+      ( mySMESHGUI ? app->moduleName( mySMESHGUI->moduleName() ) : QString(""), myHelpFileName );
+  }
+  else
+  {
 #ifdef WIN32
-    platform = "winapplication";
+    QString platform = "winapplication";
 #else
-    platform = "application";
+    QString platform = "application";
 #endif
     SUIT_MessageBox::warning(this, tr( "WRN_WARNING" ),
                              tr( "EXTERNAL_BROWSER_CANNOT_SHOW_PAGE" ).
-                             arg(app->resourceMgr()->stringValue( "ExternalBrowser",
-                                                                 platform)).
+                             arg(app->resourceMgr()->stringValue( "ExternalBrowser", platform)).
                              arg(myHelpFileName));
   }
 }
@@ -2271,6 +2324,10 @@ void SMESHGUI_GroupDlg::onDeactivate()
 void SMESHGUI_GroupDlg::enterEvent (QEvent*)
 {
   if (!isEnabled()) {
+    SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
+    if ( aViewWindow && !mySelector) {
+      mySelector = aViewWindow->GetSelector();
+    }
     mySMESHGUI->EmitSignalDeactivateDialog();
     setEnabled(true);
     mySelectionMode = grpNoSelection;
@@ -2292,16 +2349,16 @@ void SMESHGUI_GroupDlg::keyPressEvent( QKeyEvent* e )
     return;
 
   if ( e->key() == Qt::Key_F1 )
-    {
-      e->accept();
-      onHelp();
-    }
+  {
+    e->accept();
+    onHelp();
+  }
 }
 
 //================================================================================
 /*!
  * \brief Enable showing of the popup when Geometry selection btn is clicked
 * \param enable - true to enable
+ * \param enable - true to enable
  */
 //================================================================================
 
@@ -2337,17 +2394,17 @@ void SMESHGUI_GroupDlg::updateGeomPopup()
 void SMESHGUI_GroupDlg::onGeomSelectionButton(bool isBtnOn)
 {
   if ( myGeomPopup && isBtnOn )
-    {
-      myCurrentLineEdit = myGeomGroupLine;
-      QAction* a = myGeomPopup->exec( QCursor::pos() );
-      if (!a || myActions[a] == DIRECT_GEOM_INDEX)
-        setSelectionMode(grpGeomSelection);
-    }
+  {
+    myCurrentLineEdit = myGeomGroupLine;
+    QAction* a = myGeomPopup->exec( QCursor::pos() );
+    if (!a || myActions[a] == DIRECT_GEOM_INDEX)
+      setSelectionMode(grpGeomSelection);
+  }
   else if (!isBtnOn)
-    {
-      myCurrentLineEdit = 0;
-      setSelectionMode(grpAllSelection);
-    }
+  {
+    myCurrentLineEdit = 0;
+    setSelectionMode(grpAllSelection);
+  }
 }
 
 //=================================================================================
@@ -2358,26 +2415,26 @@ void SMESHGUI_GroupDlg::onGeomPopup( QAction* a )
 {
   int index = myActions[a];
   if ( index == GEOM_BY_MESH_INDEX )
-    {
-      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*)));
-      }
-      // set mesh object to SMESHGUI_ShapeByMeshOp and start it
-      if ( !myMesh->_is_nil() ) {
-        myIsBusy = true;
-        hide(); // stop processing selection
-        myIsBusy = false;
-        myShapeByMeshOp->setModule( mySMESHGUI );
-        myShapeByMeshOp->setStudy( 0 ); // it's really necessary
-        myShapeByMeshOp->SetMesh( myMesh );
-        myShapeByMeshOp->start();
-      }
+  {
+    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*)));
     }
+    // set mesh object to SMESHGUI_ShapeByMeshOp and start it
+    if ( !myMesh->_is_nil() ) {
+      myIsBusy = true;
+      hide(); // stop processing selection
+      myIsBusy = false;
+      myShapeByMeshOp->setModule( mySMESHGUI );
+      myShapeByMeshOp->setStudy( 0 ); // it's really necessary
+      myShapeByMeshOp->SetMesh( myMesh );
+      myShapeByMeshOp->start();
+    }
+  }
 }
 
 //================================================================================
@@ -2418,10 +2475,10 @@ void SMESHGUI_GroupDlg::onPublishShapeByMeshDlg(SUIT_Operation* op)
 void SMESHGUI_GroupDlg::onCloseShapeByMeshDlg(SUIT_Operation* op)
 {
   if ( myShapeByMeshOp == op )
-    {
-      show();
-      setSelectionMode(grpGeomSelection);
-    }
+  {
+    show();
+    setSelectionMode(grpGeomSelection);
+  }
 }
 
 //=================================================================================
@@ -2522,7 +2579,7 @@ void SMESHGUI_GroupDlg::setDefaultGroupColor()
 // function : SetAppropriateActor()
 // purpose  : Find more appropriate of visible actors, set it to myActor, allow picking
 //            NPAL19389: create a group with a selection in another group.
-//            if mesh actor is not visible - find any first visible group or submesh
+//            if mesh actor is not visible - find any first visible group or sub-mesh
 //=================================================================================
 bool SMESHGUI_GroupDlg::SetAppropriateActor()
 {
@@ -2533,21 +2590,23 @@ bool SMESHGUI_GroupDlg::SetAppropriateActor()
 
   SVTK_ViewWindow* aViewWindow = SMESH::GetCurrentVtkView();
 
-  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);
-          }
-      }
+  if (myGrpTypeGroup->checkedId() > 0) {   // try current group on geometry actor
+    SMESH_Actor* anActor = 0;
+    if (!myGroupOnGeom->_is_nil())
+      anActor = SMESH::FindActorByObject(myGroupOnGeom);
+    if (!myGroupOnFilter->_is_nil())
+      anActor = SMESH::FindActorByObject(myGroupOnFilter);
+    if (anActor && anActor->hasIO())
+    {
+      isActor = true;
+      if (aViewWindow && !aViewWindow->isVisible(anActor->getIO()))
+        isActor = false;
+      else
+        myActorsList.append(anActor);
     }
-  } else {
+    return anActor;
+  }
+  else {
     // try mesh actor
     SMESH_Actor* anActor = SMESH::FindActorByObject(myMesh);
     if (anActor && anActor->hasIO()) {
@@ -2557,42 +2616,50 @@ bool SMESHGUI_GroupDlg::SetAppropriateActor()
       else
         myActorsList.append(anActor);
     }
-    
+
     // try group actor
+    SMESH_Actor* aGroupActor = 0;
     if (!isActor && !myGroup->_is_nil()) {
-      SMESH_Actor* anActor = SMESH::FindActorByObject(myGroup);
-      if (anActor && anActor->hasIO())
-        myActorsList.append(anActor);
+      aGroupActor = SMESH::FindActorByObject(myGroup);
+      if (aGroupActor && aGroupActor->hasIO())
+        myActorsList.append(aGroupActor);
     }
-    
-    // try any visible actor of group or submesh of current mesh
+
+    // try any visible actor of group or sub-mesh 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);
-              }
+        {
+          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);
             }
           }
+        }
       }
     }
+
+    // Show a standalone group if nothing else is visible (IPAL52227)
+    if ( myActorsList.count() == 1 &&
+         myActorsList[0] == aGroupActor &&
+         aViewWindow && !aViewWindow->isVisible(aGroupActor->getIO()))
+      SMESH::UpdateView( aViewWindow, SMESH::eDisplay, aGroupActor->getIO()->getEntry() );
   }
-  
+
+
   if (myActorsList.count() > 0) {
     QListIterator<SMESH_Actor*> it( myActorsList );
     while ( it.hasNext() ) {
@@ -2601,10 +2668,10 @@ bool SMESHGUI_GroupDlg::SetAppropriateActor()
         anActor->SetPickable(true);
     }
   }
-  
+
   return ( isActor || (myActorsList.count() > 0) );
 }
-  
+
 //=======================================================================
 //function : setShowEntityMode
 //purpose  : make shown only entity corresponding to my type
index 8deca497685f11ad8575ebee2d00ff75cd9c3b1e..8819d24f0be6b22ac4aa4b4b6b5c5858e4c2f1fb 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -120,6 +120,9 @@ private slots:
   void                          onPublishShapeByMeshDlg( SUIT_Operation* );
   void                          onCloseShapeByMeshDlg( SUIT_Operation* );
 
+  void                          onOpenView();
+  void                          onCloseView();
+
 private:
   void                          initDialog( bool );
   void                          init( SMESH::SMESH_Mesh_ptr );
index 06887d6c02397075738b0a49757a849c37c149a9..258084e05a8228384a6a8b4a1e658b3347844c83 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index 2fa69da68cf099c2fd1231c0e231f921bcf21eb2..60dff8129fb19f0dd8dcf1c1a5e1fdc14483614c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index bbebee448fd10847fa185fabb658ecbaa459f3b9..6f32383c0706c598664c1c558f07d83c18bb057c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 #include "SMESHGUI.h"
 #include "SMESHGUI_Utils.h"
 #include "SMESHGUI_VTKUtils.h"
-
-#include <SMESH_TypeFilter.hxx>
-
-// SALOME GUI includes
-#include <SUIT_ResourceMgr.h>
-#include <SUIT_Desktop.h>
-#include <SUIT_Session.h>
-#include <SUIT_MessageBox.h>
+#include "SMESH_TypeFilter.hxx"
+#include <SMESH_ActorUtils.h>
 
 #include <LightApp_Application.h>
 #include <LightApp_SelectionMgr.h>
+#include <QtxColorButton.h>
+#include <SALOMEDSClient_SObject.hxx>
+#include <SALOME_ListIO.hxx>
+#include <SUIT_Desktop.h>
+#include <SUIT_MessageBox.h>
+#include <SUIT_OverrideCursor.h>
+#include <SUIT_ResourceMgr.h>
+#include <SUIT_Session.h>
 #include <SVTK_Selection.h>
 #include <SVTK_ViewWindow.h>
-#include <SALOME_ListIO.hxx>
-
-// SALOME KERNEL includes
-#include <SALOMEDSClient_SObject.hxx>
 
 // Qt includes
-#include <QHBoxLayout>
-#include <QVBoxLayout>
+#include <QButtonGroup>
+#include <QCheckBox>
+#include <QComboBox>
 #include <QGridLayout>
-#include <QPushButton>
 #include <QGroupBox>
+#include <QHBoxLayout>
+#include <QKeyEvent>
 #include <QLabel>
 #include <QLineEdit>
-#include <QKeyEvent>
 #include <QListWidget>
-#include <QButtonGroup>
-#include <QComboBox>
-#include <QtxColorButton.h>
+#include <QPushButton>
+#include <QVBoxLayout>
 
 #define SPACING 6
 #define MARGIN  11
@@ -110,7 +108,7 @@ QWidget* SMESHGUI_GroupOpDlg::createMainFrame( QWidget* theParent )
   aLay->setSpacing(SPACING);
   
   // ------------------------------------------------------
-  QGroupBox* aNameGrp = new QGroupBox(tr("NAME"), aMainGrp);
+  QGroupBox* aNameGrp = new QGroupBox(tr("RESULT"), aMainGrp);
   QHBoxLayout* aNameGrpLayout = new QHBoxLayout(aNameGrp);
   aNameGrpLayout->setMargin(MARGIN);
   aNameGrpLayout->setSpacing(SPACING);
@@ -228,11 +226,15 @@ void SMESHGUI_GroupOpDlg::Init()
   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(onSelectionDone()));
   connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), SLOT(onDeactivate()));
   connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), SLOT(reject()));
+  connect(mySMESHGUI, SIGNAL(SignalActivatedViewManager()), SLOT(onOpenView()));
+  connect(mySMESHGUI, SIGNAL(SignalCloseView()), SLOT(onCloseView()));
 
   // set selection mode
   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
     aViewWindow->SetSelectionMode(ActorSelection);
   mySelectionMgr->installFilter(new SMESH_TypeFilter (SMESH::GROUP));
+
+  setDefaultGroupColor();
 }
 
 /*!
@@ -312,6 +314,7 @@ bool SMESHGUI_GroupOpDlg::isValid( const QList<SMESH::SMESH_GroupBase_var>& theL
 */
 void SMESHGUI_GroupOpDlg::onOk()
 {
+  SUIT_OverrideCursor oc;
   setIsApplyAndClose( true );
   if ( onApply() )
     reject();
@@ -333,6 +336,32 @@ void SMESHGUI_GroupOpDlg::reject()
   QDialog::reject();
 }
 
+//=================================================================================
+// function : onOpenView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_GroupOpDlg::onOpenView()
+{
+  if ( mySelector ) {
+    SMESH::SetPointRepresentation(false);
+  }
+  else {
+    mySelector = SMESH::GetViewWindow( mySMESHGUI )->GetSelector();
+    mySMESHGUI->EmitSignalDeactivateDialog();
+    setEnabled(true);
+  }
+}
+
+//=================================================================================
+// function : onCloseView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_GroupOpDlg::onCloseView()
+{
+  onDeactivate();
+  mySelector = 0;
+}
+
 /*!
   \brief SLOT called when "Help" button pressed shows "Help" page
 */
@@ -421,6 +450,14 @@ SALOMEDS::Color SMESHGUI_GroupOpDlg::getColor() const
   return aColor;
 }
 
+/*!
+  \brief Set default color for group
+*/
+void SMESHGUI_GroupOpDlg::setDefaultGroupColor()
+{
+  myColorBtn->setColor( SMESH::GetColor( "SMESH", "default_grp_color", QColor( 255, 170, 0 ) ) );
+}
+
 /*!
   \brief SLOT, called when selection is changed. Current implementation does 
    nothing. The method should be redefined in derived classes to update 
@@ -461,8 +498,12 @@ void SMESHGUI_GroupOpDlg::enterEvent(QEvent*)
 {
   mySMESHGUI->EmitSignalDeactivateDialog();
   setEnabled(true);
-  if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+  SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
+  if ( aViewWindow ) {
     aViewWindow->SetSelectionMode(ActorSelection);
+    if (!mySelector)
+      mySelector = aViewWindow->GetSelector();
+  }
   mySelectionMgr->installFilter(new SMESH_TypeFilter (SMESH::GROUP));
 }
 
@@ -475,6 +516,7 @@ void SMESHGUI_GroupOpDlg::reset()
 {
   myNameEdit->setText("");
   myNameEdit->setFocus();
+  setDefaultGroupColor();
 }
 
 /*!
@@ -498,7 +540,7 @@ void SMESHGUI_GroupOpDlg::setName( const QString& theName )
 }
 
 /*!
-  \brief Provides reaction on \93F1\94 button pressing
+  \brief Provides reaction on �F1� button pressing
   \param e  key press event
 */
 void SMESHGUI_GroupOpDlg::keyPressEvent( QKeyEvent* e )
@@ -951,35 +993,55 @@ void SMESHGUI_CutGroupsDlg::onSelectionDone()
   \param theModule module
 */
 SMESHGUI_DimGroupDlg::SMESHGUI_DimGroupDlg( SMESHGUI* theModule )
-: SMESHGUI_GroupOpDlg( theModule )
+  : SMESHGUI_GroupOpDlg( theModule )
 {
   setWindowTitle( tr( "CREATE_GROUP_OF_UNDERLYING_ELEMS" ) );
   setHelpFileName( "group_of_underlying_elements_page.html" );
 
   QGroupBox* anArgGrp = getArgGrp();
 
-  QLabel* aLbl = new QLabel( tr( "ELEMENTS_TYPE" ), anArgGrp );
-  
-  myCombo = new QComboBox( anArgGrp );
-  static QStringList anItems;
-  if ( anItems.isEmpty() )
+  QLabel* aTypeLbl = new QLabel( tr( "ELEMENTS_TYPE" ), anArgGrp );
+
+  myTypeCombo = new QComboBox( anArgGrp );
+  QStringList anItems;
   {
-    anItems.append( tr( "NODE" ) );
-    anItems.append( tr( "EDGE" ) );
-    anItems.append( tr( "FACE" ) );
-    anItems.append( tr( "VOLUME" ) );
+    anItems.append( tr( "MESH_NODE" ) );
+    anItems.append( tr( "SMESH_EDGE" ) );
+    anItems.append( tr( "SMESH_FACE" ) );
+    anItems.append( tr( "SMESH_VOLUME" ) );
+    anItems.append( tr( "SMESH_ELEM0D" ) );
+    anItems.append( tr( "SMESH_BALL" ) );
   }
-  myCombo->addItems( anItems );
-  myCombo->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
-  
+  myTypeCombo->addItems( anItems );
+  myTypeCombo->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+
+  QLabel* aNbNoLbl = new QLabel( tr( "NUMBER_OF_COMMON_NODES" ), anArgGrp );
+
+  myNbNoCombo = new QComboBox( anArgGrp );
+  anItems.clear();
+  {
+    anItems.append( tr( "ALL" ) );
+    anItems.append( tr( "MAIN" ) );
+    anItems.append( tr( "AT_LEAST_ONE" ) );
+    anItems.append( tr( "MAJORITY" ) );
+  }
+  myNbNoCombo->addItems( anItems );
+  myNbNoCombo->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+
   myListWg = new QListWidget( anArgGrp );
 
+  myUnderlOnlyChk = new QCheckBox( tr("UNDERLYING_ENTITIES_ONLY"), anArgGrp );
+  myUnderlOnlyChk->setChecked( false );
+
   // layout
   QGridLayout* aLay = new QGridLayout( anArgGrp );
   aLay->setSpacing( SPACING );
-  aLay->addWidget( aLbl, 0, 0 );
-  aLay->addWidget( myCombo, 0, 1 );
-  aLay->addWidget( myListWg, 1, 0, 1, 2 );
+  aLay->addWidget( aTypeLbl,        0, 0 );
+  aLay->addWidget( myTypeCombo,     0, 1 );
+  aLay->addWidget( aNbNoLbl,        1, 0 );
+  aLay->addWidget( myNbNoCombo,     1, 1 );
+  aLay->addWidget( myListWg,        2, 0, 1, 2 );
+  aLay->addWidget( myUnderlOnlyChk, 3, 0 );
 }
 
 /*!
@@ -1007,7 +1069,7 @@ void SMESHGUI_DimGroupDlg::reset()
 */
 SMESH::ElementType SMESHGUI_DimGroupDlg::getElementType() const
 {
-  return (SMESH::ElementType)( myCombo->currentIndex() + 1 );
+  return (SMESH::ElementType)( myTypeCombo->currentIndex() + 1 );
 }
 
 /*!
@@ -1017,7 +1079,7 @@ SMESH::ElementType SMESHGUI_DimGroupDlg::getElementType() const
 */
 void SMESHGUI_DimGroupDlg::setElementType( const SMESH::ElementType& theElemType )
 {
-  myCombo->setCurrentIndex( theElemType - 1 );
+  myTypeCombo->setCurrentIndex( theElemType - 1 );
 }
 
 /*!
@@ -1047,10 +1109,19 @@ bool SMESHGUI_DimGroupDlg::onApply()
   QStringList anEntryList;
   try
   {
-    SMESH::ListOfGroups_var aList = convert( myGroups );
+    SMESH::ListOfIDSources_var aList = new SMESH::ListOfIDSources();
+    aList->length( myGroups.count() );
+    QList<SMESH::SMESH_GroupBase_var>::const_iterator anIter = myGroups.begin();
+    for ( int i = 0; anIter != myGroups.end(); ++anIter, ++i )
+      aList[ i ] = SMESH::SMESH_IDSource::_narrow( *anIter );
+
     SMESH::ElementType anElemType = getElementType();
-    SMESH::SMESH_Group_var aNewGrp = 
-      aMesh->CreateDimGroup( aList, anElemType, aName.toLatin1().constData() );
+    SMESH::NB_COMMON_NODES_ENUM aNbCoNodes =
+      (SMESH::NB_COMMON_NODES_ENUM) myNbNoCombo->currentIndex();
+
+    SMESH::SMESH_Group_var aNewGrp =
+      aMesh->CreateDimGroup( aList, anElemType, aName.toLatin1().constData(),
+                             aNbCoNodes, myUnderlOnlyChk->isChecked() );
     if ( !CORBA::is_nil( aNewGrp ) )
     {
       aNewGrp->SetColor(  getColor() );
@@ -1092,5 +1163,3 @@ void SMESHGUI_DimGroupDlg::onSelectionDone()
   myListWg->clear();
   myListWg->addItems( aNames );
 }
-
-
index db086cd79e45926ab53e307d65541f5c251b94bb..f4191a9428a1a91f08a4eccc13d1557a95cda2f0 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 #include <SALOMEconfig.h>
 #include CORBA_SERVER_HEADER(SMESH_Group)
 
-class QPushButton;
-class QtxColorButton;
+class LightApp_SelectionMgr;
+class QCheckBox;
 class QComboBox;
-class QListWidget;
 class QGroupBox;
 class QLineEdit;
+class QListWidget;
+class QPushButton;
+class QtxColorButton;
 class SMESHGUI;
-class LightApp_SelectionMgr;
 class SVTK_Selector;
 
 /*
@@ -87,6 +88,7 @@ protected:
   SMESH::ListOfGroups*      convert( const QList<SMESH::SMESH_GroupBase_var>& );
 
   SALOMEDS::Color           getColor() const;
+  void                      setDefaultGroupColor();
 
   void                      setIsApplyAndClose( const bool theFlag );
   bool                      isApplyAndClose() const;
@@ -104,6 +106,9 @@ private slots:
 
   void                      onDeactivate();
 
+  void                      onOpenView();
+  void                      onCloseView();
+
 private:
   QWidget*                  createButtonFrame( QWidget* );
   QWidget*                  createMainFrame  ( QWidget* );
@@ -235,8 +240,11 @@ protected slots:
   virtual void                      onSelectionDone();
 
 private:
-  QComboBox*                        myCombo;
+  QComboBox*                        myTypeCombo;
+  QComboBox*                        myNbNoCombo;
   QListWidget*                      myListWg;
+  QCheckBox*                        myUnderlOnlyChk;
+  
   QList<SMESH::SMESH_GroupBase_var> myGroups;
 };
 
index ec8fa4ad8d02be3b981d23080475307079650a89..42d4893430bff745ceb747d3da109d3851be59f6 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -42,7 +42,7 @@ namespace SMESH
     SMESH::SMESH_Group_var aGroup;
     try {
       if ( !theMesh->_is_nil() )
-        aGroup = theMesh->CreateGroup( theType, theGroupName.toUtf8().data() );
+        aGroup = theMesh->CreateGroup( theType, SMESH::toUtf8(theGroupName) );
     }
     catch( const SALOME::SALOME_Exception& S_ex ) {
       SalomeApp_Tools::QtCatchCorbaException( S_ex );
index e9910d05843bfa16c7f432c06129b80f7be07719..cde518df4cabd0a6771dca5de1c6b09d6879ae9a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 630100e7174f28b7773217b1ded4e0186b0653f0..06d9172e43f2560ee9c8085c573681e4811a30a2 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 #include <utilities.h>
 
 // SALOME GUI includes
-#include <SUIT_Session.h>
+#include <LightApp_Application.h>
 #include <SUIT_MessageBox.h>
+#include <SUIT_OverrideCursor.h>
 #include <SUIT_ResourceMgr.h>
-#include <LightApp_Application.h>
+#include <SUIT_Session.h>
 #include <SalomeApp_IntSpinBox.h>
 
 // Qt includes
@@ -150,7 +151,7 @@ void SMESHGUI_GenericHypothesisCreator::editHypothesis( SMESH::SMESH_Hypothesis_
   }
   else {
     emit finished( QDialog::Accepted );
-        delete myDlg;
+    delete myDlg;
   }
 }
 
@@ -246,6 +247,12 @@ QFrame* SMESHGUI_GenericHypothesisCreator::buildStdFrame()
       changeWidgets().append( w );
     }
   }
+  if ( QWidget* w = getHelperWidget() )
+  {
+    w->setParent( fr );
+    w->move( QPoint( 0, 0 ) );
+    lay->addWidget( w );
+  }
 
   return fr;
 }
@@ -264,6 +271,7 @@ void SMESHGUI_GenericHypothesisCreator::onDialogFinished( int result )
   bool res = result==QDialog::Accepted;
   if( res )
   {
+    SUIT_OverrideCursor wc;
       /*QString paramValues = */storeParams();
       // No longer needed since NoteBook appears and "Value" OB field shows names of variable
 //       if ( !paramValues.isEmpty() ) {
@@ -512,6 +520,17 @@ QWidget* SMESHGUI_GenericHypothesisCreator::getCustomWidget( const StdParam & /*
 {
   return 0;
 }
+//================================================================================
+/*!
+ * \brief Returns a widget representing not a hypothesis parameter but some helper widget
+ */
+//================================================================================
+
+QWidget* SMESHGUI_GenericHypothesisCreator::getHelperWidget() const
+{
+  return 0;
+}
+
 bool SMESHGUI_GenericHypothesisCreator::getParamFromCustomWidget( StdParam&, QWidget* ) const
 {
   return false;
@@ -646,6 +665,7 @@ void SMESHGUI_HypothesisDlg::setCustomFrame( QFrame* f )
 
 void SMESHGUI_HypothesisDlg::accept()
 {
+  SUIT_OverrideCursor wc; // some creators temporary set params to a hyp which can be long
   QString msg;
   if ( myCreator && !myCreator->checkParams( msg ) )
   {
index fcadee8ddaf1942e4d7bdc0b31c393cc0e5c007e..44997d0e617257de1b1f350a234d5e0e25ca1436 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -114,6 +114,7 @@ protected:
   virtual void                 attuneStdWidget( QWidget*, const int ) const;
   virtual QWidget*             getCustomWidget( const StdParam&, 
                                                 QWidget*, const int ) const;
+  virtual QWidget*             getHelperWidget() const;
   virtual bool                 getParamFromCustomWidget( StdParam&, QWidget* ) const;
   virtual void                 valueChanged( QWidget* );
   virtual QString              caption() const;
@@ -157,20 +158,19 @@ public:
 protected slots:
   virtual void accept();
   virtual void reject();
-  void onHelp(); 
+  void onHelp();
 
-private:
+ private:
   SMESHGUI_GenericHypothesisCreator* myCreator;
   QLabel *myIconLabel, *myTypeLabel;
   QString myHelpFileName;
 };
 
 /*!
- * \brief Class containing information about hypothesis
-*/
-class HypothesisData
+ * \brief Information about a hypothesis
+ */
+struct HypothesisData
 {
-public:
   HypothesisData( const QString&, const QString&, const QString&,
                   const QString&, const QString&, const QString&,
                   const QString&, const QList<int>&, const bool,
index fa29da180e0efe8ed73680d34caa0e020d9e08f2..62fbba01125bbe372b277bde2c7e7a33b2d2580b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -629,7 +629,7 @@ namespace SMESH
             {
               SMESH_Hypothesis_var hypo = SMESH_Hypothesis::_narrow( SObjectToObject( aHypObj ) );
               SObjectList meshList = GetMeshesUsingAlgoOrHypothesis( hypo );
-              for( int i = 0; i < meshList.size(); i++ )
+              for( size_t i = 0; i < meshList.size(); i++ )
                 RemoveHypothesisOrAlgorithmOnMesh( meshList[ i ], hypo );
             }
         }
@@ -729,7 +729,7 @@ namespace SMESH
   QString GetMessageOnAlgoStateErrors(const algo_error_array& errors)
   {
     QString resMsg; // PAL14861 = QObject::tr("SMESH_WRN_MISSING_PARAMETERS") + ":\n";
-    for ( int i = 0; i < errors.length(); ++i ) {
+    for ( size_t i = 0; i < errors.length(); ++i ) {
       const SMESH::AlgoStateError & error = errors[ i ];
       const bool hasAlgo = ( strlen( error.algoName ) != 0 );
       QString msg;
index 8768e07112e19d35bd31c137facdb367aef08e3f..2627552d5954593b5f8dae153ee4516c81e1c2d7 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
diff --git a/src/SMESHGUI/SMESHGUI_IdPreview.cxx b/src/SMESHGUI/SMESHGUI_IdPreview.cxx
new file mode 100644 (file)
index 0000000..7999bee
--- /dev/null
@@ -0,0 +1,202 @@
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&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, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// 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 "SMESHGUI_IdPreview.h"
+
+#include <SALOME_Actor.h>
+#include <SMDS_Mesh.hxx>
+#include <SVTK_ViewWindow.h>
+
+#include <TColStd_MapOfInteger.hxx>
+#include <TColStd_MapIteratorOfMapOfInteger.hxx>
+
+#include <vtkActor2D.h>
+#include <vtkDataSetMapper.h>
+#include <vtkLabeledDataMapper.h>
+#include <vtkMaskPoints.h>
+#include <vtkPointData.h>
+#include <vtkProperty2D.h>
+#include <vtkRenderer.h>
+#include <vtkSelectVisiblePoints.h>
+#include <vtkTextProperty.h>
+#include <vtkUnstructuredGrid.h>
+
+// Extracted from SMESHGUI_MergeDlg.cxx
+
+SMESHGUI_IdPreview::SMESHGUI_IdPreview(SVTK_ViewWindow* theViewWindow):
+  myViewWindow(theViewWindow)
+{
+  myIdGrid = vtkUnstructuredGrid::New();
+
+  // Create and display actor
+  vtkDataSetMapper* aMapper = vtkDataSetMapper::New();
+  aMapper->SetInputData( 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->SetInputData(myPointsNumDataSet);
+  myPtsMaskPoints->SetOnRatio(1);
+
+  myPtsSelectVisiblePoints = vtkSelectVisiblePoints::New();
+  myPtsSelectVisiblePoints->SetInputConnection(myPtsMaskPoints->GetOutputPort());
+  myPtsSelectVisiblePoints->SelectInvisibleOff();
+  myPtsSelectVisiblePoints->SetTolerance(0.1);
+    
+  myPtsLabeledDataMapper = vtkLabeledDataMapper::New();
+  myPtsLabeledDataMapper->SetInputConnection(myPtsSelectVisiblePoints->GetOutputPort());
+  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 SMESHGUI_IdPreview::SetPointsData ( SMDS_Mesh*                   theMesh,
+                                         const 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 SMESHGUI_IdPreview::SetElemsData( const std::vector<int> & theElemsIdMap,
+                                       const std::list<gp_XYZ> & aGrCentersXYZ )
+{
+  vtkPoints* aPoints = vtkPoints::New();
+  aPoints->SetNumberOfPoints( theElemsIdMap.size() );
+  myIDs = theElemsIdMap;
+
+  std::list<gp_XYZ>::const_iterator coordIt = aGrCentersXYZ.begin();
+  for( int i = 0; coordIt != aGrCentersXYZ.end(); coordIt++, i++ )
+    aPoints->SetPoint( i, coordIt->X(), coordIt->Y(), coordIt->Z() );
+
+  myIdGrid->SetPoints(aPoints);
+  aPoints->Delete();
+
+  myIdActor->GetMapper()->Update();
+}
+
+void SMESHGUI_IdPreview::AddToRender(vtkRenderer* theRenderer)
+{
+  myIdActor->AddToRender(theRenderer);
+
+  myPtsSelectVisiblePoints->SetRenderer(theRenderer);
+  theRenderer->AddActor2D(myPointLabels);
+}
+
+void SMESHGUI_IdPreview::RemoveFromRender(vtkRenderer* theRenderer)
+{
+  myIdActor->RemoveFromRender(theRenderer);
+
+  myPtsSelectVisiblePoints->SetRenderer(theRenderer);
+  theRenderer->RemoveActor(myPointLabels);
+}
+
+void SMESHGUI_IdPreview::SetPointsLabeled( bool theIsPointsLabeled, bool theIsActorVisible )
+{
+  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->SetInputData( aDataSet );
+    myPointLabels->SetVisibility( theIsActorVisible );
+  }
+  else {
+    myPointLabels->SetVisibility( false );
+  }
+}
+
+SMESHGUI_IdPreview::~SMESHGUI_IdPreview()
+{
+  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();
+}
diff --git a/src/SMESHGUI/SMESHGUI_IdPreview.h b/src/SMESHGUI/SMESHGUI_IdPreview.h
new file mode 100644 (file)
index 0000000..ac547ee
--- /dev/null
@@ -0,0 +1,79 @@
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&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, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// 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_IdPreview_H
+#define SMESHGUI_IdPreview_H
+
+#include "SMESH_SMESHGUI.hxx"
+
+#include <list>
+#include <vector>
+
+#include <gp_XYZ.hxx>
+
+class SALOME_Actor;
+class SMDS_Mesh;
+class SVTK_ViewWindow;
+class TColStd_MapOfInteger;
+class vtkActor2D;
+class vtkLabeledDataMapper;
+class vtkMaskPoints;
+class vtkRenderer;
+class vtkSelectVisiblePoints;
+class vtkTextProperty;
+class vtkUnstructuredGrid;
+
+/*!
+ * \brief To display in the viewer IDs of selected elements or nodes
+ */
+class SMESHGUI_IdPreview
+{
+public:
+  SMESHGUI_IdPreview(SVTK_ViewWindow* theViewWindow);
+  ~SMESHGUI_IdPreview();
+
+  void SetPointsData( SMDS_Mesh* theMesh, const TColStd_MapOfInteger & theNodesIdMap );
+  void SetElemsData ( const std::vector<int> &  theElemsIdMap,
+                      const std::list<gp_XYZ> & theGrCentersXYZ );
+  void SetPointsLabeled( bool theIsPointsLabeled, bool theIsActorVisible = true );
+
+  void AddToRender     ( vtkRenderer* theRenderer );
+  void RemoveFromRender( vtkRenderer* theRenderer );
+
+protected:
+
+  SVTK_ViewWindow*        myViewWindow;
+
+  vtkUnstructuredGrid*    myIdGrid;
+  SALOME_Actor*           myIdActor;
+
+  vtkUnstructuredGrid*    myPointsNumDataSet;
+  vtkMaskPoints*          myPtsMaskPoints;
+  vtkSelectVisiblePoints* myPtsSelectVisiblePoints;
+  vtkLabeledDataMapper*   myPtsLabeledDataMapper;
+  bool                    myIsPointsLabeled;
+  vtkActor2D*             myPointLabels;
+
+  std::vector<int>        myIDs;
+};
+
+#endif
index 4c535901b68e1449f70e6d05c49ed4feda5aae0b..24597e2afda4a7187a0b2c3cf8ec20e5ab7b9c79 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 74ea3dc4b5c6993164309b81b6c37c61f448e1b5..1767a2805ebbd2b177749c070cfd6718f3da0284 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
@@ -305,7 +305,7 @@ void SMESHGUI_Make2DFrom3DOp::selectionDone()
         _PTR(SObject) sobj =
           SMESHGUI::activeStudy()->studyDS()->FindObjectID( ids[i].toLatin1().constData() );
         mySrcMesh = SMESH::SObjectToInterface<SMESH::SMESH_Mesh>( sobj );  
-        isMesh = !mySrcMesh->_is_nil();
+        //isMesh = !mySrcMesh->_is_nil(); // EAP - it's sometimes necessary to copy to a new mesh
       }
       myDlg->setNewMeshEnabled( isMesh );
     }
@@ -374,7 +374,7 @@ bool SMESHGUI_Make2DFrom3DOp::isValid( QString& msg ) const
       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 )
+      for ( int j = 0; j < (int) types->length(); ++j )
         if ( types[j] == SMESH::VOLUME )
           hasVolumes = true;
         else if ( types[j] == SMESH::FACE )
index 79867d7912ab0bfbe532d13bdeabb8b05f98d7d8..fd6fad57c497f5c4515644649725ac38e7fa6096 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index 2754b34a92436c064a1a15b786e5bdc3d0ac919b..f578c1c2f504ded1d79b6efeaab9f82d2c9c0031 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 #define SPACING 6
 #define MARGIN  11
 
+namespace
+{
+  enum { MANUAL_MODE = 0, SEARCH_MODE }; // how a node to move is specified
+}
+
 /*!
  * \brief Dialog to publish a sub-shape of the mesh main shape
  *        by selecting mesh elements
@@ -326,7 +331,8 @@ void SMESHGUI_MakeNodeAtPointDlg::ConstructorsClicked (int constructorId)
       myDestDX->hide();
       myDestDY->hide();
       myDestDZ->hide();
-      if (myNodeToMoveGrp->isVisible()) {myNodeToMoveGrp->hide();}
+      if (myNodeToMoveGrp->isVisible()) myNodeToMoveGrp->hide();
+      myDestBtn->setChecked( true );
       break;
     }
   }
@@ -346,6 +352,7 @@ void SMESHGUI_MakeNodeAtPointDlg::ConstructorsClicked (int constructorId)
 SMESHGUI_MakeNodeAtPointOp::SMESHGUI_MakeNodeAtPointOp()
 {
   mySimulation = 0;
+  mySMESHGUI = 0;
   myDlg = new SMESHGUI_MakeNodeAtPointDlg;
   myFilter = 0;
   myHelpFileName = "mesh_through_point_page.html";
@@ -355,14 +362,15 @@ SMESHGUI_MakeNodeAtPointOp::SMESHGUI_MakeNodeAtPointOp()
   myDestCoordChanged = true;
 
   // connect signals and slots
-  connect(myDlg->myDestinationX, SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview()));
-  connect(myDlg->myDestinationY, SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview()));
-  connect(myDlg->myDestinationZ, SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview()));
-  connect(myDlg->myDestDX, SIGNAL (valueChanged(double)), this, SLOT(onDestCoordChanged()));
-  connect(myDlg->myDestDY, SIGNAL (valueChanged(double)), this, SLOT(onDestCoordChanged()));
-  connect(myDlg->myDestDZ, SIGNAL (valueChanged(double)), this, SLOT(onDestCoordChanged()));
-  connect(myDlg->myId,SIGNAL (textChanged(const QString&)),SLOT(redisplayPreview()));
-  connect(myDlg->myPreviewChkBox,   SIGNAL (toggled(bool)),SLOT(redisplayPreview()));
+  connect(myDlg->myDestinationX,  SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview()));
+  connect(myDlg->myDestinationY,  SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview()));
+  connect(myDlg->myDestinationZ,  SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview()));
+  connect(myDlg->myDestDX,        SIGNAL (valueChanged(double)), this, SLOT(onDestCoordChanged()));
+  connect(myDlg->myDestDY,        SIGNAL (valueChanged(double)), this, SLOT(onDestCoordChanged()));
+  connect(myDlg->myDestDZ,        SIGNAL (valueChanged(double)), this, SLOT(onDestCoordChanged()));
+  connect(myDlg->myId,            SIGNAL (textChanged(const QString&)),SLOT(redisplayPreview()));
+  connect(myDlg->myPreviewChkBox, SIGNAL (toggled(bool)),              SLOT(redisplayPreview()));
+  connect(myDlg->myButtonGroup,   SIGNAL (buttonClicked(int)),         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
@@ -395,7 +403,10 @@ void SMESHGUI_MakeNodeAtPointOp::startOperation()
 
   // init simulation with a current View
   if ( mySimulation ) delete mySimulation;
-  mySimulation = new SMESHGUI_MeshEditPreview(SMESH::GetViewWindow( getSMESHGUI() ));
+  mySMESHGUI = getSMESHGUI();
+  mySimulation = new SMESHGUI_MeshEditPreview(SMESH::GetViewWindow( mySMESHGUI ) );
+  connect(mySMESHGUI, SIGNAL (SignalActivatedViewManager()), this, SLOT(onOpenView()));
+  connect(mySMESHGUI, SIGNAL (SignalCloseView()), this, SLOT(onCloseView()));
   vtkProperty* aProp = vtkProperty::New();
   aProp->SetRepresentationToWireframe();
   aProp->SetColor(250, 0, 250);
@@ -431,18 +442,11 @@ void SMESHGUI_MakeNodeAtPointOp::startOperation()
   myDlg->myDestDZ->setReadOnly(true);
   myDlg->myRButNodeToMove->setChecked(true);
 
-  myDlg->ConstructorsClicked(GetConstructorId());
+  myDlg->ConstructorsClicked( GetConstructorId() );
 
   myDlg->show();
 
   onSelectionDone(); // init myMeshActor
-
-  if ( myMeshActor ) {
-//     myMeshActor->SetRepresentation( VTK_WIREFRAME );
-    myMeshActor->SetPointRepresentation(true);
-    SMESH::RepaintCurrentView();
-    redisplayPreview();
-  }
 }
 
 //=================================================================================
@@ -463,12 +467,20 @@ int SMESHGUI_MakeNodeAtPointOp::GetConstructorId()
 void SMESHGUI_MakeNodeAtPointOp::stopOperation()
 {
   myNoPreview = true;
-  mySimulation->SetVisibility(false);
+  if ( mySimulation )
+  {
+    mySimulation->SetVisibility(false);
+    delete mySimulation;
+    mySimulation = 0;
+  }
   if ( myMeshActor ) {
-    myMeshActor->SetPointRepresentation(false);
-    SMESH::RepaintCurrentView();
     myMeshActor = 0;
   }
+  SMESH::SetPointRepresentation( false );
+  SMESH::RepaintCurrentView();
+
+  disconnect(mySMESHGUI, SIGNAL (SignalActivatedViewManager()), this, SLOT(onOpenView()));
+  disconnect(mySMESHGUI, SIGNAL (SignalCloseView()),            this, SLOT(onCloseView()));
   selectionMgr()->removeFilter( myFilter );
   SMESHGUI_SelectionOp::stopOperation();
 }
@@ -593,6 +605,8 @@ void SMESHGUI_MakeNodeAtPointOp::onSelectionDone()
 {
   if ( !myDlg->isVisible() || !myDlg->isEnabled() )
     return;
+
+  myNoPreview = true;
   try {
     SALOME_ListIO aList;
     selectionMgr()->selectedObjects(aList, SVTK_Viewer::Type());
@@ -601,6 +615,10 @@ void SMESHGUI_MakeNodeAtPointOp::onSelectionDone()
     Handle(SALOME_InteractiveObject) anIO = aList.First();
     SMESH_Actor* aMeshActor = SMESH::FindActorByEntry(anIO->getEntry());
 
+    if (( myDlg->myIdBtn->isChecked() && myDlg->myIdBtn->isEnabled() ) ||
+        ( !myDlg->myNodeToMoveGrp->isVisible() ))
+      myMeshActor = aMeshActor;
+
     if (!aMeshActor) { // coord by geom
       if ( myDlg->myDestBtn->isChecked() ) {
         GEOM::GEOM_Object_var geom = SMESH::IObjectToInterface<GEOM::GEOM_Object>(anIO);
@@ -609,63 +627,56 @@ void SMESHGUI_MakeNodeAtPointOp::onSelectionDone()
           if ( GEOMBase::GetShape(geom, aShape) &&
                aShape.ShapeType() == TopAbs_VERTEX ) {
             gp_Pnt P = BRep_Tool::Pnt(aShape);
-            myNoPreview = true;
             myDlg->myDestinationX->SetValue(P.X());
             myDlg->myDestinationY->SetValue(P.Y());
             myDlg->myDestinationZ->SetValue(P.Z());
-            myNoPreview = false;
-            redisplayPreview();
           }
         }
+        myNoPreview = false;
+        redisplayPreview();
         return;
       }
     }
 
-    if ( !myMeshActor )
-      myMeshActor = aMeshActor;
-
     QString aString;
     int nbElems = SMESH::GetNameOfSelectedElements(selector(),anIO, aString);
     if (nbElems == 1) {
       if (SMDS_Mesh* aMesh = aMeshActor->GetObject()->GetMesh()) {
         if (const SMDS_MeshNode* aNode = aMesh->FindNode(aString.toInt())) {
-          myNoPreview = true;
           if ( myDlg->myDestBtn->isChecked() ) { // set coord
             myDlg->myDestinationX->SetValue(aNode->X());
             myDlg->myDestinationY->SetValue(aNode->Y());
             myDlg->myDestinationZ->SetValue(aNode->Z());
-            myNoPreview = false;
-            redisplayPreview();
           }
           else if ( myDlg->myIdBtn->isChecked() &&
                     myDlg->myIdBtn->isEnabled() ) { // set node to move
             myDlg->myId->setText(aString);
-            myNoPreview = false;
+            myDlg->myCurrentX->SetValue( aNode->X() );
+            myDlg->myCurrentY->SetValue( aNode->Y() );
+            myDlg->myCurrentZ->SetValue( aNode->Z() );
             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->myDestinationX->GetValue() - x;
-            double dy = myDlg->myDestinationY->GetValue() - y;
-            double dz = myDlg->myDestinationZ->GetValue() - z;
-            myDlg->myCurrentX->SetValue(x);
-            myDlg->myCurrentY->SetValue(y);
-            myDlg->myCurrentZ->SetValue(z);
-            myDlg->myDestDX->SetValue(dx);
-            myDlg->myDestDY->SetValue(dy);
-            myDlg->myDestDZ->SetValue(dz);
-            myDlg->myDestDX->setReadOnly(false);
-            myDlg->myDestDY->setReadOnly(false);
-            myDlg->myDestDZ->setReadOnly(false);
-          }
+          double x = myDlg->myCurrentX->GetValue();
+          double y = myDlg->myCurrentY->GetValue();
+          double z = myDlg->myCurrentZ->GetValue();
+          double dx = myDlg->myDestinationX->GetValue() - x;
+          double dy = myDlg->myDestinationY->GetValue() - y;
+          double dz = myDlg->myDestinationZ->GetValue() - z;
+          myDlg->myDestDX->SetValue(dx);
+          myDlg->myDestDY->SetValue(dy);
+          myDlg->myDestDZ->SetValue(dz);
+          myDlg->myDestDX->setReadOnly(false);
+          myDlg->myDestDY->setReadOnly(false);
+          myDlg->myDestDZ->setReadOnly(false);
         }
       }
     }
   } catch (...) {
   }
+
+  myNoPreview = false;
+  redisplayPreview();
 }
 
 //================================================================================
@@ -680,12 +691,15 @@ void SMESHGUI_MakeNodeAtPointOp::redisplayPreview()
     return;
   myNoPreview = true;
 
+  if ( !myMeshActor && GetConstructorId() == SEARCH_MODE )
+    onSelectionDone();
+
   SMESH::MeshPreviewStruct_var aMeshPreviewStruct;
 
   bool moveShown = false;
   if ( myMeshActor)
   {
-    const bool isPreview = myDlg->myPreviewChkBox->isChecked();
+    const bool  isPreview = myDlg->myPreviewChkBox->isChecked();
     const bool isMoveNode = myDlg->myRButMoveWithoutNode->isChecked();
     QString msg;
     if ( isValid( msg ) )
@@ -714,22 +728,28 @@ void SMESHGUI_MakeNodeAtPointOp::redisplayPreview()
                 myDlg->myDestinationX->SetValue(x);
                 myDlg->myDestinationY->SetValue(y);
                 myDlg->myDestinationZ->SetValue(z);
-              }
-              if ( myDestCoordChanged ) {
-                dx = myDlg->myDestinationX->GetValue() - x;
-                dy = myDlg->myDestinationY->GetValue() - y;
-                dz = myDlg->myDestinationZ->GetValue() - z;
                 myDlg->myDestDX->SetValue(dx);
                 myDlg->myDestDY->SetValue(dy);
                 myDlg->myDestDZ->SetValue(dz);
               }
-              else {
-                dx = myDlg->myDestDX->GetValue() + x;
-                dy = myDlg->myDestDY->GetValue() + y;
-                dz = myDlg->myDestDZ->GetValue() + z;
-                myDlg->myDestinationX->SetValue(dx);
-                myDlg->myDestinationY->SetValue(dy);
-                myDlg->myDestinationZ->SetValue(dz);
+              else
+              {
+                if ( myDestCoordChanged ) {
+                  dx = myDlg->myDestinationX->GetValue() - x;
+                  dy = myDlg->myDestinationY->GetValue() - y;
+                  dz = myDlg->myDestinationZ->GetValue() - z;
+                  myDlg->myDestDX->SetValue(dx);
+                  myDlg->myDestDY->SetValue(dy);
+                  myDlg->myDestDZ->SetValue(dz);
+                }
+                else {
+                  dx = myDlg->myDestDX->GetValue() + x;
+                  dy = myDlg->myDestDY->GetValue() + y;
+                  dz = myDlg->myDestDZ->GetValue() + z;
+                  myDlg->myDestinationX->SetValue(dx);
+                  myDlg->myDestinationY->SetValue(dy);
+                  myDlg->myDestinationZ->SetValue(dz);
+                }
               }
               myDlg->myCurrentX->SetValue(x);
               myDlg->myCurrentY->SetValue(y);
@@ -765,7 +785,8 @@ void SMESHGUI_MakeNodeAtPointOp::redisplayPreview()
             }
           }
         }
-      }catch (...) {
+      }
+      catch (...) {
       }
     }
   }
@@ -787,7 +808,8 @@ void SMESHGUI_MakeNodeAtPointOp::redisplayPreview()
     aMeshPreviewStruct->elementConnectivities.length(1);
     aMeshPreviewStruct->elementConnectivities[0] = 0;
   }
-
+  if (!mySimulation)
+    mySimulation = new SMESHGUI_MeshEditPreview(SMESH::GetViewWindow( mySMESHGUI ));
   // display data
   if ( aMeshPreviewStruct.operator->() )
   {
@@ -801,6 +823,33 @@ void SMESHGUI_MakeNodeAtPointOp::redisplayPreview()
   myNoPreview = false;
 }
 
+//=================================================================================
+/*!
+ * \brief SLOT called when the viewer opened
+ */
+//=================================================================================
+void SMESHGUI_MakeNodeAtPointOp::onOpenView()
+{
+  if ( mySimulation ) {
+    mySimulation->SetVisibility(false);
+    SMESH::SetPointRepresentation(false);
+  }
+  else {
+    mySimulation = new SMESHGUI_MeshEditPreview(SMESH::GetViewWindow( mySMESHGUI ));
+  }
+}
+
+//=================================================================================
+/*!
+ * \brief SLOT called when the viewer closed
+ */
+//=================================================================================
+void SMESHGUI_MakeNodeAtPointOp::onCloseView()
+{
+  delete mySimulation;
+  mySimulation = 0;
+}
+
 //================================================================================
 /*!
  * \brief SLOT called when the node id is manually changed
@@ -839,7 +888,7 @@ void SMESHGUI_MakeNodeAtPointOp::onTextChange( const QString& theText )
 void SMESHGUI_MakeNodeAtPointOp::activateSelection()
 {
   selectionMgr()->clearFilters();
-  SMESH::SetPointRepresentation(false);
+  SMESH::SetPointRepresentation( true );
   selectionMgr()->installFilter( myFilter );
   setSelectionMode( NodeSelection );
 }
index 24be56a428fabd94d59e307bd488096a05851df8..805f9505ec3a43e5e9a79dc75c853c74bcd34d22 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -73,6 +73,8 @@ private slots:
   void                           onTextChange( const QString& );
   void                           onUpdateDestination();
   void                           onDestCoordChanged();
+  void                           onOpenView();
+  void                           onCloseView();
 
 private:
   int                           GetConstructorId();
@@ -81,6 +83,7 @@ private:
 
   SUIT_SelectionFilter*         myFilter;
   int                           myMeshOldDisplayMode;
+  SMESHGUI*                     mySMESHGUI;
   SMESHGUI_MeshEditPreview*     mySimulation;
   SMESH_Actor*                  myMeshActor;
   bool                          myNoPreview;
index 9f7c9bb2674f624b587049dabbce145073aa0980..4b30659ebe8f87193bf6d16a5a2933b4528793ca 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -198,6 +198,7 @@ SMESHGUI_MinDistance::SMESHGUI_MinDistance( QWidget* parent )
   clear();
 
   //setTarget( FirstTgt );
+  selectionChanged();
 }
 
 /*!
@@ -500,13 +501,21 @@ void SMESHGUI_MinDistance::secondEdited()
   setTarget( SecondTgt );
   if ( sender() == mySecondTgt )
     clear();
+  QString text = mySecondTgt->text();
+  if ( !mySecondActor )
+  {
+    selectionChanged();
+    mySecondTgt->setText( text );
+  }
   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 ( !text.isEmpty() ) {
+        TColStd_MapOfInteger ID;
+        ID.Add( text.toLong() );
+        selector->AddOrRemoveIndex( IO, ID, false );
+      }
     }
     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
       aViewWindow->highlight( IO, true, true );
@@ -519,8 +528,8 @@ void SMESHGUI_MinDistance::secondEdited()
 void SMESHGUI_MinDistance::compute()
 {
   SUIT_OverrideCursor wc;
-  SMESH::SMESH_IDSource_wrap s1;
-  SMESH::SMESH_IDSource_wrap s2;
+  SMESH::IDSource_wrap s1;
+  SMESH::IDSource_wrap s2;
   bool isOrigin = mySecond->checkedId() == OriginTgt;
 
   // process first target
@@ -760,7 +769,8 @@ void SMESHGUI_BoundingBox::updateSelection()
 
   sourceEdited();
 
-  //selectionChanged();
+  if ( mySource->text().isEmpty() )
+    selectionChanged();
 }
 
 /*!
@@ -1206,6 +1216,9 @@ void SMESHGUI_BasicProperties::updateSelection()
   selMgr->installFilter( myFilter );
   
   connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( selectionChanged() ) );
+
+  if ( mySource->text().isEmpty() )
+    selectionChanged();
 }
 
 /*!
index 964f7418dbf740d99044507b027dddfff0c605d9..a9ea2b7e774e77c5787211653cd81f1cd10e81f5 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 046bd063c7f71b280a438b4cfed5e9801ae9771e..46e68d3464da2ea8cfcf72a81160edff0671717d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 #include "SMESHGUI_MergeDlg.h"
 
 #include "SMESHGUI.h"
-#include "SMESHGUI_Utils.h"
-#include "SMESHGUI_VTKUtils.h"
+#include "SMESHGUI_IdPreview.h"
 #include "SMESHGUI_MeshUtils.h"
 #include "SMESHGUI_SpinBox.h"
+#include "SMESHGUI_Utils.h"
+#include "SMESHGUI_VTKUtils.h"
 
 #include <SMESH_Actor.h>
 #include <SMESH_TypeFilter.hxx>
 #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 <QButtonGroup>
+#include <QCheckBox>
+#include <QGridLayout>
 #include <QGroupBox>
+#include <QHBoxLayout>
+#include <QKeyEvent>
 #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
+namespace
 {
-  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->SetInputData( 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->SetInputData(myPointsNumDataSet);
-      myPtsMaskPoints->SetOnRatio(1);
-
-      myPtsSelectVisiblePoints = vtkSelectVisiblePoints::New();
-      myPtsSelectVisiblePoints->SetInputConnection(myPtsMaskPoints->GetOutputPort());
-      myPtsSelectVisiblePoints->SelectInvisibleOff();
-      myPtsSelectVisiblePoints->SetTolerance(0.1);
-    
-      myPtsLabeledDataMapper = vtkLabeledDataMapper::New();
-      myPtsLabeledDataMapper->SetInputConnection(myPtsSelectVisiblePoints->GetOutputPort());
-      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->SetInputData( 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();
+  enum ActionType { MERGE_NODES, MERGE_ELEMENTS, TYPE_AUTO=0, TYPE_MANUAL };
+}
 
-      myPointLabels->Delete();
 
-//       myTimeStamp->Delete();
-    }
-  };
+QPixmap SMESHGUI_MergeDlg::IconFirst()
+{
+  static const char * iconFirst[] = {
+    "18 10 2 1",
+    "       g None",
+    ".      g #000000",
+    "         .     .  ",
+    "  ..    ..    ..  ",
+    "  ..   ...   ...  ",
+    "  ..  ....  ....  ",
+    "  .. ..... .....  ",
+    "  .. ..... .....  ",
+    "  ..  ....  ....  ",
+    "  ..   ...   ...  ",
+    "  ..    ..    ..  ",
+    "         .     .  "};
+  return iconFirst;
 }
 
-static const char * IconFirst[] = {
-"18 10 2 1",
-"       g None",
-".      g #000000",
-"         .     .  ",
-"  ..    ..    ..  ",
-"  ..   ...   ...  ",
-"  ..  ....  ....  ",
-"  .. ..... .....  ",
-"  .. ..... .....  ",
-"  ..  ....  ....  ",
-"  ..   ...   ...  ",
-"  ..    ..    ..  ",
-"         .     .  "};
-
 //=================================================================================
 // class    : SMESHGUI_MergeDlg()
 // purpose  :
@@ -307,42 +117,40 @@ SMESHGUI_MergeDlg::SMESHGUI_MergeDlg (SMESHGUI* theModule, int theAction)
 {
   setModal(false);
   setAttribute(Qt::WA_DeleteOnClose, true);
-  setWindowTitle(myAction == 1 ? tr("SMESH_MERGE_ELEMENTS") : tr("SMESH_MERGE_NODES"));
+  setWindowTitle(myAction == MERGE_ELEMENTS ? tr("SMESH_MERGE_ELEMENTS") : tr("SMESH_MERGE_NODES"));
 
-  myIdPreview = new SMESH::TIdPreview(SMESH::GetViewWindow( mySMESHGUI ));
+  myIdPreview = new SMESHGUI_IdPreview(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 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 to switch dialog behaviour (myTypeId)
+
+  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 = TYPE_AUTO;
 
   /***************************************************************/
   // Controls for mesh defining
+
   GroupMesh = new QGroupBox(tr("SMESH_SELECT_WHOLE_MESH"), this);
   QHBoxLayout* GroupMeshLayout = new QHBoxLayout(GroupMesh);
   GroupMeshLayout->setSpacing(SPACING);
@@ -358,42 +166,44 @@ SMESHGUI_MergeDlg::SMESHGUI_MergeDlg (SMESHGUI* theModule, int theAction)
   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"), 
+
+  GroupCoincident = new QGroupBox(myAction == MERGE_ELEMENTS ?
+                                  tr("COINCIDENT_ELEMENTS") :
+                                  tr("COINCIDENT_NODES"),
                                   this);
 
-  QVBoxLayout* aCoincidentLayout = new QVBoxLayout(GroupCoincident);
+  QGridLayout* aCoincidentLayout = new QGridLayout(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);
+  if (myAction == MERGE_NODES) // case merge nodes
+  {
+    /***************************************************************/
+    // Node specific Controls: tolerance, ...
+
+    NodeSpecWidget = new QWidget( this );
+
+    QLabel* TextLabelTolerance = new QLabel(tr("SMESH_TOLERANCE"), NodeSpecWidget);
+    SpinBoxTolerance = new SMESHGUI_SpinBox( NodeSpecWidget );
     SpinBoxTolerance->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
 
-    GroupExclude = new QGroupBox(tr("EXCLUDE_GROUPS"), foo);
+    SeparateCornersAndMedium = new QCheckBox(tr("SEPARATE_CORNERS_AND_MEDIUM"), NodeSpecWidget );
+    SeparateCornersAndMedium->setEnabled( false );
+
+    QGridLayout* NodeSpecLayout = new QGridLayout(NodeSpecWidget);
+    NodeSpecLayout->setSpacing(SPACING);
+    NodeSpecLayout->setMargin(0);
+
+    NodeSpecLayout->addWidget(TextLabelTolerance,       0, 0 );
+    NodeSpecLayout->addWidget(SpinBoxTolerance,         0, 1 );
+    NodeSpecLayout->addWidget(SeparateCornersAndMedium, 1, 0, 1, 2 );
+
+    /***************************************************************/
+    // Exclude groups
+
+    GroupExclude = new QGroupBox(tr("EXCLUDE_GROUPS"), this );
     GroupExclude->setCheckable( true );
     GroupExclude->setChecked( false );
     ListExclude = new QListWidget( GroupExclude );
@@ -402,50 +212,81 @@ SMESHGUI_MergeDlg::SMESHGUI_MergeDlg (SMESHGUI* theModule, int theAction)
     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);
+    /***************************************************************/
+    // Nodes to keep
+
+    GroupKeep = new QGroupBox(tr("KEEP_NODES"), this);
+    SelectKeepNodesButton = new QPushButton( GroupKeep );
+    SelectKeepNodesButton->setIcon( IconSelect );
+    QLabel*       selectLabel = new QLabel(tr("SELECT"));
+    QRadioButton*   idsButton = new QRadioButton(tr("SMESH_NODES"), GroupKeep);
+    QRadioButton* groupButton = new QRadioButton(tr("GROUP_SUBMESH"), GroupKeep);
+    KeepFromButGroup = new QButtonGroup( this );
+    KeepFromButGroup->addButton( idsButton,   0 );
+    KeepFromButGroup->addButton( groupButton, 1 );
+    groupButton->setChecked( true );
+    KeepList = new QListWidget( GroupKeep );
+    KeepList->setSelectionMode(QAbstractItemView::ExtendedSelection);
+    KeepList->setFlow(QListView::TopToBottom);
+    AddKeepNodesButton    = new QPushButton(tr("SMESH_BUT_ADD"), GroupKeep );
+    RemoveKeepNodesButton = new QPushButton(tr("SMESH_BUT_REMOVE"), GroupKeep );
+    QGridLayout* GroupKeepLayout = new QGridLayout(GroupKeep);
+    GroupKeepLayout->setSpacing( SPACING );
+    GroupKeepLayout->setMargin ( MARGIN );
+    GroupKeepLayout->addWidget( SelectKeepNodesButton, 0, 0 );
+    GroupKeepLayout->addWidget( selectLabel,           0, 1 );
+    GroupKeepLayout->addWidget( idsButton,             0, 2 );
+    GroupKeepLayout->addWidget( groupButton,           0, 3, 1, 2 );
+    GroupKeepLayout->addWidget( KeepList,              1, 0, 3, 4 );
+    GroupKeepLayout->addWidget( AddKeepNodesButton,    1, 4, 1, 1 );
+    GroupKeepLayout->addWidget( RemoveKeepNodesButton, 2, 4, 1, 1 );
+    GroupKeepLayout->setRowStretch(3, 5);
+
+    // Costruction of the logical filter
+    QList<SUIT_SelectionFilter*> aListOfFilters;
+    aListOfFilters << new SMESH_TypeFilter (SMESH::SUBMESH)
+                   << new SMESH_TypeFilter (SMESH::GROUP);
+    mySubMeshOrGroupFilter =
+      new SMESH_LogicalFilter (aListOfFilters, SMESH_LogicalFilter::LO_OR, /*takeOwnership=*/true);
   }
   else {
-    TextLabelTolerance = 0;
-    SpinBoxTolerance = 0;
-    GroupExclude = 0;
-    ListExclude = 0;
+    NodeSpecWidget         = 0;
+    SpinBoxTolerance       = 0;
+    GroupExclude           = 0;
+    ListExclude            = 0;
+    KeepFromButGroup       = 0;
+    SelectKeepNodesButton  = 0;
+    AddKeepNodesButton     = 0;
+    RemoveKeepNodesButton  = 0;
+    KeepList               = 0;
+    mySubMeshOrGroupFilter = 0;
   }
 
-  GroupCoincidentWidget = new QWidget(GroupCoincident);
-  QGridLayout* GroupCoincidentLayout = new QGridLayout(GroupCoincidentWidget);
-  GroupCoincidentLayout->setSpacing(SPACING);
-  GroupCoincidentLayout->setMargin(0);
-
-  ListCoincident = new QListWidget(GroupCoincidentWidget);
+  ListCoincident = new QListWidget(GroupCoincident);
   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);
-  ShowIDs = new QCheckBox(myAction == 1 ? tr("SHOW_ELEMS_IDS") : tr("SHOW_NODES_IDS"), GroupCoincidentWidget);
+  DetectButton      = new QPushButton(tr("DETECT"),           GroupCoincident);
+  AddGroupButton    = new QPushButton(tr("SMESH_BUT_ADD"),    GroupCoincident);
+  RemoveGroupButton = new QPushButton(tr("SMESH_BUT_REMOVE"), GroupCoincident);
 
-  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);
-  GroupCoincidentLayout->addWidget(ShowIDs,           4, 1);
-  GroupCoincidentLayout->setRowMinimumHeight(1, 10);
-  GroupCoincidentLayout->setRowStretch(1, 5);
+  SelectAllCB = new QCheckBox(tr("SELECT_ALL"), GroupCoincident);
+  ShowIDs = new QCheckBox(myAction == MERGE_ELEMENTS ? tr("SHOW_ELEMS_IDS") : tr("SHOW_NODES_IDS"), GroupCoincident);
 
-  aCoincidentLayout->addWidget(GroupCoincidentWidget);
+  aCoincidentLayout->addWidget(ListCoincident,    0, 0, 4, 2);
+  aCoincidentLayout->addWidget(DetectButton,      0, 2);
+  aCoincidentLayout->addWidget(AddGroupButton,    2, 2);
+  aCoincidentLayout->addWidget(RemoveGroupButton, 3, 2);
+  aCoincidentLayout->addWidget(SelectAllCB,       4, 0);
+  aCoincidentLayout->addWidget(ShowIDs,           4, 1);
+  aCoincidentLayout->setRowMinimumHeight(1, 10);
+  aCoincidentLayout->setRowStretch(1, 5);
 
   /***************************************************************/
   // Controls for editing the selected group
-  GroupEdit = new QGroupBox(tr("EDIT_SELECTED_GROUP"), this);
+
+  GroupEdit = new QGroupBox(myAction == MERGE_NODES ?
+                            tr("EDIT_SELECTED_NODE_GROUP") :
+                            tr("EDIT_SELECTED_ELEM_GROUP"), this);
   QGridLayout* GroupEditLayout = new QGridLayout(GroupEdit);
   GroupEditLayout->setSpacing(SPACING);
   GroupEditLayout->setMargin(MARGIN);
@@ -462,7 +303,7 @@ SMESHGUI_MergeDlg::SMESHGUI_MergeDlg (SMESHGUI* theModule, int theAction)
   RemoveElemButton = new QPushButton(GroupEdit);
   RemoveElemButton->setIcon(IconRemove);
   SetFirstButton = new QPushButton(GroupEdit);
-  SetFirstButton->setIcon(QPixmap(IconFirst));
+  SetFirstButton->setIcon(IconFirst());
 
   GroupEditLayout->addWidget(ListEdit,         0, 0, 2, 1);
   GroupEditLayout->addWidget(AddElemButton,    0, 1);
@@ -494,16 +335,49 @@ SMESHGUI_MergeDlg::SMESHGUI_MergeDlg (SMESHGUI* theModule, int theAction)
   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 );
+  if (myAction == MERGE_NODES)
+  {
+    QWidget* LeftWdg = new QWidget( this );
+    QVBoxLayout* LeftLayout = new QVBoxLayout(LeftWdg);
+    LeftLayout->setSpacing(SPACING);
+    LeftLayout->setMargin(0);
+    LeftLayout->addWidget(TypeBox);
+    LeftLayout->addWidget(GroupMesh);
+    LeftLayout->addWidget(NodeSpecWidget);
+    LeftLayout->addWidget(GroupCoincident);
+    LeftLayout->addStretch();
+    LeftLayout->addWidget(GroupButtons);
+    LeftLayout->setStretch( 3, 10 );
+
+    QWidget* RightWdg = new QWidget( this );
+    QVBoxLayout* RightLayout = new QVBoxLayout(RightWdg);
+    RightLayout->setSpacing(SPACING);
+    RightLayout->setMargin(0);
+    RightLayout->addWidget(GroupExclude);
+    RightLayout->addWidget(GroupKeep);
+    RightLayout->addWidget(GroupEdit);
+    RightLayout->setStretch( 0, 4 );
+    RightLayout->setStretch( 1, 5 );
+
+    QHBoxLayout* DlgLayout = new QHBoxLayout(this);
+    DlgLayout->setSpacing(SPACING*2);
+    DlgLayout->setMargin(MARGIN);
+    DlgLayout->addWidget( LeftWdg );
+    DlgLayout->addWidget( RightWdg );
+  }
+  else
+  {
+    QVBoxLayout* DlgLayout = new QVBoxLayout(this);
+    DlgLayout->setSpacing(SPACING);
+    DlgLayout->setMargin(MARGIN);
+    DlgLayout->addWidget(TypeBox);
+    DlgLayout->addWidget(GroupMesh);
+    DlgLayout->addWidget(GroupCoincident);
+    DlgLayout->addWidget(GroupEdit);
+    DlgLayout->addWidget(GroupButtons);
+  }
+
+  GroupCoincident->hide();
   GroupEdit->hide();
 
   this->resize(10,10);
@@ -528,16 +402,14 @@ SMESHGUI_MergeDlg::~SMESHGUI_MergeDlg()
 //=================================================================================
 void SMESHGUI_MergeDlg::Init()
 {
-  if (myAction == 0) {
+  if ( myAction == MERGE_NODES ) {
     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; 
+  myEditCurrentArgument = (QWidget*)LineEditMesh;
 
   myActor = 0;
   mySubMeshOrGroup = SMESH::SMESH_subMesh::_nil();
@@ -546,13 +418,21 @@ void SMESHGUI_MergeDlg::Init()
 
   mySMESHGUI->SetActiveDialogBox((QDialog*)this);
   myIsBusy = false;
-  
+
   /* signals and slots connections */
   connect(buttonOk,     SIGNAL(clicked()), this, SLOT(ClickOnOk()));
   connect(buttonCancel, SIGNAL(clicked()), this, SLOT(reject()));
   connect(buttonApply,  SIGNAL(clicked()), this, SLOT(ClickOnApply()));
   connect(buttonHelp,   SIGNAL(clicked()), this, SLOT(ClickOnHelp()));
 
+  if ( KeepList )
+  {
+    connect(SelectKeepNodesButton, SIGNAL (clicked()), this, SLOT(SetEditCurrentArgument()));
+    connect(KeepFromButGroup, SIGNAL (buttonClicked(int)), SLOT(onKeepNodeSourceChanged(int)));
+    connect(AddKeepNodesButton, SIGNAL (clicked()), this, SLOT(onAddKeepNode()));
+    connect(RemoveKeepNodesButton, SIGNAL (clicked()), this, SLOT(onRemoveKeepNode()));
+    connect(KeepList, SIGNAL (itemSelectionChanged()), this, SLOT(onSelectKeepNode()));
+  }
   connect(SelectMeshButton, SIGNAL (clicked()), this, SLOT(SetEditCurrentArgument()));
   connect(DetectButton, SIGNAL (clicked()), this, SLOT(onDetect()));
   connect(ListCoincident, SIGNAL (itemSelectionChanged()), this, SLOT(onSelectGroup()));
@@ -563,21 +443,22 @@ void SMESHGUI_MergeDlg::Init()
   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(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(reject()));
-
+  connect(mySMESHGUI, SIGNAL (SignalActivatedViewManager()), this,  SLOT(onOpenView()));
+  connect(mySMESHGUI, SIGNAL (SignalCloseView()), this, SLOT(onCloseView()));
   // Init Mesh field from selection
   SelectionIntoArgument();
 
   // Update Buttons
   updateControls();
   
-  if (myAction == 0)
+  if ( myAction == MERGE_NODES )
     myHelpFileName = "merging_nodes_page.html";
   else
     myHelpFileName = "merging_elements_page.html";
@@ -587,8 +468,9 @@ void SMESHGUI_MergeDlg::Init()
 // function : FindGravityCenter()
 // purpose  :
 //=================================================================================
-void SMESHGUI_MergeDlg::FindGravityCenter(TColStd_MapOfInteger & theElemsIdMap, 
-                                          std::list< gp_XYZ > & theGrCentersXYZ)
+void SMESHGUI_MergeDlg::FindGravityCenter(TColStd_MapOfInteger & theElemsIdMap,
+                                          std::vector<int>&      theIDs,
+                                          std::list< gp_XYZ > &  theGrCentersXYZ)
 {
   if (!myActor)
     return;
@@ -600,11 +482,13 @@ void SMESHGUI_MergeDlg::FindGravityCenter(TColStd_MapOfInteger & theElemsIdMap,
 
   int nbNodes;
 
+  theIDs.reserve( theElemsIdMap.Extent() );
   TColStd_MapIteratorOfMapOfInteger idIter( theElemsIdMap );
   for( ; idIter.More(); idIter.Next() ) {
     const SMDS_MeshElement* anElem = aMesh->FindElement(idIter.Key());
     if ( !anElem )
       continue;
+    theIDs.push_back( idIter.Key() );
 
     gp_XYZ anXYZ(0., 0., 0.);
     SMDS_ElemIteratorPtr nodeIt = anElem->nodesIterator();
@@ -628,7 +512,7 @@ bool SMESHGUI_MergeDlg::ClickOnApply()
     return false;
 
   try {
-    if (myTypeId == 0)
+    if (myTypeId == TYPE_AUTO)
       onDetect();
 
     SUIT_OverrideCursor aWaitCursor;
@@ -638,7 +522,7 @@ bool SMESHGUI_MergeDlg::ClickOnApply()
     SMESH::array_of_long_array_var aGroupsOfElements = new SMESH::array_of_long_array;
 
     if ( ListCoincident->count() == 0) {
-      if (myAction == 0)
+      if ( myAction == MERGE_NODES )
         SUIT_MessageBox::warning(this,
                                  tr("SMESH_WARNING"),
                                  tr("SMESH_NO_NODES_DETECTED"));
@@ -662,31 +546,72 @@ bool SMESHGUI_MergeDlg::ClickOnApply()
       aGroupsOfElements[anArrayNum++] = anIds.inout();
     }
 
-    if( myAction == 0 )
-      aMeshEditor->MergeNodes (aGroupsOfElements.inout());
+    SMESH::ListOfIDSources_var nodesToKeep;
+    SMESH::IDSource_wrap tmpIdSource;
+    if ( myAction == MERGE_NODES )
+    {
+      nodesToKeep = new SMESH::ListOfIDSources();
+      int i, nb = KeepList->count();
+      if ( isKeepNodesIDsSelection() )
+      {
+        SMESH::long_array_var anIdList = new SMESH::long_array();
+        anIdList->length(nb);
+        for (i = 0; i < nb; i++)
+          anIdList[i] = KeepList->item(i)->text().toInt();
+
+        if ( nb > 0 )
+        {
+          tmpIdSource = aMeshEditor->MakeIDSource( anIdList, SMESH::NODE );
+          nodesToKeep->length( 1 );
+          nodesToKeep[0] = SMESH::SMESH_IDSource::_duplicate( tmpIdSource.in() );
+        }
+      }
+      else
+      {
+        nodesToKeep->length( nb );
+        int nbObj = 0;
+        for (i = 0; i < nb; i++)
+        {
+          QString entry = KeepList->item( i )->data( Qt::UserRole ).toString();
+          Handle(SALOME_InteractiveObject) anIO =
+            new SALOME_InteractiveObject( entry.toStdString().c_str(), "SMESH" );
+          SMESH::SMESH_IDSource_var idSrc =
+            SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( anIO );
+          if ( !idSrc->_is_nil() )
+            nodesToKeep[ nbObj++ ] = SMESH::SMESH_IDSource::_duplicate( idSrc );
+        }
+        nodesToKeep->length( nbObj );
+      }
+      KeepList->clear();
+    }
+
+    if( myAction == MERGE_NODES )
+      aMeshEditor->MergeNodes (aGroupsOfElements.inout(), nodesToKeep);
     else
       aMeshEditor->MergeElements (aGroupsOfElements.inout());
 
-    if ( myTypeId == 0 ) {
-      if (myAction == 0 )
+    if ( myTypeId == TYPE_AUTO ) {
+      if (myAction == MERGE_NODES )
         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()));
     }
-      
+    if ( & nodesToKeep.in() )
+      nodesToKeep->length(0); // release before tmpIdSource calls UnRegister()
 
-  } catch(...) {
   }
-  
+  catch(...) {
+  }
+
   ListCoincident->clear();
-  
+
   myEditCurrentArgument = (QWidget*)LineEditMesh;
 
   SMESH::UpdateView();
   SMESHGUI::Modified();
-  
+
   return true;
 }
 
@@ -721,6 +646,31 @@ void SMESHGUI_MergeDlg::reject()
   QDialog::reject();
 }
 
+//=================================================================================
+// function : onOpenView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_MergeDlg::onOpenView()
+{
+  if ( mySelector ) {
+    SMESH::SetPointRepresentation(false);
+  }
+  else {
+    mySelector = SMESH::GetViewWindow( mySMESHGUI )->GetSelector();
+    ActivateThisDialog();
+  }
+}
+
+//=================================================================================
+// function : onCloseView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_MergeDlg::onCloseView()
+{
+  DeactivateActiveDialog();
+  mySelector = 0;
+}
+
 //=================================================================================
 // function : ClickOnHelp()
 // purpose  :
@@ -775,9 +725,33 @@ void SMESHGUI_MergeDlg::updateControls()
 {
   if (ListEdit->count() == 0)
     SetFirstButton->setEnabled(false);
-  bool enable = !(myMesh->_is_nil()) && (ListCoincident->count() || (myTypeId == 0));
+
+  bool groupsEmpty = ( myTypeId != TYPE_AUTO );
+  for (int i = 0; i < ListCoincident->count() && groupsEmpty; i++) {
+    QStringList aListIds = ListCoincident->item(i)->text().split(" ", QString::SkipEmptyParts);
+    groupsEmpty = ( aListIds.count() < 2 );
+  }
+  bool enable = ( !myMesh->_is_nil() && !groupsEmpty );
   buttonOk->setEnabled(enable);
   buttonApply->setEnabled(enable);
+  DetectButton->setEnabled( !myMesh->_is_nil() );
+
+  if ( myAction == MERGE_NODES )
+  {
+    bool has2ndOrder = (( !myMesh->_is_nil() ) &&
+                        ( myMesh->NbEdgesOfOrder( SMESH::ORDER_QUADRATIC ) > 0 ||
+                          myMesh->NbFacesOfOrder( SMESH::ORDER_QUADRATIC ) > 0 ||
+                          myMesh->NbVolumesOfOrder( SMESH::ORDER_QUADRATIC ) > 0 ));
+
+    SeparateCornersAndMedium->setEnabled( has2ndOrder );
+
+    if ( myEditCurrentArgument != KeepList )
+    {
+      AddKeepNodesButton->setEnabled( false );
+      RemoveKeepNodesButton->setEnabled( false );
+      KeepList->clearSelection();
+    }
+  }
 }
 
 //=================================================================================
@@ -801,10 +775,10 @@ void SMESHGUI_MergeDlg::onDetect()
 
     SMESH::SMESH_IDSource_var src;
     if ( mySubMeshOrGroup->_is_nil() ) src = SMESH::SMESH_IDSource::_duplicate( myMesh );
-    else src = SMESH::SMESH_IDSource::_duplicate( mySubMeshOrGroup );
+    else                               src = SMESH::SMESH_IDSource::_duplicate( mySubMeshOrGroup );
 
     switch (myAction) {
-    case 0 :
+    case MERGE_NODES :
       for ( int i = 0; GroupExclude->isChecked() && i < ListExclude->count(); i++ ) {
         if ( ListExclude->item( i )->checkState() == Qt::Checked ) {
           aExcludeGroups->length( aExcludeGroups->length()+1 );
@@ -814,23 +788,25 @@ void SMESHGUI_MergeDlg::onDetect()
       aMeshEditor->FindCoincidentNodesOnPartBut(src.in(),
                                                 SpinBoxTolerance->GetValue(), 
                                                 aGroupsArray.out(),
-                                                aExcludeGroups.in());
+                                                aExcludeGroups.in(),
+                                                SeparateCornersAndMedium->isEnabled() &&
+                                                SeparateCornersAndMedium->isChecked());
       break;
-    case 1 :
+    case MERGE_ELEMENTS :
       aMeshEditor->FindEqualElements(src.in(), aGroupsArray.out());
       break;
     }
     
-    for (int i = 0; i < aGroupsArray->length(); i++) {
+    for (int i = 0; i < (int)aGroupsArray->length(); i++) {
       SMESH::long_array& aGroup = aGroupsArray[i];
 
       QStringList anIDs;
-      for (int j = 0; j < aGroup.length(); j++)
+      for (int j = 0; j < (int)aGroup.length(); j++)
         anIDs.append(QString::number(aGroup[j]));
 
       ListCoincident->addItem(anIDs.join(" "));
     }
-   } catch(...) {
+  } catch(...) {
   }
 
   ListCoincident->selectAll();
@@ -850,11 +826,22 @@ void SMESHGUI_MergeDlg::onSelectGroup()
   if( ListCoincident->count() != ListCoincident->selectedItems().count() )
     SelectAllCB->setChecked( false );
 
+  if ( myEditCurrentArgument == (QWidget*)KeepList && KeepList &&
+       !isKeepNodesIDsSelection() )
+  {
+    // restore selection of nodes after selection of sub-meshes
+    mySelectionMgr->clearFilters();
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+      aViewWindow->SetSelectionMode( NodeSelection );
+    SMESH::SetPointRepresentation( true );
+    myEditCurrentArgument = ListCoincident;
+  }
+
   myEditCurrentArgument = (QWidget*)ListCoincident;
 
   myIsBusy = true;
   ListEdit->clear();
-  
+
   TColStd_MapOfInteger anIndices;
   QList<QListWidgetItem*> selItems = ListCoincident->selectedItems();
   QListWidgetItem* anItem;
@@ -867,7 +854,7 @@ void SMESHGUI_MergeDlg::onSelectGroup()
     for (int i = 0; i < aListIds.count(); i++)
       anIndices.Add(aListIds[i].toInt());
   }
-  
+
   if (selItems.count() == 1) {
     ListEdit->addItems(aListIds);
     ListEdit->selectAll();
@@ -879,14 +866,15 @@ void SMESHGUI_MergeDlg::onSelectGroup()
   mySelectionMgr->setSelectedObjects(aList,false);
   
   if (ShowIDs->isChecked()) 
-    if (myAction == 0) {
+    if ( myAction == MERGE_NODES ) {
       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);
+      std::vector<int>    anIDs;
+      FindGravityCenter(anIndices, anIDs, aGrCentersXYZ);
+      myIdPreview->SetElemsData( anIDs, aGrCentersXYZ );
       myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility());
     }
   else
@@ -932,18 +920,30 @@ void SMESHGUI_MergeDlg::onSelectElementFromGroup()
   mySelectionMgr->setSelectedObjects(aList);
   
   if (ShowIDs->isChecked())
-    if (myAction == 0) {
+    if (myAction == MERGE_NODES) {
       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);
+      std::vector<int>    anIDs;
+      FindGravityCenter(anIndices, anIDs, aGrCentersXYZ);
+      myIdPreview->SetElemsData(anIDs, aGrCentersXYZ);
       myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility());
     }
   else 
     myIdPreview->SetPointsLabeled(false);
+
+  if ( myEditCurrentArgument == (QWidget*)KeepList && KeepList &&
+       !isKeepNodesIDsSelection() )
+  {
+    // restore selection of nodes after selection of sub-meshes
+    mySelectionMgr->clearFilters();
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+      aViewWindow->SetSelectionMode( NodeSelection );
+    SMESH::SetPointRepresentation( true );
+    myEditCurrentArgument = ListCoincident;
+  }
 }
 
 //=================================================================================
@@ -1101,14 +1101,33 @@ void SMESHGUI_MergeDlg::SetEditCurrentArgument()
   mySelectionMgr->clearSelected();
   mySelectionMgr->clearFilters();
 
-  if (send == SelectMeshButton) {
+  if (send == SelectMeshButton)
+  {
     myEditCurrentArgument = (QWidget*)LineEditMesh;
     SMESH::SetPointRepresentation(false);
     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
       aViewWindow->SetSelectionMode(ActorSelection);
-    if (myTypeId == 1)
+    if (myTypeId == TYPE_MANUAL)
       mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter);
   }
+  else if ( send == SelectKeepNodesButton && send )
+  {
+    myEditCurrentArgument = (QWidget*)KeepList;
+    KeepList->setWrapping( isKeepNodesIDsSelection() );
+    if ( isKeepNodesIDsSelection() )
+    {
+      SMESH::SetPointRepresentation( true );
+      if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+        aViewWindow->SetSelectionMode( NodeSelection );
+    }
+    else
+    {
+      SMESH::SetPointRepresentation( false );
+      if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+        aViewWindow->SetSelectionMode( ActorSelection );
+      mySelectionMgr->installFilter( mySubMeshOrGroupFilter );
+    }
+  }
 
   myEditCurrentArgument->setFocus();
   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
@@ -1117,19 +1136,21 @@ void SMESHGUI_MergeDlg::SetEditCurrentArgument()
 
 //=================================================================================
 // function : SelectionIntoArgument()
-// purpose  : Called when selection as changed or other case
+// purpose  : Called when selection has changed or other case
 //=================================================================================
 void SMESHGUI_MergeDlg::SelectionIntoArgument()
 {
-  if (myEditCurrentArgument == (QWidget*)LineEditMesh) {
+  if (myEditCurrentArgument == (QWidget*)LineEditMesh)
+  {
     QString aString = "";
     LineEditMesh->setText(aString);
-    
+
     ListCoincident->clear();
     ListEdit->clear();
     myActor = 0;
+    myMesh = SMESH::SMESH_Mesh::_nil();
     QString aCurrentEntry = myEntry;
-    
+
     int nbSel = SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aString);
     if (nbSel != 1) {
       myIdPreview->SetPointsLabeled(false);
@@ -1142,30 +1163,33 @@ void SMESHGUI_MergeDlg::SelectionIntoArgument()
 
     SALOME_ListIO aList;
     mySelectionMgr->selectedObjects(aList);
-    
+
     Handle(SALOME_InteractiveObject) IO = aList.First();
     myEntry = IO->getEntry();
     myMesh = SMESH::GetMeshByIO(IO);
-    
+
+    if ( myEntry != aCurrentEntry && KeepList )
+      KeepList->clear();
+
     if (myMesh->_is_nil())
       return;
 
     LineEditMesh->setText(aString);
-    
+
     myActor = SMESH::FindActorByEntry(IO->getEntry());
     if (!myActor)
       myActor = SMESH::FindActorByObject(myMesh);
-    
-    if ( myActor && myTypeId == 1 && mySelector->IsSelectionEnabled() ) {
+
+    if ( myActor && myTypeId == TYPE_MANUAL && mySelector->IsSelectionEnabled() ) {
       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) {
+
+      if (myAction == MERGE_NODES) {
         SMESH::SetPointRepresentation(true);
         if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
           aViewWindow->SetSelectionMode(NodeSelection);
@@ -1176,10 +1200,11 @@ void SMESHGUI_MergeDlg::SelectionIntoArgument()
     }
 
     // process groups
-    if ( myAction == 0 && !myMesh->_is_nil() && myEntry != aCurrentEntry ) {
+    if ( myAction == MERGE_NODES && !myMesh->_is_nil() && myEntry != aCurrentEntry ) {
       myGroups.clear();
       ListExclude->clear();
       SMESH::ListOfGroups_var aListOfGroups = myMesh->GetGroups();
+      GroupExclude->setEnabled( aListOfGroups->length() > 0 );
       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
@@ -1197,6 +1222,59 @@ void SMESHGUI_MergeDlg::SelectionIntoArgument()
 
     updateControls();
   }
+
+  else if (myEditCurrentArgument == (QWidget*)KeepList && KeepList)
+  {
+    AddKeepNodesButton->setEnabled( false );
+    RemoveKeepNodesButton->setEnabled( false );
+    if ( isKeepNodesIDsSelection() )
+    {
+      if (!myMesh->_is_nil() && !myActor)
+        myActor = SMESH::FindActorByObject(myMesh);
+
+      if ( mySelector && myActor )
+      {
+        KeepList->clearSelection();
+        QString anIDs = "";
+        int aNbNodes = SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), anIDs);
+        if (aNbNodes > 0)
+        {
+          QStringList anNodes = anIDs.split( " ", QString::SkipEmptyParts);
+          QList<QListWidgetItem*> listItemsToSel;
+          QListWidgetItem* anItem;
+          int nbFound = 0;
+          for (QStringList::iterator it = anNodes.begin(); it != anNodes.end(); ++it)
+          {
+            QList<QListWidgetItem*> found = KeepList->findItems(*it, Qt::MatchExactly);
+            foreach(anItem, found)
+              if (!anItem->isSelected())
+                listItemsToSel.push_back(anItem);
+            nbFound += found.count();
+          }
+          bool blocked = KeepList->signalsBlocked();
+          KeepList->blockSignals(true);
+          foreach(anItem, listItemsToSel) anItem->setSelected(true);
+          KeepList->blockSignals(blocked);
+          //onSelectKeepNode();
+          AddKeepNodesButton->setEnabled( nbFound < aNbNodes );
+          RemoveKeepNodesButton->setEnabled( nbFound > 0 );
+        }
+      }
+    }
+    else if ( !myMesh->_is_nil() )
+    {
+      SALOME_ListIO aList;
+      mySelectionMgr->selectedObjects(aList);
+      bool hasNewSelected = false;
+      SALOME_ListIteratorOfListIO anIt (aList);
+      for ( ; anIt.More() && !hasNewSelected; anIt.Next())
+        if ( anIt.Value()->hasEntry() )
+          hasNewSelected = isNewKeepNodesGroup( anIt.Value()->getEntry() );
+
+      AddKeepNodesButton->setEnabled( hasNewSelected );
+      //RemoveKeepNodesButton->setEnabled( KeepList->selectedItems().count() );
+    }
+  }
 }
 
 //=================================================================================
@@ -1205,13 +1283,17 @@ void SMESHGUI_MergeDlg::SelectionIntoArgument()
 //=================================================================================
 void SMESHGUI_MergeDlg::DeactivateActiveDialog()
 {
-  if (GroupConstructors->isEnabled()) {
-    GroupConstructors->setEnabled(false);
+  if (TypeBox->isEnabled()) {
     TypeBox->setEnabled(false);
     GroupMesh->setEnabled(false);
     GroupCoincident->setEnabled(false);
     GroupEdit->setEnabled(false);
     GroupButtons->setEnabled(false);
+    if (myAction == MERGE_NODES)
+    {
+      GroupExclude->setEnabled(false);
+      GroupKeep->setEnabled(false);
+    }
     mySMESHGUI->ResetState();
     mySMESHGUI->SetActiveDialogBox(0);
   }
@@ -1228,12 +1310,16 @@ 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);
+  if (myAction == MERGE_NODES)
+  {
+    GroupExclude->setEnabled(false);
+    GroupKeep->setEnabled(false);
+  }
 
   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
   mySMESHGUI->SetActiveDialogBox((QDialog*)this);
@@ -1244,10 +1330,15 @@ void SMESHGUI_MergeDlg::ActivateThisDialog()
 // function : enterEvent()
 // purpose  :
 //=================================================================================
-void SMESHGUI_MergeDlg::enterEvent(QEvent*)
+void SMESHGUI_MergeDlg::enterEvent (QEvent*)
 {
-  if (!GroupConstructors->isEnabled())
+  if ( !TypeBox->isEnabled() ) {
+    SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
+    if ( aViewWindow && !mySelector) {
+      mySelector = aViewWindow->GetSelector();
+    }
     ActivateThisDialog();
+  }
 }
 
 //=================================================================================
@@ -1278,20 +1369,22 @@ void SMESHGUI_MergeDlg::onTypeChanged (int id)
   myTypeId = id;
   switch (id)
   {
-  case 0: // automatic
+  case TYPE_AUTO: // 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();
+    GroupCoincident->hide();
     GroupEdit->hide();
+
+    GroupMesh->hide(); // <--- a trick to make the dialog take a minimal size
+    GroupMesh->show();
     break;
 
-  case 1: // manual
+  case TYPE_MANUAL: // manual
+
     SMESH::UpdateView();
 
     // Costruction of the logical filter
@@ -1303,29 +1396,193 @@ void SMESHGUI_MergeDlg::onTypeChanged (int id)
     if (aSmeshGroupFilter)    aListOfFilters.append(aSmeshGroupFilter);
     
     myMeshOrSubMeshOrGroupFilter =
-      new SMESH_LogicalFilter (aListOfFilters, SMESH_LogicalFilter::LO_OR);
+      new SMESH_LogicalFilter (aListOfFilters, SMESH_LogicalFilter::LO_OR, true);
 
-    if (myAction == 0) {
-      GroupCoincidentWidget->show();
+    if (myAction == MERGE_NODES) {
       SMESH::SetPointRepresentation(true);
       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
         if( mySelector->IsSelectionEnabled() )
           aViewWindow->SetSelectionMode(NodeSelection);
     }
     else {
-      GroupCoincident->show();
       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
         if( mySelector->IsSelectionEnabled() )
           aViewWindow->SetSelectionMode(CellSelection);
     }
+    GroupCoincident->show();
     GroupEdit->show();
     break;
   }
+  SelectionIntoArgument();
+
   updateControls();
 
   qApp->processEvents();
   updateGeometry();
   resize(10,10);
+}
 
-  SelectionIntoArgument();
+//=======================================================================
+//function : isKeepNodesIDsSelection
+//purpose  : Return true of Nodes to keep are selected by IDs
+//=======================================================================
+
+bool SMESHGUI_MergeDlg::isKeepNodesIDsSelection()
+{
+  return KeepFromButGroup && KeepFromButGroup->checkedId() == 0;
+}
+
+//=======================================================================
+//function : isNewKeepNodesGroup
+//purpose  : Return true if an object with given entry is NOT present in KeepList
+//=======================================================================
+
+bool SMESHGUI_MergeDlg::isNewKeepNodesGroup( const char* entry )
+{
+  if ( !entry || isKeepNodesIDsSelection() )
+    return false;
+
+  for ( int i = 0; i < KeepList->count(); i++ )
+    if ( KeepList->item( i )->data( Qt::UserRole ).toString() == entry )
+      return false;
+
+  return true;
+}
+
+//=======================================================================
+//function : onAddKeepNode
+//purpose  : SLOT called when [Add] of Nodes To Keep group is pressed
+//=======================================================================
+
+void SMESHGUI_MergeDlg::onAddKeepNode()
+{
+  if ( myIsBusy )
+    return;
+  myIsBusy = true;
+
+  if ( isKeepNodesIDsSelection() )
+  {
+    //KeepList->clearSelection();
+    QString anIDs = "";
+    int aNbNodes = 0;
+    if ( myActor )
+      aNbNodes = SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), anIDs);
+    if (aNbNodes > 0)
+    {
+      QStringList anNodes = anIDs.split( " ", QString::SkipEmptyParts);
+      QList<QListWidgetItem*> listItemsToSel;
+      QListWidgetItem* anItem;
+      for (QStringList::iterator it = anNodes.begin(); it != anNodes.end(); ++it)
+      {
+        QList<QListWidgetItem*> found = KeepList->findItems(*it, Qt::MatchExactly);
+        if (found.count() == 0) {
+          anItem = new QListWidgetItem(*it);
+          KeepList->addItem(anItem);
+          if (!anItem->isSelected())
+            listItemsToSel.push_back(anItem);
+        }
+        else {
+          foreach(anItem, found)
+            if (!anItem->isSelected())
+              listItemsToSel.push_back(anItem);
+        }
+      }
+      bool blocked = KeepList->signalsBlocked();
+      KeepList->blockSignals(true);
+      foreach(anItem, listItemsToSel) anItem->setSelected(true);
+      KeepList->blockSignals(blocked);
+      //onSelectKeepNode();
+    }
+    RemoveKeepNodesButton->setEnabled( aNbNodes > 0 );
+  }
+  else
+  {
+    SALOME_ListIO aList;
+    mySelectionMgr->selectedObjects(aList);
+    SALOME_ListIteratorOfListIO anIt (aList);
+    for ( ; anIt.More(); anIt.Next()) {
+      Handle(SALOME_InteractiveObject) anIO = anIt.Value();
+      if ( isNewKeepNodesGroup( anIO->getEntry() ))
+      {
+        QListWidgetItem* anItem = new QListWidgetItem( anIO->getName() );
+        anItem->setData( Qt::UserRole, QString( anIO->getEntry() ));
+        KeepList->addItem(anItem);
+      }
+    }
+    //RemoveKeepNodesButton->setEnabled( KeepList->selectedItems().count() );
+  }
+
+  AddKeepNodesButton->setEnabled( false );
+
+  myIsBusy = false;
+}
+
+//=======================================================================
+//function : onRemoveKeepNode
+//purpose  : SLOT called when [Remove] of Nodes To Keep group is pressed
+//=======================================================================
+
+void SMESHGUI_MergeDlg::onRemoveKeepNode()
+{
+  // if ( isKeepNodesIDsSelection() )
+  // {
+  // }
+  // else
+  {
+    QList<QListWidgetItem*> selItems = KeepList->selectedItems();
+    QListWidgetItem* item;
+    foreach(item, selItems) delete item;
+  }
+  if ( isKeepNodesIDsSelection() )
+  {
+    AddKeepNodesButton->setEnabled( false );
+  }
+  RemoveKeepNodesButton->setEnabled( false );
+}
+
+//=======================================================================
+//function : onSelectKeepNode
+//purpose  : SLOT called when selection in KeepList changes
+//=======================================================================
+
+void SMESHGUI_MergeDlg::onSelectKeepNode()
+{
+  if ( myIsBusy || !isEnabled() ) return;
+  myIsBusy = true;
+
+  if ( isKeepNodesIDsSelection() )
+  {
+    if ( myActor )
+    {
+      mySelectionMgr->clearSelected();
+      TColStd_MapOfInteger aIndexes;
+      QList<QListWidgetItem*> selItems = KeepList->selectedItems();
+      QListWidgetItem* anItem;
+      foreach(anItem, selItems) aIndexes.Add(anItem->text().toInt());
+      mySelector->AddOrRemoveIndex(myActor->getIO(), aIndexes, false);
+      SALOME_ListIO aList;
+      aList.Append(myActor->getIO());
+      mySelectionMgr->setSelectedObjects(aList,false);
+
+      AddKeepNodesButton->setEnabled( false );
+      RemoveKeepNodesButton->setEnabled( aIndexes.Extent() > 0 );
+    }
+  }
+  else
+  {
+    RemoveKeepNodesButton->setEnabled( KeepList->selectedItems().count() );
+  }
+  myIsBusy = false;
+}
+
+//=======================================================================
+//function : onKeepNodeSourceChanged
+//purpose  : SLOT called when type of source of Nodes To Keep change from
+//           IDs to groups or vice versa
+//=======================================================================
+
+void SMESHGUI_MergeDlg::onKeepNodeSourceChanged(int isGroup)
+{
+  KeepList->clear();
+  SelectKeepNodesButton->click();
 }
index fed3a1865c3557d6f1ec50ea4e5e0c7f2f8e0b10..86595b82a1295d217d3c22220855feaff6966215 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 
 // STL includes
 #include <list>
+#include <vector>
 
 // IDL includes
 #include <SALOMEconfig.h>
 #include CORBA_SERVER_HEADER(SMESH_Mesh)
 
+class LightApp_SelectionMgr;
+class QButtonGroup;
+class QCheckBox;
 class QGroupBox;
 class QLabel;
 class QLineEdit;
+class QListWidget;
 class QPushButton;
 class QRadioButton;
-class QCheckBox;
-class QListWidget;
-class QButtonGroup;
 class SMESHGUI;
+class SMESHGUI_IdPreview;
 class SMESHGUI_SpinBox;
 class SMESH_Actor;
-class SVTK_Selector;
-class LightApp_SelectionMgr;
 class SUIT_SelectionFilter;
+class SVTK_Selector;
 class TColStd_MapOfInteger;
 
 namespace SMESH
@@ -76,13 +78,18 @@ public:
   SMESHGUI_MergeDlg( SMESHGUI*, int );
   ~SMESHGUI_MergeDlg();
 
+  static QPixmap IconFirst();
+
 private:
   void                      Init();
   void                      enterEvent( QEvent* );              /* mouse enter the QWidget */
   void                      keyPressEvent( QKeyEvent* );
   void                      onEditGroup();
+  bool                      isKeepNodesIDsSelection();
+  bool                      isNewKeepNodesGroup( const char* entry );
 
-  void                      FindGravityCenter( TColStd_MapOfInteger&, 
+  void                      FindGravityCenter( TColStd_MapOfInteger&,
+                                               std::vector<int>& , 
                                                std::list<gp_XYZ>& );
   // add the centers of gravity of ElemsIdMap elements to the GrCentersXYZ list
 
@@ -99,16 +106,15 @@ private:
   SMESH::SMESH_IDSource_var mySubMeshOrGroup;
   SMESH_Actor*              myActor;
   SUIT_SelectionFilter*     myMeshOrSubMeshOrGroupFilter;
+  SUIT_SelectionFilter*     mySubMeshOrGroupFilter;
 
-  SMESH::TIdPreview*        myIdPreview;
+  SMESHGUI_IdPreview*       myIdPreview;
 
   int                       myAction;
   bool                      myIsBusy;
-  int                       myTypeId;
+  int                       myTypeId; // manual(1) or automatic(0)
 
   // Widgets
-  QGroupBox*                GroupConstructors;
-  QRadioButton*             RadioButton;
 
   QGroupBox*                GroupButtons;
   QPushButton*              buttonOk;
@@ -121,10 +127,12 @@ private:
   QPushButton*              SelectMeshButton;
   QLineEdit*                LineEditMesh;
 
-  QGroupBox*                GroupCoincident;
-  QWidget*                  GroupCoincidentWidget;
-  QLabel*                   TextLabelTolerance;
+  QWidget*                  NodeSpecWidget;
   SMESHGUI_SpinBox*         SpinBoxTolerance;
+  QCheckBox*                SeparateCornersAndMedium;
+
+  QGroupBox*                GroupCoincident;
+  //QWidget*                  GroupCoincidentWidget;
   QPushButton*              DetectButton;
   QListWidget*              ListCoincident;
   QPushButton*              AddGroupButton;
@@ -141,6 +149,13 @@ private:
   QGroupBox*                GroupExclude;
   QListWidget*              ListExclude;
 
+  QGroupBox*                GroupKeep;
+  QButtonGroup*             KeepFromButGroup;
+  QPushButton*              SelectKeepNodesButton;
+  QPushButton*              AddKeepNodesButton;
+  QPushButton*              RemoveKeepNodesButton;
+  QListWidget*              KeepList;
+
   QGroupBox*                TypeBox;
   QButtonGroup*             GroupType;
     
@@ -158,6 +173,10 @@ protected slots:
   void                      ClickOnHelp();
   void                      updateControls();
   void                      onDetect();
+  void                      onAddKeepNode();
+  void                      onRemoveKeepNode();
+  void                      onSelectKeepNode();
+  void                      onKeepNodeSourceChanged(int);
   void                      onAddGroup();
   void                      onRemoveGroup();
   void                      onSelectGroup();
@@ -171,6 +190,8 @@ protected slots:
   void                      DeactivateActiveDialog();
   void                      ActivateThisDialog();
   void                      onTypeChanged(int);
+  void                      onOpenView();
+  void                      onCloseView();
 };
 
 #endif // SMESHGUI_MergeDlg_H
index a381acde05148beca0aabdb3259b4ac85151d585..4973a5d1ebe264ae5894f53b262e7bed94c6ee21 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index f8d8b108e1d7db746ade6e4717979c321953389d..67923e3b032bc53f49f745983dfb4f41fd5045b2 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 7f8b060c8dc934368925c38cac90ddda89c4424a..50fe4e59246f8db15af2859fbdb98c499f001f34 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -173,7 +173,7 @@ void SMESHGUI_MeshEditPreview::SetData (const SMESH::MeshPreviewStruct* previewD
   vtkPoints* aPoints = vtkPoints::New();
   aPoints->SetNumberOfPoints(aNodesXYZ.length());
 
-  for ( int i = 0; i < aNodesXYZ.length(); i++ ) {
+  for ( size_t i = 0; i < aNodesXYZ.length(); i++ ) {
     aPoints->SetPoint( i, aNodesXYZ[i].x, aNodesXYZ[i].y, aNodesXYZ[i].z );
   }
   myGrid->SetPoints(aPoints);
@@ -197,7 +197,7 @@ void SMESHGUI_MeshEditPreview::SetData (const SMESH::MeshPreviewStruct* previewD
   vtkIdList *anIdList = vtkIdList::New();
   int aNodePos = 0;
 
-  for ( int i = 0; i < anElemTypes.length(); i++ ) {
+  for ( size_t i = 0; i < anElemTypes.length(); i++ ) {
     const SMESH::ElementSubType& anElementSubType = anElemTypes[i];
     SMDSAbs_ElementType aType = SMDSAbs_ElementType(anElementSubType.SMDS_ElementType);
     vtkIdType aNbNodes = anElementSubType.nbNodesInElement;
@@ -299,7 +299,7 @@ void SMESHGUI_MeshEditPreview::SetArrowShapeAndNb( int         nbArrows,
   myLabelActors.resize( nbArrows, ( vtkTextActor*) NULL );
   char label[] = "X";
   if ( labels )
-    for ( int iP = 0, iA = 0; iA < nbArrows; ++iA )
+    for ( int iA = 0; iA < nbArrows; ++iA )
     {
       label[0] = labels[iA];
       vtkTextMapper* text = vtkTextMapper::New();
@@ -333,7 +333,7 @@ void SMESHGUI_MeshEditPreview::SetArrows( const gp_Ax1* axes,
 {
   vtkPoints* aPoints = myGrid->GetPoints();
 
-  for ( int iP = 0, iA = 0; iA < myLabelActors.size(); ++iA )
+  for ( int iP = 0, iA = 0; iA < (int) myLabelActors.size(); ++iA )
   {
     gp_Trsf trsf;
     trsf.SetTransformation( gp_Ax3( axes[iA].Location(), axes[iA].Direction() ), gp::XOY() );
index 7eaff287ad4e8ae18445fee88ebf1f3fce7742c6..a506a371800e07f079d93872067cb06802ee49b3 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index e91afa388e3d91e894bc3caf141d2a711369106e..7957b4fddef4eb9555e35f9246fb40f59ad5b336 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -231,9 +231,11 @@ SMESHGUI_MeshInfo::SMESHGUI_MeshInfo( QWidget* parent )
   // object
   QLabel* aNameLab     = new QLabel( tr( "NAME_LAB" ), this );
   QLabel* aName        = createField();
+  aName->setObjectName("meshName");
   aName->setMinimumWidth( 150 );
   QLabel* aObjLab      = new QLabel( tr( "OBJECT_LAB" ), this );
   QLabel* aObj         = createField();
+  aObj->setObjectName("meshType");
   aObj->setMinimumWidth( 150 );
   myWidgets[ index++ ] << aNameLab << aName;
   myWidgets[ index++ ] << aObjLab  << aObj;
@@ -242,6 +244,7 @@ SMESHGUI_MeshInfo::SMESHGUI_MeshInfo( QWidget* parent )
   QWidget* aNodesLine  = createLine();
   QLabel*  aNodesLab   = new QLabel( tr( "NODES_LAB" ), this );
   QLabel*  aNodes      = createField();
+  aNodes->setObjectName("nbNodes");
   myWidgets[ index++ ] << aNodesLine;
   myWidgets[ index++ ] << aNodesLab << aNodes;
 
@@ -258,9 +261,13 @@ SMESHGUI_MeshInfo::SMESHGUI_MeshInfo( QWidget* parent )
   // ... Number elements
   QWidget* aNbLine     = createLine(); 
   QLabel*  aNbTotal    = createField();
+  aNbTotal->setObjectName("totalNbElems");
   QLabel*  aNbLin      = createField();
+  aNbLin->setObjectName("totalNbLinearElems");
   QLabel*  aNbQuad     = createField();
+  aNbQuad->setObjectName("totalNbQuadraticElems");
   QLabel*  aNbBiQuad   = createField();
+  aNbBiQuad->setObjectName("totalNbBiQuadraticElems");
   myWidgets[ index++ ] << aNbLine;
   myWidgets[ index++ ] << new QLabel( "", this ) << aNbTotal << aNbLin << aNbQuad << aNbBiQuad;
 
@@ -268,6 +275,8 @@ SMESHGUI_MeshInfo::SMESHGUI_MeshInfo( QWidget* parent )
   QWidget* a0DLine     = createLine();
   QLabel*  a0DLab      = new QLabel( tr( "0D_LAB" ), this );
   QLabel*  a0DTotal    = createField();
+  a0DTotal->setObjectName("nb0D");
+
   myWidgets[ index++ ] << a0DLine;
   myWidgets[ index++ ] << a0DLab << a0DTotal;
 
@@ -275,6 +284,7 @@ SMESHGUI_MeshInfo::SMESHGUI_MeshInfo( QWidget* parent )
   QWidget* aBallLine     = createLine();
   QLabel*  aBallLab      = new QLabel( tr( "BALL_LAB" ), this );
   QLabel*  aBallTotal    = createField();
+  aBallTotal->setObjectName("nbBall");
   myWidgets[ index++ ] << aBallLine;
   myWidgets[ index++ ] << aBallLab << aBallTotal;
 
@@ -282,8 +292,11 @@ SMESHGUI_MeshInfo::SMESHGUI_MeshInfo( QWidget* parent )
   QWidget* a1DLine     = createLine();
   QLabel*  a1DLab      = new QLabel( tr( "1D_LAB" ), this );
   QLabel*  a1DTotal    = createField();
+  a1DTotal->setObjectName("nb1D");
   QLabel*  a1DLin      = createField();
+  a1DLin->setObjectName("nbLinear1D");
   QLabel*  a1DQuad     = createField();
+  a1DQuad->setObjectName("nbQuadratic1D");
   myWidgets[ index++ ] << a1DLine;
   myWidgets[ index++ ] << a1DLab << a1DTotal << a1DLin << a1DQuad;
 
@@ -291,55 +304,91 @@ SMESHGUI_MeshInfo::SMESHGUI_MeshInfo( QWidget* parent )
   QWidget* a2DLine      = createLine();
   QLabel*  a2DLab       = new QLabel( tr( "2D_LAB" ), this );
   QLabel*  a2DTotal     = createField();
+  a2DTotal->setObjectName("nb2D");
   QLabel*  a2DLin       = createField();
+  a2DLin->setObjectName("nbLinear2D");
   QLabel*  a2DQuad      = createField();
+  a2DQuad->setObjectName("nbQuadratic2D");
   QLabel*  a2DBiQuad    = createField();
+  a2DBiQuad->setObjectName("nbBiQuadratic2D");
   QLabel*  a2DTriLab    = new QLabel( tr( "TRIANGLES_LAB" ), this );
   QLabel*  a2DTriTotal  = createField();
+  a2DTriTotal->setObjectName("nbTriangle");
   QLabel*  a2DTriLin    = createField();
+  a2DTriLin->setObjectName("nbLinearTriangle");
   QLabel*  a2DTriQuad   = createField();
+  a2DTriQuad->setObjectName("nbQuadraticTriangle");
   QLabel*  a2DTriBiQuad = createField();
+    a2DTriBiQuad->setObjectName("nbBiQuadraticTriangle");
   QLabel*  a2DQuaLab    = new QLabel( tr( "QUADRANGLES_LAB" ), this );
   QLabel*  a2DQuaTotal  = createField();
+  a2DQuaTotal->setObjectName("nbQuadrangle");
   QLabel*  a2DQuaLin    = createField();
+  a2DQuaLin->setObjectName("nbLinearQuadrangle");
   QLabel*  a2DQuaQuad   = createField();
+  a2DQuaQuad->setObjectName("nbQuadraticQuadrangle");
   QLabel*  a2DQuaBiQuad = createField();
+  a2DQuaBiQuad->setObjectName("nbBiQuadraticQuadrangle");
   QLabel*  a2DPolLab    = new QLabel( tr( "POLYGONS_LAB" ), this );
   QLabel*  a2DPolTotal  = createField();
+  a2DPolTotal->setObjectName("nbPolygon");
+  QLabel*  a2DPolLin    = createField();
+  a2DPolLin->setObjectName("nbLinearPolygon");
+  QLabel*  a2DPolQuad   = createField();
+  a2DPolQuad->setObjectName("nbQuadraticPolygon");
   myWidgets[ index++ ] << a2DLine;
   myWidgets[ index++ ] << a2DLab    << a2DTotal    << a2DLin    << a2DQuad    << a2DBiQuad;
   myWidgets[ index++ ] << a2DTriLab << a2DTriTotal << a2DTriLin << a2DTriQuad << a2DTriBiQuad;
   myWidgets[ index++ ] << a2DQuaLab << a2DQuaTotal << a2DQuaLin << a2DQuaQuad << a2DQuaBiQuad;
-  myWidgets[ index++ ] << a2DPolLab << a2DPolTotal;
+  myWidgets[ index++ ] << a2DPolLab << a2DPolTotal << a2DPolLin << a2DPolQuad;
 
   // ... 3D elements
   QWidget* a3DLine      = createLine();
   QLabel*  a3DLab       = new QLabel( tr( "3D_LAB" ), this );
   QLabel*  a3DTotal     = createField();
+  a3DTotal->setObjectName("nb3D");
   QLabel*  a3DLin       = createField();
+  a3DLin->setObjectName("nbLinear3D");
   QLabel*  a3DQuad      = createField();
+  a3DQuad->setObjectName("nbQuadratic3D");
   QLabel*  a3DBiQuad    = createField();
+  a3DBiQuad->setObjectName("nbBiQuadratic3D");
   QLabel*  a3DTetLab    = new QLabel( tr( "TETRAHEDRONS_LAB" ), this );
   QLabel*  a3DTetTotal  = createField();
+  a3DTetTotal->setObjectName("nbTetrahedron");
   QLabel*  a3DTetLin    = createField();
+  a3DTetLin->setObjectName("nbLinearTetrahedron");
   QLabel*  a3DTetQuad   = createField();
+  a3DTetQuad->setObjectName("nbQudraticTetrahedron");
   QLabel*  a3DHexLab    = new QLabel( tr( "HEXAHEDONRS_LAB" ), this );
   QLabel*  a3DHexTotal  = createField();
+  a3DHexTotal->setObjectName("nbHexahedron");
   QLabel*  a3DHexLin    = createField();
+  a3DHexLin->setObjectName("nbLinearHexahedron");
   QLabel*  a3DHexQuad   = createField();
+  a3DHexQuad->setObjectName("nbQuadraticHexahedron");
   QLabel*  a3DHexBiQuad = createField();
+  a3DHexBiQuad->setObjectName("nbBiQuadraticHexahedron");
   QLabel*  a3DPyrLab    = new QLabel( tr( "PYRAMIDS_LAB" ), this );
   QLabel*  a3DPyrTotal  = createField();
+  a3DPyrTotal->setObjectName("nbPyramid");
   QLabel*  a3DPyrLin    = createField();
+  a3DPyrLin->setObjectName("nbLinearPyramid");
   QLabel*  a3DPyrQuad   = createField();
+  a3DPyrQuad->setObjectName("nbQuadraticPyramid");
   QLabel*  a3DPriLab    = new QLabel( tr( "PRISMS_LAB" ), this );
   QLabel*  a3DPriTotal  = createField();
+  a3DPriTotal->setObjectName("nbPrism");
   QLabel*  a3DPriLin    = createField();
+  a3DPriLin->setObjectName("nbLinearPrism");
   QLabel*  a3DPriQuad   = createField();
+  a3DPriQuad->setObjectName("nbQuadraticPrism");
   QLabel*  a3DHexPriLab   = new QLabel( tr( "HEX_PRISMS_LAB" ), this );
   QLabel*  a3DHexPriTotal = createField();
+  a3DHexPriTotal->setObjectName("nbHexagonalPrism");
   QLabel*  a3DPolLab    = new QLabel( tr( "POLYHEDRONS_LAB" ), this );
   QLabel*  a3DPolTotal  = createField();
+  a3DPolTotal->setObjectName("nbPolyhedron");
   myWidgets[ index++ ] << a3DLine;
   myWidgets[ index++ ] << a3DLab    << a3DTotal    << a3DLin    << a3DQuad    << a3DBiQuad;
   myWidgets[ index++ ] << a3DTetLab << a3DTetTotal << a3DTetLin << a3DTetQuad;
@@ -414,6 +463,8 @@ SMESHGUI_MeshInfo::SMESHGUI_MeshInfo( QWidget* parent )
   l->addWidget( a2DQuaBiQuad, 17, 4 );
   l->addWidget( a2DPolLab,    18, 0 );
   l->addWidget( a2DPolTotal,  18, 1 );
+  l->addWidget( a2DPolLin,    18, 2 );
+  l->addWidget( a2DPolQuad,   18, 3 );
   l->addWidget( a3DLine,      19, 1, 1, 4 );
   l->addWidget( a3DLab,       20, 0 );
   l->addWidget( a3DTotal,     20, 1 );
@@ -503,8 +554,9 @@ void SMESHGUI_MeshInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
     myWidgets[i1D][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Edge] ) );
     long nbTriangles     = info[SMDSEntity_Triangle]   + info[SMDSEntity_Quad_Triangle]   + info[SMDSEntity_BiQuad_Triangle];
     long nbQuadrangles   = info[SMDSEntity_Quadrangle] + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_BiQuad_Quadrangle];
+    long nb2DPolygons    = info[SMDSEntity_Polygon]    + info[SMDSEntity_Quad_Polygon];
     long nb2DLinear      = info[SMDSEntity_Triangle]        + info[SMDSEntity_Quadrangle] + info[SMDSEntity_Polygon];
-    long nb2DQuadratic   = info[SMDSEntity_Quad_Triangle]   + info[SMDSEntity_Quad_Quadrangle];
+    long nb2DQuadratic   = info[SMDSEntity_Quad_Triangle]   + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_Quad_Polygon];
     long nb2DBiQuadratic = info[SMDSEntity_BiQuad_Triangle] + info[SMDSEntity_BiQuad_Quadrangle];
     long nb2DTotal       = nb2DLinear + nb2DQuadratic + nb2DBiQuadratic;
 
@@ -520,7 +572,9 @@ void SMESHGUI_MeshInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
     myWidgets[i2DQuadrangles][iLinear]      ->setProperty( "text", QString::number( info[SMDSEntity_Quadrangle] ) );
     myWidgets[i2DQuadrangles][iQuadratic]   ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Quadrangle] ) );
     myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_BiQuad_Quadrangle] ) );
-    myWidgets[i2DPolygons][iTotal]          ->setProperty( "text", QString::number( info[SMDSEntity_Polygon] ) );
+    myWidgets[i2DPolygons][iTotal]          ->setProperty( "text", QString::number( nb2DPolygons ));
+    myWidgets[i2DPolygons][iLinear]         ->setProperty( "text", QString::number( info[SMDSEntity_Polygon] ) );
+    myWidgets[i2DPolygons][iQuadratic]      ->setProperty( "text", QString::number( info[SMDSEntity_Quad_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];
@@ -583,6 +637,8 @@ void SMESHGUI_MeshInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
           myWidgets[i2DQuadrangles][iLinear]      ->setProperty( "text", "?" );
           myWidgets[i2DQuadrangles][iQuadratic]   ->setProperty( "text", "?" );
           myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", "?" );
+          myWidgets[i2DPolygons][iLinear]         ->setProperty( "text", "?" );
+          myWidgets[i2DPolygons][iQuadratic]      ->setProperty( "text", "?" );
           myWidgets[i2DPolygons][iTotal]          ->setProperty( "text", "?" );
           myWidgets[iNb][iTotal]                  ->setProperty( "text", "?" );
           myWidgets[iNb][iLinear]                 ->setProperty( "text", "?" );
@@ -712,6 +768,8 @@ void SMESHGUI_MeshInfo::clear()
   myWidgets[i2DQuadrangles][iLinear]      ->setProperty( "text", QString::number( 0 ) );
   myWidgets[i2DQuadrangles][iQuadratic]   ->setProperty( "text", QString::number( 0 ) );
   myWidgets[i2DQuadrangles][iBiQuadratic] ->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i2DPolygons][iLinear]         ->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i2DPolygons][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 ) );
@@ -836,6 +894,8 @@ void SMESHGUI_MeshInfo::saveInfo( QTextStream &out )
   out << QString( SPACING_INFO*3, ' ' ) << tr( "BI_QUADRATIC_LAB" ) << ": " << ( myWidgets[i2DQuadrangles][iBiQuadratic]->property( "text" ) ).toString() << "\n";
   out << QString( SPACING_INFO*2, ' ' ) << tr( "POLYGONS_LAB" )     << "\n";
   out << QString( SPACING_INFO*3, ' ' ) << tr( "TOTAL_LAB" )        << ": " << ( myWidgets[i2DPolygons][iTotal]->property( "text" ) ).toString() << "\n";
+  out << QString( SPACING_INFO*3, ' ' ) << tr( "LINEAR_LAB" )       << ": " << ( myWidgets[i2DPolygons][iLinear]->property( "text" ) ).toString() << "\n";
+  out << QString( SPACING_INFO*3, ' ' ) << tr( "QUADRATIC_LAB" )    << ": " << ( myWidgets[i2DPolygons][iQuadratic]->property( "text" ) ).toString() << "\n";
   out << QString( SPACING_INFO,   ' ' ) << tr( "3D_LAB" )           << "\n";
   out << QString( SPACING_INFO*2, ' ' ) << tr( "TOTAL_LAB" )        << ": " << ( myWidgets[i3D][iTotal]->property( "text" ) ).toString() << "\n";
   out << QString( SPACING_INFO*2, ' ' ) << tr( "LINEAR_LAB" )       << ": " << ( myWidgets[i3D][iLinear]->property( "text" ) ).toString() << "\n";
@@ -1046,6 +1106,16 @@ SMESHGUI_ElemInfo::XYZ SMESHGUI_ElemInfo::gravityCenter( const SMDS_MeshElement*
   return xyz;
 }
 
+/*!
+  \brief Calculate normal vector to the mesh face
+  \param element mesh face
+*/
+SMESHGUI_ElemInfo::XYZ SMESHGUI_ElemInfo::normal( const SMDS_MeshElement* element )
+{
+  gp_XYZ n = SMESH::getNormale( dynamic_cast<const SMDS_MeshFace*>( element ) );
+  return XYZ(n.X(), n.Y(), n.Z());
+}
+
 /*!
   \brief This slot is called from "Show Previous" button click.
   Shows information on the previous group of the items.
@@ -1198,7 +1268,7 @@ void SMESHGUI_SimpleElemInfo::information( const QList<long>& ids )
           SMESH::ListOfGroups_var groups = aMesh->GetGroups();
           myInfo->append( "" ); // separator
           bool top_created = false;
-          for ( int i = 0; i < groups->length(); i++ ) {
+          for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
             SMESH::SMESH_GroupBase_var aGrp = groups[i];
             if ( CORBA::is_nil( aGrp ) ) continue;
             QString aName = aGrp->GetName();
@@ -1423,6 +1493,12 @@ void SMESHGUI_SimpleElemInfo::information( const QList<long>& ids )
         // Gravity center
         XYZ gc = gravityCenter( e );
         myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "GRAVITY_CENTER" ) ).arg( gc.x() ).arg( gc.y() ).arg( gc.z() ) );
+        
+        // Normal vector
+        if( e->GetType() == SMDSAbs_Face ) {
+          XYZ gc = normal( e );
+          myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( SMESHGUI_ElemInfo::tr( "NORMAL_VECTOR" ) ).arg( gc.x() ).arg( gc.y() ).arg( gc.z() ) );
+        }
 
         // Element position
         if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) {
@@ -1452,7 +1528,7 @@ void SMESHGUI_SimpleElemInfo::information( const QList<long>& ids )
           SMESH::ListOfGroups_var  groups = aMesh->GetGroups();
           myInfo->append( "" ); // separator
           bool top_created = false;
-          for ( int i = 0; i < groups->length(); i++ ) {
+          for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
             SMESH::SMESH_GroupBase_var aGrp = groups[i];
             if ( CORBA::is_nil( aGrp ) ) continue;
             QString aName = aGrp->GetName();
@@ -1712,7 +1788,7 @@ void SMESHGUI_TreeElemInfo::information( const QList<long>& ids )
         if ( !CORBA::is_nil( aMesh ) ) {
           SMESH::ListOfGroups_var groups = aMesh->GetGroups();
           QTreeWidgetItem* groupsItem = 0;
-          for ( int i = 0; i < groups->length(); i++ ) {
+          for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
             SMESH::SMESH_GroupBase_var aGrp = groups[i];
             if ( CORBA::is_nil( aGrp ) ) continue;
             QString aName = aGrp->GetName();
@@ -1967,6 +2043,23 @@ void SMESHGUI_TreeElemInfo::information( const QList<long>& ids )
         QTreeWidgetItem* zItem = createItem( gcItem );
         zItem->setText( 0, "Z" );
         zItem->setText( 1, QString::number( gc.z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+
+        // normal vector
+        if( e->GetType() == SMDSAbs_Face ) {
+          XYZ gc = normal( e );
+          QTreeWidgetItem* nItem = createItem( elemItem, Bold );
+          nItem->setText( 0, SMESHGUI_ElemInfo::tr( "NORMAL_VECTOR" ) );
+          QTreeWidgetItem* xItem = createItem( nItem );
+          xItem->setText( 0, "X" );
+          xItem->setText( 1, QString::number( gc.x(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+          QTreeWidgetItem* yItem = createItem( nItem );
+          yItem->setText( 0, "Y" );
+          yItem->setText( 1, QString::number( gc.y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+          QTreeWidgetItem* zItem = createItem( nItem );
+          zItem->setText( 0, "Z" );
+          zItem->setText( 1, QString::number( gc.z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+        }
+
         // element position
         SMESH::SMESH_Mesh_ptr aMesh = actor()->GetObject()->GetMeshServer();
         if ( e->GetType() >= SMDSAbs_Edge && e->GetType() <= SMDSAbs_Volume ) {
@@ -1993,7 +2086,7 @@ void SMESHGUI_TreeElemInfo::information( const QList<long>& ids )
         if ( !CORBA::is_nil( aMesh ) ) {
           SMESH::ListOfGroups_var  groups = aMesh->GetGroups();
           QTreeWidgetItem* groupsItem = 0;
-          for ( int i = 0; i < groups->length(); i++ ) {
+          for ( CORBA::ULong i = 0; i < groups->length(); i++ ) {
             SMESH::SMESH_GroupBase_var aGrp = groups[i];
             if ( CORBA::is_nil( aGrp ) ) continue;
             QString aName = aGrp->GetName();
@@ -2212,8 +2305,11 @@ void SMESHGUI_TreeElemInfo::saveInfo( QTextStream &out )
 /*!
   \brief Contructor
 */
-GrpComputor::GrpComputor( SMESH::SMESH_GroupBase_ptr grp, QTreeWidgetItem* item, QObject* parent )
-  : QObject( parent ), myItem( item )
+GrpComputor::GrpComputor( SMESH::SMESH_GroupBase_ptr grp,
+                          QTreeWidgetItem*           item,
+                          QObject*                   parent,
+                          bool                       toComputeSize)
+  : QObject( parent ), myItem( item ), myToComputeSize( toComputeSize )
 {
   myGroup = SMESH::SMESH_GroupBase::_narrow( grp );
 }
@@ -2226,9 +2322,9 @@ void GrpComputor::compute()
   if ( !CORBA::is_nil( myGroup ) && myItem ) {
     QTreeWidgetItem* item = myItem;
     myItem = 0;
-    int nbNodes = myGroup->GetNumberOfNodes();
+    int nb = myToComputeSize ? myGroup->Size() : myGroup->GetNumberOfNodes();
     item->treeWidget()->removeItemWidget( item, 1 );
-    item->setText( 1, QString::number( nbNodes ));
+    item->setText( 1, QString::number( nb ));
   }
 }
 
@@ -2460,10 +2556,28 @@ void SMESHGUI_AddInfo::groupInfo( SMESH::SMESH_GroupBase_ptr grp, QTreeWidgetIte
     etypeItem->setText( 1, etype );
   }
 
-  // size
+  SMESH::SMESH_Mesh_var mesh = grp->GetMesh();
+  bool            meshLoaded = mesh->IsLoaded();
+
+  // size. Don't call grp->Size() for GroupOnFilter - issue IPAL52831
+  int groupSize = -1;
+  if ( grp->IsNodeInfoAvailable() || CORBA::is_nil( aFltGroup ))
+    groupSize = grp->Size();
+
   QTreeWidgetItem* sizeItem = createItem( parent, Bold );
   sizeItem->setText( 0, tr( "SIZE" ) );
-  sizeItem->setText( 1, QString::number( grp->Size() ) );
+  if ( groupSize > -1 ) {
+    sizeItem->setText( 1, QString::number( groupSize ) );
+  }
+  else {
+    QPushButton* btn = new QPushButton( tr( meshLoaded ? "COMPUTE" : "LOAD"), this );
+    setItemWidget( sizeItem, 1, btn );
+    GrpComputor* comp = new GrpComputor( grp, sizeItem, this, /*size=*/true );
+    connect( btn, SIGNAL( clicked() ), comp, SLOT( compute() ) );
+    myComputors.append( comp );
+    if ( !meshLoaded )
+      connect( btn, SIGNAL( clicked() ), this, SLOT( changeLoadToCompute() ) );
+  }
 
   // color
   SALOMEDS::Color color = grp->GetColor();
@@ -2476,9 +2590,7 @@ void SMESHGUI_AddInfo::groupInfo( SMESH::SMESH_GroupBase_ptr grp, QTreeWidgetIte
     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 );
+    bool toShowNodes = groupSize >= 0 ? ( grp->IsNodeInfoAvailable() || nbNodesLimit <= 0 || groupSize <= nbNodesLimit ) : false;
     if ( toShowNodes && meshLoaded ) {
       // already calculated and up-to-date
       nodesItem->setText( 1, QString::number( grp->GetNumberOfNodes() ) );
@@ -2531,7 +2643,7 @@ void SMESHGUI_AddInfo::showGroups()
       itemGroups->setData( 0, Qt::UserRole, GROUPS_ID );
 
       // total number of groups > 10, show extra widgets for info browsing
-      if ( myGroups->length() > MAXITEMS ) {
+      if ((int) 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() ) );
@@ -2592,7 +2704,7 @@ void SMESHGUI_AddInfo::showSubMeshes()
       itemSubMeshes->setData( 0, Qt::UserRole, SUBMESHES_ID );
 
       // total number of sub-meshes > 10, show extra widgets for info browsing
-      if ( mySubMeshes->length() > MAXITEMS ) {
+      if ((int) 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() ) );
@@ -2800,12 +2912,12 @@ 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 );
+    myAddInfo->showInfo( obj );  // nb of nodes in a group can be computed by myAddInfo,
+    myBaseInfo->showInfo( obj ); // and it will be used by myBaseInfo (IPAL52871)
     myCtrlInfo->showInfo( obj );
 
     myActor = SMESH::FindActorByEntry( IO->getEntry() );
-    SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector();
+    SVTK_Selector* selector = SMESH::GetSelector();
     QString ID;
     int nb = 0;
     if ( myActor && selector ) {
@@ -2969,7 +3081,7 @@ void SMESHGUI_MeshInfoDlg::modeChanged()
 */
 void SMESHGUI_MeshInfoDlg::idChanged()
 {
-  SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector();
+  SVTK_Selector* selector = SMESH::GetSelector();
   if ( myActor && selector ) {
     Handle(SALOME_InteractiveObject) IO = myActor->getIO();
     TColStd_MapOfInteger ID;
@@ -3340,7 +3452,8 @@ void SMESHGUI_CtrlInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
       // free nodes
       computeFreeNodesInfo();
       // double nodes
-      computeDoubleNodesInfo();
+      if ( Max( (int)mesh->NbNodes(), (int)mesh->NbElements() ) <= ctrlLimit )
+        computeDoubleNodesInfo();
     }
     else {
       myButtons[0]->setEnabled( true );
@@ -3380,6 +3493,11 @@ void SMESHGUI_CtrlInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
       myButtons[4]->setEnabled( true );
       myButtons[5]->setEnabled( true );
     }
+#ifdef DISABLE_PLOT2DVIEWER
+    myMainLayout->setRowStretch(11,0);
+    for( int i=22; i<=24; i++)
+      myMainLayout->itemAt(i)->widget()->setVisible( false );
+#endif
   }
   else {
     myMainLayout->setRowStretch(11,0);
@@ -3402,6 +3520,11 @@ void SMESHGUI_CtrlInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
        myButtons[7]->setEnabled( true );
        myButtons[8]->setEnabled( true );
      }
+#ifdef DISABLE_PLOT2DVIEWER
+    myMainLayout->setRowStretch(16,0);
+    for( int i=32; i<=34; i++)
+      myMainLayout->itemAt(i)->widget()->setVisible( false );
+#endif
   }
   else {
     myMainLayout->setRowStretch(16,0);
@@ -3481,6 +3604,7 @@ void SMESHGUI_CtrlInfo::computeOverConstrainedVolumesInfo()
 
 void SMESHGUI_CtrlInfo::computeAspectRatio()
 {
+#ifndef DISABLE_PLOT2DVIEWER
   myButtons[5]->setEnabled( false );
 
   if ( myObject->_is_nil() ) return;
@@ -3494,10 +3618,12 @@ void SMESHGUI_CtrlInfo::computeAspectRatio()
     myPlot->replot();
   }
   delete aHistogram;
+#endif
 }
 
 void SMESHGUI_CtrlInfo::computeAspectRatio3D()
 {
+#ifndef DISABLE_PLOT2DVIEWER
   myButtons[8]->setEnabled( false );
 
   if ( myObject->_is_nil() ) return;
@@ -3511,6 +3637,7 @@ void SMESHGUI_CtrlInfo::computeAspectRatio3D()
     myPlot3D->replot();
   }
   delete aHistogram;
+#endif
 }
 
 /*!
@@ -3540,6 +3667,7 @@ void SMESHGUI_CtrlInfo::setTolerance( double theTolerance )
   myWidgets[2]->setText("");
 }
 
+#ifndef DISABLE_PLOT2DVIEWER
 Plot2d_Histogram* SMESHGUI_CtrlInfo::getHistogram( SMESH::NumericalFunctor_ptr aNumFun )
 {
   SMESH::SMESH_Mesh_var mesh = myObject->GetMesh();
@@ -3569,6 +3697,7 @@ Plot2d_Histogram* SMESHGUI_CtrlInfo::getHistogram( SMESH::NumericalFunctor_ptr a
   }
   return aHistogram;
 }
+#endif
 
 void SMESHGUI_CtrlInfo::saveInfo( QTextStream &out ) {
   out << QString( 20, '-' ) << "\n";
index 54ee1aca5191d91d0e2e8bbd161d55940c04f9a9..f06db38d25970f98f15e0f82723fd91571869cc7 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 #include "SMESH_SMESHGUI.hxx"
 #include "SMESH_ControlsDef.hxx"
 
-#include <Plot2d_Histogram.h>
+#ifndef DISABLE_PLOT2DVIEWER
+  #include <Plot2d_Histogram.h>
+#else
+  #include <qwt_plot.h>
+#endif
 
 #include <QFrame>
 #include <QDialog>
@@ -158,6 +162,7 @@ protected:
   {
     double myX, myY, myZ;
     XYZ() { myX = myY = myZ = 0.0; }
+    XYZ(double x, double y, double z) { myX = x; myY = y; myZ = z; }
     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; }
@@ -176,6 +181,7 @@ protected:
   Connectivity nodeConnectivity( const SMDS_MeshNode* );
   QString      formatConnectivity( Connectivity, int );
   XYZ          gravityCenter( const SMDS_MeshElement* );
+  XYZ          normal( const SMDS_MeshElement* );
 
 signals:
   void         itemInfo( int );
@@ -244,7 +250,7 @@ class GrpComputor: public QObject
   Q_OBJECT;
 
 public:
-  GrpComputor( SMESH::SMESH_GroupBase_ptr, QTreeWidgetItem*, QObject* );
+  GrpComputor( SMESH::SMESH_GroupBase_ptr, QTreeWidgetItem*, QObject*, bool = false);
   QTreeWidgetItem* getItem() { return myItem; }
 
 public slots:
@@ -253,6 +259,7 @@ public slots:
 private:
   SMESH::SMESH_GroupBase_var myGroup;
   QTreeWidgetItem*           myItem;
+  bool                       myToComputeSize;
 };
 
 class SMESHGUI_EXPORT SMESHGUI_AddInfo : public QTreeWidget
@@ -308,7 +315,9 @@ private:
   QwtPlot*              createPlot( QWidget* );
   void                  setFontAttributes( QWidget* );
   void                  clearInternal();
+#ifndef DISABLE_PLOT2DVIEWER
   Plot2d_Histogram*     getHistogram( SMESH::NumericalFunctor_ptr functor );
+#endif
   void                  computeNb( int ft, int iBut, int iWdg );
 
 private slots:
index 59900714e0e1032b34a505f89e98239253467205..71590dc9687377fe224e8b064d0c0d83d5d2364c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
@@ -66,7 +66,7 @@ SMESHGUI_MeshInfosBox::SMESHGUI_MeshInfosBox(const bool full, QWidget* theParent
   myNbTrai(0), myNbLinTrai(0), myNbQuadTrai(0), myNbBiQuadTrai(0),
   myNbQuad(0), myNbLinQuad(0), myNbQuadQuad(0), myNbBiQuadQuad(0),
   myNbFace(0), myNbLinFace(0), myNbQuadFace(0), myNbBiQuadFace(0),
-  myNbPolyg(0),
+  myNbPolyg(0), myNbQuadPolyg(0),
   myNbHexa(0), myNbLinHexa(0), myNbQuadHexa(0), myNbBiQuadHexa(0),
   myNbTetra(0),myNbLinTetra(0),myNbQuadTetra(0),
   myNbPyra(0), myNbLinPyra(0), myNbQuadPyra(0),
@@ -219,8 +219,15 @@ SMESHGUI_MeshInfosBox::SMESHGUI_MeshInfosBox(const bool full, QWidget* theParent
     // ... poligones
     lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_POLYGONES")), this );
     l->addWidget( lab,           row, 0 );
+    // --
     myNbPolyg    = new QLabel( this );
     l->addWidget( myNbPolyg,     row, 1 );
+    // --
+    myNbLinPolyg = new QLabel( this );
+    l->addWidget( myNbLinPolyg,    row, 2 );
+    // --
+    myNbQuadPolyg = new QLabel( this );
+    l->addWidget( myNbQuadPolyg,   row, 3 );
 
     addSeparator(this);          // add separator
 
@@ -432,12 +439,14 @@ void SMESHGUI_MeshInfosBox::SetMeshInfo(const SMESH::long_array& theInfo)
                                                theInfo[SMDSEntity_Quadrangle] +
                                                theInfo[SMDSEntity_Quad_Quadrangle] +
                                                theInfo[SMDSEntity_BiQuad_Quadrangle] +
-                                               theInfo[SMDSEntity_Polygon] ));
+                                               theInfo[SMDSEntity_Polygon] +
+                                               theInfo[SMDSEntity_Quad_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_Quad_Quadrangle] +
+                                               theInfo[SMDSEntity_Quad_Polygon] ));
   myNbBiQuadFace ->setText( QString("%1").arg( theInfo[SMDSEntity_BiQuad_Triangle] +
                                                theInfo[SMDSEntity_BiQuad_Quadrangle] ));
 
@@ -481,7 +490,10 @@ void SMESHGUI_MeshInfosBox::SetMeshInfo(const SMESH::long_array& theInfo)
     myNbQuadQuad   ->setText( QString("%1").arg( theInfo[SMDSEntity_Quad_Quadrangle] ));
     myNbBiQuadQuad ->setText( QString("%1").arg( theInfo[SMDSEntity_BiQuad_Quadrangle]));
     // poligones
-    myNbPolyg      ->setText( QString("%1").arg( theInfo[SMDSEntity_Polygon] ));
+    myNbPolyg      ->setText( QString("%1").arg( theInfo[SMDSEntity_Polygon] +
+                                                 theInfo[SMDSEntity_Quad_Polygon] ));
+    myNbLinPolyg   ->setText( QString("%1").arg( theInfo[SMDSEntity_Polygon] ));
+    myNbQuadPolyg  ->setText( QString("%1").arg( theInfo[SMDSEntity_Quad_Polygon] ));
 
     // tetras
     myNbTetra      ->setText( QString("%1").arg( theInfo[SMDSEntity_Tetra] +
index 92e752976b4518c77313e0f39b1656d3e07edcda..b1d51256a0f5e5764f9c8ed779337b684dffbd1a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
@@ -69,6 +69,8 @@ private:
   QLabel* myNbQuadFace;
   QLabel* myNbBiQuadFace;
   QLabel* myNbPolyg;
+  QLabel* myNbLinPolyg;
+  QLabel* myNbQuadPolyg;
   QLabel* myNbHexa;
   QLabel* myNbLinHexa;
   QLabel* myNbQuadHexa;
index cdb3bc91921a0b281f767a7c241ceffbf53a4ce9..351639e8996ced854ba1501105c9a42571d5902f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -206,11 +206,11 @@ void SMESHGUI_MeshOp::startOperation()
     for ( int i = SMESH::DIM_0D; i <= SMESH::DIM_3D; i++ )
     {
       connect( myDlg->tab( i ), SIGNAL( createHyp( const int, const int ) ),
-              this, SLOT( onCreateHyp( const int, const int ) ) );
+               this, SLOT( onCreateHyp( const int, const int ) ) );
       connect( myDlg->tab( i ), SIGNAL( editHyp( const int, const int ) ),
-              this, SLOT( onEditHyp( const int, const int ) ) );
+               this, SLOT( onEditHyp( const int, const int ) ) );
       connect( myDlg->tab( i ), SIGNAL( selectAlgo( const int ) ),
-              this, SLOT( onAlgoSelected( const int ) ) );
+               this, SLOT( onAlgoSelected( const int ) ) );
     }
     connect( myDlg, SIGNAL( hypoSet( const QString& )), SLOT( onHypoSet( const QString& )));
     connect( myDlg, SIGNAL( geomSelectionByMesh( bool )), SLOT( onGeomSelectionByMesh( bool )));
@@ -551,9 +551,17 @@ void SMESHGUI_MeshOp::selectionDone()
         for ( ; aSubShapesIter != aGEOMs.end(); aSubShapesIter++, iSubSh++) {
           QString aSubGeomEntry = (*aSubShapesIter);
           _PTR(SObject) pSubGeom = studyDS()->FindObjectID(aSubGeomEntry.toLatin1().data());
-          GEOM::GEOM_Object_var aSubGeomVar =
-            GEOM::GEOM_Object::_narrow(_CAST(SObject,pSubGeom)->GetObject());
-          aSeq[iSubSh] = aSubGeomVar;
+         
+          if( pSubGeom ) { 
+            SALOMEDS_SObject* sobj = _CAST(SObject,pSubGeom);
+            if( sobj ) {
+              GEOM::GEOM_Object_var aSubGeomVar =
+                GEOM::GEOM_Object::_narrow(sobj->GetObject());
+              if( !aSubGeomVar->_is_nil() ){
+                aSeq[iSubSh] = aSubGeomVar;
+              }
+            }
+          }
         }
       } else {
         // get geometry by selected sub-mesh
@@ -658,7 +666,7 @@ void SMESHGUI_MeshOp::selectionDone()
           {
             selectionMgr()->clearFilters();
             selectObject( pSubmesh );
-            SMESHGUI::GetSMESHGUI()->switchToOperation(704);
+            SMESHGUI::GetSMESHGUI()->switchToOperation( SMESHOp::OpEditMeshOrSubMesh );
             return;
           }
           else
@@ -851,6 +859,60 @@ static bool isCompatible(const HypothesisData* theAlgoData,
   return ( SMESH::IsAvailableHypothesis( theAlgoData, theHypData->TypeName, isOptional ));
 }
 
+//================================================================================
+/*!
+ * \brief check compatibility of the geometry
+  * \param theAlgoData - to select hypos able to be used by this algo
+  * \param theCurrentGeomToSelect - the current name of the selected geometry
+  * \param theGeomVar - currently selected geometry
+  * \retval bool - check result
+ */
+//================================================================================
+bool SMESHGUI_MeshOp::isCompatibleToGeometry(HypothesisData* theAlgoData,
+                                             QString theCurrentGeomToSelect,
+                                             GEOM::GEOM_Object_var theGeomVar)
+{
+  if ( theGeomVar->_is_nil() )
+    return true;
+
+  bool isApplicable = false;
+  if ( theCurrentGeomToSelect == myLastGeomToSelect && !theCurrentGeomToSelect.isEmpty() ) {
+    THypLabelIsAppMap::const_iterator iter = myHypMapIsApplicable.find( theAlgoData->Label );
+    if ( iter != myHypMapIsApplicable.end() && iter.key() == theAlgoData->Label ) {
+      isApplicable = iter.value();
+      return isApplicable;
+    }
+  }
+  bool toCheckIsApplicableToAll = !myIsMesh;
+  if ( toCheckIsApplicableToAll )
+    toCheckIsApplicableToAll = ( theGeomVar->GetType() == GEOM_GROUP );
+  isApplicable = SMESH::IsApplicable( theAlgoData->TypeName, theGeomVar, toCheckIsApplicableToAll );
+  myHypMapIsApplicable.insert( theAlgoData->Label, isApplicable );
+  return isApplicable;
+}
+
+//================================================================================
+/*!
+ * \brief check compatibility of the mesh type
+  * \param theAlgoData - to select hypos able to be used by this algo
+  * \param theMeshType - type of mesh for filtering algorithms
+  * \retval bool - check result
+ */
+//================================================================================
+bool SMESHGUI_MeshOp::isCompatibleToMeshType(HypothesisData* theAlgoData,
+                                             QString theMeshType)
+{
+  bool isAvailableAlgo = ( theAlgoData->OutputTypes.count() == 0 );
+  QStringList::const_iterator inElemType = theAlgoData->OutputTypes.begin();
+  for ( ; inElemType != theAlgoData->OutputTypes.end(); inElemType++ ) {
+    if ( *inElemType == theMeshType ) {
+      isAvailableAlgo = true;
+      break;
+    }
+  }
+  return isAvailableAlgo;
+}
+
 //================================================================================
 /*!
  * \brief Gets available hypotheses or algorithms
@@ -858,7 +920,9 @@ static bool isCompatible(const HypothesisData* theAlgoData,
   * \param theHypType - specifies whether algorims or hypotheses or additional ones
   * are retrieved (possible values are in HypType enumeration)
   * \param theHyps - Output list of hypotheses' names
-  * \param theAlgoData - to select hypos able to be used by this algo (optional)
+  * \param thePrevAlgoData - to select hypos able to be used by previously algo (optional)
+  * \param theNextAlgoData - to select hypos able to be used by next algo (optional)
+  * \param theMeshType - type of mesh for filtering algorithms (optional)
  *
  * Gets available hypotheses or algorithm in accordance with input parameters
  */
@@ -867,7 +931,9 @@ void SMESHGUI_MeshOp::availableHyps( const int       theDim,
                                      const int       theHypType,
                                      QStringList&    theHyps,
                                      THypDataList&   theDataList,
-                                     HypothesisData* theAlgoData ) const
+                                     HypothesisData* thePrevAlgoData,
+                                     HypothesisData* theNextAlgoData,
+                                     const QString&  theMeshType)
 {
   theDataList.clear();
   theHyps.clear();
@@ -876,14 +942,35 @@ void SMESHGUI_MeshOp::availableHyps( const int       theDim,
   QStringList aHypTypeNameList = SMESH::GetAvailableHypotheses( isAlgo, theDim, isAux, myIsOnGeometry, !myIsMesh );
 
   QStringList::const_iterator anIter;
+  GEOM::GEOM_Object_var aGeomVar;
+  QString aCurrentGeomToSelect;
+  if ( !theMeshType.isEmpty() ) {
+    aCurrentGeomToSelect = myDlg->selectedObject( myToCreate ? SMESHGUI_MeshDlg::Geom : SMESHGUI_MeshDlg::Obj );
+    if ( _PTR(SObject) so = studyDS()->FindObjectID( aCurrentGeomToSelect.toLatin1().data() )) {
+      aGeomVar = SMESH::GetGeom( so );
+    }
+   if ( aCurrentGeomToSelect != myLastGeomToSelect )
+     myHypMapIsApplicable.clear();
+  }
+
   for ( anIter = aHypTypeNameList.begin(); anIter != aHypTypeNameList.end(); ++anIter )
   {
     HypothesisData* aData = SMESH::GetHypothesisData( *anIter );
-    if ( isCompatible ( theAlgoData, aData, theHypType )) {
+    if ( ( isCompatible ( thePrevAlgoData, aData, theHypType ) &&
+           isCompatible ( theNextAlgoData, aData, theHypType ) ) ||
+           ( theMeshType == "ANY" && aData->InputTypes.isEmpty())) {
+      if ( !theMeshType.isEmpty() && theDim >= SMESH::DIM_2D &&
+           ( ( theMeshType != "ANY" && !isCompatibleToMeshType( aData, theMeshType )) ||
+           !isCompatibleToGeometry( aData, aCurrentGeomToSelect, aGeomVar )))
+        continue;
       theDataList.append( aData );
       theHyps.append( aData->Label );
     }
   }
+
+  if ( !theMeshType.isEmpty() && !aCurrentGeomToSelect.isEmpty() &&
+       myLastGeomToSelect != aCurrentGeomToSelect )
+    myLastGeomToSelect = aCurrentGeomToSelect;
 }
 
 //================================================================================
@@ -1413,42 +1500,41 @@ void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex,
   // check that tab enabled of one less dimension
   if ( aDim > SMESH::DIM_0D )
   {
-    if ( isAccessibleDim( aDim - 1 ) )
-    {
-      if (( myDlg->currentMeshType() != MT_ANY ) &&
-          ( !algoData || ( myIsOnGeometry && algoData->InputTypes.isEmpty() )))
-        for (int i = aDim - 1; i >= SMESH::DIM_0D; i--)
-          if ( isAccessibleDim( i ) ) {
+    if ( isAccessibleDim( aDim - 1 ) ) {
+      if ( algoData && myIsOnGeometry ) {
+        for (int i = aDim - 1; i >= SMESH::DIM_0D; i--) {
+          if ( isAccessibleDim( i ) && ( currentHyp( i, Algo ) < 0 ||
+             algoData->InputTypes.isEmpty() ) ) {
             myDlg->disableTab( i );
             setCurrentHyp(i, Algo, -1);
           }
+        }
+      }
     }
-    else if ( algoData && myIsOnGeometry && !algoData->InputTypes.isEmpty() )
-    {
+    if ( algoData && myIsOnGeometry && !algoData->InputTypes.isEmpty() ) {
       myDlg->enableTab( aDim - 1 );
     }
-  }
-
-  // check that algorithms of other dimentions are compatible with
-  // the selected one
-  if ( !algoData ) { // all algos becomes available
-    if (myDlg->currentMeshType() == MT_ANY || aDim == SMESH::DIM_1D || aDim == SMESH::DIM_0D)
-      availableHyps( aDim, Algo, anAvailable, myAvailableHypData[ aDim ][ Algo ]);
-    else{
-      anAvailable.clear();
-      for (int i = 0; i < myFilteredAlgoData[aDim].count(); ++i) {
-        HypothesisData* aCurAlgo = myFilteredAlgoData[aDim][ i ];
-        anAvailable.append( aCurAlgo->Label );
+    if ( !algoData ) {
+      if ( aDim != SMESH::DIM_2D || ( aDim == SMESH::DIM_2D &&
+         currentHyp( SMESH::DIM_2D, Algo ) < 0) ) {
+        for (int i = aDim - 1; i >= SMESH::DIM_0D; i--)
+          myDlg->enableTab( i );
+      }
+      else {
+        for (int i = aDim - 1; i >= SMESH::DIM_0D; i--)
+          myDlg->disableTab( i );
       }
     }
-    myDlg->tab( aDim )->setAvailableHyps( Algo, anAvailable );
   }
+
+  int algoDim = aDim;
+  HypothesisData* a3DAlgo = 0;
   // 2 loops: backward and forward from algo dimension
-  for ( int forward = false; forward <= true; ++forward )
+  for ( int forward = 0; forward <= 1; ++forward )
   {
-    int dim = aDim + 1, lastDim = SMESH::DIM_3D, dir = 1;
+    int dim = algoDim + 1, lastDim = SMESH::DIM_3D, dir = 1;
     if ( !forward ) {
-      dim = aDim - 1; lastDim = SMESH::DIM_0D; dir = -1;
+      dim = algoDim - 1; lastDim = SMESH::DIM_0D; dir = -1;
     }
     HypothesisData* prevAlgo = algoData;
     bool noCompatible = false;
@@ -1463,47 +1549,47 @@ void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex,
         algoByDim[ dim ] = 0;
         continue;
       }
+      HypothesisData* nextAlgo = 0;
+      if ( myMaxShapeDim == SMESH::DIM_3D && a3DAlgo && dim == SMESH::DIM_2D ) {
+        nextAlgo = a3DAlgo;
+      }
       // get currently selected algo
       int algoIndex = currentHyp( dim, Algo );
       HypothesisData* curAlgo = hypData( dim, Algo, algoIndex );
-      if ( curAlgo ) { // some algo selected
-        if ( !isCompatible( prevAlgo, curAlgo, Algo ))
-          curAlgo = 0;
+
+      QString anCompareType = currentMeshTypeName(myDlg->currentMeshType());
+      QString anCurrentCompareType = "";
+      if ( dim == SMESH::DIM_3D || anCompareType == "ANY" )
+        anCurrentCompareType = anCompareType;
+      else if ( dim == SMESH::DIM_2D ) {
+        anCurrentCompareType = (anCompareType == "HEXA" || anCompareType == "QUAD") ? "QUAD" : "TRIA";
+        nextAlgo = 0;
       }
+
       // set new available algoritms
-      if (myDlg->currentMeshType() == MT_ANY || dim == SMESH::DIM_1D || dim == SMESH::DIM_0D)
-        availableHyps( dim, Algo, anAvailable, myAvailableHypData[dim][Algo], prevAlgo );
-      else{
-        anAvailable.clear();
-        myAvailableHypData[dim][Algo].clear();
-        for (int i = 0; i < myFilteredAlgoData[dim].count(); ++i) {
-          HypothesisData* aCurAlgo = myFilteredAlgoData[dim][ i ];
-          if ( isCompatible ( prevAlgo, aCurAlgo, Algo )) {
-            anAvailable.append( aCurAlgo->Label );
-            myAvailableHypData[dim][Algo].append( aCurAlgo );
-          }
-        }
-      }
+      availableHyps( dim, Algo, anAvailable, myAvailableHypData[dim][Algo], prevAlgo, nextAlgo, anCurrentCompareType);
       HypothesisData* soleCompatible = 0;
       if ( anAvailable.count() == 1 )
         soleCompatible = myAvailableHypData[dim][Algo][0];
-      if ( dim == aTopDim && prevAlgo ) {// all available algoritms should be selectable any way
-        if (myDlg->currentMeshType() == MT_ANY)
-          availableHyps( dim, Algo, anAvailable, myAvailableHypData[dim][Algo], 0 );
-      }
       myDlg->tab( dim )->setAvailableHyps( Algo, anAvailable );
       noCompatible = anAvailable.isEmpty();
-
-      // restore previously selected algo
       algoIndex = myAvailableHypData[dim][Algo].indexOf( curAlgo );
-      if ( !isSubmesh && algoIndex < 0 && soleCompatible && !forward && dim != SMESH::DIM_0D)
+      if ( !isSubmesh && algoIndex < 0 && soleCompatible && !forward && dim != SMESH::DIM_0D) {
         // select the sole compatible algo
         algoIndex = myAvailableHypData[dim][Algo].indexOf( soleCompatible );
+      }
       setCurrentHyp( dim, Algo, algoIndex);
 
       // remember current algo
       prevAlgo = algoByDim[ dim ] = hypData( dim, Algo, algoIndex );
     }
+    if ( myMaxShapeDim == SMESH::DIM_3D && forward && algoDim == SMESH::DIM_1D )
+    {
+      algoDim = SMESH::DIM_3D;
+      forward = -1;
+      a3DAlgo = prevAlgo;
+      continue;
+    }
   }
 
   // set hypotheses corresponding to the found algoritms
@@ -1545,7 +1631,7 @@ void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex,
              myObjHyps[ dim ][ type ].count() > 0 &&
              curHypType == SMESH::toQStr( myObjHyps[ dim ][ type ].first().first->GetName()) )
         {
-          HypothesisData* hypData = SMESH::GetHypothesisData( curHyp->GetName() );
+          HypothesisData* hypData = SMESH::GetHypothesisData( SMESH::toQStr( curHyp->GetName() ));
           for (int i = 0; i < myAvailableHypData[ dim ][ Algo ].count(); ++i) {
             curAlgo = myAvailableHypData[ dim ][ Algo ][ i ];
             if (curAlgo && hypData && isCompatible(curAlgo, hypData, type))
@@ -1561,7 +1647,7 @@ void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex,
       {
         // check if a selected hyp is compatible with the curAlgo
         if ( !curHyp->_is_nil() ) {
-          HypothesisData* hypData = SMESH::GetHypothesisData( curHyp->GetName() );
+          HypothesisData* hypData = SMESH::GetHypothesisData( SMESH::toQStr( curHyp->GetName() ));
           if ( !isCompatible( curAlgo, hypData, type ))
             curHyp = SMESH::SMESH_Hypothesis::_nil();
         }
@@ -2154,7 +2240,7 @@ void SMESHGUI_MeshOp::readMesh()
     if ( myObjHyps[ dim ][ Algo ].count() > 0 )
     {
       SMESH::SMESH_Hypothesis_var aVar = myObjHyps[ dim ][ Algo ].first().first;
-      HypothesisData* algoData = SMESH::GetHypothesisData( aVar->GetName() );
+      HypothesisData* algoData = SMESH::GetHypothesisData( SMESH::toQStr( aVar->GetName() ));
       aHypIndex = myAvailableHypData[ dim ][ Algo ].indexOf ( algoData );
       //       if ( aHypIndex < 0 && algoData ) {
       //         // assigned algo is incompatible with other algorithms
@@ -2292,12 +2378,12 @@ bool SMESHGUI_MeshOp::editMeshOrSubMesh( QString& theMess )
   // First, remove old algos in order to avoid messages on algorithm hiding
   for ( int dim = aDim; dim <= SMESH::DIM_3D; dim++ )
   {
-    if ( isAccessibleDim( dim ) && myObjHyps[ dim ][ Algo ].count() > 0 )
+    if ( /*isAccessibleDim( dim ) &&*/ myObjHyps[ dim ][ Algo ].count() > 0 )
     {
       SMESH::SMESH_Hypothesis_var anOldAlgo = myObjHyps[ dim ][ Algo ].first().first;
       SMESH::SMESH_Hypothesis_var anAlgoVar = getAlgo( dim );
       if ( anAlgoVar->_is_nil() || // no new algo selected or
-           strcmp(anOldAlgo->GetName(), anAlgoVar->GetName()) ) // algo change
+           SMESH::toQStr(anOldAlgo->GetName()) != SMESH::toQStr(anAlgoVar->GetName())) // algo change
       {
         // remove old algorithm
         SMESH::RemoveHypothesisOrAlgorithmOnMesh ( pObj, myObjHyps[ dim ][ Algo ].first().first );
@@ -2580,98 +2666,48 @@ void SMESHGUI_MeshOp::onAlgoSetByMeshType( const int theTabIndex, const int theI
   * \param theIndex - Index of current type of mesh
  */
 //================================================================================
-void SMESHGUI_MeshOp::setFilteredAlgoData( const int theTabIndex, const int theIndex)
+void SMESHGUI_MeshOp::setFilteredAlgoData( const int theTabIndex, const int theIndex )
 {
-  int aDim;
-  THypDataList anAvailableAlgsData;
   QStringList anAvailableAlgs;
-  QString anCompareType = "";
-  bool isAvailableChoiceAlgo = false;
-  int anCurrentAvailableAlgo = 0;
+  QString anCompareType = currentMeshTypeName( theIndex );
+  int anCurrentAvailableAlgo = -1;
   bool isNone = true;
-  switch ( theIndex ) {
-  case MT_ANY:
-    anCompareType = "ANY";
-    aDim = SMESH::DIM_3D;
-    break;
-  case MT_TRIANGULAR:
+  int aDim = SMESH::DIM_3D;
+  if ( theIndex == MT_TRIANGULAR || theIndex == MT_QUADRILATERAL)
     aDim = SMESH::DIM_2D;
-    anCompareType = "TRIA";
-    break;
-  case MT_QUADRILATERAL:
-    aDim = SMESH::DIM_2D;
-    anCompareType = "QUAD";
-    break;
-  case MT_TETRAHEDRAL:
-    aDim = SMESH::DIM_3D;
-    anCompareType = "TETRA";
-    break;
-  case MT_HEXAHEDRAL:
-    aDim = SMESH::DIM_3D;
-    anCompareType = "HEXA";
-    break;
-  default:;
-  }
-
-  bool toCheckIsApplicableToAll = !myIsMesh;
-  GEOM::GEOM_Object_var aGeomVar;
-  QString anEntry =
-    myDlg->selectedObject( myToCreate ? SMESHGUI_MeshDlg::Geom : SMESHGUI_MeshDlg::Obj );
-  if ( _PTR(SObject) so = studyDS()->FindObjectID( anEntry.toLatin1().data() ))
-  {
-    aGeomVar = SMESH::GetGeom( so );
-    if ( !aGeomVar->_is_nil() && toCheckIsApplicableToAll )
-      toCheckIsApplicableToAll = ( aGeomVar->GetType() == GEOM_GROUP );
-  }
-
   if ( anCompareType == "ANY" )
   {
+    bool isReqDisBound = false;
+    int aReqDim = SMESH::DIM_3D;
     for ( int dim = SMESH::DIM_3D; dim >= SMESH::DIM_2D; dim-- )
     {
+      anCurrentAvailableAlgo = -1;
       isNone = currentHyp( dim, Algo ) < 0;
-      isAvailableChoiceAlgo = false;
-      // retrieves a list of available algorithms from resources
-      availableHyps( dim, Algo, anAvailableAlgs, anAvailableAlgsData );
       //return current algo in current tab and set new algorithm list
-      HypothesisData* algoCur;
+      HypothesisData* algoCur = 0;
       if ( !isNone && !myAvailableHypData[dim][Algo].empty() ) {
         algoCur = myAvailableHypData[dim][Algo].at( currentHyp( dim, Algo ) );
       }
-      myAvailableHypData[dim][Algo].clear();
-      anAvailableAlgs.clear();
-      if ( dim != SMESH::DIM_2D || currentHyp( SMESH::DIM_3D, Algo ) < 0 ||
-           myAvailableHypData[SMESH::DIM_3D][Algo].empty() ||
-           !myAvailableHypData[SMESH::DIM_3D][Algo].at( currentHyp( SMESH::DIM_3D, Algo ) )->InputTypes.isEmpty() )
-      {
-        for (int i = 0 ; i < anAvailableAlgsData.count(); i++)
-        {
-          HypothesisData* curAlgo = anAvailableAlgsData.at(i);
-          if ( aGeomVar->_is_nil() ||
-              SMESH::IsApplicable( curAlgo->TypeName, aGeomVar, toCheckIsApplicableToAll ))
-          {
-            anAvailableAlgs.append( curAlgo->Label );
-            myAvailableHypData[dim][Algo].append( curAlgo );
-          }
-        }
-        if ( !isNone && algoCur ) {
-          for (int i = 0 ; i < myAvailableHypData[dim][Algo].count(); i++)
-          {
-            HypothesisData* algoAny = myAvailableHypData[dim][Algo].at(i);
-            if ( algoAny->Label == algoCur->Label ){
-              isAvailableChoiceAlgo = true;
-              anCurrentAvailableAlgo = i;
-              break;
-            }
-          }
-        }
-        else if ( !isNone ) {
-          isAvailableChoiceAlgo = true;
-          anCurrentAvailableAlgo = currentHyp( dim, Algo );
-        }
+      HypothesisData* prevAlgo = 0;
+      HypothesisData* nextAlgo = 0;
+      if ( dim == SMESH::DIM_2D ) {
+        prevAlgo = hypData( SMESH::DIM_1D, Algo, currentHyp( SMESH::DIM_1D, Algo ) );
+        if ( aDim == SMESH::DIM_3D )
+          nextAlgo = hypData( SMESH::DIM_3D, Algo, currentHyp( SMESH::DIM_3D, Algo ) );
       }
+      // retrieves a list of available algorithms from resources
+      availableHyps( dim, Algo, anAvailableAlgs, myAvailableHypData[dim][Algo], prevAlgo, nextAlgo, anCompareType);
+      anCurrentAvailableAlgo = myAvailableHypData[dim][Algo].indexOf( algoCur );
       myDlg->tab( dim )->setAvailableHyps( Algo, anAvailableAlgs );
-      if ( isAvailableChoiceAlgo )
-        setCurrentHyp( dim, Algo, anCurrentAvailableAlgo );
+      setCurrentHyp( dim, Algo, anCurrentAvailableAlgo );
+      if ( anCurrentAvailableAlgo > -1 )
+        isReqDisBound = algoCur->InputTypes.isEmpty();
+      else if ( dim != SMESH::DIM_3D && currentHyp( SMESH::DIM_3D, Algo ) >= 0 )
+        isReqDisBound = true;
+      if ( isReqDisBound ) {
+        aReqDim = dim;
+        break;
+      }
     }
     if ( !myIsOnGeometry )
       for ( int i = SMESH::DIM_0D; i <= SMESH::DIM_3D; i++ ) {
@@ -2680,142 +2716,100 @@ void SMESHGUI_MeshOp::setFilteredAlgoData( const int theTabIndex, const int theI
       }
     else
       for ( int i = SMESH::DIM_0D; i <= SMESH::DIM_3D; i++ ) {
-        if ( i > myMaxShapeDim ) myDlg->disableTab( i );
-        else                     myDlg->enableTab( i );
+        if ( i > myMaxShapeDim || ( isReqDisBound && i < aReqDim ) ) myDlg->disableTab( i );
+        else                                                         myDlg->enableTab( i );
       }
     myDlg->setCurrentTab( theTabIndex );
   }
   else
   {
-    QString anCurrentAlgo;
+    HypothesisData* anCurrentAlgo;
     bool isReqDisBound = true;
     QString anCurrentCompareType = anCompareType;
     isNone = currentHyp( aDim, Algo ) < 0;
-    if ( !isNone && !myAvailableHypData[aDim][Algo].empty() &&
-        myAvailableHypData[aDim][Algo].count() != anAvailableAlgsData.count() )
+    if ( !isNone && !myAvailableHypData[aDim][Algo].empty() )
       isReqDisBound = myAvailableHypData[aDim][Algo].at( currentHyp( aDim, Algo ) )->InputTypes.isEmpty();
-    else if ( !isNone )
-      isReqDisBound = anAvailableAlgsData.at( currentHyp( aDim, Algo ) )->InputTypes.isEmpty();
     for ( int dim = aDim; dim >= SMESH::DIM_2D; dim-- )
     {
       bool isNoneAlg = currentHyp( dim, Algo ) < 0;
-      isAvailableChoiceAlgo = false;
-      // retrieves a list of available algorithms from resources
-      availableHyps( dim, Algo, anAvailableAlgs, anAvailableAlgsData );
+      anCurrentAvailableAlgo = -1;
+      HypothesisData* prevAlgo = 0;
+      HypothesisData* nextAlgo = 0;
+      if ( dim == SMESH::DIM_2D ) {
+        prevAlgo = hypData( SMESH::DIM_1D, Algo, currentHyp( SMESH::DIM_1D, Algo ) );
+        if ( aDim == SMESH::DIM_3D )
+          nextAlgo = hypData( SMESH::DIM_3D, Algo, currentHyp( SMESH::DIM_3D, Algo ) );
+      }
       // finding algorithm which is selected
-      if ( !isNoneAlg && !myAvailableHypData[dim][Algo].empty() &&
-          myAvailableHypData[dim][Algo].count() != anAvailableAlgsData.count() )
-        anCurrentAlgo = myAvailableHypData[dim][Algo].at( currentHyp( dim, Algo ) )->Label;
-      else if ( !isNoneAlg )
-        anCurrentAlgo = anAvailableAlgsData.at( currentHyp( dim, Algo ) )->Label;
-      anAvailableAlgs.clear();
-      myAvailableHypData[dim][Algo].clear();
-      myFilteredAlgoData[dim].clear();
-      // finding and adding algorithm depending on the type mesh
-      for ( int i = 0 ; i < anAvailableAlgsData.count(); i++ )
-      {
-        HypothesisData* algoIn = anAvailableAlgsData.at( i );
-        bool isAvailableAlgo = ( algoIn->OutputTypes.count() == 0 );
-        QStringList::const_iterator inElemType = algoIn->OutputTypes.begin();
-        for ( ; inElemType != algoIn->OutputTypes.end(); inElemType++ )
-        {
-          if ( *inElemType == anCurrentCompareType ) {
-            isAvailableAlgo = true;
-            break;
-          }
-        }
-        if ( isAvailableAlgo || algoIn->OutputTypes.count()==0 ) {
-          if ( aGeomVar->_is_nil() || myMaxShapeDim != dim ||
-               SMESH::IsApplicable( algoIn->TypeName, aGeomVar, toCheckIsApplicableToAll ))
-          {
-            anAvailableAlgs.append( algoIn->Label );
-            myAvailableHypData[dim][Algo].append( algoIn );
-            myFilteredAlgoData[dim].append( algoIn );
-          }
-        }
-        //algorithm will be active, if the chosen algorithm available in the current mesh type
-        if ( !isNoneAlg &&  isAvailableAlgo && algoIn->Label == anCurrentAlgo ) {
-          isAvailableChoiceAlgo = true;
-          anCurrentAvailableAlgo = anAvailableAlgs.count() - 1 ;
-        }
+      if ( !isNoneAlg ) {
+        anCurrentAlgo = myAvailableHypData[dim][Algo].at( currentHyp( dim, Algo ) );
       }
+      // retrieves a list of available algorithms from resources
+      availableHyps( dim, Algo, anAvailableAlgs, myAvailableHypData[dim][Algo], prevAlgo, nextAlgo, anCurrentCompareType );
+      // finding and adding algorithm depending on the type mesh
+      anCurrentAvailableAlgo = myAvailableHypData[dim][Algo].indexOf( anCurrentAlgo );
       //set new algorithm list and select the current algorithm
       myDlg->tab( dim )->setAvailableHyps( Algo, anAvailableAlgs );
-      anCurrentCompareType = ( anCompareType == "HEXA" ) ? "QUAD" : "TRIA";
-      if ( isAvailableChoiceAlgo )
-        setCurrentHyp( dim, Algo, anCurrentAvailableAlgo );
-      else
-        setCurrentHyp( dim, Algo, -1 );
+      anCurrentCompareType = ( anCompareType == "HEXA" || anCompareType == "QUAD" ) ? "QUAD" : "TRIA";
+      setCurrentHyp( dim, Algo, anCurrentAvailableAlgo );
     }
 
     if ( isNone || isReqDisBound ) {
       for ( int i = SMESH::DIM_0D; i <= myMaxShapeDim; i++ ) {
         if ( aDim != i ) {
           myDlg->disableTab( i );
-          setCurrentHyp(i, Algo, -1);
         }
       }
     }
     else if ( !isNone ) {
-      if ( aDim == SMESH::DIM_2D){
+      if ( aDim == SMESH::DIM_2D) {
         myDlg->disableTab( SMESH::DIM_3D );
         setCurrentHyp( SMESH::DIM_3D, Algo, -1);
       }
-      for ( int i = myMaxShapeDim; i > SMESH::DIM_0D; i-- )
-      {
-        isReqDisBound = ( currentHyp( i, Algo ) < 0 ) ? true :
-            myAvailableHypData[i][Algo].at( currentHyp( i, Algo ) )->InputTypes.isEmpty();
-        if ( isReqDisBound ) {
-          for (int j = i - 1; j >= SMESH::DIM_0D; j--){
-            myDlg->disableTab( j );
-            setCurrentHyp( j , Algo, -1 );
+      for ( int i = myMaxShapeDim; i > SMESH::DIM_0D; i-- ) {
+        bool isNoneAlg = currentHyp( i, Algo ) < 0;
+        if ( !isNoneAlg )
+          isReqDisBound = myAvailableHypData[i][Algo].at( currentHyp( i, Algo ) )->InputTypes.isEmpty();
+        else
+          isReqDisBound = true;
+        if ( isReqDisBound && isNoneAlg ) {
+          for (int j = i - 1; j >= SMESH::DIM_0D; j--) {
+            if ( j < aDim && currentHyp( j+1, Algo ) < 0 ) {
+              myDlg->disableTab( j );
+              setCurrentHyp( j , Algo, -1 );
+            }
           }
           break;
         }
+        else if ( isNoneAlg ) {
+          myDlg->disableTab( i );
+        }
       }
     }
     myDlg->enableTab( aDim );
     myDlg->setCurrentTab( aDim );
   }
+  THypDataList anAvailableAlgsData;
   QStringList aHypothesesSetsList = SMESH::GetHypothesesSets( aDim );
   QStringList aFilteredHypothesesSetsList;
   aFilteredHypothesesSetsList.clear();
   QStringList::const_iterator inHypoSetName = aHypothesesSetsList.begin();
-  for ( ; inHypoSetName != aHypothesesSetsList.end(); ++inHypoSetName )
-  {
+  for ( ; inHypoSetName != aHypothesesSetsList.end(); ++inHypoSetName ) {
     HypothesesSet* currentHypoSet = SMESH::GetHypothesesSet( *inHypoSetName );
     bool isAvailable = false;
     currentHypoSet->init( true );
-    while ( currentHypoSet->next(), currentHypoSet->more() )
-    {
+    while ( currentHypoSet->next(), currentHypoSet->more() ) {
       isAvailable = false;
-      if ( HypothesisData* algoDataIn = SMESH::GetHypothesisData( currentHypoSet->current() ))
-      {
-        for (int i = SMESH::DIM_0D; i <= myMaxShapeDim; i++)
-        {
-          if ( myAvailableHypData[i][Algo].count() == 0 ) {
-            availableHyps( i, Algo, anAvailableAlgs, anAvailableAlgsData );
-            for ( int j = 0 ; j < anAvailableAlgsData.count(); j++ )
-            {
-              HypothesisData* aCurAlgo = anAvailableAlgsData.at( j );
-              if ( aCurAlgo->Label == algoDataIn->Label ){
-                isAvailable = true;
-                break;
-              }
-            }
-          }
-          else {
-            for (int j = 0; j < myAvailableHypData[i][Algo].count(); ++j) {
-              HypothesisData* aCurAlgo = hypData( i, Algo, j );
-              if ( aCurAlgo->Label == algoDataIn->Label ){
-                isAvailable = true;
-                break;
-              }
-            }
+      if ( HypothesisData* algoDataIn = SMESH::GetHypothesisData( currentHypoSet->current() )) {
+        for (int i = SMESH::DIM_0D; i <= myMaxShapeDim; i++) {
+          int anCurrentAvailableAlgo = myAvailableHypData[i][Algo].indexOf( algoDataIn );
+          if ( anCurrentAvailableAlgo > -1 ) {
+            isAvailable = true;
+            break;
           }
-          if ( isAvailable ) break;
         }
-        if ( !isAvailable ) break;
+        if ( !isAvailable )
+          break;
       }
     }
     if ( isAvailable )
@@ -2823,3 +2817,35 @@ void SMESHGUI_MeshOp::setFilteredAlgoData( const int theTabIndex, const int theI
   }
   myDlg->setHypoSets( aFilteredHypothesesSetsList );
 }
+
+//================================================================================
+/*!
+ * \brief Get current name types of mesh
+  * \param theIndex - current index types of mesh
+  * \retval QString - result
+ */
+//================================================================================
+QString SMESHGUI_MeshOp::currentMeshTypeName( const int theIndex ) const
+{
+  QString aMeshType = "";
+  switch ( theIndex ) {
+  case MT_ANY:
+    aMeshType = "ANY";
+    break;
+  case MT_TRIANGULAR:
+    aMeshType = "TRIA";
+    break;
+  case MT_QUADRILATERAL:
+    aMeshType = "QUAD";
+    break;
+  case MT_TETRAHEDRAL:
+    aMeshType = "TETRA";
+    break;
+  case MT_HEXAHEDRAL:
+    aMeshType = "HEXA";
+    break;
+  default:;
+  }
+  return aMeshType;
+}
+
index 99a699ba489bc9244d3d62afb0048319c505b4a4..206f4504e97784ff74d3f3a85b681b7d1b72172d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -89,13 +89,21 @@ protected slots:
 
 private:
   typedef QList<HypothesisData*> THypDataList; // typedef: list of hypothesis data
+  typedef QMap<QString, bool>    THypLabelIsAppMap; // typedef: map of hypothesis is applicable
 
   bool                           isValid( QString& ) const;
+  bool                           isCompatibleToGeometry( HypothesisData* ,
+                                                         QString,
+                                                         GEOM::GEOM_Object_var);
+  bool                           isCompatibleToMeshType( HypothesisData* ,
+                                                         QString);
   void                           availableHyps( const int, 
                                                 const int,
                                                 QStringList&,
                                                 THypDataList&,
-                                                HypothesisData* = 0 ) const;
+                                                HypothesisData* = 0,
+                                                HypothesisData* = 0,
+                                                const QString& = "");
   void                           existingHyps( const int, 
                                                const int, 
                                                _PTR(SObject),
@@ -137,6 +145,7 @@ private:
   void                           createMeshTypeList( QStringList& );
   void                           setAvailableMeshType( const QStringList& );
   void                           setFilteredAlgoData( const int, const int );
+  QString                        currentMeshTypeName( const int ) const;
 
 private:
 
@@ -152,7 +161,8 @@ private:
                                                  //   edited mesh/sub-mesh
   // hypdata corresponding to hypotheses present in myDlg
   THypDataList                   myAvailableHypData[4][NbHypTypes];
-  THypDataList                   myFilteredAlgoData[4];
+  QString                        myLastGeomToSelect;
+  THypLabelIsAppMap              myHypMapIsApplicable;
   bool                           myIgnoreAlgoSelection;
   HypothesesSet* myHypoSet;
   int myDim, myType, myMaxShapeDim;
index 4feeca8da3c818da0352f49f080f17c8a58ab70e..d911a2a26ad16a4edbbf3e5bba273d3567a949db 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index 629d3d3528d0b2f73f5bc88864e8e2ece4ee873f..b428c7a4a92442e28b8e6fb3d11bc0634a4b4a8c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index 88a471b21667566872e6d30c1a876b054bd0e832..8960747f0aecc2d785262d74dc12c925014a6813 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index 6b4940ed1960c1cfbbc2cc45dbbc05413302d143..1eca936021b2a32b899637fc218ec66604c7aadb 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index 46bf3ef55f73d3773143e785055c307d01a84b01..dd4d753377e5abe513a2ca41257535fde408d23f 100755 (executable)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -391,6 +391,8 @@ void SMESHGUI_MeshPatternDlg::Init()
   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(onSelectionDone()));
   connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), SLOT(onDeactivate()));
   connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), SLOT(reject()));
+  connect(mySMESHGUI, SIGNAL(SignalActivatedViewManager()), SLOT( onOpenView()));
+  connect(mySMESHGUI, SIGNAL(SignalCloseView()), SLOT( onCloseView()));
 
   myTypeGrp->button(Type_2d)->setChecked(true);
   onTypeChanged(Type_2d);
@@ -558,6 +560,32 @@ void SMESHGUI_MeshPatternDlg::reject()
   QDialog::reject();
 }
 
+//=================================================================================
+// function : onOpenView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_MeshPatternDlg::onOpenView()
+{
+  if(!mySelector) {
+    mySelector = SMESH::GetViewWindow( mySMESHGUI )->GetSelector();
+    mySMESHGUI->EmitSignalDeactivateDialog();
+    setEnabled(true);
+    activateSelection();
+    connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(onSelectionDone()));
+  }
+}
+
+//=================================================================================
+// function : onCloseView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_MeshPatternDlg::onCloseView()
+{
+  onDeactivate();
+  mySelector = 0;
+}
+
+
 //=================================================================================
 // function : onHelp()
 // purpose  :
@@ -715,8 +743,13 @@ void SMESHGUI_MeshPatternDlg::enterEvent (QEvent*)
   if (myIsCreateDlgOpen)
     return;
 
-  if (myReverseChk->isChecked())
+  if (myReverseChk->isChecked()) {
+    SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
+    if ( aViewWindow && !mySelector) {
+      mySelector = aViewWindow->GetSelector();
+    }
     displayPreview();
+  }
   mySMESHGUI->EmitSignalDeactivateDialog();
   setEnabled(true);
   activateSelection();
index 43317618f40971ba28f2585a431c4495963be220..5b656f726cdb8543f32958ab6bcacb74ff06ce50 100755 (executable)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -98,6 +98,8 @@ private slots:
   void                                onCloseCreationDlg();
   void                                onTextChanged( const QString& );
   void                                onNodeChanged( int );
+  void                                onOpenView();
+  void                                onCloseView();
 
 private:
   QWidget*                            createButtonFrame( QWidget* );
index d4e69f5e2dca66c01b3188ceb17e9f4bad445aac..8663e55563f767b816dd996263b39bfbd91ab8ba 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index fcadc44d908ade341bc26cf3a6703c30eeb69c91..ae8b7ff85a2c9a7107d9b68e8d2e629685692ef5 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index e42a8389dc2383dfe70e7f75ac97817df9e0ee55..d598d95e9231b99cd6f28c890ec2da58e09e32df 100755 (executable)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -112,8 +112,8 @@ SMESHGUI_MultiEditDlg
                         const bool the3d2d,
                         bool       theDoInit):
   SMESHGUI_PreviewDlg(theModule),
-  mySelector(SMESH::GetViewWindow(theModule)->GetSelector()),
   mySelectionMgr(SMESH::GetSelectionMgr(theModule)),
+  mySelector(SMESH::GetViewWindow(theModule)->GetSelector()),
   mySMESHGUI(theModule)
 {
   setModal(false);
@@ -397,6 +397,8 @@ void SMESHGUI_MultiEditDlg::Init()
   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(onSelectionDone()));
   connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), SLOT(onDeactivate()));
   connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), SLOT(reject()));
+  connect(mySMESHGUI, SIGNAL(SignalActivatedViewManager()), SLOT( onOpenView()));
+  connect(mySMESHGUI, SIGNAL(SignalCloseView()), SLOT( onCloseView()));
 
   // dialog controls
   connect(myFilterBtn, SIGNAL(clicked()), SLOT(onFilterBtn()  ));
@@ -476,6 +478,30 @@ void SMESHGUI_MultiEditDlg::reject()
   QDialog::reject();
 }
 
+//=================================================================================
+// function : onOpenView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_MultiEditDlg::onOpenView()
+{
+  if(!mySelector) {
+    mySelector = SMESH::GetViewWindow( mySMESHGUI )->GetSelector();
+    mySMESHGUI->EmitSignalDeactivateDialog();
+    setEnabled(true);
+  }
+}
+
+//=================================================================================
+// function : onCloseView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_MultiEditDlg::onCloseView()
+{
+  onDeactivate();
+  mySelector = 0;
+}
+
+
 //=================================================================================
 // function : onHelp()
 // purpose  :
@@ -588,6 +614,10 @@ void SMESHGUI_MultiEditDlg::onDeactivate()
 void SMESHGUI_MultiEditDlg::enterEvent (QEvent*)
 {
   if (!isEnabled()) {
+    SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
+    if ( aViewWindow && !mySelector) {
+      mySelector = aViewWindow->GetSelector();
+    }
     mySMESHGUI->EmitSignalDeactivateDialog();
     setEnabled(true);
     setSelectionMode();
@@ -645,6 +675,9 @@ void SMESHGUI_MultiEditDlg::onFilterAccepted()
 //=======================================================================
 bool SMESHGUI_MultiEditDlg::isIdValid (const int theId) const
 {
+  if ( !myActor )
+    return true; // filter can't work w/o actor
+
   SVTK_Selector* aSelector = SMESH::GetSelector();
   Handle(SMESHGUI_Filter) aFilter =
     Handle(SMESHGUI_Filter)::DownCast(aSelector->GetFilter(myFilterType));
@@ -1079,7 +1112,7 @@ bool SMESHGUI_ChangeOrientationDlg::process (SMESH::SMESH_MeshEditor_ptr theEdit
 
 int SMESHGUI_ChangeOrientationDlg::nbElemsInMesh()
 {
-  return ( myFilterType = SMESH::FaceFilter ) ? myMesh->NbFaces() : myMesh->NbVolumes();
+  return ( myFilterType == SMESH::FaceFilter ) ? myMesh->NbFaces() : myMesh->NbVolumes();
 }
 
 /*!
@@ -1283,7 +1316,7 @@ bool SMESHGUI_CuttingOfQuadsDlg::process (SMESH::SMESH_MeshEditor_ptr theEditor,
     {
       if ( hasObj )
         return theEditor->QuadTo4Tri( obj ), true;
-      SMESH::SMESH_IDSource_wrap elems = theEditor->MakeIDSource( theIds, SMESH::FACE );
+      SMESH::IDSource_wrap elems = theEditor->MakeIDSource( theIds, SMESH::FACE );
       theEditor->QuadTo4Tri( elems );
       return true;
     }
@@ -1539,7 +1572,6 @@ SMESHGUI_SplitVolumesDlg::SMESHGUI_SplitVolumesDlg(SMESHGUI* theModule)
   QLabel* dXLbl = new QLabel( tr("SMESH_DX"), myFacetSelGrp);
   QLabel* dYLbl = new QLabel( tr("SMESH_DY"), myFacetSelGrp);
   QLabel* dZLbl = new QLabel( tr("SMESH_DZ"), myFacetSelGrp);
-  QPushButton* axisBtn[3];
   for ( int i = 0; i < 3; ++i )
   {
     myPointSpin[i] = new SMESHGUI_SpinBox( myFacetSelGrp );
@@ -1619,7 +1651,7 @@ bool SMESHGUI_SplitVolumesDlg::process (SMESH::SMESH_MeshEditor_ptr theEditor,
                                         const SMESH::long_array&    theIds,
                                         SMESH::SMESH_IDSource_ptr   theObj)
 {
-  SMESH::SMESH_IDSource_wrap obj = theObj;
+  SMESH::IDSource_wrap obj = theObj;
   if ( CORBA::is_nil( obj ))
     obj = theEditor->MakeIDSource( theIds, SMESH::VOLUME );
   else
@@ -1950,7 +1982,7 @@ void SMESHGUI_SplitVolumesDlg::onSetDir()
     if ( sender() == myAxisBtn[i] )
       break;
   if ( i == 3 )
-    i == 0;
+    i = 0;
   myDirSpin[i]->SetValue(1.);
 
   if ( myActor && !myMesh->_is_nil() && myMesh->NbNodes() > 0 )
index a8a0d0a62dbbdcbb7ee24c3d6fe0033e1cc01f32..2f92d6b00dfdc4d125cc0f22b2c30d47ede6e881 100755 (executable)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -102,6 +102,8 @@ protected slots:
   virtual void              onToAllChk();
   void                      onFilterAccepted();
   virtual void              on3d2dChanged(int);
+  void                      onOpenView();
+  void                      onCloseView();
 
   SMESH::NumericalFunctor_ptr getNumericalFunctor();
 
index 6988b3972e3c97b9bb165555edaf78fd811d1a40..5a2cf87b8e20c0e192aff50ad89ab6d6a64a807f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -230,8 +230,8 @@ namespace SMESH
 //=================================================================================
 SMESHGUI_NodesDlg::SMESHGUI_NodesDlg( SMESHGUI* theModule ): 
   QDialog( SMESH::GetDesktop( theModule ) ),
-  mySelector( SMESH::GetViewWindow( theModule )->GetSelector() ),
   mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
+  mySelector( SMESH::GetViewWindow( theModule )->GetSelector() ),
   mySMESHGUI( theModule )
 {
   setModal( false );
@@ -382,8 +382,9 @@ void SMESHGUI_NodesDlg::Init()
   connect( mySMESHGUI,     SIGNAL( SignalDeactivateActiveDialog() ), SLOT( DeactivateActiveDialog() ) );
   /* to close dialog if study frame change */
   connect( mySMESHGUI,     SIGNAL( SignalStudyFrameChanged() ),      SLOT( reject() ) );
-  connect(mySMESHGUI,      SIGNAL(SignalCloseAllDialogs()),          SLOT(reject()));
-
+  connect( mySMESHGUI,     SIGNAL( SignalCloseAllDialogs() ),        SLOT( reject() ) );
+  connect( mySMESHGUI,     SIGNAL( SignalActivatedViewManager() ),   SLOT( onOpenView() ) );
+  connect( mySMESHGUI,     SIGNAL( SignalCloseView() ),              SLOT( onCloseView() ) );
   // set selection mode
   SMESH::SetPointRepresentation( true );
   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ) )
@@ -402,7 +403,6 @@ void SMESHGUI_NodesDlg::ValueChangedInSpinBox( double newValue )
     double vx = SpinBox_X->GetValue();
     double vy = SpinBox_Y->GetValue();
     double vz = SpinBox_Z->GetValue();
-
     mySimulation->SetPosition( vx, vy, vz );
   }
 }
@@ -547,7 +547,6 @@ void SMESHGUI_NodesDlg::reject()
   disconnect( mySelectionMgr, 0, this, 0 );
   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ) )
     aViewWindow->SetSelectionMode( ActorSelection );
-
   mySimulation->SetVisibility( false );
   SMESH::SetPointRepresentation( false );
   mySMESHGUI->ResetState();
@@ -555,6 +554,36 @@ void SMESHGUI_NodesDlg::reject()
   QDialog::reject();
 }
 
+//=================================================================================
+// function : onOpenView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_NodesDlg::onOpenView()
+{
+  if ( mySelector && mySimulation ) {
+    mySimulation->SetVisibility(false);
+    SMESH::SetPointRepresentation(false);
+  }
+  else {
+    SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
+    mySelector = aViewWindow->GetSelector();
+    mySimulation = new SMESH::TNodeSimulation(aViewWindow);
+    ActivateThisDialog();
+  }
+}
+
+//=================================================================================
+// function : onCloseView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_NodesDlg::onCloseView()
+{
+  DeactivateActiveDialog();
+  mySelector = 0;
+  delete mySimulation;
+  mySimulation = 0;
+}
+
 //=================================================================================
 // function : ClickOnHelp()
 // purpose  :
@@ -644,8 +673,14 @@ void SMESHGUI_NodesDlg::SelectionIntoArgument()
 //=================================================================================
 void SMESHGUI_NodesDlg::enterEvent( QEvent* )
 {
-  if ( !GroupConstructors->isEnabled() )
+  if ( !GroupConstructors->isEnabled() ) {
+    SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
+    if ( aViewWindow && !mySelector && !mySimulation) {
+      mySelector = aViewWindow->GetSelector();
+      mySimulation = new SMESH::TNodeSimulation(aViewWindow);
+    }
     ActivateThisDialog();
+  }
 }
 
 //=================================================================================
@@ -678,7 +713,6 @@ void SMESHGUI_NodesDlg::ActivateThisDialog()
   SMESH::SetPointRepresentation( true );
   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ) )
     aViewWindow->SetSelectionMode( NodeSelection );
-
   SelectionIntoArgument();
 }
 
index b5b2faa9ddb4658bc5825d5b50fadce91c4a48bb..5843d3bf1087edf2156d0924d1c61a1e799ee7f7 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -117,6 +117,8 @@ private slots:
   void                    ActivateThisDialog();
   void                    SelectionIntoArgument();
   void                    ValueChangedInSpinBox( double );
+  void                    onOpenView();
+  void                    onCloseView();
 };
 
 #endif // SMESHGUI_NODESDLG_H
index 59c4e139d5a1f37ebc5ce05fa2a4a6beebd5b172..36d78d77b248c52b465e8db4244758a2af17ae8e 100755 (executable)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 4e5097c93cbb4ddc20be63c2d76b61688f9c5aed..d88583e832e445c376756218d5adf4405ef5a5a9 100755 (executable)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 18c28a441a7ae5f2f0cf851d787fa3237fd76182..9f492bf17024f1552b8233880eeda004220edd96 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
@@ -29,6 +29,7 @@ namespace SMESHOp {
     OpSelectFiltersLibrary   = 1010,   // MENU TOOLS - SELECTION FILTERS LIBRARY
     OpReset                  = 1020,   // RESET
     OpScalarBarProperties    = 1021,   // SCALAR BAR PROPERTIES
+    OpShowScalarBar          = 1022,   // SHOW SCALAR BAR
     OpSaveDistribution       = 1030,   // SAVE DISTRIBUTION
     OpShowDistribution       = 1031,   // SHOW DISTRIBUTION
 #ifndef DISABLE_PLOT2DVIEWER
@@ -144,6 +145,7 @@ namespace SMESHOp {
     OpQuadraticPentahedron   = 4107,   // MENU MODIFICATION - ADD - QUADRATIC PENTAHEDRON
     OpQuadraticHexahedron    = 4108,   // MENU MODIFICATION - ADD - QUADRATIC HEXAHEDRON
     OpTriQuadraticHexahedron = 4109,   // MENU MODIFICATION - ADD - TRIQUADRATIC HEXAHEDRON
+    OpQuadraticPolygon       = 4110,   // MENU MODIFICATION - ADD - QUADRATIC POLYGON
     OpRemoveNodes            = 4200,   // MENU MODIFICATION - REMOVE - NODE
     OpRemoveElements         = 4201,   // MENU MODIFICATION - REMOVE - ELEMENTS
     OpRemoveOrphanNodes      = 4202,   // MENU MODIFICATION - REMOVE - ORPHAN NODES
@@ -174,6 +176,7 @@ namespace SMESHOp {
     OpPatternMapping         = 4512,   // MENU MODIFICATION - PATTERN MAPPING
     OpConvertMeshToQuadratic = 4513,   // MENU MODIFICATION - CONVERT TO/FROM QUADRATIC
     OpCreateBoundaryElements = 4514,   // MENU MODIFICATION - CREATE BOUNDARY ELEMENTS
+    OpSplitBiQuadratic       = 4515,   // MENU MODIFICATION - SPLIT BI-QUADRATIC TO LINEAR
     // Measurements -------------------//--------------------------------
     OpPropertiesLength       = 5000,   // MENU MEASUREMENTS - BASIC PROPERTIES - LENGTH
     OpPropertiesArea         = 5001,   // MENU MEASUREMENTS - BASIC PROPERTIES - AREA
index 5b469954ca9a90833c85aecfdbc3870d61f9f1d2..376c35af843b72f1c148b835ecd75c6d9af74d2a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 4d7a821ea1fedcfe8dc982f6f28a9b77799aff54..42e30ef39be20f15f1476b094573311e55f01bbc 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 747cd59a82be15a6220fdc5a746fdee67d7cdd88..614a2558c24687f8b581c737ff526af437a1cec3 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 3c2087bffdb46d8c02b4074fab3da87edb02fa17..f4f3ca63f8be48419ac6aabc0ae5c7f6e3378535 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
diff --git a/src/SMESHGUI/SMESHGUI_PreVisualObj.cxx b/src/SMESHGUI/SMESHGUI_PreVisualObj.cxx
new file mode 100644 (file)
index 0000000..8107a11
--- /dev/null
@@ -0,0 +1,142 @@
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&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, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// 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 "SMESHGUI_PreVisualObj.h"
+
+#include <SMDS_Mesh.hxx>
+#include <SMESH_Actor.h>
+
+SMESHGUI_PreVisualObj::SMESHGUI_PreVisualObj()
+{
+  myMesh = new SMDS_Mesh();
+}
+
+bool SMESHGUI_PreVisualObj::Update( int theIsClear = true )
+{
+  return false;
+}
+
+void SMESHGUI_PreVisualObj::UpdateFunctor( const SMESH::Controls::FunctorPtr& theFunctor )
+{
+  if ( theFunctor ) theFunctor->SetMesh( GetMesh() );
+}
+
+int SMESHGUI_PreVisualObj::GetElemDimension( const int theObjId )
+{
+  if ( const SMDS_MeshElement* anElem = myMesh->FindElement( theObjId ))
+  {
+    switch ( anElem->GetType() )
+    {
+    case SMDSAbs_Edge  :     return 1;
+    case SMDSAbs_Face  :     return 2;
+    case SMDSAbs_Volume:     return 3;
+    // case SMDSAbs_0DElement : return 0;
+    // case SMDSAbs_Ball :      return 0;
+    default            :     return 0;
+    }
+  }
+  return -1;
+}
+
+int SMESHGUI_PreVisualObj::GetNbEntities( const SMDSAbs_ElementType theType ) const
+{
+  return myMesh->GetMeshInfo().NbElements( theType );
+}
+
+SMESH::SMESH_Mesh_ptr SMESHGUI_PreVisualObj::GetMeshServer()
+{
+  return SMESH::SMESH_Mesh::_nil();
+}
+
+//=================================================================================
+// function : GetEdgeNodes
+// purpose  : Retrieve ids of nodes from edge of elements ( edge is numbered from 1 )
+//=================================================================================
+
+bool SMESHGUI_PreVisualObj::GetEdgeNodes( const int theElemId,
+                                          const int theEdgeNum,
+                                          int&      theNodeId1,
+                                          int&      theNodeId2 ) const
+{
+  const SMDS_MeshElement* e = myMesh->FindElement( theElemId );
+  if ( !e || e->GetType() != SMDSAbs_Face )
+    return false;
+
+  int nbNodes = e->NbCornerNodes();
+  if ( theEdgeNum < 0 || theEdgeNum > nbNodes )
+    return false;
+
+  theNodeId1 = e->GetNode( theEdgeNum-1 )->GetID();
+  theNodeId2 = e->GetNode( theEdgeNum % nbNodes )->GetID();
+
+  return true;
+}
+
+bool SMESHGUI_PreVisualObj::IsValid() const
+{
+  return GetNbEntities( SMDSAbs_All ) > 0;
+}
+
+vtkUnstructuredGrid* SMESHGUI_PreVisualObj::GetUnstructuredGrid()
+{
+  return myMesh->getGrid();
+}
+
+
+vtkIdType SMESHGUI_PreVisualObj::GetNodeObjId( int theVTKID )
+{
+  const SMDS_MeshNode* aNode = myMesh->FindNodeVtk( theVTKID );
+  return aNode ? aNode->GetID() : -1;
+}
+
+vtkIdType SMESHGUI_PreVisualObj::GetNodeVTKId( int theObjID )
+{
+  const SMDS_MeshNode* aNode = myMesh->FindNode( theObjID );
+  return aNode ? aNode->GetID() : -1;
+}
+
+vtkIdType SMESHGUI_PreVisualObj::GetElemObjId( int theVTKID )
+{
+  return this->GetMesh()->fromVtkToSmds(theVTKID);
+}
+
+vtkIdType SMESHGUI_PreVisualObj::GetElemVTKId( int theObjID )
+{
+  const SMDS_MeshElement* e = myMesh->FindElement(theObjID);
+  return e ? e->getVtkId() : -1;
+}
+
+void SMESHGUI_PreVisualObj::ClearEntitiesFlags()
+{
+  myEntitiesState = SMESH_Actor::eAllEntity;
+  myEntitiesFlag = false;
+}
+
+bool SMESHGUI_PreVisualObj::GetEntitiesFlag()
+{
+  return myEntitiesFlag;
+}
+
+unsigned int SMESHGUI_PreVisualObj::GetEntitiesState()
+{
+  return myEntitiesState;
+}
diff --git a/src/SMESHGUI/SMESHGUI_PreVisualObj.h b/src/SMESHGUI/SMESHGUI_PreVisualObj.h
new file mode 100644 (file)
index 0000000..dcbfac9
--- /dev/null
@@ -0,0 +1,71 @@
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&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, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// 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_PreVisualObj.h
+//  Module : SMESH
+//
+#ifndef SMESHGUI_PreVisualObj_H
+#define SMESHGUI_PreVisualObj_H
+
+#include "SMESH_SMESHGUI.hxx"
+
+#include "SMESH_Object.h"
+
+/*!
+ * \brief Incarnation of SMESH_VisualObj allowing usage of SMESH_Actor
+ *        to show arbitrary mesh data. SMESHGUI_PreVisualObj encapsulates
+ *        a instance of SMDS_Mesh that can be filled by its user.
+ *        Main usage: to initialize a SMESH_Actor to display some preview
+ */
+class SMESHGUI_EXPORT SMESHGUI_PreVisualObj : public SMESH_VisualObj
+{
+  mutable SMDS_Mesh* myMesh;
+  bool               myEntitiesFlag;
+  unsigned int       myEntitiesState;
+
+ public:
+  SMESHGUI_PreVisualObj();
+  virtual SMDS_Mesh* GetMesh() const { return myMesh; }
+
+  virtual bool Update( int theIsClear );
+  virtual bool NulData() { return false; }
+  virtual void UpdateFunctor( const SMESH::Controls::FunctorPtr& theFunctor );
+  virtual int  GetElemDimension( const int theObjId );
+  virtual int  GetNbEntities( const SMDSAbs_ElementType theType) const;
+  virtual bool IsValid() const;
+  virtual bool GetEdgeNodes( const int theElemId,
+                             const int theEdgeNum,
+                             int&      theNodeId1,
+                             int&      theNodeId2 ) const;
+
+  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();
+
+  virtual SMESH::SMESH_Mesh_ptr GetMeshServer();
+  virtual vtkUnstructuredGrid*  GetUnstructuredGrid();
+};
+
+#endif
index 4ecb44cabf556f96e7afd618cd9337287e40a070..68deaf5a5c65c9bdc16b7234404ecbe8dee70f28 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -448,7 +448,7 @@ SMESHGUI_Preferences_ScalarBarDlg::SMESHGUI_Preferences_ScalarBarDlg( SMESHGUI*
   connect( mySelectionMgr,      SIGNAL( currentSelectionChanged() ), this, SLOT( onSelectionChanged() ) );
   connect( mySMESHGUI,          SIGNAL( SignalCloseAllDialogs() ),   this, SLOT( reject() ) );
 
-  myHelpFileName = "quality_page.html";
+  myHelpFileName = "scalar_bar_dlg.html";
 }
 
 //=================================================================================================
index d286d2c411f36ecfc74e260bb50f4a9bc8c76efd..88718598e5c88bbde2da04f3a7b395b8fcd08ea1 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 3fc6b4776bec1966066417f5e8eb629f443c0583..8dc5f52c936104e0451554d3ae1b8ec8c3cbf321 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 // purpose  :
 //=================================================================================
 SMESHGUI_PreviewDlg::SMESHGUI_PreviewDlg(SMESHGUI* theModule) :
-  mySMESHGUI(theModule),
   QDialog(SMESH::GetDesktop( theModule )),
+  mySMESHGUI(theModule),
   myIsApplyAndClose( false )
 {
   mySimulation = new SMESHGUI_MeshEditPreview(SMESH::GetViewWindow( mySMESHGUI ));
+  connect(mySMESHGUI, SIGNAL(SignalCloseView()),            this, SLOT(onCloseView()));
+  connect(mySMESHGUI, SIGNAL(SignalActivatedViewManager()), this, SLOT(onOpenView()));
 }
 
 //=================================================================================
@@ -66,7 +68,7 @@ SMESHGUI_PreviewDlg::~SMESHGUI_PreviewDlg()
 // purpose  : Show preview in the viewer
 //=================================================================================
 void SMESHGUI_PreviewDlg::showPreview(){
-  if(mySimulation)
+  if(mySimulation && mySimulation->GetActor())
     mySimulation->SetVisibility(true);
 }
 
@@ -75,7 +77,7 @@ void SMESHGUI_PreviewDlg::showPreview(){
 // purpose  : Hide preview in the viewer
 //=================================================================================
 void SMESHGUI_PreviewDlg::hidePreview(){
-  if(mySimulation)
+  if(mySimulation && mySimulation->GetActor())
     mySimulation->SetVisibility(false);
 }
 
@@ -87,7 +89,6 @@ void SMESHGUI_PreviewDlg::connectPreviewControl(){
   connect(myPreviewCheckBox, SIGNAL(toggled(bool)), this, SLOT(onDisplaySimulation(bool)));
 }
 
-
 //=================================================================================
 // function : toDisplaySimulation
 // purpose  : 
@@ -124,16 +125,38 @@ bool SMESHGUI_PreviewDlg::isApplyAndClose() const
   return myIsApplyAndClose;
 }
 
+//=================================================================================
+// function : onCloseView()
+// purpose  : SLOT called when close view
+//=================================================================================
+void SMESHGUI_PreviewDlg::onCloseView()
+{
+  if ( mySimulation && mySimulation->GetActor())
+    mySimulation->SetVisibility(false);
+  delete mySimulation;
+  mySimulation=0;
+}
 
+//=================================================================================
+// function : onOpenView()
+// purpose  : SLOT called when open view
+//=================================================================================
+void SMESHGUI_PreviewDlg::onOpenView()
+{
+  if ( !mySimulation)
+    mySimulation = new SMESHGUI_MeshEditPreview(SMESH::GetViewWindow( mySMESHGUI ));
+}
 //=================================================================================
 // class    : SMESHGUI_SMESHGUI_MultiPreviewDlg()
 // purpose  :
 //=================================================================================
 SMESHGUI_MultiPreviewDlg::SMESHGUI_MultiPreviewDlg( SMESHGUI* theModule ) :
-  mySMESHGUI( theModule ),
   QDialog( SMESH::GetDesktop( theModule ) ),
+  mySMESHGUI( theModule ),
   myIsApplyAndClose( false )
 {
+  mySimulationList.clear();
+  connect(mySMESHGUI, SIGNAL(SignalCloseView()), this, SLOT(onCloseView()));
 }
 
 //=================================================================================
@@ -152,7 +175,8 @@ SMESHGUI_MultiPreviewDlg::~SMESHGUI_MultiPreviewDlg()
 void SMESHGUI_MultiPreviewDlg::showPreview()
 {
   for ( int i = 0; i < mySimulationList.count(); i++ )
-    mySimulationList[i]->SetVisibility( true );
+    if(mySimulationList[i] && mySimulationList[i]->GetActor())
+      mySimulationList[i]->SetVisibility( true );
 }
 
 //=================================================================================
@@ -162,7 +186,8 @@ void SMESHGUI_MultiPreviewDlg::showPreview()
 void SMESHGUI_MultiPreviewDlg::hidePreview()
 {
   for ( int i = 0; i < mySimulationList.count(); i++ )
-    mySimulationList[i]->SetVisibility( false );
+    if(mySimulationList[i] && mySimulationList[i]->GetActor())
+      mySimulationList[i]->SetVisibility( false );
 }
 
 //=================================================================================
@@ -174,7 +199,6 @@ void SMESHGUI_MultiPreviewDlg::connectPreviewControl()
   connect( myPreviewCheckBox, SIGNAL( toggled( bool ) ), this, SLOT( onDisplaySimulation( bool ) ) );
 }
 
-
 //=================================================================================
 // function : toDisplaySimulation
 // purpose  : 
@@ -227,3 +251,13 @@ void SMESHGUI_MultiPreviewDlg::setSimulationPreview( QList<SMESH::MeshPreviewStr
     mySimulationList[i]->SetData( theMeshPreviewStruct[i].operator->() );
   }
 }
+
+//=================================================================================
+// function : onCloseView()
+// purpose  : SLOT called when close view
+//=================================================================================
+void SMESHGUI_MultiPreviewDlg::onCloseView()
+{
+  qDeleteAll( mySimulationList );
+  mySimulationList.clear();
+}
index 1b63f92240a5f4edc5b662a19c5094b3d18bc877..32a277a6575e84b82d6b1ef78239c72550215173 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -58,8 +58,9 @@ protected:
 
 protected slots:
  void                      toDisplaySimulation();
+ void                      onCloseView();
+ void                      onOpenView();
  virtual void              onDisplaySimulation( bool );
-
   
 protected:
   SMESHGUI*                 mySMESHGUI;              /* Current SMESHGUI object */  
@@ -87,6 +88,7 @@ protected:
 
 protected slots:
  void                      toDisplaySimulation();
+ void                      onCloseView();
  virtual void              onDisplaySimulation( bool );
 
   
index 400a02532f77e09d797a6bbdb724343d35509910..d1c732fafb600333d6aafb188fd3577d2d625db6 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -156,8 +156,8 @@ SMESHGUI_PropertiesDlg::SMESHGUI_PropertiesDlg( const VTK::MarkerMap& customMark
   myBallGrp = new QGroupBox( tr( "BALLS" ), mainFrame() );
   QLabel* ballColorLab = new QLabel( tr( "COLOR" ), myBallGrp );
   myBallColor = new QtxColorButton( myBallGrp );
-  QLabel* ballSizeLab = new QLabel( tr( "SIZE" ), myBallGrp );
-  myBallSize = new QtxIntSpinBox( myBallGrp );
+  // QLabel* ballSizeLab = new QLabel( tr( "SIZE" ), myBallGrp );
+  // myBallSize = new QtxIntSpinBox( myBallGrp );
   QLabel* ballScaleLab = new QLabel( tr( "SCALE_FACTOR" ), myBallGrp );
   myBallScale = new QtxDoubleSpinBox( 1e-2, 1e7, 0.5, myBallGrp );
   hl = new QHBoxLayout( myBallGrp );
@@ -165,12 +165,12 @@ SMESHGUI_PropertiesDlg::SMESHGUI_PropertiesDlg( const VTK::MarkerMap& customMark
   hl->setSpacing( SPACING );
   hl->addWidget( ballColorLab );
   hl->addWidget( myBallColor );
-  hl->addWidget( ballSizeLab );
-  hl->addWidget( myBallSize );
+  // hl->addWidget( ballSizeLab );
+  // hl->addWidget( myBallSize );
   hl->addWidget( ballScaleLab );
   hl->addWidget( myBallScale );
   widthLab1 = qMax( widthLab1, ballColorLab->minimumSizeHint().width() );
-  widthLab2 = qMax( widthLab2, ballSizeLab->minimumSizeHint().width() );
+  // widthLab2 = qMax( widthLab2, ballSizeLab->minimumSizeHint().width() );
   
   // -- orientation vector controls
   myOrientationGrp = new QGroupBox( tr( "ORIENTATIONS" ), mainFrame() );
@@ -234,13 +234,13 @@ SMESHGUI_PropertiesDlg::SMESHGUI_PropertiesDlg( const VTK::MarkerMap& customMark
   myVolumeColor->label()->setMinimumWidth( widthLab2 );
   outlineWidthLab->setMinimumWidth( widthLab2 );
   elem0dSizeLab->setMinimumWidth( widthLab2 );
-  ballSizeLab->setMinimumWidth( widthLab2 );
+  // ballSizeLab->setMinimumWidth( widthLab2 );
   orientationScaleLab->setMinimumWidth( widthLab2 );
 
   myEdgeWidth->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
   myOutlineWidth->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
   myElem0dSize->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
-  myBallSize->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
+  // myBallSize->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
   myBallScale->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
   myOrientationSize->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
   myShrinkSize->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
@@ -248,7 +248,7 @@ SMESHGUI_PropertiesDlg::SMESHGUI_PropertiesDlg( const VTK::MarkerMap& customMark
   // initialize widgets
   myNodeMarker->setCustomMarkers( customMarkers );
   myElem0dSize->setRange( 1, 10 );
-  myBallSize->setRange( 1, 10 );
+  // myBallSize->setRange( 1, 10 );
   myEdgeWidth->setRange( 1, 5 );
   myOutlineWidth->setRange( 1, 5 );
   myShrinkSize->setRange( 20, 100 );
@@ -522,19 +522,19 @@ QColor SMESHGUI_PropertiesDlg::ballColor() const
   \brief Set discrete elements (balls) size
   \param size discrete elements (balls) size
 */
-void SMESHGUI_PropertiesDlg::setBallSize( int size )
+/*void SMESHGUI_PropertiesDlg::setBallSize( int size )
 {
   myBallSize->setValue( size );
-}
+}*/
 
 /*!
   \brief Get discrete elements (balls) size
   \return current discrete elements (balls) size
 */
-int SMESHGUI_PropertiesDlg::ballSize() const
+/*int SMESHGUI_PropertiesDlg::ballSize() const
 {
   return myBallSize->value();
-}
+}*/
 
 /*!
   \brief Set discrete elements (balls) scale factor
index 5ec3ce6200065554c3d89e53dd4ebe5c40106223..c2f964653351fe655f2226db5a96e04eabae0675 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -82,8 +82,8 @@ public:
 
   void              setBallColor( const QColor& );
   QColor            ballColor() const;
-  void              setBallSize( int );
-  int               ballSize() const;
+  // void           setBallSize( int );
+  // int            ballSize() const;
   void              setBallScale( double );
   double            ballScale() const;
 
@@ -134,7 +134,7 @@ private:
   QtxIntSpinBox*          myElem0dSize;
   // - balls
   QtxColorButton*         myBallColor;
-  QtxIntSpinBox*          myBallSize;
+  // QtxIntSpinBox*       myBallSize;
   QtxDoubleSpinBox*       myBallScale;
   // - orientation vectors
   QtxColorButton*         myOrientationColor;
index 9654bc166922a4f5fe618ecf2b5018eb76c12b7a..1ebfd06227d4aeace34ea6495fa66f0c7e473292 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -80,8 +80,8 @@
 SMESHGUI_RemoveElementsDlg
 ::SMESHGUI_RemoveElementsDlg(SMESHGUI* theModule)
   : QDialog(SMESH::GetDesktop(theModule)),
-    mySelector(SMESH::GetViewWindow(theModule)->GetSelector()),
     mySelectionMgr(SMESH::GetSelectionMgr(theModule)),
+    mySelector(SMESH::GetViewWindow(theModule)->GetSelector()),
     mySMESHGUI(theModule),
     myBusy(false),
     myFilterDlg(0)
@@ -204,7 +204,9 @@ void SMESHGUI_RemoveElementsDlg::Init()
   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(reject()));
+  connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()),      this, SLOT(reject()));
+  connect(mySMESHGUI, SIGNAL (SignalActivatedViewManager()), this, SLOT(onOpenView()));
+  connect(mySMESHGUI, SIGNAL (SignalCloseView()),            this, SLOT(onCloseView()));
   connect(myEditCurrentArgument, SIGNAL(textChanged(const QString&)),
           SLOT(onTextChange(const QString&)));
 
@@ -234,6 +236,10 @@ void SMESHGUI_RemoveElementsDlg::ClickOnApply()
     try {
       SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
       aResult = aMeshEditor->RemoveElements(anArrayOfIdeces.in());
+
+      if ( myActor && myMesh->NbElements() == 0 )
+        myActor->SetRepresentation(SMESH_Actor::ePoint);
+
     } catch (const SALOME::SALOME_Exception& S_ex) {
       SalomeApp_Tools::QtCatchCorbaException(S_ex);
       myEditCurrentArgument->clear();
@@ -277,6 +283,28 @@ void SMESHGUI_RemoveElementsDlg::reject()
   QDialog::reject();
 }
 
+//=================================================================================
+// function : onOpenView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_RemoveElementsDlg::onOpenView()
+{
+  if(!mySelector) {
+    mySelector = SMESH::GetViewWindow( mySMESHGUI )->GetSelector();
+    ActivateThisDialog();
+  }
+}
+
+//=================================================================================
+// function : onCloseView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_RemoveElementsDlg::onCloseView()
+{
+  DeactivateActiveDialog();
+  mySelector = 0;
+}
+
 //=================================================================================
 // function : ClickOnHelp()
 // purpose  :
@@ -332,6 +360,11 @@ void SMESHGUI_RemoveElementsDlg::onTextChange(const QString& theNewText)
         aViewWindow->highlight(anIO,true,true);
     }
   }
+  else
+  {
+    QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts);
+    myNbOkElements = aListId.count();
+  }
   
   myBusy = false;
   updateButtons();
@@ -344,7 +377,7 @@ void SMESHGUI_RemoveElementsDlg::onTextChange(const QString& theNewText)
 void SMESHGUI_RemoveElementsDlg::SelectionIntoArgument()
 {
   if (myBusy) return;                                  // busy
-  if (myFilterDlg && myFilterDlg->isVisible()) return; // filter digl active
+  if (myFilterDlg && myFilterDlg->isVisible()) return; // filter dlg active
   if (!GroupButtons->isEnabled()) return;              // inactive
 
   // clear
@@ -453,8 +486,13 @@ void SMESHGUI_RemoveElementsDlg::ActivateThisDialog()
 //=================================================================================
 void SMESHGUI_RemoveElementsDlg::enterEvent(QEvent*)
 {
-  if (!GroupConstructors->isEnabled())
+  if (!GroupConstructors->isEnabled()) {
+    SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
+    if ( aViewWindow && !mySelector) {
+      mySelector = aViewWindow->GetSelector();
+    }
     ActivateThisDialog();
+  }
 }
 
 //=================================================================================
@@ -483,11 +521,20 @@ void SMESHGUI_RemoveElementsDlg::setFilters()
     SUIT_MessageBox::critical(this,
                               tr("SMESH_ERROR"),
                               tr("NO_MESH_SELECTED"));
-   return;
+    return;
   }
   if ( !myFilterDlg )
     myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, SMESH::ALL );
 
+  QList<int> types;
+  if ( myMesh->NbEdges()     ) types << SMESH::EDGE;
+  if ( myMesh->NbFaces()     ) types << SMESH::FACE;
+  if ( myMesh->NbVolumes()   ) types << SMESH::VOLUME;
+  if ( myMesh->NbBalls()     ) types << SMESH::BALL;
+  if ( myMesh->Nb0DElements()) types << SMESH::ELEM0D;
+  if ( types.count() > 1 )     types << SMESH::ALL;
+
+  myFilterDlg->Init( types );
   myFilterDlg->SetSelection();
   myFilterDlg->SetMesh( myMesh );
   myFilterDlg->SetSourceWg( LineEditC1A1 );
index b4872622310c4e12b5df6502a244aa30a7232864..2a614c09b9a0352b525e19b7db1a84da74cea63f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -106,6 +106,8 @@ private slots:
   void                   DeactivateActiveDialog();
   void                   ActivateThisDialog();
   void                   onTextChange( const QString& );
+  void                   onOpenView();
+  void                   onCloseView();
   void                   setFilters();
   void                   updateButtons();
 };
index 5780ce55ac1a7e89d9dd60fda1743555e1a5f693..8b9ab2e551367ba37d6d3287dc219ba512c18228 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -34,6 +34,7 @@
 #include "SMESHGUI_IdValidator.h"
 #include "SMESHGUI_FilterDlg.h"
 
+#include <SMESH_TypeFilter.hxx>
 #include <SMESH_Actor.h>
 #include <SMDS_Mesh.hxx>
 
@@ -80,8 +81,8 @@
 SMESHGUI_RemoveNodesDlg
 ::SMESHGUI_RemoveNodesDlg(SMESHGUI* theModule)
   : QDialog(SMESH::GetDesktop(theModule)),
-    mySelector(SMESH::GetViewWindow(theModule)->GetSelector()),
     mySelectionMgr(SMESH::GetSelectionMgr(theModule)),
+    mySelector(SMESH::GetViewWindow(theModule)->GetSelector()),
     mySMESHGUI(theModule),
     myBusy(false),
     myFilterDlg(0)
@@ -204,16 +205,22 @@ void SMESHGUI_RemoveNodesDlg::Init()
   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(reject()));
+  connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()),      this, SLOT(reject()));
+  connect(mySMESHGUI, SIGNAL (SignalActivatedViewManager()), this, SLOT(onOpenView()));
+  connect(mySMESHGUI, SIGNAL (SignalCloseView()),            this, SLOT(onCloseView()));
   connect(myEditCurrentArgument, SIGNAL(textChanged(const QString&)),
-          SLOT(onTextChange(const QString&)));
-  
+          this,                  SLOT (onTextChange(const QString&)));
+
   SMESH::SetPointRepresentation(true);
-  
+
+  mySelectionMgr->clearFilters();
+  mySelectionMgr->installFilter( new SMESH_TypeFilter( SMESH::IDSOURCE ));
+
   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
     aViewWindow->SetSelectionMode(NodeSelection);
 
-  SelectionIntoArgument();
+  //SelectionIntoArgument();
+  mySelectionMgr->setSelectedObjects( SALOME_ListIO() );
 }
 
 //=================================================================================
@@ -283,6 +290,32 @@ void SMESHGUI_RemoveNodesDlg::reject()
   QDialog::reject();
 }
 
+
+//=================================================================================
+// function : onOpenView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_RemoveNodesDlg::onOpenView()
+{
+  if ( mySelector) {
+    SMESH::SetPointRepresentation(false);
+  }
+  else {
+    mySelector = SMESH::GetViewWindow( mySMESHGUI )->GetSelector();
+    ActivateThisDialog();
+  }
+}
+
+//=================================================================================
+// function : onCloseView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_RemoveNodesDlg::onCloseView()
+{
+  DeactivateActiveDialog();
+  mySelector = 0;
+}
+
 //=================================================================================
 // function : ClickOnHelp()
 // purpose  :
@@ -384,16 +417,16 @@ void SMESHGUI_RemoveNodesDlg::SelectionIntoArgument()
           myBusy = true;
           myEditCurrentArgument->setText(aString);
           myBusy = false;
-          
+
           // OK
-          
+
           myNbOkNodes = nbNodes;
         } // if (nbNodes > 0)
       } // if (myActor)
     } // if (!myMesh->_is_nil())
   } // if (nbSel == 1)
 
-  updateButtons();        
+  updateButtons();
 }
 
 //=================================================================================
@@ -446,6 +479,9 @@ void SMESHGUI_RemoveNodesDlg::ActivateThisDialog()
 
   mySMESHGUI->SetActiveDialogBox((QDialog*)this); // ??
 
+  mySelectionMgr->clearFilters();
+  mySelectionMgr->installFilter( new SMESH_TypeFilter( SMESH::IDSOURCE ));
+
   SMESH::SetPointRepresentation(true);
   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
     aViewWindow->SetSelectionMode(NodeSelection);
@@ -459,8 +495,13 @@ void SMESHGUI_RemoveNodesDlg::ActivateThisDialog()
 //=================================================================================
 void SMESHGUI_RemoveNodesDlg::enterEvent(QEvent*)
 {
-  if (!GroupConstructors->isEnabled())
+  if (!GroupConstructors->isEnabled()) {
+    SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
+    if ( aViewWindow && !mySelector) {
+      mySelector = aViewWindow->GetSelector();
+    }
     ActivateThisDialog();
+  }
 }
 
 //=================================================================================
index 0ffc235ace83cd13e4586bdb90d6575bd97a9bd4..19efac9ddb8597ea99f295661e052e81f6990b45 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -106,6 +106,8 @@ private slots:
   void                   DeactivateActiveDialog();
   void                   ActivateThisDialog();
   void                   onTextChange( const QString& );
+  void                   onOpenView();
+  void                   onCloseView();
   void                   setFilters();
   void                   updateButtons();
 };
index 0c70bfdbbea70a49111519ffce67878b1cdc2517..64f5c8d3fd647549e754e9d6afadb43bbd87b64a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 26ae2b311e8186e8b26aacff2a0035da6822aae5..748a6e8e7acd6962126e7ba343b1dc33642a81ee 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 064df39099964d8ede3b7d6cefba351ad91a1a07..b9ac6adef878cbbc5815aeca312c0783a14d4a67 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index e0908171b24a3a222f6c99d88555d9e4544eef7e..5afcaa7dab4c35e17e2b64efea8c3ae2ab797003 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 6e5ccb913b39dcda6f835c7685952f1401cb4a6e..82a7a0451b30c1bcecce4cbfdf92e208191a7d80 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -35,6 +35,7 @@
 #include "SMESHGUI_IdValidator.h"
 #include "SMESHGUI_MeshEditPreview.h"
 #include "SMESHGUI_FilterDlg.h"
+#include "SMESHGUI_ExtrusionDlg.h"
 
 #include <SMESH_Actor.h>
 #include <SMESH_TypeFilter.hxx>
 SMESHGUI_RevolutionDlg::SMESHGUI_RevolutionDlg( SMESHGUI* theModule )
   : SMESHGUI_PreviewDlg( theModule ),
     mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
-    myVectorDefinition(NONE_SELECT),
-    myFilterDlg( 0 ),
-    mySelectedObject(SMESH::SMESH_IDSource::_nil()),
-    myActor(0)
+    myVectorDefinition(NONE_SELECT)
 {
-  mySimulation = new SMESHGUI_MeshEditPreview(SMESH::GetViewWindow( mySMESHGUI ));
-
   SUIT_ResourceMgr* mgr = SMESH::GetResourceMgr( mySMESHGUI );
-  QPixmap image0 ( mgr->loadPixmap("SMESH", tr("ICON_DLG_EDGE")));
-  QPixmap image1 ( mgr->loadPixmap("SMESH", tr("ICON_DLG_TRIANGLE")));
-  QPixmap image2 ( mgr->loadPixmap("SMESH", tr("ICON_SELECT")));
+  QPixmap image ( mgr->loadPixmap("SMESH", tr("ICON_SELECT")));
 
   setModal(false);
   setAttribute(Qt::WA_DeleteOnClose, true);
   setWindowTitle(tr("REVOLUTION_AROUND_AXIS"));
   setSizeGripEnabled(true);
-  
+
   QVBoxLayout* SMESHGUI_RevolutionDlgLayout = new QVBoxLayout(this);
   SMESHGUI_RevolutionDlgLayout->setSpacing(SPACING);
   SMESHGUI_RevolutionDlgLayout->setMargin(MARGIN);
 
   /***************************************************************/
-  ConstructorsBox = new QGroupBox(tr("SMESH_REVOLUTION"), 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("REVOLUTION_1D"), this);
+  GroupArguments = new QGroupBox(tr("REVOLUTION"), 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);
+  SelectorWdg = new SMESHGUI_3TypesSelector( GroupArguments );
 
   // Controls for axis defining
   GroupAxis = new QGroupBox(tr("SMESH_AXIS"), GroupArguments);
@@ -160,7 +123,8 @@ SMESHGUI_RevolutionDlg::SMESHGUI_RevolutionDlg( SMESHGUI* theModule )
 
   TextLabelPoint = new QLabel(tr("SMESH_POINT"), GroupAxis);
   SelectPointButton  = new QPushButton(GroupAxis);
-  SelectPointButton->setIcon(image2);
+  SelectPointButton->setIcon(image);
+  SelectPointButton->setCheckable(true);
 
   TextLabelX = new QLabel(tr("SMESH_X"), GroupAxis);
   SpinBox_X = new SMESHGUI_SpinBox(GroupAxis);
@@ -173,7 +137,8 @@ SMESHGUI_RevolutionDlg::SMESHGUI_RevolutionDlg( SMESHGUI* theModule )
 
   TextLabelVector = new QLabel(tr("SMESH_VECTOR"), GroupAxis);
   SelectVectorButton = new QPushButton(GroupAxis);
-  SelectVectorButton->setIcon(image2);
+  SelectVectorButton->setIcon(image);
+  SelectVectorButton->setCheckable(true);
 
   TextLabelDX = new QLabel(tr("SMESH_DX"), GroupAxis);
   SpinBox_DX = new SMESHGUI_SpinBox(GroupAxis);
@@ -237,17 +202,16 @@ SMESHGUI_RevolutionDlg::SMESHGUI_RevolutionDlg( SMESHGUI* theModule )
   MakeGroupsCheck = new QCheckBox(tr("SMESH_MAKE_GROUPS"), GroupArguments);
   MakeGroupsCheck->setChecked(true);
 
-  GroupArgumentsLayout->addWidget(TextLabelElements,    0, 0);
-  GroupArgumentsLayout->addWidget(SelectElementsButton, 0, 1);
-  GroupArgumentsLayout->addWidget(LineEditElements,     0, 2);
-  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(myPreviewCheckBox,    5, 0, 1, 4);
-  GroupArgumentsLayout->addWidget(MakeGroupsCheck,      6, 0, 1, 4);
+  GroupArgumentsLayout->addWidget(SelectorWdg,          0, 0, 1, 4);
+  GroupArgumentsLayout->addWidget(GroupAxis,            1, 0, 1, 4);
+  GroupArgumentsLayout->addWidget(GroupAngleBox,        2, 0, 1, 4);
+  GroupArgumentsLayout->addWidget(TextLabelTolerance,   3, 0, 1, 2);
+  GroupArgumentsLayout->addWidget(SpinBox_Tolerance,    3, 2, 1, 2);
+  GroupArgumentsLayout->addWidget(myPreviewCheckBox,    4, 0, 1, 4);
+  GroupArgumentsLayout->addWidget(MakeGroupsCheck,      5, 0, 1, 4);
+
+  SelectorWdg->GetButtonGroup()->addButton( SelectVectorButton );
+  SelectorWdg->GetButtonGroup()->addButton( SelectPointButton );
 
   /***************************************************************/
   GroupButtons = new QGroupBox(this);
@@ -274,7 +238,6 @@ SMESHGUI_RevolutionDlg::SMESHGUI_RevolutionDlg( SMESHGUI* theModule )
   GroupButtonsLayout->addWidget(buttonHelp);
 
   /***************************************************************/
-  SMESHGUI_RevolutionDlgLayout->addWidget(ConstructorsBox);
   SMESHGUI_RevolutionDlgLayout->addWidget(GroupArguments);
   SMESHGUI_RevolutionDlgLayout->addWidget(GroupButtons);
 
@@ -294,23 +257,10 @@ SMESHGUI_RevolutionDlg::SMESHGUI_RevolutionDlg( SMESHGUI* theModule )
 
   SpinBox_Tolerance->RangeStepAndValidator(0.0, COORD_MAX, 0.00001, "len_tol_precision");
 
-  RadioButton1->setChecked(true);
-
   mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
 
   mySMESHGUI->SetActiveDialogBox((QDialog*)this);
 
-  // Costruction of the logical filter
-  SMESH_TypeFilter* aMeshOrSubMeshFilter = new SMESH_TypeFilter (SMESH::MESHorSUBMESH);
-  SMESH_TypeFilter* aSmeshGroupFilter    = new SMESH_TypeFilter (SMESH::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 = "revolution_page.html";
 
   Init();
@@ -326,9 +276,7 @@ SMESHGUI_RevolutionDlg::SMESHGUI_RevolutionDlg( SMESHGUI* theModule )
   connect(buttonCancel, SIGNAL(clicked()), this, SLOT(reject()));
   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(SelectPointButton,    SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
   connect(SelectVectorButton,   SIGNAL(clicked()), this, SLOT(onSelectVectorButton()));
 
@@ -336,16 +284,21 @@ SMESHGUI_RevolutionDlg::SMESHGUI_RevolutionDlg( SMESHGUI* theModule )
   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(onVectorChanged()));
-  connect(SpinBox_DY, SIGNAL(valueChanged(double)), this, SLOT(onVectorChanged()));
-  connect(SpinBox_DZ, SIGNAL(valueChanged(double)), this, SLOT(onVectorChanged()));
-
-  connect(mySMESHGUI,     SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog()));
-  connect(mySelectionMgr, SIGNAL(currentSelectionChanged()),      this, SLOT(SelectionIntoArgument()));
+  connect(SpinBox_DX, SIGNAL(valueChanged(double)), this, SLOT(CheckIsEnable()));
+  connect(SpinBox_DY, SIGNAL(valueChanged(double)), this, SLOT(CheckIsEnable()));
+  connect(SpinBox_DZ, SIGNAL(valueChanged(double)), this, SLOT(CheckIsEnable()));
+  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(mySMESHGUI,     SIGNAL(SignalDeactivateActiveDialog()), SLOT(DeactivateActiveDialog()));
+  connect(mySelectionMgr, SIGNAL(currentSelectionChanged()),      SLOT(SelectionIntoArgument()));
+  connect(SelectorWdg,    SIGNAL(selectionChanged()), this, SLOT(toDisplaySimulation()));
+  connect(SelectorWdg,    SIGNAL(selectionChanged()), this, SLOT(CheckIsEnable()));
   /* to close dialog if study change */
-  connect(mySMESHGUI,       SIGNAL(SignalCloseAllDialogs()), this, SLOT(reject()));
-  connect(LineEditElements, SIGNAL(textChanged(const QString&)),   SLOT(onTextChange(const QString&)));
-  connect(CheckBoxMesh,     SIGNAL(toggled(bool)),                 SLOT(onSelectMesh(bool)));
+  connect(mySMESHGUI,       SIGNAL(SignalCloseAllDialogs()),      this, SLOT(reject()));
+  connect(mySMESHGUI,       SIGNAL(SignalActivatedViewManager()), this, SLOT(onOpenView()));
+  connect(mySMESHGUI,       SIGNAL(SignalCloseView()),            this, SLOT(onCloseView()));
 
   connect(GroupAngle,        SIGNAL(buttonClicked(int)),   this, SLOT(toDisplaySimulation()));
   connect(SpinBox_Angle,     SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
@@ -357,8 +310,7 @@ SMESHGUI_RevolutionDlg::SMESHGUI_RevolutionDlg( SMESHGUI* theModule )
 
   connect(SpinBox_Angle, SIGNAL(textChanged(const QString&)), this, SLOT(onAngleTextChange(const QString&)));
 
-  ConstructorsClicked(0);
-  SelectionIntoArgument();
+  CheckIsEnable();
 }
 
 //=================================================================================
@@ -367,12 +319,6 @@ SMESHGUI_RevolutionDlg::SMESHGUI_RevolutionDlg( SMESHGUI* theModule )
 //=================================================================================
 SMESHGUI_RevolutionDlg::~SMESHGUI_RevolutionDlg()
 {
-  delete mySimulation;
-  if ( myFilterDlg ) {
-    myFilterDlg->setParent( 0 );
-    delete myFilterDlg;
-    myFilterDlg = 0;
-  }
 }
 
 //=================================================================================
@@ -381,17 +327,6 @@ SMESHGUI_RevolutionDlg::~SMESHGUI_RevolutionDlg()
 //=================================================================================
 void SMESHGUI_RevolutionDlg::Init (bool ResetControls)
 {
-  myBusy = false;
-
-  myEditCurrentArgument = 0;
-  LineEditElements->clear();
-  myElementsId = "";
-  myNbOkElements = 0;
-  myIDs.clear();
-
-  myActor = 0;
-  myMesh = SMESH::SMESH_Mesh::_nil();
-
   if (ResetControls) {
     SpinBox_X->SetValue(0.0);
     SpinBox_Y->SetValue(0.0);
@@ -404,68 +339,51 @@ void SMESHGUI_RevolutionDlg::Init (bool ResetControls)
     SpinBox_NbSteps->setValue(1);
     SpinBox_Tolerance->SetValue(1e-05);
 
-    CheckBoxMesh->setChecked(false);
-    onSelectMesh(false);
     myPreviewCheckBox->setChecked(false);
     onDisplaySimulation(false);
   }
+  SelectorWdg->Clear();
 }
 
 //=================================================================================
-// function : ConstructorsClicked()
-// purpose  : Radio button management
+// function : CheckIsEnable()
+// purpose  : Check whether the Ok and Apply buttons should be enabled or not
 //=================================================================================
-void SMESHGUI_RevolutionDlg::ConstructorsClicked (int constructorId)
-{
-  disconnect(mySelectionMgr, 0, this, 0);
 
-  /*  SALOME_ListIO io;
-  mySelectionMgr->selectedObjects( io );
-  SALOME_ListIO aList;
-  mySelectionMgr->setSelectedObjects( aList );*/
+void SMESHGUI_RevolutionDlg::CheckIsEnable()
+{  
+  bool anIsEnable = SelectorWdg->IsAnythingSelected() && IsAxisOk();
 
-  buttonApply->setEnabled(false);
-  buttonOk->setEnabled(false);
-  mySimulation->SetVisibility(false);
-
-  Selection_Mode aSelMode = ActorSelection;
+  buttonOk->setEnabled(anIsEnable);
+  buttonApply->setEnabled(anIsEnable);
+}
 
-  switch (constructorId) {
-  case 0:
-    {
-      GroupArguments->setTitle(tr("REVOLUTION_1D"));
-      aSelMode = EdgeSelection;
-      break;
-    }
-  case 1:
-    {
-      GroupArguments->setTitle(tr("REVOLUTION_2D"));
-      aSelMode = FaceSelection;
-      break;
-    }
-  }
+//=================================================================================
+// function : isValid
+// purpose  : Return true in case if values entered into dialog are valid
+//=================================================================================
+bool SMESHGUI_RevolutionDlg::isValid()
+{
+  QString msg;
+  bool ok = true;
+  ok = SpinBox_X->isValid( msg, true ) && ok;
+  ok = SpinBox_Y->isValid( msg, true ) && ok;
+  ok = SpinBox_Z->isValid( msg, true ) && ok;
+  ok = SpinBox_DX->isValid( msg, true ) && ok;
+  ok = SpinBox_DY->isValid( msg, true ) && ok;
+  ok = SpinBox_DZ->isValid( msg, true ) && ok;
+  ok = SpinBox_Angle->isValid( msg, true ) && ok;
+  ok = SpinBox_NbSteps->isValid( msg, true ) && ok;
+  ok = SpinBox_Tolerance->isValid( msg, true ) && ok;
 
-  if (myEditCurrentArgument != (QWidget*)LineEditElements) {
-    SMESH::SetPointRepresentation(false);
+  if( !ok ) {
+    QString str( tr( "SMESH_INCORRECT_INPUT" ) );
+    if ( !msg.isEmpty() )
+      str += "\n" + msg;
+    SUIT_MessageBox::critical( this, tr( "SMESH_ERROR" ), str );
+    return false;
   }
-
-  if (!CheckBoxMesh->isChecked())
-    {
-      LineEditElements->clear();
-      myIDs.clear();
-      myNbOkElements = 0;
-      if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-        aViewWindow->SetSelectionMode(aSelMode);
-    }
-
-  myEditCurrentArgument = (QWidget*)LineEditElements;
-  LineEditElements->setFocus();
-
-  if (CheckBoxMesh->isChecked())
-    onSelectMesh(true);
-
-  connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
-  //  mySelectionMgr->setSelectedObjects( io );
+  return true;
 }
 
 //=================================================================================
@@ -480,14 +398,7 @@ bool SMESHGUI_RevolutionDlg::ClickOnApply()
   if (!isValid())
     return false;
 
-  if (myNbOkElements && 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();
+  if ( SelectorWdg->IsAnythingSelected() && IsAxisOk() ) {
 
     SMESH::AxisStruct anAxis;
 
@@ -498,8 +409,8 @@ bool SMESHGUI_RevolutionDlg::ClickOnApply()
     anAxis.vy = SpinBox_DY->GetValue();
     anAxis.vz = SpinBox_DZ->GetValue();
 
-    double anAngle = (SpinBox_Angle->GetValue())*M_PI/180.;
-    long aNbSteps = (long)SpinBox_NbSteps->value();
+    double    anAngle = (SpinBox_Angle->GetValue())*M_PI/180.;
+    long     aNbSteps = (long)SpinBox_NbSteps->value();
     double aTolerance = SpinBox_Tolerance->GetValue();
 
     if ( GroupAngle->checkedId() == 1 )
@@ -516,50 +427,61 @@ bool SMESHGUI_RevolutionDlg::ClickOnApply()
     aParameters << SpinBox_NbSteps->text();
     aParameters << SpinBox_Tolerance->text();
 
+    bool meshHadNewTypeBefore = true;
+    int  maxSelType = 0;
+    const bool makeGroups = ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() );
+
     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->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);
-      }
+
+      SMESH::SMESH_Mesh_var mesh = SelectorWdg->GetMesh();
+
+      mesh->SetParameters( aParameters.join(":").toLatin1().constData() );
+
+      SMESH::ListOfIDSources_var nodes = new SMESH::ListOfIDSources();
+      SMESH::ListOfIDSources_var edges = new SMESH::ListOfIDSources();
+      SMESH::ListOfIDSources_var faces = new SMESH::ListOfIDSources();
+      maxSelType = SelectorWdg->GetSelected( nodes, edges, faces );
+
+      // is it necessary to switch on the next Display Mode?
+      SMESH::ElementType newType = (SMESH::ElementType)( maxSelType + 1 );
+      SMESH::array_of_ElementType_var oldTypes = mesh->GetTypes();
+      meshHadNewTypeBefore = false;
+      for ( size_t i = 0; i < oldTypes->length() && !meshHadNewTypeBefore; ++i )
+        meshHadNewTypeBefore = ( oldTypes[i] >= newType );
+
+      SMESH::SMESH_MeshEditor_var aMeshEditor = mesh->GetMeshEditor();
+
+      SMESH::ListOfGroups_var groups = 
+        aMeshEditor->RotationSweepObjects( nodes, edges, faces, anAxis,
+                                           anAngle, aNbSteps, aTolerance, makeGroups);
 
     } catch (...) {
     }
 
-    SMESH::UpdateView();
-    SMESH::Update(myIO, SMESH::eDisplay);
-    if ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() )
+    SMESH_Actor* actor = SelectorWdg->GetActor();
+    if ( actor && !meshHadNewTypeBefore )
+    {
+      unsigned int aMode = actor->GetEntityMode();
+      switch ( maxSelType ) {
+      case SMESH::NODE: // extrude node -> edges
+        actor->SetRepresentation(SMESH_Actor::eEdge);
+        actor->SetEntityMode( aMode |= SMESH_Actor::eEdges ); break;
+      case SMESH::EDGE: // edge -> faces
+        actor->SetRepresentation(SMESH_Actor::eSurface);
+        actor->SetEntityMode( aMode |= SMESH_Actor::eFaces ); break;
+      case SMESH::FACE: // faces -> volumes
+        actor->SetRepresentation(SMESH_Actor::eSurface);
+        actor->SetEntityMode( aMode |= SMESH_Actor::eVolumes ); break;
+      }
+    }
+    if ( actor )
+      SMESH::Update( actor->getIO(), actor->GetVisibility() );
+    if ( makeGroups )
       mySMESHGUI->updateObjBrowser(true); // new groups may appear
     Init(false);
-    ConstructorsClicked(GetConstructorId());
-    mySelectedObject = SMESH::SMESH_IDSource::_nil();
-    SelectionIntoArgument();
+    mySelectionMgr->clearSelected();
+    SelectorWdg->Clear();
 
     SMESHGUI::Modified();
   }
@@ -597,6 +519,32 @@ void SMESHGUI_RevolutionDlg::reject()
   QDialog::reject();
 }
 
+//=================================================================================
+// function : onOpenView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_RevolutionDlg::onOpenView()
+{
+  if ( mySelector ) {
+    mySimulation->SetVisibility(false);
+    SMESH::SetPointRepresentation(false);
+  }
+  else {
+    mySelector = SMESH::GetViewWindow( mySMESHGUI )->GetSelector();
+    ActivateThisDialog();
+  }
+}
+
+//=================================================================================
+// function : onCloseView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_RevolutionDlg::onCloseView()
+{
+  DeactivateActiveDialog();
+  mySelector = 0;
+}
+
 //=================================================================================
 // function : ClickOnHelp()
 // purpose  :
@@ -634,159 +582,48 @@ void SMESHGUI_RevolutionDlg::onAngleTextChange (const QString& theNewText)
   RadioButton4->setEnabled( isNumber );
 }
 
-//=======================================================================
-// function : onTextChange()
-// purpose  :
-//=======================================================================
-void SMESHGUI_RevolutionDlg::onTextChange (const QString& theNewText)
-{
-  QLineEdit* send = (QLineEdit*)sender();
-
-  if (myBusy) return;
-  myBusy = true;
-
-  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) {
-    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++;
-      }
-
-      mySelector->AddOrRemoveIndex(myActor->getIO(), newIndices, false);
-      if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-        aViewWindow->highlight( myActor->getIO(), true, true );
-      
-      myElementsId = theNewText;
-    }
-  }
-
-  if (myNbOkElements && IsAxisOk()) {
-    buttonOk->setEnabled(true);
-    buttonApply->setEnabled(true);
-  }
-  onDisplaySimulation(true);
-
-  myBusy = false;
-}
-
 //=================================================================================
 // function : SelectionIntoArgument()
 // purpose  : Called when selection as changed or other case
 //=================================================================================
 void SMESHGUI_RevolutionDlg::SelectionIntoArgument()
 {
-  if (myBusy) return;
-
-  // clear
-  QString aString = "";
-
-  myBusy = true;
-  if (myEditCurrentArgument == (QWidget*)LineEditElements) {
-    LineEditElements->setText(aString);
-    myNbOkElements = 0;
-    buttonOk->setEnabled(false);
-    buttonApply->setEnabled(false);
-  }
-  myBusy = false;
-
   if (!GroupButtons->isEnabled()) // inactive
     return;
+  
+  if ( SelectVectorButton->isChecked() ||
+       SelectPointButton->isChecked() )
+  {
+    // get selected mesh
+    SALOME_ListIO aList;
+    mySelectionMgr->selectedObjects(aList);
+    int nbSel = aList.Extent();
+    if (nbSel != 1)
+      return;
 
-  // get selected mesh
-  SALOME_ListIO aList;
-  mySelectionMgr->selectedObjects(aList);
-  int nbSel = aList.Extent();
-  if (nbSel != 1) 
-    return;
-
-  Handle(SALOME_InteractiveObject) IO = aList.First();
-  SMESH::SMESH_Mesh_var aMeshVar = SMESH::GetMeshByIO(IO);
-  if (aMeshVar->_is_nil())
-    return;
-
-  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 ) {
-      MakeGroupsCheck->setChecked(false);
-      MakeGroupsCheck->setEnabled(false);
-    } else {
-      MakeGroupsCheck->setEnabled(true);
-    }
-
-    if (CheckBoxMesh->isChecked()) {
-      SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aString);
-
-      if (!SMESH::IObjectToInterface<SMESH::SMESH_IDSource>(IO)->_is_nil())
-        mySelectedObject = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>(IO);
-      else
-        return;
-    } else {
-      aNbUnits = SMESH::GetNameOfSelectedElements(mySelector, IO, aString);
-      myElementsId = aString;
-      if (aNbUnits < 1)
-        return;
-    }
-    myNbOkElements = true;
-  } else {
+    Handle(SALOME_InteractiveObject) IO = aList.First();
+    TColStd_IndexedMapOfInteger aMapIndex;
+    mySelector->GetIndex(IO,aMapIndex);
+    if ( aMapIndex.Extent() != 1 )
+      return;
 
-    SMDS_Mesh* aMesh = anActor->GetObject()->GetMesh();
-    if (!aMesh)
+    SMESH_Actor* anActor = SMESH::FindActorByEntry( IO->getEntry() );
+    SMDS_Mesh*     aMesh = anActor ? anActor->GetObject()->GetMesh() : 0;
+    if ( !aMesh )
       return;
 
-    bool isNodeSelected = (myEditCurrentArgument == (QWidget*)SpinBox_X ||
-                           (myEditCurrentArgument == (QWidget*)SpinBox_DX && 
+    bool isNodeSelected = ((myEditCurrentArgument == (QWidget*)SpinBox_X ) ||
+                           (myEditCurrentArgument == (QWidget*)SpinBox_DX &&
                             myVectorDefinition==POINT_SELECT));
 
-    bool isFaceSelected = (myEditCurrentArgument == (QWidget*)SpinBox_DX && 
+    bool isFaceSelected = (myEditCurrentArgument == (QWidget*)SpinBox_DX &&
                            myVectorDefinition==FACE_SELECT);
 
-    if(isNodeSelected) {
-      aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, IO, aString);
-    }
-    else if(isFaceSelected){
-      aNbUnits = SMESH::GetNameOfSelectedElements(mySelector, IO, aString);
-    }
-    
-    if (aNbUnits != 1)
-      return;
-
-    if(isNodeSelected) {
-      const SMDS_MeshNode * n = aMesh->FindNode(aString.toInt());
+    if ( isNodeSelected )
+    {
+      const SMDS_MeshNode * n = aMesh->FindNode( aMapIndex(1) );
       if (!n)
         return;
-
       double x = n->X();
       double y = n->Y();
       double z = n->Z();
@@ -801,30 +638,21 @@ void SMESHGUI_RevolutionDlg::SelectionIntoArgument()
         SpinBox_DZ->SetValue(z - SpinBox_Z->GetValue());
       }
     }
-    else if(isFaceSelected){
-      const SMDS_MeshFace* face = dynamic_cast<const SMDS_MeshFace*>(aMesh->FindElement(aString.toInt()));
+    else if ( isFaceSelected )
+    {
+      const SMDS_MeshFace* face =
+        dynamic_cast<const SMDS_MeshFace*>(aMesh->FindElement(aMapIndex(1)));
       if (!face)
         return;
-      
       gp_XYZ aNormale = SMESH::getNormale(face);
       SpinBox_DX->SetValue(aNormale.X());
       SpinBox_DY->SetValue(aNormale.Y());
       SpinBox_DZ->SetValue(aNormale.Z());
-      
-    }
-  }
-
-  myBusy = true;
-  if (myEditCurrentArgument == (QWidget*)LineEditElements)
-    LineEditElements->setText(aString);
-  myBusy = false;
 
-  // OK
-  if (myNbOkElements && IsAxisOk()) {
-    buttonOk->setEnabled(true);
-    buttonApply->setEnabled(true);
+    }
   }
 
+  CheckIsEnable();
   onDisplaySimulation(true);
 }
 
@@ -840,35 +668,13 @@ void SMESHGUI_RevolutionDlg::SetEditCurrentArgument()
   mySelectionMgr->clearSelected();
   mySelectionMgr->clearFilters();
 
-  if (send == SelectElementsButton) {
-    mySimulation->SetVisibility(false);
-    myEditCurrentArgument = (QWidget*)LineEditElements;
-    SMESH::SetPointRepresentation(false);
-    if (CheckBoxMesh->isChecked()) {
-      if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-        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);
-        }
-    }
-  } else if (send == SelectPointButton) {
+  if (send == SelectPointButton) {
     myEditCurrentArgument = (QWidget*)SpinBox_X;
+    myEditCurrentArgument->setFocus();
     SMESH::SetPointRepresentation(true);
     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
       aViewWindow->SetSelectionMode(NodeSelection);
   }
-
-  myEditCurrentArgument->setFocus();
   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
   SelectionIntoArgument();
 }
@@ -879,10 +685,11 @@ void SMESHGUI_RevolutionDlg::SetEditCurrentArgument()
 //=================================================================================
 void SMESHGUI_RevolutionDlg::DeactivateActiveDialog()
 {
-  if (ConstructorsBox->isEnabled()) {
-    ConstructorsBox->setEnabled(false);
+  if (GroupButtons->isEnabled())
+  {
     GroupArguments->setEnabled(false);
     GroupButtons->setEnabled(false);
+    SelectorWdg->setEnabled(false);
     mySMESHGUI->ResetState();
     mySMESHGUI->SetActiveDialogBox(0);
   }
@@ -896,14 +703,11 @@ void SMESHGUI_RevolutionDlg::ActivateThisDialog()
 {
   /* Emit a signal to deactivate the active dialog */
   mySMESHGUI->EmitSignalDeactivateDialog();
-  ConstructorsBox->setEnabled(true);
   GroupArguments->setEnabled(true);
   GroupButtons->setEnabled(true);
+  SelectorWdg->setEnabled(true);
 
   mySMESHGUI->SetActiveDialogBox((QDialog*)this);
-
-  ConstructorsClicked(GetConstructorId());
-  SelectionIntoArgument();
 }
 
 //=================================================================================
@@ -912,71 +716,13 @@ void SMESHGUI_RevolutionDlg::ActivateThisDialog()
 //=================================================================================
 void SMESHGUI_RevolutionDlg::enterEvent (QEvent*)
 {
-  if (!ConstructorsBox->isEnabled())
+  if (!GroupButtons->isEnabled()) {
+    SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
+    if ( aViewWindow && !mySelector) {
+      mySelector = aViewWindow->GetSelector();
+    }
     ActivateThisDialog();
-}
-
-//=======================================================================
-//function : onSelectMesh
-//purpose  :
-//=======================================================================
-void SMESHGUI_RevolutionDlg::onSelectMesh (bool 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();
-    mySimulation->SetVisibility(false);
-    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 {
-    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);
-      }
-
-    LineEditElements->setReadOnly(false);
-    LineEditElements->setValidator(myIdValidator);
-    onTextChange(LineEditElements->text());
-    mySimulation->SetVisibility(false);
-  }
-
-  SelectionIntoArgument();
-
-  if (!toSelectMesh)
-    LineEditElements->setText( myIDs );
-}
-
-//=================================================================================
-// function : GetConstructorId()
-// purpose  :
-//=================================================================================
-int SMESHGUI_RevolutionDlg::GetConstructorId()
-{
-  return GroupConstructors->checkedId();
 }
 
 //=================================================================================
@@ -990,22 +736,6 @@ bool SMESHGUI_RevolutionDlg::IsAxisOk()
           SpinBox_DZ->GetValue() != 0);
 }
 
-//=================================================================================
-// function : onVectorChanged()
-// purpose  :
-//=================================================================================
-void SMESHGUI_RevolutionDlg::onVectorChanged()
-{
-  if (IsAxisOk()) {
-    buttonOk->setEnabled(true);
-    buttonApply->setEnabled(true);
-  } else {
-    buttonOk->setEnabled(false);
-    buttonApply->setEnabled(false);
-  }
-  onDisplaySimulation(true);
-}
-
 //=================================================================================
 // function : keyPressEvent()
 // purpose  :
@@ -1030,17 +760,8 @@ void SMESHGUI_RevolutionDlg::onDisplaySimulation(bool toDisplayPreview)
 {
   if (myPreviewCheckBox->isChecked() && toDisplayPreview)
   {
-    //display preview
-    if (myNbOkElements && IsAxisOk())
+    if (SelectorWdg->IsAnythingSelected() && 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();
@@ -1050,33 +771,34 @@ void SMESHGUI_RevolutionDlg::onDisplaySimulation(bool toDisplayPreview)
       anAxis.vy = SpinBox_DY->GetValue();
       anAxis.vz = SpinBox_DZ->GetValue();
 
-      double anAngle = (SpinBox_Angle->GetValue())*M_PI/180.;
-      long aNbSteps = (long)SpinBox_NbSteps->value();
+      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;
       
-      try {
+      try
+      {
         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());
-      catch (...) {}
+
+        SMESH::SMESH_Mesh_var             mesh = SelectorWdg->GetMesh();
+        SMESH::SMESH_MeshEditor_var meshEditor = mesh->GetMeshEditPreviewer();
+        SMESH::ListOfGroups_var         groups;
+
+        SMESH::ListOfIDSources_var nodes = new SMESH::ListOfIDSources();
+        SMESH::ListOfIDSources_var edges = new SMESH::ListOfIDSources();
+        SMESH::ListOfIDSources_var faces = new SMESH::ListOfIDSources();
+        SelectorWdg->GetSelected( nodes, edges, faces );
+        const bool makeGroups = false;
+
+        meshEditor->RotationSweepObjects(nodes, edges, faces, 
+                                         anAxis, anAngle, aNbSteps, aTolerance, makeGroups );
+
+        SMESH::MeshPreviewStruct_var aMeshPreviewStruct = meshEditor->GetPreviewData();
+        mySimulation->SetData( aMeshPreviewStruct._retn() );
+      }
+      catch (...) {}
     }
     else
     {
@@ -1094,7 +816,8 @@ void SMESHGUI_RevolutionDlg::onDisplaySimulation(bool toDisplayPreview)
 // function : onSelectVectorButton()
 // purpose  : [slot]
 //=================================================================================
-void SMESHGUI_RevolutionDlg::onSelectVectorButton(){
+void SMESHGUI_RevolutionDlg::onSelectVectorButton()
+{
   if(SelectVectorMenu) {
     SelectVectorMenu->exec( QCursor::pos() );
   }
@@ -1104,7 +827,8 @@ void SMESHGUI_RevolutionDlg::onSelectVectorButton(){
 // function : onSelectVectorMenu()
 // purpose  : [slot]
 //=================================================================================
-void SMESHGUI_RevolutionDlg::onSelectVectorMenu( QAction* action){
+void SMESHGUI_RevolutionDlg::onSelectVectorMenu( QAction* action)
+{
   if(!action)
     return;
 
@@ -1131,58 +855,4 @@ void SMESHGUI_RevolutionDlg::onSelectVectorMenu( QAction* action){
   SelectionIntoArgument();
 }
 
-//=================================================================================
-// function : setFilters()
-// purpose  : SLOT. Called when "Filter" button pressed.
-//=================================================================================
-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;  
-    types.append( SMESH::EDGE );
-    types.append( SMESH::FACE );
-    myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, types );
-  }
-  myFilterDlg->Init( GetConstructorId() ? SMESH::FACE : SMESH::EDGE );
 
-  myFilterDlg->SetSelection();
-  myFilterDlg->SetMesh( myMesh );
-  myFilterDlg->SetSourceWg( LineEditElements );
-
-  myFilterDlg->show();
-}
-
-//=================================================================================
-// function : isValid
-// purpose  :
-//=================================================================================
-bool SMESHGUI_RevolutionDlg::isValid()
-{
-  QString msg;
-  bool ok = true;
-  ok = SpinBox_X->isValid( msg, true ) && ok;
-  ok = SpinBox_Y->isValid( msg, true ) && ok;
-  ok = SpinBox_Z->isValid( msg, true ) && ok;
-  ok = SpinBox_DX->isValid( msg, true ) && ok;
-  ok = SpinBox_DY->isValid( msg, true ) && ok;
-  ok = SpinBox_DZ->isValid( msg, true ) && ok;
-  ok = SpinBox_Angle->isValid( msg, true ) && ok;
-  ok = SpinBox_NbSteps->isValid( msg, true ) && ok;
-  ok = SpinBox_Tolerance->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;
-}
index 811f65132d8bbda4fc5d326b3d3ebebafc87bc44..ec29fc93072b2f2823da5ef47c584887532ec603 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 #include <SALOMEconfig.h>
 #include CORBA_SERVER_HEADER(SMESH_Mesh)
 
+class LightApp_SelectionMgr;
+class QAction;
 class QButtonGroup;
+class QCheckBox;
 class QGroupBox;
 class QLabel;
 class QLineEdit;
+class QMenu;
 class QPushButton;
 class QRadioButton;
-class QCheckBox;
-class SalomeApp_IntSpinBox;
-class SMESHGUI_IdValidator;
-class SMESHGUI_SpinBox;
+class SALOME_Actor;
 class SMESHGUI;
+class SMESHGUI_3TypesSelector;
 class SMESHGUI_FilterDlg;
+class SMESHGUI_IdValidator;
+class SMESHGUI_MeshEditPreview;
+class SMESHGUI_SpinBox;
 class SMESH_Actor;
-class SVTK_Selector;
-class LightApp_SelectionMgr;
 class SMESH_LogicalFilter;
-class SALOME_Actor;
-class SMESHGUI_MeshEditPreview;
-class QMenu;
-class QAction;
+class SVTK_Selector;
+class SalomeApp_IntSpinBox;
 
 //=================================================================================
 // class    : SMESHGUI_RevolutionDlg
@@ -85,27 +86,11 @@ private:
   
   bool                      isValid();
   
-  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;
-
-  bool                      myBusy;
-  SMESH::SMESH_Mesh_var     myMesh;
-  SMESH_Actor*              myActor;
-  SMESH_LogicalFilter*      myMeshOrSubMeshOrGroupFilter;
-  SMESHGUI_MeshEditPreview* mySimulation;
-  SALOME_Actor*             myPreviewActor;
+  QWidget*                  myEditCurrentArgument;   /* Current  argument */
 
-  QGroupBox*                ConstructorsBox;
-  QButtonGroup*             GroupConstructors;
-  QRadioButton*             RadioButton1;
-  QRadioButton*             RadioButton2;
+  SMESHGUI_3TypesSelector*  SelectorWdg;
   QGroupBox*                GroupButtons;
   QPushButton*              buttonOk;
   QPushButton*              buttonCancel;
@@ -113,10 +98,6 @@ private:
   QPushButton*              buttonHelp;
   QGroupBox*                GroupArguments;
   QGroupBox*                GroupAxis;
-  QLabel*                   TextLabelElements;
-  QPushButton*              SelectElementsButton;
-  QLineEdit*                LineEditElements;
-  QCheckBox*                CheckBoxMesh;
   QCheckBox*                MakeGroupsCheck;
   QGroupBox*                GroupAngleBox;
   QButtonGroup*             GroupAngle;
@@ -153,17 +134,13 @@ private:
 
   
   QString                   myHelpFileName;
-  QString                   myIDs;
-  
-  QPushButton*              myFilterBtn;
-  SMESHGUI_FilterDlg*       myFilterDlg;
 
 protected slots:
   virtual void              onDisplaySimulation( bool );
-  virtual void                      reject();
+  virtual void              reject();
    
 private slots:
-  void                      ConstructorsClicked( int );
+  void                      CheckIsEnable();
   void                      ClickOnOk();
   bool                      ClickOnApply();
   void                      ClickOnHelp();
@@ -171,13 +148,11 @@ private slots:
   void                      SelectionIntoArgument();
   void                      DeactivateActiveDialog();
   void                      ActivateThisDialog();
-  void                      onTextChange( const QString& );
   void                      onAngleTextChange( const QString& );
-  void                      onSelectMesh( bool );
-  void                      onVectorChanged();
   void                      onSelectVectorMenu( QAction* );
   void                      onSelectVectorButton();
-  void                      setFilters();
+  void                      onOpenView();
+  void                      onCloseView();
 };
 
 #endif // SMESHGUI_REVOLUTIONDLG_H
index 1a9724012a00cc871ad913e4172f765c8373c473..81568b57d01fd72afa21c1bd601149e3ae24eccb 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&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,6 @@
 #include "SMESHGUI_MeshUtils.h"
 #include "SMESHGUI_IdValidator.h"
 #include "SMESHGUI_FilterDlg.h"
-#include "SMESHGUI_MeshEditPreview.h"
 
 #include <SMESH_Actor.h>
 #include <SMESH_TypeFilter.hxx>
@@ -309,7 +308,9 @@ SMESHGUI_RotationDlg::SMESHGUI_RotationDlg( SMESHGUI* theModule ) :
   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(reject()));
+  connect(mySMESHGUI,       SIGNAL (SignalActivatedViewManager()), this, SLOT(onOpenView()));
+  connect(mySMESHGUI,       SIGNAL (SignalActivatedViewManager()), this, SLOT(onOpenView()));
+  connect(mySMESHGUI,       SIGNAL (SignalCloseView()),            this, SLOT(onCloseView()));
   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)));
@@ -360,9 +361,21 @@ void SMESHGUI_RotationDlg::Init (bool ResetControls)
   buttonOk->setEnabled(false);
   buttonApply->setEnabled(false);
 
+  if ( !ResetControls && !isApplyAndClose() && // make highlight move upon [Apply] (IPAL20729)
+       myActor && !myActor->getIO().IsNull() &&
+       ActionGroup->button( MOVE_ELEMS_BUTTON )->isChecked() &&
+       !CheckBoxMesh->isChecked() ) // move selected elements
+  {
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+    {
+      aViewWindow->highlight( myActor->getIO(), false, false );
+      aViewWindow->highlight( myActor->getIO(), true, true );
+    }
+  }
   myActor = 0;
 
-  if (ResetControls) {
+  if (ResetControls)
+  {
     SpinBox_X->SetValue(0.0);
     SpinBox_Y->SetValue(0.0);
     SpinBox_Z->SetValue(0.0);
@@ -376,10 +389,6 @@ void SMESHGUI_RotationDlg::Init (bool ResetControls)
     CheckBoxMesh->setChecked(false);
     myPreviewCheckBox->setChecked(false);
     onDisplaySimulation(false);
-
-//     MakeGroupsCheck->setChecked(false);
-//     MakeGroupsCheck->setEnabled(false);
-//    onSelectMesh(false);
   }
 
   onSelectMesh(CheckBoxMesh->isChecked());
@@ -522,7 +531,6 @@ bool SMESHGUI_RotationDlg::ClickOnApply()
         anApp->browseObjects( anEntryList, isApplyAndClose() );
     }
     Init(false);
-    SelectionIntoArgument();
 
     SMESHGUI::Modified();
   }
@@ -560,6 +568,32 @@ void SMESHGUI_RotationDlg::reject()
   QDialog::reject();
 }
 
+
+//=================================================================================
+// function : onOpenView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_RotationDlg::onOpenView()
+{
+  if ( mySelector ) {
+    SMESH::SetPointRepresentation(false);
+  }
+  else {
+    mySelector = SMESH::GetViewWindow( mySMESHGUI )->GetSelector();
+    ActivateThisDialog();
+  }
+}
+
+//=================================================================================
+// function : onCloseView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_RotationDlg::onCloseView()
+{
+  DeactivateActiveDialog();
+  mySelector = 0;
+}
+
 //=================================================================================
 // function : ClickOnHelp()
 // purpose  :
@@ -643,6 +677,7 @@ void SMESHGUI_RotationDlg::onTextChange (const QString& theNewText)
 void SMESHGUI_RotationDlg::SelectionIntoArgument()
 {
   if (myBusy) return;
+  if (myFilterDlg && myFilterDlg->isVisible()) return; // filter dlg active
 
   // clear
   myActor = 0;
@@ -671,34 +706,35 @@ void SMESHGUI_RotationDlg::SelectionIntoArgument()
 
   int aNbUnits = 0;
 
-  if (myEditCurrentArgument == (QWidget*)LineEditElements) {
+  if (myEditCurrentArgument == (QWidget*)LineEditElements)
+  {
     myElementsId = "";
     myObjects.clear();
     myObjectsNames.clear();
     myMeshes.clear();
 
-    for ( SALOME_ListIteratorOfListIO it( aList ); it.More(); it.Next() ) {
+    for ( SALOME_ListIteratorOfListIO it( aList ); it.More(); it.Next() )
+    {
       Handle(SALOME_InteractiveObject) IO = it.Value();
       SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO( IO );
       if ( aMesh->_is_nil() )
         return;
-      
+
       myActor = SMESH::FindActorByObject( aMesh );
       if ( !myActor )
         myActor = SMESH::FindActorByEntry( IO->getEntry() );
-      if ( !myActor && !CheckBoxMesh->isChecked() )
-        return;
-      
-      if ( !SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO )->_is_nil() ) {
-        if ( _PTR(Study) aStudy = SMESH::GetActiveStudyDocument() ) {
-          _PTR(SObject) obj = aStudy->FindObjectID( qPrintable( QString( IO->getEntry() ) ) );
-          _PTR(GenericAttribute) anAttr;
-          if ( obj && obj->FindAttribute( anAttr, "AttributeName" ) ) {
-            _PTR(AttributeName) aNameAttr( anAttr );
-            myObjects << SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
-            myObjectsNames << aNameAttr->Value().c_str();
-            myMeshes << aMesh;
-          }
+      // if ( !myActor && !CheckBoxMesh->isChecked() ) -- elems can be selected by Filter
+      //   return;
+
+      SMESH::SMESH_IDSource_var idSrc = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
+      if ( _PTR(SObject) obj = SMESH::FindSObject( idSrc ))
+      {
+        std::string name = obj->GetName();
+        if ( !name.empty() )
+        {
+          myObjects << idSrc;
+          myObjectsNames << name.c_str();
+          myMeshes << aMesh;
         }
       }
     }
@@ -714,71 +750,30 @@ void SMESHGUI_RotationDlg::SelectionIntoArgument()
     else if ( ActionGroup->checkedId() != MOVE_ELEMS_BUTTON ) {
       MakeGroupsCheck->setEnabled(true);
     }
-    if (CheckBoxMesh->isChecked()) {
-      SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aString);
 
+    if (CheckBoxMesh->isChecked()) {
       if ( myMeshes.isEmpty() )
         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 {
+      SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aString);
+    }
+    else {
       aNbUnits = SMESH::GetNameOfSelectedElements(mySelector, aList.First(), aString);
       myElementsId = aString;
       if (aNbUnits < 1)
         return;
-      }
+    }
 
     myNbOkElements = true;
 
-  } else {
+  }
+  else // set coordinates by picked nodes
+  {
     Handle(SALOME_InteractiveObject) IO = aList.First();
-    if ((SMESH::GetMeshByIO(IO))->_is_nil())
-      return;
-      
-    SMESH_Actor* anActor = SMESH::FindActorByObject(SMESH::GetMeshByIO(IO));
+
+    SMESH_Actor* anActor = SMESH::FindActorByEntry( IO->getEntry() );
     if (!anActor)
-      anActor = SMESH::FindActorByEntry(IO->getEntry());
-    if (!anActor && !CheckBoxMesh->isChecked())
       return;
-      
+
     aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, IO, aString);
     if (aNbUnits != 1)
       return;
@@ -912,8 +907,13 @@ void SMESHGUI_RotationDlg::ActivateThisDialog()
 //=================================================================================
 void SMESHGUI_RotationDlg::enterEvent (QEvent*)
 {
-  if (!GroupConstructors->isEnabled())
+  if (!GroupConstructors->isEnabled()) {
+    SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
+    if ( aViewWindow && !mySelector) {
+      mySelector = aViewWindow->GetSelector();
+    }
     ActivateThisDialog();
+  }
 }
 
 //=================================================================================
@@ -947,7 +947,6 @@ void SMESHGUI_RotationDlg::onSelectMesh (bool toSelectMesh)
       aViewWindow->SetSelectionMode( CellSelection );
     LineEditElements->setReadOnly(false);
     LineEditElements->setValidator(myIdValidator);
-    onTextChange(LineEditElements->text());
     hidePreview();
   }
 
@@ -1062,9 +1061,20 @@ void SMESHGUI_RotationDlg::setFilters()
                               tr("NO_MESH_SELECTED"));
    return;
   }
-  if ( !myFilterDlg )
+  if ( !myFilterDlg ) {
     myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, SMESH::ALL );
+    connect(myFilterDlg, SIGNAL(Accepted()), SLOT(onFilterAccepted()));
+  }
+
+  QList<int> types;
+  if ( myMeshes[0]->NbEdges()     ) types << SMESH::EDGE;
+  if ( myMeshes[0]->NbFaces()     ) types << SMESH::FACE;
+  if ( myMeshes[0]->NbVolumes()   ) types << SMESH::VOLUME;
+  if ( myMeshes[0]->NbBalls()     ) types << SMESH::BALL;
+  if ( myMeshes[0]->Nb0DElements()) types << SMESH::ELEM0D;
+  if ( types.count() > 1 )          types << SMESH::ALL;
 
+  myFilterDlg->Init( types );
   myFilterDlg->SetSelection();
   myFilterDlg->SetMesh( myMeshes[0] );
   myFilterDlg->SetSourceWg( LineEditElements );
@@ -1072,6 +1082,23 @@ void SMESHGUI_RotationDlg::setFilters()
   myFilterDlg->show();
 }
 
+//=======================================================================
+// name    : onFilterAccepted()
+// Purpose : SLOT. Called when Filter dlg closed with OK button.
+//           Activate [Apply] if no Actor is available
+//=======================================================================
+void SMESHGUI_RotationDlg::onFilterAccepted()
+{
+  if ( myMeshes.length() > 0 && !buttonOk->isEnabled() )
+  {
+    myElementsId = LineEditElements->text();
+    QStringList aListElementsId = myElementsId.split(" ", QString::SkipEmptyParts);
+    myNbOkElements = aListElementsId.count();
+    buttonOk->setEnabled( myNbOkElements );
+    buttonApply->setEnabled( myNbOkElements );
+  }
+}
+
 //=================================================================================
 // function : isValid
 // purpose  :
index 3f2c1b9ce7273549f1e9cdc88f46d1e44f8dc177..736bafb5916d2e621244939294dce81c3d6c33f6 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -135,6 +135,7 @@ private:
 protected slots:
   virtual void           onDisplaySimulation( bool );
   virtual void           reject();
+  void                   onFilterAccepted();
  
 private slots:
   void                   ClickOnOk();
@@ -148,6 +149,8 @@ private slots:
   void                   onSelectMesh( bool );
   void                   onVectorChanged();
   void                   onActionClicked( int );
+  void                   onOpenView();
+  void                   onCloseView();
   void                   setFilters();
 };
 
index e07177bf1ff7d6463b7dbbfbb0aefcb6d0d3e6ce..2248ac60eec32fefcdca45ed4615c8bd62df4e25 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
@@ -308,7 +308,10 @@ SMESHGUI_ScaleDlg::SMESHGUI_ScaleDlg( SMESHGUI* theModule ) :
   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(reject()));
+  connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()),      this, SLOT(reject()));
+  connect(mySMESHGUI, SIGNAL(SignalActivatedViewManager()), this, SLOT(onOpenView()));
+  connect(mySMESHGUI, SIGNAL(SignalCloseView()),            this, SLOT(onCloseView()));
+
   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)));
@@ -486,7 +489,7 @@ bool SMESHGUI_ScaleDlg::ClickOnApply()
           }
         else {
           SMESH::SMESH_MeshEditor_var aMeshEditor = myMeshes[0]->GetMeshEditor();
-          SMESH::SMESH_IDSource_wrap src = aMeshEditor->MakeIDSource(anElementsId, SMESH::ALL);
+          SMESH::IDSource_wrap src = aMeshEditor->MakeIDSource(anElementsId, SMESH::ALL);
           myMeshes[0]->SetParameters( aParameters.join( ":" ).toLatin1().constData() );
           aMeshEditor->Scale( src, aPoint, aScaleFact, false);
         }
@@ -503,7 +506,7 @@ bool SMESHGUI_ScaleDlg::ClickOnApply()
             }
           else {
             SMESH::SMESH_MeshEditor_var aMeshEditor = myMeshes[0]->GetMeshEditor();
-            SMESH::SMESH_IDSource_wrap src = aMeshEditor->MakeIDSource(anElementsId, SMESH::ALL);
+            SMESH::IDSource_wrap src = aMeshEditor->MakeIDSource(anElementsId, SMESH::ALL);
             myMeshes[0]->SetParameters(aParameters.join( ":" ).toLatin1().constData());
             groups = aMeshEditor->ScaleMakeGroups( src, aPoint, aScaleFact);
           }
@@ -518,7 +521,7 @@ bool SMESHGUI_ScaleDlg::ClickOnApply()
           }
           else {
             SMESH::SMESH_MeshEditor_var aMeshEditor = myMeshes[0]->GetMeshEditor();
-            SMESH::SMESH_IDSource_wrap src = aMeshEditor->MakeIDSource(anElementsId, SMESH::ALL);
+            SMESH::IDSource_wrap src = aMeshEditor->MakeIDSource(anElementsId, SMESH::ALL);
             myMeshes[0]->SetParameters(aParameters.join( ":" ).toLatin1().constData());
             aMeshEditor->Scale( src, aPoint, aScaleFact, true);
           }
@@ -541,7 +544,7 @@ bool SMESHGUI_ScaleDlg::ClickOnApply()
         else {
           SMESH::SMESH_MeshEditor_var aMeshEditor = myMeshes[0]->GetMeshEditor();
           myMeshes[0]->SetParameters(aParameters.join( ":" ).toLatin1().constData());
-          SMESH::SMESH_IDSource_wrap src = aMeshEditor->MakeIDSource(anElementsId, SMESH::ALL);
+          SMESH::IDSource_wrap src = aMeshEditor->MakeIDSource(anElementsId, SMESH::ALL);
           mesh = aMeshEditor->ScaleMakeMesh( src, aPoint, aScaleFact, makeGroups,
                                              LineEditNewMesh->text().toLatin1().data());
           if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( mesh ) )
@@ -605,6 +608,31 @@ void SMESHGUI_ScaleDlg::reject()
   QDialog::reject();
 }
 
+//=================================================================================
+// function : onOpenView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_ScaleDlg::onOpenView()
+{
+  if ( mySelector ) {
+    SMESH::SetPointRepresentation(false);
+  }
+  else {
+    mySelector = SMESH::GetViewWindow( mySMESHGUI )->GetSelector();
+    ActivateThisDialog();
+  }
+}
+
+//=================================================================================
+// function : onCloseView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_ScaleDlg::onCloseView()
+{
+  DeactivateActiveDialog();
+  mySelector = 0;
+}
+
 //=================================================================================
 // function : ClickOnHelp()
 // purpose  :
@@ -687,6 +715,8 @@ void SMESHGUI_ScaleDlg::onTextChange (const QString& theNewText)
 void SMESHGUI_ScaleDlg::SelectionIntoArgument()
 {
   if (myBusy) return;
+  if (myFilterDlg && myFilterDlg->isVisible()) return; // filter dlg active
+
   BusyLocker lock( myBusy );
   // clear
   myActor = 0;
@@ -713,38 +743,39 @@ void SMESHGUI_ScaleDlg::SelectionIntoArgument()
 
   int aNbUnits = 0;
 
-  if (myEditCurrentArgument == (QWidget*)LineEditElements) {
+  if (myEditCurrentArgument == (QWidget*)LineEditElements)
+  {
     myElementsId = "";
     myObjects.clear();
     myObjectsNames.clear();
     myMeshes.clear();
 
-    for ( SALOME_ListIteratorOfListIO it( aList ); it.More(); it.Next() ) {
+    for ( SALOME_ListIteratorOfListIO it( aList ); it.More(); it.Next() )
+    {
       Handle(SALOME_InteractiveObject) IO = it.Value();
       SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO( IO );
       if ( aMesh->_is_nil() )
         return;
-  
+
       myActor = SMESH::FindActorByObject( aMesh );
       if ( !myActor )
         myActor = SMESH::FindActorByEntry( IO->getEntry() );
-      if ( !myActor && !CheckBoxMesh->isChecked() )
-        return;
-
-      if ( !SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO )->_is_nil() ) {
-        if ( _PTR(Study) aStudy = SMESH::GetActiveStudyDocument() ) {
-          _PTR(SObject) obj = aStudy->FindObjectID( qPrintable( QString( IO->getEntry() ) ) );
-          _PTR(GenericAttribute) anAttr;
-          if ( obj && obj->FindAttribute( anAttr, "AttributeName" ) ) {
-            _PTR(AttributeName) aNameAttr( anAttr );
-            myObjects << SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
-            myObjectsNames << aNameAttr->Value().c_str();
-            myMeshes << aMesh;
-          }
+      // if ( !myActor && !CheckBoxMesh->isChecked() ) -- elems can be selected by Filter
+      //   return;
+
+      SMESH::SMESH_IDSource_var idSrc = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
+      if ( _PTR(SObject) obj = SMESH::FindSObject( idSrc ))
+      {
+        std::string name = obj->GetName();
+        if ( !name.empty() )
+        {
+          myObjects << idSrc;
+          myObjectsNames << name.c_str();
+          myMeshes << aMesh;
         }
       }
     }
-      
+
     // MakeGroups is available if there are groups and "Copy"
     int aNbGroups = 0;
     for ( int i = 0; i < myMeshes.count(); i++ )
@@ -759,50 +790,11 @@ void SMESHGUI_ScaleDlg::SelectionIntoArgument()
     }
 
     if (CheckBoxMesh->isChecked()) {
-      SMESH::GetNameOfSelectedIObjects( mySelectionMgr, aString );
       if (myMeshes.isEmpty())
         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 {
+      SMESH::GetNameOfSelectedIObjects( mySelectionMgr, aString );
+    }
+    else {
       aNbUnits = SMESH::GetNameOfSelectedElements(mySelector, aList.First(), aString);
       myElementsId = aString;
       if (aNbUnits < 1)
@@ -810,15 +802,14 @@ void SMESHGUI_ScaleDlg::SelectionIntoArgument()
     }
 
     myNbOkElements = true;
-  } else {
+
+  }
+  else // set coordinates by a picked node
+  {
     Handle(SALOME_InteractiveObject) IO = aList.First();
-    if ((SMESH::GetMeshByIO(IO))->_is_nil())
-      return;
 
-    SMESH_Actor* anActor = SMESH::FindActorByObject(SMESH::GetMeshByIO(IO));
+    SMESH_Actor* anActor = SMESH::FindActorByEntry( IO->getEntry() );
     if (!anActor)
-      anActor = SMESH::FindActorByEntry(IO->getEntry());
-    if (!anActor && !CheckBoxMesh->isChecked())
       return;
 
     aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, IO, aString);
@@ -944,8 +935,13 @@ void SMESHGUI_ScaleDlg::ActivateThisDialog()
 //=================================================================================
 void SMESHGUI_ScaleDlg::enterEvent (QEvent*)
 {
-  if (!ConstructorsBox->isEnabled())
+  if (!ConstructorsBox->isEnabled()) {
+    SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
+    if ( aViewWindow && !mySelector) {
+      mySelector = aViewWindow->GetSelector();
+    }
     ActivateThisDialog();
+  }
 }
 
 //=======================================================================
@@ -1070,15 +1066,24 @@ void SMESHGUI_ScaleDlg::keyPressEvent( QKeyEvent* e )
 //=================================================================================
 void SMESHGUI_ScaleDlg::setFilters()
 {
-  if(myMeshes.isEmpty()) {
-    SUIT_MessageBox::critical(this,
-                              tr("SMESH_ERROR"),
-                              tr("NO_MESH_SELECTED"));
-   return;
+  if ( myMeshes.isEmpty() ) {
+    SUIT_MessageBox::critical(this, tr("SMESH_ERROR"), tr("NO_MESH_SELECTED"));
+    return;
   }
-  if ( !myFilterDlg )
+  if ( !myFilterDlg ) {
     myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, SMESH::ALL );
+    connect(myFilterDlg, SIGNAL(Accepted()), SLOT(onFilterAccepted()));
+  }
+
+  QList<int> types;
+  if ( myMeshes[0]->NbEdges()     ) types << SMESH::EDGE;
+  if ( myMeshes[0]->NbFaces()     ) types << SMESH::FACE;
+  if ( myMeshes[0]->NbVolumes()   ) types << SMESH::VOLUME;
+  if ( myMeshes[0]->NbBalls()     ) types << SMESH::BALL;
+  if ( myMeshes[0]->Nb0DElements()) types << SMESH::ELEM0D;
+  if ( types.count() > 1 )          types << SMESH::ALL;
 
+  myFilterDlg->Init( types );
   myFilterDlg->SetSelection();
   myFilterDlg->SetMesh( myMeshes[0] );
   myFilterDlg->SetSourceWg( LineEditElements );
@@ -1086,6 +1091,23 @@ void SMESHGUI_ScaleDlg::setFilters()
   myFilterDlg->show();
 }
 
+//=======================================================================
+// name    : onFilterAccepted()
+// Purpose : SLOT. Called when Filter dlg closed with OK button.
+//           Activate [Apply] if no Actor is available
+//=======================================================================
+void SMESHGUI_ScaleDlg::onFilterAccepted()
+{
+  if ( myMeshes.length() > 0 && !buttonOk->isEnabled() )
+  {
+    myElementsId = LineEditElements->text();
+    QStringList aListElementsId = myElementsId.split(" ", QString::SkipEmptyParts);
+    myNbOkElements = aListElementsId.count();
+    buttonOk->setEnabled   ( myNbOkElements );
+    buttonApply->setEnabled( myNbOkElements );
+  }
+}
+
 //=================================================================================
 // function : isValid
 // purpose  :
@@ -1147,7 +1169,7 @@ void SMESHGUI_ScaleDlg::onDisplaySimulation( bool toDisplayPreview ) {
           }
         else {
           SMESH::SMESH_MeshEditor_var aMeshEditor = myMeshes[0]->GetMeshEditPreviewer();
-          SMESH::SMESH_IDSource_wrap src = aMeshEditor->MakeIDSource(anElementsId, SMESH::ALL);
+          SMESH::IDSource_wrap src = aMeshEditor->MakeIDSource(anElementsId, SMESH::ALL);
           aMeshEditor->Scale( src, aPoint, aScaleFact, copy);
           aMeshPreviewStruct << aMeshEditor->GetPreviewData();
         }
index 378b17af0f5b092819bf4cf5ba481872cbdddcc4..bdd285b2830037460d00395d599460656b14d81b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
@@ -131,6 +131,7 @@ private:
 protected slots:
   virtual void           onDisplaySimulation( bool );
   virtual void           reject();
+  void                   onFilterAccepted();
    
 private slots:
   void                   ConstructorsClicked( int );
@@ -144,6 +145,8 @@ private slots:
   void                   onTextChange( const QString& );
   void                   onSelectMesh( bool );
   void                   onActionClicked( int );
+  void                   onOpenView();
+  void                   onCloseView();
   void                   setFilters();
 };
 
index 94331c90156b446112fc6377a8cc3d36f5ab0afd..3d446d96d43f9019368789e84136041d16b5ff83 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -128,12 +128,14 @@ QVariant SMESHGUI_Selection::parameter( const int ind, const QString& p ) const
   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=="hasGeomReference" )     val = QVariant( hasGeomReference( ind ) );
+  else if ( p=="isEditableHyp" )        val = QVariant( isEditableHyp( 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 ) );
+  else if ( p=="isScalarBarVisible")    val = QVariant( isScalarBarVisible( ind ) );
   else if ( p=="hasChildren")           val = QVariant( hasChildren( ind ) );
   else if ( p=="nbChildren")            val = QVariant( nbChildren( ind ) );
   else if ( p=="isContainer")           val = QVariant( isContainer( ind ) );
@@ -257,6 +259,16 @@ bool SMESHGUI_Selection::isDistributionVisible(int ind) const {
   return (actor && actor->GetScalarBarActor() && actor->GetScalarBarActor()->GetDistributionVisibility());
 } 
 
+//=======================================================================
+//function : isScalarBarVisible
+//purpose  : Visible/Invisible Scalar Bar
+//=======================================================================
+
+bool SMESHGUI_Selection::isScalarBarVisible(int ind) const {
+  SMESH_Actor* actor = getActor( ind );
+  return (actor && actor->GetScalarBarActor() && actor->GetScalarBarActor()->GetVisibility());
+}
+
 //=======================================================================
 //function : shrinkMode
 //purpose  : return either 'IsSrunk', 'IsNotShrunk' or 'IsNotShrinkable'
@@ -344,7 +356,7 @@ QString SMESHGUI_Selection::controlMode() const
     QString mode = myControls[0];
     for( int ind = 1; ind < myControls.count(); ind++ ) {
       if( mode != myControls[ind] )
-        return "eNone";
+        return "eMixed"; // different controls used for different actors
     }
     return mode;
   }
@@ -463,7 +475,7 @@ int SMESHGUI_Selection::dim( int ind ) const
       if ( !CORBA::is_nil( idSrc ) )
       {
         SMESH::array_of_ElementType_var types = idSrc->GetTypes();
-        for ( int i = 0; i < types->length(); ++ i) {
+        for ( size_t 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;
@@ -481,62 +493,78 @@ int SMESHGUI_Selection::dim( int ind ) const
 
 //=======================================================================
 //function : isComputable
-//purpose  : 
+//purpose  : return true for a ready-to-compute mesh
 //=======================================================================
 
-QVariant SMESHGUI_Selection::isComputable( int ind ) const
+bool SMESHGUI_Selection::isComputable( int ind ) const
 {
-  if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" )
+  if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] == "Mesh" )
   {
+    QMap<int,int> modeMap;
     _PTR(SObject) so = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() );
-    CORBA::Object_var obj = SMESH::SObjectToObject( so, SMESH::GetActiveStudyDocument() );
-    if( !CORBA::is_nil( obj ) ) {
-      SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( obj );
-      if ( !CORBA::is_nil( mesh ) ) {
-        if ( mesh->HasShapeToMesh() ) {
-          GEOM::GEOM_Object_var shape = SMESH::GetShapeOnMeshOrSubMesh( so );
-          return QVariant( !shape->_is_nil() );
-        }
-        else
-        {
-          return QVariant( mesh->NbFaces() !=0 );
-        }
-      }
-      else
-      {
-        GEOM::GEOM_Object_var shape = SMESH::GetShapeOnMeshOrSubMesh( so );
-        return QVariant( !shape->_is_nil() );
-      }
-    }
+    SMESHGUI_PrecomputeOp::getAssignedAlgos( so, modeMap );
+    return modeMap.size() > 0;
   }
-  return QVariant( false );
+  return false;
 }
 
 //=======================================================================
 //function : isPreComputable
-//purpose  : 
+//purpose  : returns true for a mesh with algorithms
 //=======================================================================
 
-QVariant SMESHGUI_Selection::isPreComputable( int ind ) const
+bool SMESHGUI_Selection::isPreComputable( int ind ) const
+{
+  if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] == "Mesh" )
+  {
+    int maxDim = dim( ind );
+    if ( maxDim < 2 ) // we can preview 1D or 2D
+    {
+      QMap<int,int> modeMap;
+      _PTR(SObject) pMesh = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() );
+      SMESHGUI_PrecomputeOp::getAssignedAlgos( pMesh, modeMap );
+      if ( modeMap.size() > 1 )
+        return (( modeMap.contains( SMESH::DIM_3D )) ||
+                ( modeMap.contains( SMESH::DIM_2D ) && maxDim < 1 ));
+    }
+  }
+  return false;
+}
+
+//=======================================================================
+//function : hasGeomReference
+//purpose  : returns true for a mesh or sub-mesh on geometry
+//=======================================================================
+
+bool SMESHGUI_Selection::hasGeomReference( 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 );
+    _PTR(SObject) so = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() );
+    GEOM::GEOM_Object_var shape = SMESH::GetShapeOnMeshOrSubMesh( so );
+    return !shape->_is_nil();
   }
-  return QVariant( false );
+  return false;
 }
 
 //=======================================================================
-//function : hasReference
+//function : isEditableHyp
 //purpose  : 
 //=======================================================================
 
-QVariant SMESHGUI_Selection::hasReference( int ind ) const
+bool SMESHGUI_Selection::isEditableHyp( int ind ) const
 {
-  return QVariant( isReference( ind ) );
+  bool isEditable = true;
+  if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] == "Hypothesis" )
+  {
+    _PTR(SObject) so = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() );
+    SMESH::SMESH_Hypothesis_var hyp = SMESH::SObjectToInterface<SMESH::SMESH_Hypothesis>( so );
+    if ( !hyp->_is_nil() )
+    {
+      isEditable = hyp->HasParameters();
+    }
+  }
+  return isEditable;
 }
 
 //=======================================================================
@@ -544,17 +572,17 @@ QVariant SMESHGUI_Selection::hasReference( int ind ) const
 //purpose  : 
 //=======================================================================
 
-QVariant SMESHGUI_Selection::isVisible( int ind ) const
+bool SMESHGUI_Selection::isVisible( int ind ) const
 {
   if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" )
   {
     SMESH_Actor* actor = SMESH::FindActorByEntry( entry( ind ).toLatin1().data() );
     if ( actor && actor->hasIO() ) {
       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetCurrentVtkView() )
-        return QVariant( aViewWindow->isVisible( actor->getIO() ) );
+        return aViewWindow->isVisible( actor->getIO() );
     }
   }
-  return QVariant( false );
+  return false;
 }
 
 //=======================================================================
index 3ba1bf4cb3809c171ed491c8c565f1fb95a4e4fa..e3146cad3e341b718553d2afa07889b4fd01761a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -56,14 +56,16 @@ public:
   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 bool            isComputable( int ) const;
+  virtual bool            isPreComputable( int ) const;
+  virtual bool            hasGeomReference( int ) const;
+  virtual bool            isEditableHyp( int ) const;
+  virtual bool            isVisible( int ) const;
 
-  virtual QString         quadratic2DMode(int ) const;
+  virtual QString         quadratic2DMode( int ) const;
 
-  virtual bool            isDistributionVisible(int ) const;
+  virtual bool            isDistributionVisible( int ) const;
+  virtual bool            isScalarBarVisible( int ) const;
   virtual bool            hasChildren( int ) const;
   virtual int             nbChildren( int ) const;
   virtual bool            isContainer( int ) const;
index daf2bf493ff5e4a499d2e05130a58e42b61b6543..9ea28adf97673f27bcee7b3b667edb60cc19c683 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index c8080f9ae3057bfded5227a6e01fedf298495c1b..578915713ebed2a78b8d4d8a3c7558f83f2d2a1b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 6bb73e2dd149ba914d5187d05010f232c81fcdf8..d7f598c826fea5462c582ea2d461cb8626f04674 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 #include "SMESHGUI_SewingDlg.h"
 
 #include "SMESHGUI.h"
+#include "SMESHGUI_IdPreview.h"
+#include "SMESHGUI_IdValidator.h"
+#include "SMESHGUI_MergeDlg.h"
+#include "SMESHGUI_MeshUtils.h"
+#include "SMESHGUI_PreVisualObj.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 <SMDS_Mesh.hxx>
+#include <SMESH_Actor.h>
+#include <SMESH_TypeDefs.hxx>
 
 // SALOME GUI includes
-#include <SUIT_Session.h>
-#include <SUIT_ResourceMgr.h>
+#include <LightApp_Application.h>
+#include <LightApp_SelectionMgr.h>
+#include <SALOMEDSClient_Study.hxx>
+#include <SALOME_ListIO.hxx>
 #include <SUIT_Desktop.h>
 #include <SUIT_MessageBox.h>
 #include <SUIT_OverrideCursor.h>
-
-#include <LightApp_Application.h>
-#include <LightApp_SelectionMgr.h>
-
+#include <SUIT_ResourceMgr.h>
+#include <SUIT_Session.h>
 #include <SVTK_ViewModel.h>
 #include <SVTK_ViewWindow.h>
-#include <SALOME_ListIO.hxx>
+#include <SalomeApp_IntSpinBox.h>
+#include <SalomeApp_Tools.h>
 
 // OCCT includes
 #include <TColStd_MapOfInteger.hxx>
 // Qt includes
 #include <QApplication>
 #include <QButtonGroup>
+#include <QCheckBox>
+#include <QGridLayout>
 #include <QGroupBox>
+#include <QHBoxLayout>
+#include <QKeyEvent>
 #include <QLabel>
 #include <QLineEdit>
+#include <QListWidget>
 #include <QPushButton>
 #include <QRadioButton>
-#include <QCheckBox>
-#include <QHBoxLayout>
+#include <QToolButton>
 #include <QVBoxLayout>
-#include <QGridLayout>
-#include <QKeyEvent>
-
-// IDL includes
-#include <SALOMEconfig.h>
-#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
 
 #define SPACING 6
 #define MARGIN  11
 
+namespace
+{
+  enum ActionType { MODE_AUTO=0, MODE_MANUAL,
+                    MOVE_LEFT_1=0, MOVE_RIGHT_1, MOVE_LEFT_2, MOVE_RIGHT_2,
+                    GROUP_COLOR=Qt::UserRole, GROUP_INDEX };
+}
+
+//=================================================================================
+/*!
+ * \brief Dispalayer of free borders
+ */
+//=================================================================================
+
+struct SMESHGUI_SewingDlg::BorderGroupDisplayer
+{
+  const SMESH::ListOfFreeBorders& myBorders;
+  const SMESH::FreeBordersGroup&  myGroup;
+  QColor                          myColor;
+  SMESH::SMESH_Mesh_ptr           myMesh;
+
+  std::vector< SMESH_Actor* >     myPartActors;
+  SVTK_ViewWindow*                myViewWindow;
+  SMESHGUI_IdPreview              myIdPreview;
+
+  BorderGroupDisplayer( const SMESH::CoincidentFreeBorders& borders,
+                        int                                 groupIndex,
+                        QColor                              color,
+                        SMESH::SMESH_Mesh_ptr               mesh);
+  ~BorderGroupDisplayer();
+  void Hide();
+  void ShowGroup( bool wholeBorders );
+  void ShowPart( int partIndex, bool toEdit );
+  void Update();
+
+private:
+  void getPartEnds( int partIndex, std::vector<int> & ids, std::list<gp_XYZ>& coords);
+};
+
 //=================================================================================
 // class    : SMESHGUI_SewingDlg()
 // purpose  :
@@ -89,6 +131,7 @@ SMESHGUI_SewingDlg::SMESHGUI_SewingDlg( SMESHGUI* theModule )
   QPixmap image2 (mgr->loadPixmap("SMESH", tr("ICON_SMESH_SEWING_BORDERTOSIDE")));
   QPixmap image3 (mgr->loadPixmap("SMESH", tr("ICON_SMESH_SEWING_SIDEELEMENTS")));
   QPixmap image4 (mgr->loadPixmap("SMESH", tr("ICON_SELECT")));
+  QPixmap IconRemove(mgr->loadPixmap("SMESH", tr("ICON_REMOVE")));
 
   setModal(false);
   setAttribute(Qt::WA_DeleteOnClose, true);
@@ -203,9 +246,166 @@ SMESHGUI_SewingDlg::SMESHGUI_SewingDlg( SMESHGUI* theModule )
   // Control for the polyedres creation to obtain conform mesh
   CheckBoxPolyedrs = new QCheckBox(tr("CREATE_POLYEDRS_NEAR_BOUNDARY"), GroupArguments);
 
+  /***************************************************************/
+  // Controls to switch free borders mode ( auto || manual )
+
+  ModeGroup = new QGroupBox( tr( "SMESH_MODE" ), GroupArguments );
+  ModeButGrp = new QButtonGroup( ModeGroup );
+  QHBoxLayout* aModeGroupLayout = new QHBoxLayout( ModeGroup );
+  aModeGroupLayout->setMargin( MARGIN );
+  aModeGroupLayout->setSpacing( SPACING );
+
+  QRadioButton* rb1 = new QRadioButton( tr( "SMESH_AUTOMATIC" ), ModeGroup );
+  QRadioButton* rb2 = new QRadioButton( tr( "SMESH_MANUAL"    ), ModeGroup );
+  ModeButGrp->addButton( rb1, MODE_AUTO );
+  ModeButGrp->addButton( rb2, MODE_MANUAL );
+  aModeGroupLayout->addWidget( rb1 );
+  aModeGroupLayout->addWidget( rb2 );
+  rb1->setChecked(true);
+
+  /***************************************************************/
+  // Controls for detecting coincident free borders
+
+  SewFreeBordersWidget = new QWidget( GroupArguments );
+  QVBoxLayout* aSewFreeBordersLayout = new QVBoxLayout( SewFreeBordersWidget );
+  aSewFreeBordersLayout->setMargin( 0 );
+  aSewFreeBordersLayout->setSpacing( SPACING );
+
+  // Tolerance
+  QWidget* TolAndAuto = new QWidget(SewFreeBordersWidget);
+  QLabel* TextLabelTolerance = new QLabel(tr("SMESH_TOLERANCE"), TolAndAuto);
+  SpinBoxTolerance = new SMESHGUI_SpinBox(TolAndAuto);
+  SpinBoxTolerance->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
+  SpinBoxTolerance->RangeStepAndValidator(0.0, COORD_MAX, 0.00001, "len_tol_precision");
+  SpinBoxTolerance->SetValue(0.); // auto-tolerance
+
+  // Auto Sewing
+  AutoSewCheck = new QCheckBox(tr("AUTO_SEWING"), TolAndAuto);
+  AutoSewCheck->setChecked( true );
+
+  // mesh
+  QGroupBox* GroupMesh = new QGroupBox(tr("SMESH_MESH"), SewFreeBordersWidget);
+  QHBoxLayout* GroupMeshLayout = new QHBoxLayout(GroupMesh);
+  GroupMeshLayout->setSpacing(SPACING);
+  GroupMeshLayout->setMargin(MARGIN);
+
+  QLabel* 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);
+
+  QGridLayout* TolAndAutoLayout = new QGridLayout( TolAndAuto );
+  TolAndAutoLayout->setSpacing(SPACING);
+  TolAndAutoLayout->setMargin(0);
+  TolAndAutoLayout->addWidget(GroupMesh,          0, 0, 1, 2 );
+  TolAndAutoLayout->addWidget(TextLabelTolerance, 1, 0 );
+  TolAndAutoLayout->addWidget(SpinBoxTolerance,   1, 1 );
+  TolAndAutoLayout->addWidget(AutoSewCheck,       2, 0 );
+
+  aSewFreeBordersLayout->addWidget( TolAndAuto );
+
+  /******************/
+  // Coincident group
+  GroupCoincidentWidget = new QWidget(SewFreeBordersWidget);
+  QGridLayout* GroupCoincidentLayout = new QGridLayout(GroupCoincidentWidget);
+  GroupCoincidentLayout->setSpacing(SPACING);
+  GroupCoincidentLayout->setMargin(0);
+
+  QGroupBox* GroupCoincident = new QGroupBox(tr("COINCIDENT_FREE_BORDERS"), GroupCoincidentWidget);
+  QGridLayout* aCoincidentLayout = new QGridLayout(GroupCoincident);
+  aCoincidentLayout->setSpacing(SPACING);
+  aCoincidentLayout->setMargin(MARGIN);
+
+  /*******/
+  // borders
+  ListCoincident = new QListWidget(GroupCoincident);
+  ListCoincident->setSelectionMode(QListWidget::ExtendedSelection);
+
+  DetectButton      = new QPushButton(tr("DETECT"),           GroupCoincident);
+  RemoveGroupButton = new QPushButton(tr("SMESH_BUT_REMOVE"), GroupCoincident);
+
+  SelectAllCheck = new QCheckBox(tr("SELECT_ALL"), GroupCoincident);
+
+  aCoincidentLayout->addWidget(ListCoincident,    0, 0, 5, 2);
+  aCoincidentLayout->addWidget(DetectButton,      1, 2);
+  aCoincidentLayout->addWidget(RemoveGroupButton, 3, 2);
+  aCoincidentLayout->addWidget(SelectAllCheck,    5, 0);
+  aCoincidentLayout->setRowMinimumHeight(1, 10);
+  aCoincidentLayout->setRowStretch      (4, 5);
+  aCoincidentLayout->setRowStretch      (5, 0);
+
+  /*****************************************/
+  // Controls for editing the selected group
+
+  QGroupBox* GroupEdit = new QGroupBox(tr("EDIT_SELECTED_GROUP"), GroupCoincidentWidget);
+  QGridLayout* GroupEditLayout = new QGridLayout(GroupEdit);
+  GroupEditLayout->setSpacing(SPACING);
+  GroupEditLayout->setMargin(MARGIN);
+
+  ListEdit = new QListWidget(GroupEdit);
+  ListEdit->setFlow( QListView::LeftToRight );
+  ListEdit->setSelectionMode(QListWidget::ExtendedSelection);
+  SetFirstButton = new QPushButton(GroupEdit);
+  SetFirstButton->setIcon(QPixmap(SMESHGUI_MergeDlg::IconFirst()));
+  RemoveElemButton = new QPushButton(GroupEdit);
+  RemoveElemButton->setIcon(IconRemove);
+
+  MoveBorderEndsButGrp = new QButtonGroup( GroupEdit );
+  QToolButton* moveBut1 = new QToolButton( GroupEdit );
+  QToolButton* moveBut2 = new QToolButton( GroupEdit );
+  QToolButton* moveBut3 = new QToolButton( GroupEdit );
+  QToolButton* moveBut4 = new QToolButton( GroupEdit );
+  moveBut1->setArrowType( Qt::LeftArrow );
+  moveBut2->setArrowType( Qt::RightArrow );
+  moveBut3->setArrowType( Qt::LeftArrow );
+  moveBut4->setArrowType( Qt::RightArrow );
+  MoveBorderEndsButGrp->addButton( moveBut1, MOVE_LEFT_1 );
+  MoveBorderEndsButGrp->addButton( moveBut2, MOVE_RIGHT_1 );
+  MoveBorderEndsButGrp->addButton( moveBut3, MOVE_LEFT_2 );
+  MoveBorderEndsButGrp->addButton( moveBut4, MOVE_RIGHT_2 );
+
+  SwapBut  = new QPushButton( "<->", GroupEdit );
+  BorderEndLine[0] = new QLineEdit( GroupEdit );
+  BorderEndLine[1] = new QLineEdit( GroupEdit );
+  BorderEndLine[0]->setReadOnly(true);
+  BorderEndLine[1]->setReadOnly(true);
+  QLabel* StepLabel = new QLabel(tr("STEP"), GroupEdit );
+  StepSpin = new SalomeApp_IntSpinBox( 1, 100000, 1, GroupEdit,
+                                       /*acceptNames=*/false, /*showTip=*/false );
+  StepSpin->setValue( 1 );
+
+  GroupEditLayout->addWidget(ListEdit,         0, 0, 1, 8);
+  GroupEditLayout->addWidget(SetFirstButton,   0, 8);
+  GroupEditLayout->addWidget(RemoveElemButton, 0, 9);
+  GroupEditLayout->addWidget(moveBut1,         1, 0);
+  GroupEditLayout->addWidget(BorderEndLine[0], 1, 1);
+  GroupEditLayout->addWidget(moveBut2,         1, 2);
+  GroupEditLayout->addWidget(moveBut3,         1, 3);
+  GroupEditLayout->addWidget(BorderEndLine[1], 1, 4);
+  GroupEditLayout->addWidget(moveBut4,         1, 5);
+  GroupEditLayout->setColumnStretch(              6, 5 );
+  GroupEditLayout->addWidget(SwapBut,          1, 7);
+  GroupEditLayout->addWidget(StepLabel,        1, 8);
+  GroupEditLayout->addWidget(StepSpin,         1, 9);
+  GroupEditLayout->setRowStretch( 0, 1 );
+
+  GroupCoincidentLayout->addWidget( GroupCoincident );
+  GroupCoincidentLayout->addWidget( GroupEdit );
+  GroupCoincidentLayout->setRowStretch( 0, 10 );
+  GroupCoincidentLayout->setRowStretch( 1, 1 );
+
+  aSewFreeBordersLayout->addWidget( GroupCoincidentWidget );
+
   // layout
+  GroupArgumentsLayout->addWidget(ModeGroup);
   GroupArgumentsLayout->addWidget(SubGroup1);
   GroupArgumentsLayout->addWidget(SubGroup2);
+  GroupArgumentsLayout->addWidget(SewFreeBordersWidget);
   GroupArgumentsLayout->addWidget(CheckBoxMerge);
   GroupArgumentsLayout->addWidget(CheckBoxPolygons);
   GroupArgumentsLayout->addWidget(CheckBoxPolyedrs);
@@ -238,6 +438,7 @@ SMESHGUI_SewingDlg::SMESHGUI_SewingDlg( SMESHGUI* theModule )
   SMESHGUI_SewingDlgLayout->addWidget(ConstructorsBox);
   SMESHGUI_SewingDlgLayout->addWidget(GroupArguments);
   SMESHGUI_SewingDlgLayout->addWidget(GroupButtons);
+  //SMESHGUI_SewingDlgLayout->setStretch( 2, 10 );
 
   /* Initialisations */
   RadioButton1->setChecked(true);
@@ -253,6 +454,10 @@ SMESHGUI_SewingDlg::SMESHGUI_SewingDlg( SMESHGUI* theModule )
 
   myHelpFileName = "sewing_meshes_page.html";
 
+  myActor = 0;
+  myStoredEntityMode = 0;
+
+  setDisplayMode();
   Init();
 
   /* signals and slots connections */
@@ -272,7 +477,9 @@ SMESHGUI_SewingDlg::SMESHGUI_SewingDlg( SMESHGUI* theModule )
   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(reject()));
+  connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()),      this, SLOT(reject()));
+  connect(mySMESHGUI, SIGNAL(SignalActivatedViewManager()), this, SLOT(onOpenView()));
+  connect(mySMESHGUI, SIGNAL(SignalCloseView()),            this, SLOT(onCloseView()));
 
   connect(LineEdit1, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
   connect(LineEdit2, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
@@ -281,6 +488,18 @@ SMESHGUI_SewingDlg::SMESHGUI_SewingDlg( SMESHGUI* theModule )
   connect(LineEdit5, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
   connect(LineEdit6, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
 
+  connect(ModeButGrp,           SIGNAL(buttonClicked(int)),     SLOT(onModeChange(int)));
+  connect(AutoSewCheck,         SIGNAL(stateChanged(int)),      SLOT(onAutoSew(int)));
+  connect(DetectButton,         SIGNAL(clicked()),              SLOT(onDetectClicked()));
+  connect(RemoveGroupButton,    SIGNAL(clicked()),              SLOT(onRemoveGroupClicked()));
+  connect(ListCoincident,       SIGNAL(itemSelectionChanged()), SLOT(onSelectGroup()));
+  connect(SelectAllCheck,       SIGNAL(stateChanged(int)),      SLOT(onSelectAll(int)));
+  connect(ListEdit,             SIGNAL(itemSelectionChanged()), SLOT(onSelectBorderPartFromGroup()));
+  connect(SetFirstButton,       SIGNAL(clicked()),              SLOT(onSetFirstClicked()));
+  connect(RemoveElemButton,     SIGNAL(clicked()),              SLOT(onRemoveElemClicked()));
+  connect(MoveBorderEndsButGrp, SIGNAL(buttonClicked(int)),     SLOT(onMoveBorderEnd(int)));
+  connect(SwapBut,              SIGNAL(clicked()),              SLOT(onSwapClicked()));
+
   ConstructorsClicked(0);
 }
 
@@ -290,6 +509,12 @@ SMESHGUI_SewingDlg::SMESHGUI_SewingDlg( SMESHGUI* theModule )
 //=================================================================================
 SMESHGUI_SewingDlg::~SMESHGUI_SewingDlg()
 {
+  for ( size_t i = 0; i < myBorderDisplayers.size(); ++i )
+  {
+    delete myBorderDisplayers[ i ];
+    myBorderDisplayers[ i ] = 0;
+  }
+  myBorderDisplayers.clear();
 }
 
 //=================================================================================
@@ -300,13 +525,16 @@ void SMESHGUI_SewingDlg::Init()
 {
   myBusy = false;
 
-  myEditCurrentArgument = LineEdit1;
-  LineEdit1->setFocus();
-  myActor = 0;
+  if ( LineEdit1->isVisible() )
+    myEditCurrentArgument = LineEdit1;
+  else
+    myEditCurrentArgument = LineEditMesh;
+  myEditCurrentArgument->setFocus();
+  //myActor = 0;
   myMesh = SMESH::SMESH_Mesh::_nil();
-  CheckBoxMerge->setChecked(false);
-  CheckBoxPolygons->setChecked(false);
-  CheckBoxPolyedrs->setChecked(false);
+  // CheckBoxMerge->setChecked(false);
+  // CheckBoxPolygons->setChecked(false);
+  // CheckBoxPolyedrs->setChecked(false);
   SelectionIntoArgument();
 }
 
@@ -347,75 +575,100 @@ void SMESHGUI_SewingDlg::ConstructorsClicked (int constructorId)
       CheckBoxPolyedrs->hide();
   }
 
+  CheckBoxMerge->setVisible ( constructorId == 3 );
+
+  if (( !SubGroup1->isVisible() ) &&
+      ( constructorId != 0 || ModeButGrp->checkedId() == MODE_MANUAL ))
+  {
+    SubGroup1->show();
+    SubGroup2->show();
+  }
+
+  if ( constructorId != 0 )
+  {
+    ModeGroup->hide();
+    SewFreeBordersWidget->hide();
+    restoreDisplayMode();
+  }
+
+  bool isNodeSelection = true;
+
   switch (constructorId) {
   case 0:
-    {
-      GroupArguments->setTitle(tr("SEW_FREE_BORDERS"));
-      SubGroup1->setTitle(tr("BORDER_1"));
-      SubGroup2->setTitle(tr("BORDER_2"));
+  {
+    GroupArguments->setTitle(tr("SEW_FREE_BORDERS"));
+    SubGroup1->setTitle(tr("BORDER_1"));
+    SubGroup2->setTitle(tr("BORDER_2"));
 
-        if (!CheckBoxPolygons->isVisible())
-          CheckBoxPolygons->show();
-        if (!CheckBoxPolyedrs->isVisible())
-          CheckBoxPolyedrs->show();
+    if (!CheckBoxPolygons->isVisible())
+      CheckBoxPolygons->show();
+    if (!CheckBoxPolyedrs->isVisible())
+      CheckBoxPolyedrs->show();
 
-      break;
+    if ( !ModeGroup->isVisible() )
+    {
+      ModeGroup->show();
     }
+    onModeChange( ModeButGrp->checkedId() );
+
+    isNodeSelection = ( ModeButGrp->checkedId() == MODE_MANUAL );
+
+    break;
+  }
   case 1:
-    {
-      GroupArguments->setTitle(tr("SEW_CONFORM_FREE_BORDERS"));
-      SubGroup1->setTitle(tr("BORDER_1"));
-      SubGroup2->setTitle(tr("BORDER_2"));
+  {
+    GroupArguments->setTitle(tr("SEW_CONFORM_FREE_BORDERS"));
+    SubGroup1->setTitle(tr("BORDER_1"));
+    SubGroup2->setTitle(tr("BORDER_2"));
 
-      TextLabel6->setEnabled(false);
-      SelectButton6->setEnabled(false);
-      LineEdit6->setEnabled(false);
+    TextLabel6->setEnabled(false);
+    SelectButton6->setEnabled(false);
+    LineEdit6->setEnabled(false);
 
-      myOk6 = true;
+    myOk6 = true;
 
-      break;
-    }
+    break;
+  }
   case 2:
-    {
-      GroupArguments->setTitle(tr("SEW_BORDER_TO_SIDE"));
-      SubGroup1->setTitle(tr("BORDER"));
-      SubGroup2->setTitle(tr("SIDE"));
-
-      TextLabel5->setEnabled(false);
-      SelectButton5->setEnabled(false);
-      LineEdit5->setEnabled(false);
-
-      if (!CheckBoxPolygons->isVisible())
-        CheckBoxPolygons->show();
-      if (!CheckBoxPolyedrs->isVisible())
-        CheckBoxPolyedrs->show();
-      
-      myOk5 = true;
-
-      break;
-    }
-  case 3:
-    {
-      GroupArguments->setTitle(tr("SEW_SIDE_ELEMENTS"));
-      SubGroup1->setTitle(tr("SIDE_1"));
-      SubGroup2->setTitle(tr("SIDE_2"));
+  {
+    GroupArguments->setTitle(tr("SEW_BORDER_TO_SIDE"));
+    SubGroup1->setTitle(tr("BORDER"));
+    SubGroup2->setTitle(tr("SIDE"));
 
-      TextLabel1->setText(tr("SMESH_ID_ELEMENTS"));
-      TextLabel2->setText(tr("NODE1_TO_MERGE"));
-      TextLabel3->setText(tr("NODE2_TO_MERGE"));
-      TextLabel4->setText(tr("SMESH_ID_ELEMENTS"));
-      TextLabel5->setText(tr("NODE1_TO_MERGE"));
-      TextLabel6->setText(tr("NODE2_TO_MERGE"));
+    TextLabel5->setEnabled(false);
+    SelectButton5->setEnabled(false);
+    LineEdit5->setEnabled(false);
 
-      LineEdit1->setValidator(new SMESHGUI_IdValidator(this));
-      LineEdit4->setValidator(new SMESHGUI_IdValidator(this));
+    if (!CheckBoxPolygons->isVisible())
+      CheckBoxPolygons->show();
+    if (!CheckBoxPolyedrs->isVisible())
+      CheckBoxPolyedrs->show();
 
-      SMESH::SetPointRepresentation(false);
+    myOk5 = true;
 
-      if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-        aViewWindow->SetSelectionMode(CellSelection);
-      break;
-    }
+    break;
+  }
+  case 3:
+  {
+    GroupArguments->setTitle(tr("SEW_SIDE_ELEMENTS"));
+    SubGroup1->setTitle(tr("SIDE_1"));
+    SubGroup2->setTitle(tr("SIDE_2"));
+
+    TextLabel1->setText(tr("SMESH_ID_ELEMENTS"));
+    TextLabel2->setText(tr("NODE1_TO_MERGE"));
+    TextLabel3->setText(tr("NODE2_TO_MERGE"));
+    TextLabel4->setText(tr("SMESH_ID_ELEMENTS"));
+    TextLabel5->setText(tr("NODE1_TO_MERGE"));
+    TextLabel6->setText(tr("NODE2_TO_MERGE"));
+
+    LineEdit1->setValidator(new SMESHGUI_IdValidator(this));
+    LineEdit4->setValidator(new SMESHGUI_IdValidator(this));
+
+    isNodeSelection = false;
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+      aViewWindow->SetSelectionMode(CellSelection);
+    break;
+  }
   }
 
   if (constructorId != 3) {
@@ -428,21 +681,612 @@ void SMESHGUI_SewingDlg::ConstructorsClicked (int constructorId)
 
     LineEdit1->setValidator(new SMESHGUI_IdValidator(this, 1));
     LineEdit4->setValidator(new SMESHGUI_IdValidator(this, 1));
+  }
 
-    SMESH::SetPointRepresentation(true);
+  if ( myActor )
+    myActor->SetPointRepresentation( isNodeSelection );
 
-    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-      aViewWindow->SetSelectionMode(NodeSelection);
-  }
+  if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+    aViewWindow->SetSelectionMode( isNodeSelection ? NodeSelection : ActorSelection );
+
+  UpdateButtons();
 
   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
   mySelectionMgr->setSelectedObjects( io );
 
   QApplication::instance()->processEvents();
   updateGeometry();
+
+  resize(100,100);
+}
+
+//=======================================================================
+//function : storeDisplayMode
+//purpose  : save representation of a mesh and switch it to wireframe mode
+//=======================================================================
+
+void SMESHGUI_SewingDlg::setDisplayMode()
+{
+  if ( myStoredEntityMode )
+    return;
+  myStoredEntityMode = 0;
+  myStoredRepresentation = -1;
+
+  if ( myActor && AutoSewCheck->isVisible() && !AutoSewCheck->isChecked() )
+  {
+    myStoredEntityMode     = myActor->GetEntityMode();
+    myStoredRepresentation = myActor->GetRepresentation();
+
+    myActor->SetEntityMode( myStoredEntityMode & ~SMESH_Actor::eVolumes );
+    myActor->SetRepresentation( SMESH_Actor::eEdge );
+  }
+}
+
+//=======================================================================
+//function : restoreDisplayMode
+//purpose  : restore representation of a mesh
+//=======================================================================
+
+void SMESHGUI_SewingDlg::restoreDisplayMode()
+{
+  if ( myActor && myStoredEntityMode )
+  {
+    if ( myActor->GetEntityMode() == ( myStoredEntityMode & ~SMESH_Actor::eVolumes ))
+      myActor->SetEntityMode( myStoredEntityMode );
+
+    if ( myActor->GetRepresentation() == SMESH_Actor::eEdge )
+      myActor->SetRepresentation( myStoredRepresentation );
+
+    myStoredEntityMode = 0;
+    myStoredRepresentation = -1;
+  }
+  for ( size_t i = 0; i < myBorderDisplayers.size(); ++i )
+    if ( myBorderDisplayers[ i ])
+      myBorderDisplayers[ i ]->Hide();
+}
+
+//=======================================================================
+//function : onModeChange
+//purpose  : SLOT called when mode (auto or manual) of Sew free borders change
+//=======================================================================
+
+void SMESHGUI_SewingDlg::onModeChange( int mode )
+{
+  if ( mode == MODE_MANUAL )
+  {
+    myEditCurrentArgument = LineEdit1;
+    if ( !SubGroup1->isVisible() )
+      SubGroup1->show(), SubGroup2->show();
+    SewFreeBordersWidget->hide();
+  }
+  else
+  {
+    myEditCurrentArgument = LineEditMesh;
+    SubGroup1->hide(), SubGroup2->hide();
+    if ( !SewFreeBordersWidget->isVisible() )
+      SewFreeBordersWidget->show();
+  }
+  if ( myActor )
+    myActor->SetPointRepresentation( mode == MODE_MANUAL );
+
+  if ( SVTK_ViewWindow* aViewWindow = SMESH::GetCurrentVtkView() )
+    aViewWindow->SetSelectionMode( mode == MODE_MANUAL ? NodeSelection : ActorSelection );
+
+  onAutoSew( AutoSewCheck->isChecked() );
+
+  QApplication::instance()->processEvents();
+  updateGeometry();
+
   resize(100,100);
 }
 
+//=======================================================================
+//function : onAutoSew
+//purpose  : SLOT called when Auto Sewing check box is checked
+//=======================================================================
+
+void SMESHGUI_SewingDlg::onAutoSew( int isAuto )
+{
+  GroupCoincidentWidget->setVisible( !isAuto );
+
+  QApplication::instance()->processEvents();
+
+  SewFreeBordersWidget->hide();
+  if ( ModeButGrp->checkedId() == MODE_AUTO )
+    SewFreeBordersWidget->show();
+
+  if ( isAuto )
+    restoreDisplayMode();
+  else
+    setDisplayMode();
+  SMESH::RepaintCurrentView();
+
+  UpdateButtons();
+
+  updateGeometry();
+  resize(minimumSizeHint());
+}
+
+//=======================================================================
+//function : haveBorders
+//purpose  : Returns true if myBorders have been initialized
+//=======================================================================
+
+bool SMESHGUI_SewingDlg::haveBorders()
+{
+  return ( & myBorders.in() &&
+           myBorders->borders.length() &&
+           myBorders->coincidentGroups.length() );
+}
+
+//=======================================================================
+//function : getGroupText
+//purpose  : Returns a text of a given group of coincident free borders
+//=======================================================================
+
+QString SMESHGUI_SewingDlg::getPartText(const SMESH::FreeBorderPart& aPART)
+{
+  typedef CORBA::Long TInt;
+  QString text;
+  if ( 0 <= aPART.border && aPART.border < (TInt)myBorders->borders.length() )
+  {
+    const SMESH::FreeBorder& aBRD = myBorders->borders[ aPART.border ];
+    if ( 0 <= aPART.node1    && aPART.node1    < (TInt)aBRD.nodeIDs.length() &&
+         0 <= aPART.nodeLast && aPART.nodeLast < (TInt)aBRD.nodeIDs.length() )
+    {
+      text += QString("( %1 %2 %3 ) ")
+        .arg( aBRD.nodeIDs[ aPART.node1 ] )
+        .arg( aBRD.nodeIDs[ aPART.node2 ] )
+        .arg( aBRD.nodeIDs[ aPART.nodeLast ] );
+    }
+  }
+  return text;
+}
+
+//=======================================================================
+//function : getGroupText
+//purpose  : Returns a text of a given group of coincident free borders
+//=======================================================================
+
+QString SMESHGUI_SewingDlg::getGroupText(int groupIndex)
+{
+  QString text;
+
+  if ( haveBorders()   &&
+       groupIndex >= 0 &&
+       groupIndex < (int)myBorders->coincidentGroups.length() )
+  {
+    const SMESH::FreeBordersGroup& aGRP = myBorders->coincidentGroups[ groupIndex ];
+
+    for ( CORBA::ULong iP = 0; iP < aGRP.length(); ++iP )
+    {
+      QString partText = getPartText( aGRP[ iP ]);
+      if ( partText.isEmpty() )
+        return "";
+      text += partText;
+    }
+  }
+  return text;
+}
+
+//=======================================================================
+//function : onDetectClicked
+//purpose  : SLOT called when [Detect] is clicked
+//=======================================================================
+
+void SMESHGUI_SewingDlg::onDetectClicked()
+{
+  myBusy = true;
+  ListCoincident->clear();
+
+  if ( myMesh->_is_nil() )
+    return;
+
+  SUIT_OverrideCursor wc;
+
+  SMESH::SMESH_MeshEditor_var editor = myMesh->GetMeshEditor();
+  myBorders = editor->FindCoincidentFreeBorders( SpinBoxTolerance->GetValue() );
+  if ( haveBorders() )
+  {
+    for ( size_t i = 0; i < myBorderDisplayers.size(); ++i )
+    {
+      delete myBorderDisplayers[ i ];
+      myBorderDisplayers[ i ] = 0;
+    }
+    myBorderDisplayers.resize( myBorders->coincidentGroups.length(), 0 );
+
+    for ( uint i = 0; i < myBorders->coincidentGroups.length(); ++i )
+    {
+      QString groupText = getGroupText( i );
+      if ( groupText.isEmpty() )
+        continue;
+
+      QColor groupColor;
+      groupColor.setHsvF( float(i) / myBorders->coincidentGroups.length(), 1., 1. );
+      QPixmap icon( QSize( 20, 20 ));
+      icon.fill( groupColor );
+
+      QListWidgetItem * item = new QListWidgetItem( icon, groupText, ListCoincident );
+      item->setData( GROUP_COLOR, groupColor );
+      item->setData( GROUP_INDEX, i );
+    }
+  }
+  myBusy = false;
+
+  onSelectGroup();
+
+  UpdateButtons();
+}
+
+//=======================================================================
+//function : onRemoveGroupClicked
+//purpose  :
+//=======================================================================
+
+void SMESHGUI_SewingDlg::onRemoveGroupClicked()
+{
+  myBusy = true;
+  QList<QListWidgetItem*> selItems = ListCoincident->selectedItems();
+  for ( int i = 0; i < selItems.count(); ++i )
+  {
+    QListWidgetItem* item = selItems[ i ];
+    item->setSelected( false );
+    int groupIndex = item->data( GROUP_INDEX ).toInt();
+    delete item;
+    if ( myBorderDisplayers[ groupIndex ])
+      myBorderDisplayers[ groupIndex ]->Hide();
+    SMESH::FreeBordersGroup& aGRP = myBorders->coincidentGroups[ groupIndex ];
+    aGRP.length( 0 );
+  }
+  myBusy = false;
+
+  onSelectGroup();
+  UpdateButtons();
+}
+
+//=======================================================================
+//function : showGroup
+//purpose  : display a group of coincident free borders in the Viewer
+//=======================================================================
+
+void SMESHGUI_SewingDlg::showGroup( QListWidgetItem* item )
+{
+  if ( !item ||
+       item->listWidget() != ListCoincident ||
+       !haveBorders())
+    return;
+
+  int    groupIndex = item->data( GROUP_INDEX ).toInt();
+  QColor groupColor = item->data( GROUP_COLOR ).value<QColor>();
+  if ( groupIndex >= 0       &&
+       groupIndex < (int)myBorders->coincidentGroups.length() )
+  {
+    if ( !myBorderDisplayers[ groupIndex ] && SMESH::GetCurrentVtkView())
+      myBorderDisplayers[ groupIndex ] = new BorderGroupDisplayer( myBorders, groupIndex, groupColor, myMesh );
+    bool wholeBorders = setCurrentGroup();
+    if ( myBorderDisplayers[ groupIndex ])
+      myBorderDisplayers[ groupIndex ]->ShowGroup( wholeBorders );
+  }
+}
+
+//=======================================================================
+//function : setCurrentGroup
+//purpose  : set index of a current free border group to myCurGroupIndex
+//=======================================================================
+
+bool SMESHGUI_SewingDlg::setCurrentGroup()
+{
+  if ( !haveBorders() )
+    return false;
+
+  QList<QListWidgetItem*> selItems = ListCoincident->selectedItems();
+  if ( selItems.count() != 1 )
+    return false;
+  
+  myCurGroupIndex = selItems[0]->data( GROUP_INDEX ).toInt();
+
+  return ( myCurGroupIndex >= 0 && myCurGroupIndex < (int)myBorders->coincidentGroups.length() );
+}
+
+//=======================================================================
+//function : setCurrentPart
+//purpose  : set index of a current free border of a current group to myCurPartIndex
+//=======================================================================
+
+bool SMESHGUI_SewingDlg::setCurrentPart()
+{
+  if ( !setCurrentGroup() )
+    return false;
+
+  if ( ListEdit->selectedItems().count() != 1 )
+    return false;
+
+  myCurPartIndex = ListEdit->currentRow();
+  const SMESH::FreeBordersGroup& aGRP = myBorders->coincidentGroups[ myCurGroupIndex ];
+
+  return ( myCurPartIndex >= 0 && myCurPartIndex < (int)aGRP.length() );
+}
+
+//=======================================================================
+//function : onSelectGroup
+//purpose  : SLOT called when selection of coincident free borders change
+//=======================================================================
+
+void SMESHGUI_SewingDlg::onSelectGroup()
+{
+  if ( myBusy )
+    return;
+  ListEdit->clear();
+  BorderEndLine[0]->clear();
+  BorderEndLine[1]->clear();
+  for ( size_t i = 0; i < myBorderDisplayers.size(); ++i )
+    if ( myBorderDisplayers[ i ])
+      myBorderDisplayers[ i ]->Hide();
+
+  QList<QListWidgetItem*> selItems = ListCoincident->selectedItems();
+
+  RemoveGroupButton->setEnabled( selItems.count() > 0 );
+
+  onSelectBorderPartFromGroup(); // enable buttons
+
+  if ( !haveBorders() )
+    return;
+
+  SelectAllCheck->blockSignals( true );
+  if ( ListCoincident->count() != selItems.count() )
+    SelectAllCheck->setChecked( false );
+  SelectAllCheck->blockSignals( false );
+
+  if ( selItems.empty() ) // nothing selected - show all
+    for ( int i = 0; i < ListCoincident->count(); ++i )
+      showGroup( ListCoincident->item( i ));
+  else
+    for ( int i = 0; i < selItems.count(); ++i )
+      showGroup( selItems[ i ]);
+
+  if ( setCurrentGroup() ) // edit a selected group
+  {
+    const SMESH::FreeBordersGroup& aGRP = myBorders->coincidentGroups[ myCurGroupIndex ];
+    for ( CORBA::ULong iP = 0; iP < aGRP.length(); ++iP )
+      new QListWidgetItem( getPartText( aGRP[ iP ]), ListEdit );
+  }
+  SMESH::RepaintCurrentView();
+}
+
+//=======================================================================
+//function : onSelectAll
+//purpose  : SLOT called when Select All is checked
+//=======================================================================
+
+void SMESHGUI_SewingDlg::onSelectAll(int isOn)
+{
+  if ( isOn )
+    ListCoincident->selectAll();
+  else
+    ListCoincident->clearSelection();
+}
+
+//=======================================================================
+//function : onSelectBorderPartFromGroup
+//purpose  : SLOT called when selection of borders in an edited group changes
+//=======================================================================
+
+void SMESHGUI_SewingDlg::onSelectBorderPartFromGroup()
+{
+  if ( myBusy ) return;
+  BorderEndLine[0]->setText("");
+  BorderEndLine[1]->setText("");
+  MoveBorderEndsButGrp->button( MOVE_LEFT_1  )->setEnabled( false );
+  MoveBorderEndsButGrp->button( MOVE_RIGHT_1 )->setEnabled( false );
+  MoveBorderEndsButGrp->button( MOVE_LEFT_2  )->setEnabled( false );
+  MoveBorderEndsButGrp->button( MOVE_RIGHT_2 )->setEnabled( false );
+  SwapBut->setEnabled( false );
+  SetFirstButton->setEnabled( false );
+  RemoveElemButton->setEnabled ( ListEdit->count() > 2 );
+
+  if ( !setCurrentGroup() )
+    return;
+
+  if ( !myBorderDisplayers[ myCurGroupIndex ]) return;
+  myBorderDisplayers[ myCurGroupIndex ]->Hide();
+
+  QList<QListWidgetItem*> selItems = ListEdit->selectedItems();
+  bool editPart = ( setCurrentPart() );
+  for ( int i = 0; i < selItems.count(); ++i )
+    myBorderDisplayers[ myCurGroupIndex ]->ShowPart( ListEdit->row( selItems[i] ), editPart );
+
+  if ( selItems.isEmpty() )
+    myBorderDisplayers[ myCurGroupIndex ]->ShowGroup( /*wholeBorders=*/ true );
+
+  if ( editPart )
+  {
+    SMESH::FreeBordersGroup& aGRP = myBorders->coincidentGroups[ myCurGroupIndex ];
+    SMESH::FreeBorderPart&   aPRT = aGRP[ myCurPartIndex ];
+    SMESH::FreeBorder&       aBRD = myBorders->borders[ aPRT.border ];
+
+    BorderEndLine[0]->setText( QString::number( aBRD.nodeIDs[ aPRT.node1 ]));
+    BorderEndLine[1]->setText( QString::number( aBRD.nodeIDs[ aPRT.nodeLast ]));
+    SwapBut->setEnabled( true );
+    SetFirstButton->setEnabled( myCurPartIndex > 0 );
+
+    int      size = (int) aBRD.nodeIDs.length();
+    bool isClosed = ( aBRD.nodeIDs[0] == aBRD.nodeIDs[ size-1 ]);
+    if ( !isClosed )
+    {
+      bool isFwd = ( Abs( aPRT.node2 - aPRT.node1 ) == 1 ) ? aPRT.node2 > aPRT.node1 : aPRT.node2 < aPRT.node1;
+      int dn     = ( isFwd ? +1 : -1 ) * StepSpin->value();
+      MoveBorderEndsButGrp->button( MOVE_LEFT_1  )->
+        setEnabled( 0 <= aPRT.node1-dn && aPRT.node1-dn < size );
+      MoveBorderEndsButGrp->button( MOVE_RIGHT_1 )->
+        setEnabled( 0 <= aPRT.node1+dn && aPRT.node1+dn < size );
+      MoveBorderEndsButGrp->button( MOVE_LEFT_2  )->
+        setEnabled( 0 <= aPRT.nodeLast-dn && aPRT.nodeLast-dn < size );
+      MoveBorderEndsButGrp->button( MOVE_RIGHT_2  )->
+        setEnabled( 0 <= aPRT.nodeLast+dn && aPRT.nodeLast+dn < size );
+    }
+    else
+    {
+      MoveBorderEndsButGrp->button( MOVE_LEFT_1  )->setEnabled( true );
+      MoveBorderEndsButGrp->button( MOVE_RIGHT_1 )->setEnabled( true );
+      MoveBorderEndsButGrp->button( MOVE_LEFT_2  )->setEnabled( true );
+      MoveBorderEndsButGrp->button( MOVE_RIGHT_2 )->setEnabled( true );
+    }
+  }
+  SMESH::RepaintCurrentView();
+}
+
+//=======================================================================
+//function : onGroupChange
+//purpose  : Update after modification of a current group by the user
+//=======================================================================
+
+void SMESHGUI_SewingDlg::onGroupChange( bool partChange )
+{
+  ListCoincident->currentItem()->setText( getGroupText( myCurGroupIndex ));
+
+  const SMESH::FreeBordersGroup& aGRP = myBorders->coincidentGroups[ myCurGroupIndex ];
+  for ( int i = 0; i < ListEdit->count(); ++i )
+    ListEdit->item( i )->setText( getPartText( aGRP[ i ]));
+
+  if ( myBorderDisplayers[ myCurGroupIndex ])
+    myBorderDisplayers[ myCurGroupIndex ]->Update();
+
+  if ( partChange )
+    onSelectBorderPartFromGroup();
+}
+
+//=======================================================================
+//function : onSetFirstClicked
+//purpose  : STOL called when |<< is clicked
+//=======================================================================
+
+void SMESHGUI_SewingDlg::onSetFirstClicked()
+{
+  if ( !setCurrentPart() || myCurPartIndex == 0 || ListEdit->count() == 0 )
+    return;
+
+  SMESH::FreeBordersGroup& aGRP = myBorders->coincidentGroups[ myCurGroupIndex ];
+
+  SMESH::FreeBorderPart new1st = aGRP[ myCurPartIndex ];
+  for ( ; myCurPartIndex > 0; --myCurPartIndex )
+    aGRP[ myCurPartIndex ] = aGRP[ myCurPartIndex - 1 ];
+
+  aGRP[ 0 ] = new1st;
+
+  onGroupChange();
+
+  myBusy = true;
+  ListEdit->clearSelection();
+  myBusy = false;
+  ListEdit->setCurrentItem( ListEdit->item(0) );//ListEdit->item(0)->setSelected(true);
+}
+
+//=======================================================================
+//function : onRemoveElemClicked
+//purpose  : 
+//=======================================================================
+
+void SMESHGUI_SewingDlg::onRemoveElemClicked()
+{
+  if ( !setCurrentGroup() )
+    return;
+
+  SMESH::FreeBordersGroup& aGRP = myBorders->coincidentGroups[ myCurGroupIndex ];
+
+  myBusy = true;
+  QList<QListWidgetItem*> selItems = ListEdit->selectedItems();
+  for ( int i = 0; i < selItems.count(); ++i )
+  {
+    int part = ListEdit->row( selItems[i] );
+    for ( ; part + 1 < (int)aGRP.length(); ++part )
+      aGRP[ part ] = aGRP[ part + 1 ];
+    if ( aGRP.length() > 0 )
+      aGRP.length( aGRP.length() - 1 );
+    delete selItems[i];
+  }
+  myBusy = false;
+
+  if ( aGRP.length() == 0 )
+    onRemoveGroupClicked();
+  else
+    onGroupChange( /*partChange=*/true );
+}
+
+//=======================================================================
+//function : onMoveBorderEnd
+//purpose  : 
+//=======================================================================
+
+void SMESHGUI_SewingDlg::onMoveBorderEnd(int button)
+{
+  if ( !setCurrentPart() )
+    return;
+
+  SMESH::FreeBordersGroup& aGRP = myBorders->coincidentGroups[ myCurGroupIndex ];
+  SMESH::FreeBorderPart&   aPRT = aGRP[ myCurPartIndex ];
+  SMESH::FreeBorder&       aBRD = myBorders->borders[ aPRT.border ];
+  int size = (int) aBRD.nodeIDs.length();
+
+  bool isClosed = ( aBRD.nodeIDs[0] == aBRD.nodeIDs[ size-1 ]);
+  if ( isClosed ) --size;
+
+  bool isFwd = ( Abs( aPRT.node2 - aPRT.node1 ) == 1 ) ? aPRT.node2 > aPRT.node1 : aPRT.node2 < aPRT.node1;
+  int dn     = ( isFwd ? +1 : -1 ) * StepSpin->value();
+  if ( button == MOVE_LEFT_1 || button == MOVE_LEFT_2 )
+    dn *= -1;
+
+  switch ( button ) {
+  case MOVE_LEFT_1:
+  case MOVE_RIGHT_1:
+    if (( isClosed ) ||
+        ( 0 <= aPRT.node1+dn && aPRT.node1+dn < size ))
+    {
+      aPRT.node1 = ( aPRT.node1 + size + dn ) % size;
+      aPRT.node2 = ( aPRT.node2 + size + dn ) % size;
+      break;
+    }
+  case MOVE_LEFT_2:
+  case MOVE_RIGHT_2:
+    if (( isClosed ) ||
+        ( 0 <= aPRT.nodeLast+dn && aPRT.nodeLast+dn < size ))
+    {
+      aPRT.nodeLast = ( aPRT.nodeLast + size + dn ) % size;
+      break;
+    }
+  default:
+    return; // impossible to move
+  }
+  
+  onGroupChange( /*partChange=*/true );
+}
+
+//=======================================================================
+//function : onSwapClicked
+//purpose  : SLOT called when <-> is clicked
+//=======================================================================
+
+void SMESHGUI_SewingDlg::onSwapClicked()
+{
+  if ( !setCurrentPart() )
+    return;
+
+  SMESH::FreeBordersGroup& aGRP = myBorders->coincidentGroups[ myCurGroupIndex ];
+  SMESH::FreeBorderPart&   aPRT = aGRP[ myCurPartIndex ];
+  SMESH::FreeBorder&       aBRD = myBorders->borders[ aPRT.border ];
+  int size = (int) aBRD.nodeIDs.length();
+
+  bool isClosed = ( aBRD.nodeIDs[0] == aBRD.nodeIDs[ size-1 ]);
+  if ( isClosed ) --size;
+
+  bool isFwd = ( Abs( aPRT.node2 - aPRT.node1 ) == 1 ) ? aPRT.node2 > aPRT.node1 : aPRT.node2 < aPRT.node1;
+
+  std::swap( aPRT.nodeLast, aPRT.node1 );
+
+  aPRT.node2 = ( aPRT.node1 + ( isFwd ? -1 : +1 ) + size ) % size;
+
+  onGroupChange( /*partChange=*/true );
+}
+
 //=================================================================================
 // function : ClickOnApply()
 // purpose  :
@@ -454,11 +1298,11 @@ bool SMESHGUI_SewingDlg::ClickOnApply()
 
   bool aResult = false;
 
-  if (IsValid()) {
-    bool toMerge = CheckBoxMerge->isChecked();
+  if (IsValid())
+  {
+    bool toMerge          = CheckBoxMerge->isChecked();
     bool toCreatePolygons = CheckBoxPolygons->isChecked();
     bool toCreatePolyedrs = CheckBoxPolyedrs->isChecked();
-
     try {
       SUIT_OverrideCursor aWaitCursor;
       SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
@@ -467,21 +1311,51 @@ bool SMESHGUI_SewingDlg::ClickOnApply()
       SMESH::SMESH_MeshEditor::Sew_Error anError;
 
       if (aConstructorId == 0)
-        anError = aMeshEditor->SewFreeBorders(LineEdit1->text().toLong(),
-                                              LineEdit2->text().toLong(),
-                                              LineEdit3->text().toLong(),
-                                              LineEdit4->text().toLong(),
-                                              LineEdit5->text().toLong(),
-                                              LineEdit6->text().toLong(),
-                                              toCreatePolygons,
-                                              toCreatePolyedrs);
+      {
+        if ( ModeButGrp->checkedId() == MODE_MANUAL )
+        {
+          anError = aMeshEditor->SewFreeBorders(LineEdit1->text().toLong(),
+                                                LineEdit2->text().toLong(),
+                                                LineEdit3->text().toLong(),
+                                                LineEdit4->text().toLong(),
+                                                LineEdit5->text().toLong(),
+                                                LineEdit6->text().toLong(),
+                                                toCreatePolygons,
+                                                toCreatePolyedrs);
+        }
+        else
+        {
+          int nbCoincGroups = ListCoincident->count();
+          if ( AutoSewCheck->isChecked() )
+          {
+            myBorders     = aMeshEditor->FindCoincidentFreeBorders( SpinBoxTolerance->GetValue() );
+            nbCoincGroups = myBorders->coincidentGroups.length();
+          }
+          CORBA::Short nbSewed = aMeshEditor->SewCoincidentFreeBorders( myBorders.inout(),
+                                                                        toCreatePolygons,
+                                                                        toCreatePolyedrs);
+          QString msg;
+          if ( nbCoincGroups == 0 )
+            msg = tr("NO_BORDERS_TO_SEW");
+          else if ( nbSewed < nbCoincGroups )
+            msg = tr("NOT_ALL_BORDERS_SEWED").arg( nbSewed ).arg( nbCoincGroups );
+          else
+            msg = tr("ALL_BORDERS_SEWED").arg( nbSewed );
+          SUIT_MessageBox::information( this, tr("SMESH_INFORMATION"), msg );
+
+          anError = SMESH::SMESH_MeshEditor::SEW_OK;
+        }
+      }
       else if (aConstructorId == 1)
+      {
         anError = aMeshEditor->SewConformFreeBorders(LineEdit1->text().toLong(),
                                                      LineEdit2->text().toLong(),
                                                      LineEdit3->text().toLong(),
                                                      LineEdit4->text().toLong(),
                                                      LineEdit5->text().toLong());
+      }
       else if (aConstructorId == 2)
+      {
         anError = aMeshEditor->SewBorderToSide(LineEdit1->text().toLong(),
                                                LineEdit2->text().toLong(),
                                                LineEdit3->text().toLong(),
@@ -489,6 +1363,7 @@ bool SMESHGUI_SewingDlg::ClickOnApply()
                                                LineEdit6->text().toLong(),
                                                toCreatePolygons,
                                                toCreatePolyedrs);
+      }
       else if (aConstructorId == 3) {
         QStringList aListElementsId1 = LineEdit1->text().split(" ", QString::SkipEmptyParts);
         QStringList aListElementsId2 = LineEdit4->text().split(" ", QString::SkipEmptyParts);
@@ -520,17 +1395,23 @@ bool SMESHGUI_SewingDlg::ClickOnApply()
         QString msg = tr(QString("ERROR_%1").arg(anError).toLatin1().data());
         SUIT_MessageBox::warning(this, tr("SMESH_WRN_WARNING"), msg);
       }
-    } catch (...) {
+    }
+    catch ( const SALOME::SALOME_Exception& S_ex )
+    {
+      SalomeApp_Tools::QtCatchCorbaException( S_ex );
+      return false;
     }
 
     if (aResult) {
-      Handle(SALOME_InteractiveObject) anIO = myActor->getIO();
-
-      SALOME_ListIO aList;
-      aList.Append(anIO);
-      mySelectionMgr->setSelectedObjects(aList, false);
-      SMESH::UpdateView();
 
+      if ( myActor )
+      {
+        Handle(SALOME_InteractiveObject) anIO = myActor->getIO();
+        SALOME_ListIO aList;
+        aList.Append(anIO);
+        mySelectionMgr->setSelectedObjects(aList, false);
+        SMESH::UpdateView();
+      }
       Init();
       ConstructorsClicked(GetConstructorId());
 
@@ -551,12 +1432,46 @@ void SMESHGUI_SewingDlg::ClickOnOk()
     reject();
 }
 
+//=================================================================================
+// function : onOpenView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_SewingDlg::onOpenView()
+{
+  if ( mySelector ) {
+    SMESH::SetPointRepresentation(false);
+  }
+  else {
+    mySelector = SMESH::GetViewWindow( mySMESHGUI )->GetSelector();
+    ActivateThisDialog();
+  }
+}
+
+//=================================================================================
+// function : onCloseView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_SewingDlg::onCloseView()
+{
+  DeactivateActiveDialog();
+  mySelector = 0;
+  myActor = 0;
+
+  for ( size_t i = 0; i < myBorderDisplayers.size(); ++i )
+  {
+    delete myBorderDisplayers[ i ];
+    myBorderDisplayers[ i ] = 0;
+  }
+  myBorderDisplayers.clear();
+}
+
 //=================================================================================
 // function : reject()
 // purpose  :
 //=================================================================================
 void SMESHGUI_SewingDlg::reject()
 {
+  restoreDisplayMode();
   //mySelectionMgr->clearSelected();
   SMESH::SetPointRepresentation(false);
   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
@@ -617,9 +1532,6 @@ void SMESHGUI_SewingDlg::onTextChange (const QString& theNewText)
   else if (send == LineEdit6)
     myOk6 = false;
 
-  buttonOk->setEnabled(false);
-  buttonApply->setEnabled(false);
-
   // hilight entered elements/nodes
   SMDS_Mesh* aMesh = 0;
 
@@ -676,7 +1588,6 @@ void SMESHGUI_SewingDlg::onTextChange (const QString& theNewText)
             isEvenOneExists = true;
       }
       
-
       mySelector->AddOrRemoveIndex(myActor->getIO(), newIndices, false);
       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
         aViewWindow->highlight( myActor->getIO(), true, true );
@@ -692,10 +1603,7 @@ void SMESHGUI_SewingDlg::onTextChange (const QString& theNewText)
     }
   }
 
-  if (IsValid()) {
-    buttonOk->setEnabled(true);
-    buttonApply->setEnabled(true);
-  }
+  UpdateButtons();
 
   myBusy = false;
 }
@@ -709,6 +1617,7 @@ void SMESHGUI_SewingDlg::SelectionIntoArgument (bool isSelectionChanged)
   if (myBusy) return;
 
   // clear
+  restoreDisplayMode();
   if (isSelectionChanged)
     myActor = 0;
 
@@ -716,13 +1625,18 @@ void SMESHGUI_SewingDlg::SelectionIntoArgument (bool isSelectionChanged)
 
   myBusy = true;
   myEditCurrentArgument->setText(aString);
+  ListCoincident->clear();
+  ListEdit->clear();
   myBusy = false;
 
+  onSelectGroup(); // erase preview
+
   if (!GroupButtons->isEnabled()) // inactive
     return;
 
   buttonOk->setEnabled(false);
   buttonApply->setEnabled(false);
+  DetectButton->setEnabled(false);
 
   // get selected mesh
   SALOME_ListIO aList;
@@ -733,21 +1647,41 @@ void SMESHGUI_SewingDlg::SelectionIntoArgument (bool isSelectionChanged)
     return;
 
   Handle(SALOME_InteractiveObject) IO = aList.First();
-  myMesh = SMESH::GetMeshByIO(IO); //@ SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(IO);
+  myMesh  = SMESH::GetMeshByIO(IO);
   myActor = SMESH::FindActorByEntry(aList.First()->getEntry());
+  if (myMesh->_is_nil())
+    return;
+
+  CheckBoxPolyedrs->setEnabled( myMesh->NbVolumes() > 0 );
 
-  if (myMesh->_is_nil() || !myActor)
+  if ( myEditCurrentArgument == LineEditMesh )
+  {
+    if ( _PTR(SObject) meshSO = SMESH::FindSObject( myMesh ))
+      LineEditMesh->setText( meshSO->GetName().c_str() );
+    ListCoincident->clear();
+    if ( AutoSewCheck->isChecked() )
+    {
+      buttonOk->setEnabled(true);
+      buttonApply->setEnabled(true);
+    }
+    DetectButton->setEnabled( myMesh->NbFaces() > 0 );
+    setDisplayMode();
+    return;
+  }
+
+  if (!myActor)
     return;
 
   // get selected elements/nodes
   int aNbUnits = 0;
-
-  if (GetConstructorId() != 3 ||
-      (myEditCurrentArgument != LineEdit1 && myEditCurrentArgument != LineEdit4)) {
+  if (( GetConstructorId() != 3 ) ||
+      ( myEditCurrentArgument != LineEdit1 && myEditCurrentArgument != LineEdit4))
+  {
     aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, IO, aString);
     if (aNbUnits != 1)
       return;
-  } else {
+  }
+  else {
     aNbUnits = SMESH::GetNameOfSelectedElements(mySelector, IO, aString);
     if (aNbUnits < 1)
       return;
@@ -771,10 +1705,7 @@ void SMESHGUI_SewingDlg::SelectionIntoArgument (bool isSelectionChanged)
   else if (myEditCurrentArgument == LineEdit6)
     myOk6 = true;
 
-  if (IsValid()) {
-    buttonOk->setEnabled(true);
-    buttonApply->setEnabled(true);
-  }
+  UpdateButtons();
 }
 
 //=================================================================================
@@ -869,8 +1800,13 @@ void SMESHGUI_SewingDlg::ActivateThisDialog()
 //=================================================================================
 void SMESHGUI_SewingDlg::enterEvent (QEvent* e)
 {
-  if (!ConstructorsBox->isEnabled())
+  if (!ConstructorsBox->isEnabled()) {
+    SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
+    if ( aViewWindow && !mySelector) {
+      mySelector = aViewWindow->GetSelector();
+    }
     ActivateThisDialog();
+  }
 }
 
 //=================================================================================
@@ -888,9 +1824,38 @@ int SMESHGUI_SewingDlg::GetConstructorId()
 //=================================================================================
 bool SMESHGUI_SewingDlg::IsValid()
 {
+  if ( myMesh->_is_nil() )
+    return false;
+
+  if ( GetConstructorId() == 0 && ModeButGrp->checkedId() == MODE_AUTO )
+  {
+    if ( AutoSewCheck->isChecked() )
+      return true;
+
+    int nbGroups = 0;
+    if ( haveBorders() )
+      for ( int i = 0; i < ListCoincident->count(); ++i )
+      {
+        int groupIndex = ListCoincident->item(i)->data( GROUP_INDEX ).toInt();
+        nbGroups += ( !getGroupText( groupIndex ).isEmpty() );
+      }
+    return nbGroups > 0;
+  }
   return (myOk1 && myOk2 && myOk3 && myOk4 && myOk5 && myOk6);
 }
 
+//=======================================================================
+//function : UpdateButtons
+//purpose  : activate [Apply] buttons
+//=======================================================================
+
+void SMESHGUI_SewingDlg::UpdateButtons()
+{
+  bool ok = IsValid();
+  buttonOk->setEnabled( ok );
+  buttonApply->setEnabled( ok );
+}
+
 //=================================================================================
 // function : keyPressEvent()
 // purpose  :
@@ -906,3 +1871,156 @@ void SMESHGUI_SewingDlg::keyPressEvent( QKeyEvent* e )
     ClickOnHelp();
   }
 }
+
+SMESHGUI_SewingDlg::
+BorderGroupDisplayer::BorderGroupDisplayer( const SMESH::CoincidentFreeBorders& borders,
+                                            int                                 groupIndex,
+                                            QColor                              color,
+                                            SMESH::SMESH_Mesh_ptr               mesh):
+  myBorders   ( borders.borders ),
+  myGroup     ( borders.coincidentGroups[ groupIndex ]),
+  myColor     ( color ),
+  myMesh      ( mesh ),
+  myViewWindow( SMESH::GetCurrentVtkView() ),
+  myIdPreview ( myViewWindow )
+{
+  Update();
+}
+
+SMESHGUI_SewingDlg::BorderGroupDisplayer::~BorderGroupDisplayer()
+{
+  for ( size_t i = 0; i < myPartActors.size(); ++i )
+  {
+    if ( myPartActors[ i ]) {
+      myViewWindow->RemoveActor( myPartActors[i] );
+      myPartActors[i]->Delete();
+    }
+  }
+  myIdPreview.SetPointsLabeled(false);
+}
+
+void SMESHGUI_SewingDlg::BorderGroupDisplayer::Hide()
+{
+  for ( size_t i = 0; i < myPartActors.size(); ++i )
+    if ( myPartActors[ i ])
+      myPartActors[ i ]->SetVisibility(false);
+
+  myIdPreview.SetPointsLabeled(false);
+}
+
+void SMESHGUI_SewingDlg::BorderGroupDisplayer::ShowGroup( bool wholeBorders )
+{
+  std::vector<int> ids;
+  std::list<gp_XYZ> coords;
+  for ( size_t i = 0; i < myPartActors.size(); ++i )
+    if ( myPartActors[ i ])
+    {
+      myPartActors[ i ]->SetPointRepresentation( wholeBorders );
+      myPartActors[ i ]->SetVisibility( true );
+      if ( wholeBorders )
+        getPartEnds( i, ids, coords );
+    }
+  if ( wholeBorders )
+    myIdPreview.SetElemsData( ids, coords );
+  myIdPreview.SetPointsLabeled( wholeBorders, true );
+}
+
+void SMESHGUI_SewingDlg::BorderGroupDisplayer::ShowPart( int partIndex, bool toEdit )
+{
+  if ( partIndex < (int) myPartActors.size() )
+  {
+    myPartActors[partIndex]->SetVisibility(true);
+    myPartActors[partIndex]->SetPointRepresentation(toEdit);
+
+    if ( toEdit )
+    {
+      std::vector<int> ids;
+      std::list<gp_XYZ> coords;
+      getPartEnds( partIndex, ids, coords );
+
+      myIdPreview.SetElemsData( ids, coords );
+      myIdPreview.SetPointsLabeled( true, /*show=*/true );
+    }
+  }
+}
+
+void SMESHGUI_SewingDlg::BorderGroupDisplayer::getPartEnds( int                partIndex,
+                                                            std::vector<int> & ids,
+                                                            std::list<gp_XYZ>& coords)
+{
+  if ( partIndex >= (int)myGroup.length() ) return;
+  const SMESH::FreeBorderPart& aPART = myGroup  [ partIndex ];
+  const SMESH::FreeBorder&      aBRD = myBorders[ aPART.border ];
+
+  ids.push_back( aBRD.nodeIDs[ aPART.node1 ]);
+  ids.push_back( aBRD.nodeIDs[ aPART.nodeLast ]);
+
+  SMDS_Mesh* mesh = myPartActors[ partIndex ]->GetObject()->GetMesh();
+
+  coords.push_back( SMESH_TNodeXYZ( mesh->FindNode( aPART.node1+1 )));
+  coords.push_back( SMESH_TNodeXYZ( mesh->FindNode( aPART.nodeLast+1 )));
+}
+
+void SMESHGUI_SewingDlg::BorderGroupDisplayer::Update()
+{
+  Hide();
+  myPartActors.resize( myGroup.length(), 0 );
+
+  for ( size_t i = 0; i < myPartActors.size(); ++i )
+  {
+    TVisualObjPtr obj;
+    if ( myPartActors[ i ])
+      obj = myPartActors[ i ]->GetObject();
+    else
+      obj = TVisualObjPtr( new SMESHGUI_PreVisualObj() );
+    SMDS_Mesh* mesh = obj->GetMesh();
+    mesh->Clear();
+
+    // add nodes
+    const SMESH::FreeBorderPart& aPRT = myGroup[ i ];
+    const SMESH::FreeBorder&     aBRD = myBorders[ aPRT.border ];
+    for ( CORBA::ULong iN = 0; iN < aBRD.nodeIDs.length(); ++iN )
+    {
+      SMESH::double_array_var xyz = myMesh->GetNodeXYZ( aBRD.nodeIDs[ iN ]);
+      if ( xyz->length() == 3 )
+        mesh->AddNode( xyz[0], xyz[1], xyz[2] );
+    }
+
+    // add edges
+    bool isFwd = ( Abs( aPRT.node2 - aPRT.node1 ) == 1 ) ? aPRT.node2 > aPRT.node1 : aPRT.node2 < aPRT.node1;
+    int dn     = isFwd ? +1 : -1;
+    int size   = (int) aBRD.nodeIDs.length();
+    int n2, n1 = aPRT.node1;
+    for ( n2 = n1 + dn; ( n2 >= 0 && n2 < size ); n2 += dn )
+    {
+      mesh->AddEdgeWithID( n1+1, n2+1, mesh->NbEdges() + 1 );
+      n1 = n2;
+      if ( n2 == aPRT.nodeLast )
+        break;
+    }
+    if ( n2 % size != aPRT.nodeLast )
+    {
+      if ( n2 < 0 ) n1 = size;
+      else          n1 = 0;
+      for ( n2 = n1 + dn; ( n2 >= 0 && n2 < size ); n2 += dn )
+      {
+        mesh->AddEdgeWithID( n1+1, n2+1, mesh->NbEdges() + 1 );
+        n1 = n2;
+        if ( n2 == aPRT.nodeLast )
+          break;
+      }
+    }
+
+    if ( !myPartActors[ i ]) // TVisualObj must be filled before actor creation
+    {
+      myPartActors[ i ] = SMESH_Actor::New( obj, "", "", 1 );
+      myPartActors[ i ]->SetEdgeColor( myColor.redF(), myColor.greenF(), myColor.blueF() );
+      myPartActors[ i ]->SetLineWidth( 3 * SMESH::GetFloat("SMESH:element_width",1));
+      myPartActors[ i ]->SetNodeColor( myColor.redF(), myColor.greenF(), myColor.blueF() );
+      myPartActors[ i ]->SetMarkerStd( VTK::MT_POINT, 13 );
+      myPartActors[ i ]->SetPickable ( false );
+      myViewWindow->AddActor( myPartActors[ i ]);
+    }
+  }
+}
+
index 7ba8a45c484fa54e5c6f730ec31a2016a93f5ca0..2bf5c591c128767ee73cfb2b3e35d61bd3dd841f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -36,6 +36,9 @@
 // IDL includes
 #include <SALOMEconfig.h>
 #include CORBA_SERVER_HEADER(SMESH_Mesh)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
+
+#include <vector>
 
 class QButtonGroup;
 class QGroupBox;
@@ -48,6 +51,10 @@ class SMESHGUI;
 class SMESH_Actor;
 class SVTK_Selector;
 class LightApp_SelectionMgr;
+class SMESHGUI_SpinBox;
+class SalomeApp_IntSpinBox;
+class QListWidget;
+class QListWidgetItem;
 
 //=================================================================================
 // class    : SMESHGUI_SewingDlg
@@ -67,7 +74,8 @@ private:
   void                    keyPressEvent( QKeyEvent* );
   int                     GetConstructorId();
   bool                    IsValid();
-  
+  void                    UpdateButtons();
+
   SMESHGUI*               mySMESHGUI;              /* Current SMESHGUI object */
   LightApp_SelectionMgr*  mySelectionMgr;          /* User shape selection */
   int                     myOk1, myOk2, myOk3, myOk4, myOk5, myOk6;    
@@ -114,13 +122,67 @@ private:
   QCheckBox*              CheckBoxPolygons;
   QCheckBox*              CheckBoxPolyedrs;
 
+  QWidget*                SewFreeBordersWidget;
+  QGroupBox*              ModeGroup;
+  QButtonGroup*           ModeButGrp;
+  //QPushButton*            SelectMeshButton;
+  QLineEdit*              LineEditMesh;
+
+  SMESHGUI_SpinBox*       SpinBoxTolerance;
+  QCheckBox*              AutoSewCheck;
+
+  QWidget*                GroupCoincidentWidget;
+  QListWidget*            ListCoincident;
+  QPushButton*            DetectButton;
+  QPushButton*            RemoveGroupButton;
+  QCheckBox*              SelectAllCheck;
+
+  QListWidget*            ListEdit;
+  QButtonGroup*           MoveBorderEndsButGrp;
+  QLineEdit*              BorderEndLine[2];
+  QPushButton*            SwapBut;
+  QPushButton*            SetFirstButton;
+  QPushButton*            RemoveElemButton;
+  SalomeApp_IntSpinBox*   StepSpin;
+
   QString                 myHelpFileName;
 
-protected slots:
+
+  struct BorderGroupDisplayer;
+  std::vector< BorderGroupDisplayer* > myBorderDisplayers;
+  SMESH::CoincidentFreeBorders_var     myBorders;
+  int                                  myCurGroupIndex;
+  int                                  myCurPartIndex;
+  int                                  myStoredRepresentation;
+  unsigned int                         myStoredEntityMode;
+
+  bool                    haveBorders();
+  QString                 getGroupText( int groupIndex );
+  QString                 getPartText( const SMESH::FreeBorderPart& part );
+  void                    showGroup( QListWidgetItem* item );
+  bool                    setCurrentGroup();
+  bool                    setCurrentPart();
+  void                    onGroupChange(bool partChange=false);
+  void                    setDisplayMode();
+  void                    restoreDisplayMode();
+
+
+ protected slots:
   virtual void            reject();
 
-private slots:
+ private slots:
   void                    ConstructorsClicked( int );
+  void                    onModeChange( int );
+  void                    onAutoSew( int );
+  void                    onDetectClicked();
+  void                    onRemoveGroupClicked();
+  void                    onSelectGroup();
+  void                    onSelectAll(int);
+  void                    onSelectBorderPartFromGroup();
+  void                    onSetFirstClicked();
+  void                    onRemoveElemClicked();
+  void                    onMoveBorderEnd(int);
+  void                    onSwapClicked();
   void                    ClickOnOk();
   bool                    ClickOnApply();
   void                    ClickOnHelp();
@@ -129,6 +191,8 @@ private slots:
   void                    DeactivateActiveDialog();
   void                    ActivateThisDialog();
   void                    onTextChange( const QString& );
+  void                    onOpenView();
+  void                    onCloseView();
 };
 
 #endif // SMESHGUI_SEWINGDLG_H
index d1a2dd8b3a30611986d144ffa2520b93c7b7a52d..a89bc1935909364b1e3b9ea247c42a98d83845d1 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 4b6abe4f46f685bb0a2fce0b9b5ebec600ba90c1..f249572f3fba2d9edb9876e5c1dd16b3694d2a51 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index df03f4559971db547b29401de65a83c1bfe7dd64..e40b5b4d1516841d33fbe45b7eeeba8e83bb7715 100755 (executable)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -93,8 +93,8 @@ private:
 SMESHGUI_SingleEditDlg
 ::SMESHGUI_SingleEditDlg(SMESHGUI* theModule)
   : QDialog(SMESH::GetDesktop(theModule)),
-    mySelector(SMESH::GetViewWindow(theModule)->GetSelector()),
     mySelectionMgr(SMESH::GetSelectionMgr(theModule)),
+    mySelector(SMESH::GetViewWindow(theModule)->GetSelector()),
     mySMESHGUI(theModule)
 {
   setModal(false);
@@ -223,6 +223,8 @@ void SMESHGUI_SingleEditDlg::Init()
   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(onSelectionDone()));
   connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), SLOT(onDeactivate()));
   connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), SLOT(reject()));
+  connect(mySMESHGUI, SIGNAL(SignalActivatedViewManager()), SLOT(onOpenView()));
+  connect(mySMESHGUI, SIGNAL(SignalCloseView()),            SLOT(onCloseView()));
   connect(myEdge, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
 
   myOkBtn->setEnabled(false);
@@ -444,6 +446,29 @@ void SMESHGUI_SingleEditDlg::onDeactivate()
   setEnabled(false);
 }
 
+//=================================================================================
+// function : onOpenView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_SingleEditDlg::onOpenView()
+{
+  if ( !mySelector ) {
+    mySelector = SMESH::GetViewWindow( mySMESHGUI )->GetSelector();
+    mySMESHGUI->EmitSignalDeactivateDialog();
+    setEnabled(true);
+  }
+}
+
+//=================================================================================
+// function : onCloseView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_SingleEditDlg::onCloseView()
+{
+  onDeactivate();
+  mySelector = 0;
+}
+
 //=======================================================================
 // name    : enterEvent()
 // Purpose : Event filter
@@ -452,8 +477,12 @@ void SMESHGUI_SingleEditDlg::enterEvent (QEvent*)
 {
   if (!isEnabled()) {
     mySMESHGUI->EmitSignalDeactivateDialog();
-    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+    SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
+    if ( aViewWindow) {
       aViewWindow->SetSelectionMode(EdgeOfCellSelection);
+      if (!mySelector)
+        mySelector = aViewWindow->GetSelector();
+    }
     setEnabled(true);
   }
 }
index 9e5261746f662ad4aabdc6c8e7d1d3215305eba3..e9299eecba33b692366bef7e3c9ace8f3bdf1347 100755 (executable)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -70,6 +70,11 @@ protected slots:
   void                    onSelectionDone();
   void                    onTextChange( const QString& );
 
+private slots:
+  void                    onOpenView();
+  void                    onCloseView();
+
+
 protected:
   void                    enterEvent( QEvent* );
   void                    keyPressEvent( QKeyEvent* );
index 6fcc47a413a11074fb140815d4e0a1c2344ca04d..e272d010c091bf338f045343605d732a81770a89 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -111,8 +111,8 @@ SMESHGUI_SmoothingDlg::SMESHGUI_SmoothingDlg( SMESHGUI* theModule )
   : QDialog( SMESH::GetDesktop( theModule ) ),
     mySMESHGUI( theModule ),
     mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
-    myFilterDlg(0),
-    mySelectedObject(SMESH::SMESH_IDSource::_nil())
+    mySelectedObject(SMESH::SMESH_IDSource::_nil()),
+    myFilterDlg(0)
 {
   QPixmap image0 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_DLG_SMOOTHING")));
   QPixmap image1 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT")));
@@ -284,7 +284,9 @@ SMESHGUI_SmoothingDlg::SMESHGUI_SmoothingDlg( SMESHGUI* theModule )
   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(reject()));
+  connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()),      this, SLOT(reject()));
+  connect(mySMESHGUI, SIGNAL (SignalActivatedViewManager()), this, SLOT(onOpenView()));
+  connect(mySMESHGUI, SIGNAL (SignalCloseView()),            this, SLOT(onCloseView()));
   connect(LineEditElements, SIGNAL(textChanged(const QString&)),
            SLOT(onTextChange(const QString&)));
   connect(LineEditNodes, SIGNAL(textChanged(const QString&)),
@@ -404,10 +406,11 @@ bool SMESHGUI_SmoothingDlg::ClickOnApply()
 
     if (aResult) {
       SMESH::Update(myIO, SMESH::eDisplay);
+      SMESH::RepaintCurrentView();
       SMESHGUI::Modified();
-      Init();
+      //Init();
 
-      mySelectedObject = SMESH::SMESH_IDSource::_nil();
+      //mySelectedObject = SMESH::SMESH_IDSource::_nil();
     }
   }
 
@@ -444,6 +447,31 @@ void SMESHGUI_SmoothingDlg::reject()
   QDialog::reject();
 }
 
+//=================================================================================
+// function : onOpenView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_SmoothingDlg::onOpenView()
+{
+  if ( mySelector ) {
+    SMESH::SetPointRepresentation(false);
+  }
+  else {
+    mySelector = SMESH::GetViewWindow( mySMESHGUI )->GetSelector();
+    ActivateThisDialog();
+  }
+}
+
+//=================================================================================
+// function : onCloseView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_SmoothingDlg::onCloseView()
+{
+  DeactivateActiveDialog();
+  mySelector = 0;
+}
+
 //=================================================================================
 // function : ClickOnHelp()
 // purpose  :
@@ -533,11 +561,12 @@ void SMESHGUI_SmoothingDlg::onTextChange (const QString& theNewText)
 
 //=================================================================================
 // function : SelectionIntoArgument()
-// purpose  : Called when selection as changed or other case
+// purpose  : Called when selection has changed or other cases
 //=================================================================================
 void SMESHGUI_SmoothingDlg::SelectionIntoArgument()
 {
   if (myBusy) return;
+  if (myFilterDlg && myFilterDlg->isVisible()) return; // filter dlg active
 
   // clear
   QString aString = "";
@@ -546,7 +575,8 @@ void SMESHGUI_SmoothingDlg::SelectionIntoArgument()
   BusyLocker lock( myBusy );
 
   if (myEditCurrentArgument == LineEditElements ||
-      myEditCurrentArgument == LineEditNodes) {
+      myEditCurrentArgument == LineEditNodes)
+  {
     myEditCurrentArgument->setText(aString);
     if (myEditCurrentArgument == LineEditElements) {
       myNbOkElements = 0;
@@ -567,44 +597,44 @@ void SMESHGUI_SmoothingDlg::SelectionIntoArgument()
   SALOME_ListIO aList;
   mySelectionMgr->selectedObjects(aList);
   int nbSel = aList.Extent();
-  if (nbSel != 1)
-    return;
-
-  Handle(SALOME_InteractiveObject) IO = aList.First();
-
-  if (myEditCurrentArgument == LineEditElements) {
-    myMesh = SMESH::GetMeshByIO(IO);
-    if (myMesh->_is_nil())
-      return;
-    myIO = IO;
-    myActor = SMESH::FindActorByObject(myMesh);
-
-    if (CheckBoxMesh->isChecked()) {
-      SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aString);
+  if (nbSel == 1)
+  {
+    Handle(SALOME_InteractiveObject) IO = aList.First();
 
-      SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( myIO );
-      if ( !CORBA::is_nil( obj ) )
-        mySelectedObject = obj;
-      else
+    if (myEditCurrentArgument == LineEditElements) {
+      myMesh = SMESH::GetMeshByIO(IO);
+      if (myMesh->_is_nil())
         return;
-      myNbOkElements = true;
-    } else {
-      // get indices of selected elements
-      TColStd_IndexedMapOfInteger aMapIndex;
-      mySelector->GetIndex(IO,aMapIndex);
-      myNbOkElements = aMapIndex.Extent();
+      myIO = IO;
+      myActor = SMESH::FindActorByObject(myMesh);
 
-      if (myNbOkElements < 1)
-        return;
+      if (CheckBoxMesh->isChecked()) {
+        SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aString);
 
-      QStringList elements;
-      for ( int i = 0; i < myNbOkElements; ++i )
-        elements << QString::number( aMapIndex( i+1 ) );
-      aString = elements.join(" ");
+        SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( myIO );
+        if ( !CORBA::is_nil( obj ) )
+          mySelectedObject = obj;
+        else
+          return;
+        myNbOkElements = true;
+      } else {
+        // 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() && myIO->isSame(IO) )
+    {
+      myNbOkNodes = SMESH::GetNameOfSelectedNodes(mySelector, IO, aString);
     }
-  } else if (myEditCurrentArgument == LineEditNodes && !myMesh->_is_nil() && myIO->isSame(IO) )
-  {
-    myNbOkNodes = SMESH::GetNameOfSelectedNodes(mySelector, IO, aString);
   }
 
   myEditCurrentArgument->setText(aString);
@@ -701,8 +731,13 @@ void SMESHGUI_SmoothingDlg::ActivateThisDialog()
 //=================================================================================
 void SMESHGUI_SmoothingDlg::enterEvent (QEvent*)
 {
-  if (!GroupConstructors->isEnabled())
+  if (!GroupConstructors->isEnabled()) {
+    SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
+    if ( aViewWindow && !mySelector) {
+      mySelector = aViewWindow->GetSelector();
+    }
     ActivateThisDialog();
+  }
 }
 
 //=======================================================================
index 792134d3833bc303fa810ac0873ad043cea82ba1..875f4fa1b96417dbe103ad237e4d9618e13fd5cd 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -125,6 +125,7 @@ private:
 protected slots:
   virtual void           reject();
 
+
 private slots:
   void                   ClickOnOk();
   bool                   ClickOnApply();
@@ -135,6 +136,8 @@ private slots:
   void                   ActivateThisDialog();
   void                   onTextChange( const QString& );
   void                   onSelectMesh( bool );
+  void                   onOpenView();
+  void                   onCloseView();
   void                   setElemFilters();
   void                   setNodeFilters();
 };
index b1817d584585dde86b11f836745315ace1ce1e09..c90cbda018cc98b80562ab3bfaff0c2dc18b5d88 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index dab3f34ba23584cb036aa0586d227eda0ec9a15f..f49212d4a88c7b876b0e6dd7f459f100005fe4ee 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
diff --git a/src/SMESHGUI/SMESHGUI_SplitBiQuad.cxx b/src/SMESHGUI/SMESHGUI_SplitBiQuad.cxx
new file mode 100644 (file)
index 0000000..a35f752
--- /dev/null
@@ -0,0 +1,255 @@
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&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, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// 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_SplitBiQuad.h
+// Author : Open CASCADE S.A.S.
+//
+
+#include "SMESHGUI_SplitBiQuad.h"
+
+#include "SMESHGUI.h"
+#include "SMESHGUI_Utils.h"
+#include "SMESH_LogicalFilter.hxx"
+#include "SMESH_TypeFilter.hxx"
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
+
+#include <LightApp_UpdateFlags.h>
+#include <SUIT_MessageBox.h>
+#include <SUIT_OverrideCursor.h>
+#include <SalomeApp_Tools.h>
+
+#include <QStringList>
+#include <QGridLayout>
+
+//================================================================================
+/*!
+ * \brief Dialog constructor
+ */
+//================================================================================
+
+SMESHGUI_SplitBiQuadDlg::SMESHGUI_SplitBiQuadDlg()
+  : SMESHGUI_Dialog( 0, /*modal=*/false, /*allowResize=*/true )
+{
+  setWindowTitle( tr( "CAPTION" ) );
+  setObjectPixmap( "SMESH", tr( "ICON_SELECT" ) );
+  createObject( tr( "MESH" ), mainFrame(), 0 );
+
+  QGridLayout* aLay = new QGridLayout( mainFrame() );
+  aLay->setMargin( 5 );
+  aLay->setSpacing( 5 );
+
+  aLay->addWidget( objectWg( 0,  Label ),   0, 0 );
+  //aLay->addWidget( objectWg( 0,  Btn ),     0, 1 );
+  aLay->addWidget( objectWg( 0,  Control ), 0, 1 );
+  objectWg( 0,  Btn )->hide();
+}
+
+//================================================================================
+/*!
+ * \brief Dialog destructor
+ */
+//================================================================================
+
+SMESHGUI_SplitBiQuadDlg::~SMESHGUI_SplitBiQuadDlg()
+{
+}
+
+//================================================================================
+/*!
+ * \brief SMESHGUI_SplitBiQuadOp constructor
+ */
+//================================================================================
+
+SMESHGUI_SplitBiQuadOp::SMESHGUI_SplitBiQuadOp()
+  : SMESHGUI_SelectionOp(), myDlg( 0 )
+{
+}
+
+//================================================================================
+/*!
+ * \brief SMESHGUI_SplitBiQuadOp destructor
+ */
+//================================================================================
+
+SMESHGUI_SplitBiQuadOp::~SMESHGUI_SplitBiQuadOp()
+{
+  if ( myDlg ) delete myDlg;
+}
+
+//================================================================================
+/*!
+ * \brief Gets dialog of this operation
+  * \retval LightApp_Dialog* - pointer to dialog of this operation
+*/
+//================================================================================
+
+LightApp_Dialog* SMESHGUI_SplitBiQuadOp::dlg() const
+{
+  return myDlg;
+}
+
+//================================================================================
+/*!
+ * \brief Creates dialog if necessary and shows it
+ *
+ * Virtual method redefined from base class called when operation is started creates
+ * dialog if necessary and shows it, activates selection
+ */
+//================================================================================
+
+void SMESHGUI_SplitBiQuadOp::startOperation()
+{
+  if( !myDlg )
+  {
+    myDlg = new SMESHGUI_SplitBiQuadDlg();
+  }
+  myHelpFileName = "split_biquad_to_linear_page.html";
+
+  SMESHGUI_SelectionOp::startOperation();
+
+  myDlg->activateObject( 0 );
+  myDlg->show();
+
+  selectionDone();
+}
+
+//================================================================================
+/*!
+ * \brief Updates dialog's look and feel
+ *
+ * Virtual method redefined from the base class updates dialog's look and feel
+ */
+//================================================================================
+
+// void SMESHGUI_SplitBiQuadOp::selectionDone()
+// {
+//   if ( !dlg()->isVisible() )
+//     return;
+
+//   SMESHGUI_SelectionOp::selectionDone();
+// }
+
+//================================================================================
+/*!
+ * \brief Creates selection filter
+  * \param theId - identifier of current selection widget
+  * \retval SUIT_SelectionFilter* - pointer to the created filter or null
+ *
+ * Creates selection filter in accordance with identifier of current selection widget
+ */
+//================================================================================
+
+SUIT_SelectionFilter* SMESHGUI_SplitBiQuadOp::createFilter( const int theId ) const
+{
+  if ( theId != 0 )
+    return 0;
+
+  QList<SUIT_SelectionFilter*> filters;
+  filters << new SMESH_TypeFilter( SMESH::IDSOURCE_FACE );
+  filters << new SMESH_TypeFilter( SMESH::IDSOURCE_VOLUME );
+  return new SMESH_LogicalFilter( filters,
+                                  SMESH_LogicalFilter::LO_OR,
+                                  /*takeOwnership=*/true );
+}
+
+//================================================================================
+/*!
+ * \brief Edits mesh
+ *
+ * Virtual slot redefined from the base class called when "Apply" button is clicked
+ */
+//================================================================================
+
+bool SMESHGUI_SplitBiQuadOp::onApply()
+{
+  SUIT_OverrideCursor aWaitCursor;
+
+  LightApp_Dialog::SelectedObjects selection;
+  myDlg->objectSelection( selection );
+  if ( selection.empty() || selection[0].empty() )
+  {
+    SUIT_MessageBox::warning( myDlg, tr( "SMESH_WRN_WARNING" ), tr("MESH_IS_NOT_SELECTED") );
+    return false;
+  }
+  QStringList& entries = selection[0];
+
+  SMESH::SMESH_Mesh_var mesh;
+  SMESH::ListOfIDSources_var idSource = new SMESH::ListOfIDSources();
+  idSource->length( entries.count() );
+
+  int nbObj = 0;
+  for ( int i = 0; i < entries.count() ; ++i )
+  {
+    _PTR(SObject) pObj = studyDS()->FindObjectID( entries[i].toLatin1().data() );
+    SMESH::SMESH_IDSource_var obj = SMESH::SObjectToInterface<SMESH::SMESH_IDSource>( pObj );
+    if( !CORBA::is_nil( obj ))
+    {
+      idSource[ nbObj++ ] = obj;
+      SMESH::SMESH_Mesh_var m = obj->GetMesh();
+      if ( !mesh->_is_nil() && mesh->GetId() != m->GetId() )
+      {
+        SUIT_MessageBox::warning( myDlg, tr( "SMESH_WRN_WARNING" ), tr("DIFFERENT_MESHES") );
+        return false;
+      }
+      mesh = m;
+    }
+  }
+  if ( CORBA::is_nil( mesh ))
+  {
+    SUIT_MessageBox::warning( myDlg, tr( "SMESH_WRN_WARNING" ), tr("REF_IS_NULL") );
+    return false;
+  }
+  if ( nbObj == 0 )
+  {
+    SUIT_MessageBox::warning( myDlg, tr( "SMESH_WRN_WARNING" ), tr("MESH_IS_NOT_SELECTED") );
+    return false;
+  }
+  idSource->length( nbObj );
+
+  bool aResult = false;
+
+  try
+  {
+    SMESH::SMESH_MeshEditor_var aEditor = mesh->GetMeshEditor();
+    aResult = true;
+    aEditor->SplitBiQuadraticIntoLinear( idSource );
+  }
+  catch ( const SALOME::SALOME_Exception& S_ex )
+  {
+    SalomeApp_Tools::QtCatchCorbaException( S_ex );
+    aResult = false;
+  }
+  catch ( ... )
+  {
+    aResult = false;
+  }
+  if( aResult )
+  {
+    SMESHGUI::Modified();
+    update( UF_ObjBrowser | UF_Model | UF_Viewer );
+    selectionDone();
+  }
+  return aResult;
+}
diff --git a/src/SMESHGUI/SMESHGUI_SplitBiQuad.h b/src/SMESHGUI/SMESHGUI_SplitBiQuad.h
new file mode 100644 (file)
index 0000000..13cbd71
--- /dev/null
@@ -0,0 +1,72 @@
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&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, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// 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_SplitBiQuad.h
+// Author : Open CASCADE S.A.S.
+//
+#ifndef SMESHGUI_SplitBiQuad_H
+#define SMESHGUI_SplitBiQuad_H
+
+#include "SMESH_SMESHGUI.hxx"
+#include "SMESHGUI_Dialog.h"
+#include "SMESHGUI_SelectionOp.h"
+
+class SMESHGUI_SplitBiQuadOp;
+
+/*!
+ * \brief Dialog performing SMESH_MeshEditor::SplitBiQuadraticIntoLinear()
+ */
+class SMESHGUI_EXPORT SMESHGUI_SplitBiQuadDlg : public SMESHGUI_Dialog
+{ 
+  Q_OBJECT       
+        
+    public:
+  SMESHGUI_SplitBiQuadDlg();
+  virtual ~SMESHGUI_SplitBiQuadDlg();
+
+  friend class SMESHGUI_SplitBiQuadOp;
+};
+
+class SMESHGUI_EXPORT SMESHGUI_SplitBiQuadOp : public SMESHGUI_SelectionOp
+{
+  Q_OBJECT
+
+public:      
+  SMESHGUI_SplitBiQuadOp();
+  virtual ~SMESHGUI_SplitBiQuadOp();
+  
+  virtual LightApp_Dialog*       dlg() const;  
+
+protected:
+  virtual void                   startOperation();
+  //virtual void                   selectionDone();
+  virtual SUIT_SelectionFilter*  createFilter( const int ) const;
+
+protected slots:
+  virtual bool                   onApply();
+
+private:
+  SMESHGUI_SplitBiQuadDlg*       myDlg;
+};
+
+#endif // SMESHGUI_SplitBiQuad_H
index 2a014f21ed9a54df8ada71f00949157385da8f66..d5c5d473d3b3dfe6ebfd62dd0d92cd4245a0cd50 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&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,6 @@
 #include "SMESHGUI_MeshUtils.h"
 #include "SMESHGUI_IdValidator.h"
 #include "SMESHGUI_FilterDlg.h"
-#include "SMESHGUI_MeshEditPreview.h"
 
 #include <SMESH_Actor.h>
 #include <SMESH_TypeFilter.hxx>
@@ -312,7 +311,10 @@ SMESHGUI_SymmetryDlg::SMESHGUI_SymmetryDlg( SMESHGUI* theModule )
   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(reject()));
+  connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()),      this, SLOT(reject()));
+  connect(mySMESHGUI, SIGNAL(SignalActivatedViewManager()), this, SLOT(onOpenView()));
+  connect(mySMESHGUI, SIGNAL(SignalCloseView()),            this, SLOT(onCloseView()));
+
   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)));
@@ -355,14 +357,25 @@ void SMESHGUI_SymmetryDlg::Init (bool ResetControls)
   myObjects.clear();
   myObjectsNames.clear();
 
-  myEditCurrentArgument = 0;
-  LineEditElements->clear();
+  myEditCurrentArgument = LineEditElements;
+  LineEditElements->setFocus();
   myElementsId = "";
   myNbOkElements = 0;
 
   buttonOk->setEnabled(false);
   buttonApply->setEnabled(false);
 
+  if ( !ResetControls && !isApplyAndClose() && // make highlight move upon [Apply] (IPAL20729)
+       myActor && !myActor->getIO().IsNull() &&
+       ActionGroup->button( MOVE_ELEMS_BUTTON )->isChecked() &&
+       !CheckBoxMesh->isChecked() ) // move selected elements
+  {
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+    {
+      aViewWindow->highlight( myActor->getIO(), false, false );
+      aViewWindow->highlight( myActor->getIO(), true, true );
+    }
+  }
   myActor = 0;
 
   if (ResetControls) {
@@ -377,11 +390,8 @@ void SMESHGUI_SymmetryDlg::Init (bool ResetControls)
     CheckBoxMesh->setChecked(false);
     myPreviewCheckBox->setChecked(false);
     onDisplaySimulation(false);
-
-//     MakeGroupsCheck->setChecked(false);
-//     MakeGroupsCheck->setEnabled(false);
-    onSelectMesh(false);
   }
+  onSelectMesh(CheckBoxMesh->isChecked());
 }
 
 //=================================================================================
@@ -581,8 +591,6 @@ bool SMESHGUI_SymmetryDlg::ClickOnApply()
         anApp->browseObjects( anEntryList, isApplyAndClose() );
     }
     Init(false);
-    ConstructorsClicked(GetConstructorId());
-    SelectionIntoArgument();
 
     SMESHGUI::Modified();
   }
@@ -619,6 +627,31 @@ void SMESHGUI_SymmetryDlg::reject()
   QDialog::reject();
 }
 
+//=================================================================================
+// function : onOpenView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_SymmetryDlg::onOpenView()
+{
+  if ( mySelector ) {
+    SMESH::SetPointRepresentation(false);
+  }
+  else {
+    mySelector = SMESH::GetViewWindow( mySMESHGUI )->GetSelector();
+    ActivateThisDialog();
+  }
+}
+
+//=================================================================================
+// function : onCloseView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_SymmetryDlg::onCloseView()
+{
+  DeactivateActiveDialog();
+  mySelector = 0;
+}
+
 //=================================================================================
 // function : ClickOnHelp()
 // purpose  :
@@ -703,6 +736,7 @@ void SMESHGUI_SymmetryDlg::onTextChange (const QString& theNewText)
 void SMESHGUI_SymmetryDlg::SelectionIntoArgument()
 {
   if (myBusy) return;
+  if (myFilterDlg && myFilterDlg->isVisible()) return; // filter dlg active
 
   // clear
   myActor = 0;
@@ -731,44 +765,44 @@ void SMESHGUI_SymmetryDlg::SelectionIntoArgument()
 
   int aNbUnits = 0;
 
-  if (myEditCurrentArgument == (QWidget*)LineEditElements) {
+  if (myEditCurrentArgument == (QWidget*)LineEditElements)
+  {
     myElementsId = "";
     myObjects.clear();
     myObjectsNames.clear();
     myMeshes.clear();
 
-    for ( SALOME_ListIteratorOfListIO it( aList ); it.More(); it.Next() ) {
+    for ( SALOME_ListIteratorOfListIO it( aList ); it.More(); it.Next() )
+    {
       Handle(SALOME_InteractiveObject) IO = it.Value();
-      
       SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO( IO );
-      if( aMesh->_is_nil() )
-        return;
+      if ( aMesh->_is_nil() )
+        continue;
 
       myActor = SMESH::FindActorByObject( aMesh );
       if ( !myActor )
         myActor = SMESH::FindActorByEntry( IO->getEntry() );
-      if ( !myActor && !CheckBoxMesh->isChecked() )
-        return;
+      // if ( !myActor && !CheckBoxMesh->isChecked() ) -- elems can be selected by Filter
+      //   return;
 
-      if ( !SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO )->_is_nil() ) {
-        if ( _PTR(Study) aStudy = SMESH::GetActiveStudyDocument() ) {
-          _PTR(SObject) obj = aStudy->FindObjectID( qPrintable( QString( IO->getEntry() ) ) );
-          _PTR(GenericAttribute) anAttr;
-          if ( obj && obj->FindAttribute( anAttr, "AttributeName" ) ) {
-            _PTR(AttributeName) aNameAttr( anAttr );
-            myObjects << SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
-            myObjectsNames << aNameAttr->Value().c_str();
-            myMeshes << aMesh;
-          }
+      SMESH::SMESH_IDSource_var idSrc = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
+      if ( _PTR(SObject) obj = SMESH::FindSObject( idSrc ))
+      {
+        std::string name = obj->GetName();
+        if ( !name.empty() )
+        {
+          myObjects << idSrc;
+          myObjectsNames << name.c_str();
+          myMeshes << aMesh;
         }
       }
     }
 
     // MakeGroups is available if there are groups and "Copy"
-      int aNbGroups = 0;
-      for ( int i = 0; i < myMeshes.count(); i++ )
-        aNbGroups += myMeshes[i]->NbGroups();
-      
+    int aNbGroups = 0;
+    for ( int i = 0; i < myMeshes.count(); i++ )
+      aNbGroups += myMeshes[i]->NbGroups();
+
     if ( aNbGroups == 0 ) {
       MakeGroupsCheck->setChecked(false);
       MakeGroupsCheck->setEnabled(false);
@@ -776,69 +810,26 @@ void SMESHGUI_SymmetryDlg::SelectionIntoArgument()
     else if ( ActionGroup->checkedId() != MOVE_ELEMS_BUTTON ) {
       MakeGroupsCheck->setEnabled(true);
     }
-    if (CheckBoxMesh->isChecked()) {
-      SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aString);
 
+    if (CheckBoxMesh->isChecked()) {
       if ( myObjects.isEmpty() ) 
         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 {
+      SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aString);
+    }
+    else {
       aNbUnits = SMESH::GetNameOfSelectedElements( mySelector, aList.First(), aString);
       myElementsId = aString;
       if (aNbUnits < 1)
         return;
     }
-
     myNbOkElements = true;
-  } else {
+  }
+  else // set coordinates by a picked node
+  {
     Handle(SALOME_InteractiveObject) IO = aList.First();
-    if ((SMESH::GetMeshByIO(IO))->_is_nil())
-      return;
 
-    SMESH_Actor* anActor = SMESH::FindActorByObject(SMESH::GetMeshByIO(IO));
+    SMESH_Actor* anActor = SMESH::FindActorByEntry( IO->getEntry() );
     if (!anActor)
-      anActor = SMESH::FindActorByEntry(IO->getEntry());
-    if (!anActor && !CheckBoxMesh->isChecked())
       return;
 
     aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, IO, aString);
@@ -968,8 +959,13 @@ void SMESHGUI_SymmetryDlg::ActivateThisDialog()
 //=================================================================================
 void SMESHGUI_SymmetryDlg::enterEvent (QEvent*)
 {
-  if (!ConstructorsBox->isEnabled())
+  if (!ConstructorsBox->isEnabled()) {
+    SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
+    if ( aViewWindow && !mySelector) {
+      mySelector = aViewWindow->GetSelector();
+    }
     ActivateThisDialog();
+  }
 }
 
 //=======================================================================
@@ -1125,15 +1121,24 @@ void SMESHGUI_SymmetryDlg::keyPressEvent( QKeyEvent* e )
 //=================================================================================
 void SMESHGUI_SymmetryDlg::setFilters()
 {
-  if(myMeshes.isEmpty()) {
-    SUIT_MessageBox::critical(this,
-                              tr("SMESH_ERROR"),
-                              tr("NO_MESH_SELECTED"));
-   return;
+  if ( myMeshes.isEmpty() ) {
+    SUIT_MessageBox::critical(this, tr("SMESH_ERROR"), tr("NO_MESH_SELECTED"));
+    return;
   }
-  if ( !myFilterDlg )
+  if ( !myFilterDlg ) {
     myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, SMESH::ALL );
+    connect(myFilterDlg, SIGNAL(Accepted()), SLOT(onFilterAccepted()));
+  }
+
+  QList<int> types;
+  if ( myMeshes[0]->NbEdges()     ) types << SMESH::EDGE;
+  if ( myMeshes[0]->NbFaces()     ) types << SMESH::FACE;
+  if ( myMeshes[0]->NbVolumes()   ) types << SMESH::VOLUME;
+  if ( myMeshes[0]->NbBalls()     ) types << SMESH::BALL;
+  if ( myMeshes[0]->Nb0DElements()) types << SMESH::ELEM0D;
+  if ( types.count() > 1 )          types << SMESH::ALL;
 
+  myFilterDlg->Init( types );
   myFilterDlg->SetSelection();
   myFilterDlg->SetMesh( myMeshes[0] );
   myFilterDlg->SetSourceWg( LineEditElements );
@@ -1141,6 +1146,23 @@ void SMESHGUI_SymmetryDlg::setFilters()
   myFilterDlg->show();
 }
 
+//=======================================================================
+// name    : onFilterAccepted()
+// Purpose : SLOT. Called when Filter dlg closed with OK button.
+//           Activate [Apply] if no Actor is available
+//=======================================================================
+void SMESHGUI_SymmetryDlg::onFilterAccepted()
+{
+  if ( myMeshes.length() > 0 && !buttonOk->isEnabled() )
+  {
+    myElementsId = LineEditElements->text();
+    QStringList aListElementsId = myElementsId.split(" ", QString::SkipEmptyParts);
+    myNbOkElements = aListElementsId.count();
+    buttonOk->setEnabled( myNbOkElements );
+    buttonApply->setEnabled( myNbOkElements );
+  }
+}
+
 //=================================================================================
 // function : isValid
 // purpose  :
@@ -1173,10 +1195,13 @@ bool SMESHGUI_SymmetryDlg::isValid()
 // 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);      
+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());
@@ -1185,7 +1210,7 @@ void SMESHGUI_SymmetryDlg::onDisplaySimulation( bool toDisplayPreview ) {
 
       SMESH::AxisStruct aMirror;
       SMESH::SMESH_MeshEditor::MirrorType aMirrorType;
-      
+
       getMirror(aMirror,aMirrorType);
 
       try {
@@ -1201,7 +1226,7 @@ void SMESHGUI_SymmetryDlg::onDisplaySimulation( bool toDisplayPreview ) {
           }
         else {
           SMESH::SMESH_MeshEditor_var aMeshEditor = myMeshes[0]->GetMeshEditPreviewer();
-          aMeshEditor->Mirror(anElementsId, aMirror, aMirrorType, copy );        
+          aMeshEditor->Mirror(anElementsId, aMirror, aMirrorType, copy );
           aMeshPreviewStruct << aMeshEditor->GetPreviewData();
         }
         setSimulationPreview(aMeshPreviewStruct);
@@ -1210,7 +1235,7 @@ void SMESHGUI_SymmetryDlg::onDisplaySimulation( bool toDisplayPreview ) {
       }
     } else {
       hidePreview();
-    } 
+    }
   } else {
     hidePreview();
   }
@@ -1220,7 +1245,9 @@ void SMESHGUI_SymmetryDlg::onDisplaySimulation( bool toDisplayPreview ) {
 // function : getMirror
 // purpose  : return mirror parameters
 //=================================================================================
-void SMESHGUI_SymmetryDlg::getMirror(SMESH::AxisStruct& theMirror, SMESH::SMESH_MeshEditor::MirrorType& theMirrorType) {
+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();
index efb69b8310080483ecec5361644232c25dfaf39c..c7845dcf69f252beecf6fe9896dfe946cd2953ca 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -139,7 +139,8 @@ private:
 protected slots:
   virtual void           onDisplaySimulation( bool );
   virtual void           reject();
-   
+  void                   onFilterAccepted();
+
 private slots:
   void                   ConstructorsClicked( int );
   void                   ClickOnOk();
@@ -153,6 +154,8 @@ private slots:
   void                   onSelectMesh( bool );
   void                   onVectorChanged();
   void                   onActionClicked( int );
+  void                   onOpenView();
+  void                   onCloseView();
   void                   setFilters();
 };
 
index ae7adcfa03066ff874cd58e8a83bf3b7491a42bb..be53d01e411b6af819f752acae39abb5693a8b4d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -313,10 +313,13 @@ SMESHGUI_TranslationDlg::SMESHGUI_TranslationDlg( SMESHGUI* theModule ) :
   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(reject()));
-  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(mySMESHGUI,       SIGNAL (SignalCloseAllDialogs()),      this, SLOT(reject()));
+  connect(mySMESHGUI,       SIGNAL (SignalActivatedViewManager()), this, SLOT(onOpenView()));
+  connect(mySMESHGUI,       SIGNAL (SignalCloseView()),            this, SLOT(onCloseView()));
+
+  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()));
@@ -359,14 +362,25 @@ void SMESHGUI_TranslationDlg::Init (bool ResetControls)
   myObjectsNames.clear();
   myMeshes.clear();
 
-  myEditCurrentArgument = 0;
-  LineEditElements->clear();
+  myEditCurrentArgument = LineEditElements;
+  LineEditElements->setFocus();
   myElementsId = "";
   myNbOkElements = 0;
 
   buttonOk->setEnabled(false);
   buttonApply->setEnabled(false);
 
+  if ( !ResetControls && !isApplyAndClose() && // make highlight move upon [Apply] (IPAL20729)
+       myActor && !myActor->getIO().IsNull() &&
+       ActionGroup->button( MOVE_ELEMS_BUTTON )->isChecked() &&
+       !CheckBoxMesh->isChecked() ) // move selected elements
+  {
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+    {
+      aViewWindow->highlight( myActor->getIO(), false, false );
+      aViewWindow->highlight( myActor->getIO(), true, true );
+    }
+  }
   myActor = 0;
 
   if (ResetControls) {
@@ -379,12 +393,10 @@ void SMESHGUI_TranslationDlg::Init (bool ResetControls)
 
     ActionGroup->button( MOVE_ELEMS_BUTTON )->setChecked(true);
     CheckBoxMesh->setChecked(false);
-//     MakeGroupsCheck->setChecked(false);
-//     MakeGroupsCheck->setEnabled(false);
     myPreviewCheckBox->setChecked(false);
     onDisplaySimulation(false);
-    onSelectMesh(false);
   }
+  onSelectMesh(CheckBoxMesh->isChecked());
 }
 
 //=================================================================================
@@ -590,7 +602,6 @@ bool SMESHGUI_TranslationDlg::ClickOnApply()
       
     Init(false);
     ConstructorsClicked(GetConstructorId());
-    SelectionIntoArgument();
 
     SMESHGUI::Modified();
   }
@@ -628,6 +639,31 @@ void SMESHGUI_TranslationDlg::reject()
   QDialog::reject();
 }
 
+//=================================================================================
+// function : onOpenView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_TranslationDlg::onOpenView()
+{
+  if ( mySelector ) {
+    SMESH::SetPointRepresentation(false);
+  }
+  else {
+    mySelector = SMESH::GetViewWindow( mySMESHGUI )->GetSelector();
+    ActivateThisDialog();
+  }
+}
+
+//=================================================================================
+// function : onCloseView()
+// purpose  :
+//=================================================================================
+void SMESHGUI_TranslationDlg::onCloseView()
+{
+  DeactivateActiveDialog();
+  mySelector = 0;
+}
+
 //=================================================================================
 // function : ClickOnHelp()
 // purpose  :
@@ -689,7 +725,6 @@ void SMESHGUI_TranslationDlg::onTextChange (const QString& theNewText)
         myNbOkElements++;
       }
     }
-
     mySelector->AddOrRemoveIndex( anIO, newIndices, false );
     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
       aViewWindow->highlight( anIO, true, true );
@@ -710,6 +745,8 @@ void SMESHGUI_TranslationDlg::onTextChange (const QString& theNewText)
 void SMESHGUI_TranslationDlg::SelectionIntoArgument()
 {
   if (myBusy) return;
+  if (myFilterDlg && myFilterDlg->isVisible()) return; // filter dlg active
+
   BusyLocker lock( myBusy );
   // clear
   myActor = 0;
@@ -735,13 +772,15 @@ void SMESHGUI_TranslationDlg::SelectionIntoArgument()
     return;
 
   int aNbUnits = 0;
-  if (myEditCurrentArgument == (QWidget*)LineEditElements) {
+  if (myEditCurrentArgument == (QWidget*)LineEditElements)
+  {
     myElementsId = "";
     myObjects.clear();
     myObjectsNames.clear();
     myMeshes.clear();
 
-    for ( SALOME_ListIteratorOfListIO it( aList ); it.More(); it.Next() ) {
+    for ( SALOME_ListIteratorOfListIO it( aList ); it.More(); it.Next() )
+    {
       Handle(SALOME_InteractiveObject) IO = it.Value();
       SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO( IO );
       if ( aMesh->_is_nil() )
@@ -751,25 +790,24 @@ void SMESHGUI_TranslationDlg::SelectionIntoArgument()
       if ( !anActor )
         anActor = SMESH::FindActorByEntry( IO->getEntry() );
 
-      if ( !anActor && !CheckBoxMesh->isChecked() )
-        return;
-
-      if ( !SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO )->_is_nil() ) {
-        if ( _PTR(Study) aStudy = SMESH::GetActiveStudyDocument() ) {
-          _PTR(SObject) obj = aStudy->FindObjectID( qPrintable( QString( IO->getEntry() ) ) );
-          _PTR(GenericAttribute) anAttr;
-          if ( obj && obj->FindAttribute( anAttr, "AttributeName" ) ) {
-            _PTR(AttributeName) aNameAttr( anAttr );
-            myObjects << SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
-            myObjectsNames << aNameAttr->Value().c_str();
-            myMeshes << aMesh;
-          }
+      // if ( !anActor && !CheckBoxMesh->isChecked() )  -- elems can be selected by Filter
+      //   return;
+
+      SMESH::SMESH_IDSource_var idSrc = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
+      if ( _PTR(SObject) obj = SMESH::FindSObject( idSrc ))
+      {
+        std::string name = obj->GetName();
+        if ( !name.empty() )
+        {
+          myObjects << idSrc;
+          myObjectsNames << name.c_str();
+          myMeshes << aMesh;
         }
       }
-
-      myActor = anActor;
+      if ( anActor )
+        myActor = anActor;
     }
-    
+
     // MakeGroups is available if there are groups and "Copy"
     int aNbGroups = 0;
     for ( int i = 0; i < myMeshes.count(); i++ )
@@ -784,10 +822,11 @@ void SMESHGUI_TranslationDlg::SelectionIntoArgument()
     }
 
     if (CheckBoxMesh->isChecked()) {
-      SMESH::GetNameOfSelectedIObjects( mySelectionMgr, aString );
       if (myMeshes.isEmpty())
         return;
-    } else {
+      SMESH::GetNameOfSelectedIObjects( mySelectionMgr, aString );
+    }
+    else {
       aNbUnits = SMESH::GetNameOfSelectedElements(mySelector, aList.First(), aString);
       myElementsId = aString;
       if (aNbUnits < 1)
@@ -795,15 +834,13 @@ void SMESHGUI_TranslationDlg::SelectionIntoArgument()
     }
 
     myNbOkElements = true;
-  } else {
+  }
+  else  // set coordinates by a picked node
+  {
     Handle(SALOME_InteractiveObject) IO = aList.First();
-    if ((SMESH::GetMeshByIO(IO))->_is_nil())
-      return;
 
-    SMESH_Actor* anActor = SMESH::FindActorByObject(SMESH::GetMeshByIO(IO));
+    SMESH_Actor* anActor = SMESH::FindActorByEntry( IO->getEntry() );
     if (!anActor)
-      anActor = SMESH::FindActorByEntry(IO->getEntry());
-    if (!anActor && !CheckBoxMesh->isChecked())
       return;
 
     aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, IO, aString);
@@ -933,8 +970,13 @@ void SMESHGUI_TranslationDlg::ActivateThisDialog()
 //=================================================================================
 void SMESHGUI_TranslationDlg::enterEvent (QEvent*)
 {
-  if (!ConstructorsBox->isEnabled())
+  if (!ConstructorsBox->isEnabled()) {
+    SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
+    if ( aViewWindow && !mySelector) {
+      mySelector = aViewWindow->GetSelector();
+    }
     ActivateThisDialog();
+  }
 }
 
 //=======================================================================
@@ -968,7 +1010,6 @@ void SMESHGUI_TranslationDlg::onSelectMesh (bool toSelectMesh)
       aViewWindow->SetSelectionMode( CellSelection );
     LineEditElements->setReadOnly(false);
     LineEditElements->setValidator(myIdValidator);
-    onTextChange(LineEditElements->text());
     hidePreview();
   }
 
@@ -1059,15 +1100,24 @@ void SMESHGUI_TranslationDlg::keyPressEvent( QKeyEvent* e )
 //=================================================================================
 void SMESHGUI_TranslationDlg::setFilters()
 {
-  if(myMeshes.isEmpty()) {
-    SUIT_MessageBox::critical(this,
-                              tr("SMESH_ERROR"),
-                              tr("NO_MESH_SELECTED"));
-   return;
+  if ( myMeshes.isEmpty() ) {
+    SUIT_MessageBox::critical(this, tr("SMESH_ERROR"), tr("NO_MESH_SELECTED"));
+    return;
   }
-  if ( !myFilterDlg )
+  if ( !myFilterDlg ) {
     myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, SMESH::ALL );
+    connect(myFilterDlg, SIGNAL(Accepted()), SLOT(onFilterAccepted()));
+  }
+
+  QList<int> types;
+  if ( myMeshes[0]->NbEdges()     ) types << SMESH::EDGE;
+  if ( myMeshes[0]->NbFaces()     ) types << SMESH::FACE;
+  if ( myMeshes[0]->NbVolumes()   ) types << SMESH::VOLUME;
+  if ( myMeshes[0]->NbBalls()     ) types << SMESH::BALL;
+  if ( myMeshes[0]->Nb0DElements()) types << SMESH::ELEM0D;
+  if ( types.count() > 1 )          types << SMESH::ALL;
 
+  myFilterDlg->Init( types );
   myFilterDlg->SetSelection();
   myFilterDlg->SetMesh( myMeshes[0] );
   myFilterDlg->SetSourceWg( LineEditElements );
@@ -1075,6 +1125,23 @@ void SMESHGUI_TranslationDlg::setFilters()
   myFilterDlg->show();
 }
 
+//=======================================================================
+// name    : onFilterAccepted()
+// Purpose : SLOT. Called when Filter dlg closed with OK button.
+//           Activate [Apply] if no Actor is available
+//=======================================================================
+void SMESHGUI_TranslationDlg::onFilterAccepted()
+{
+  if ( myMeshes.length() > 0 && !buttonOk->isEnabled() )
+  {
+    myElementsId = LineEditElements->text();
+    QStringList aListElementsId = myElementsId.split(" ", QString::SkipEmptyParts);
+    myNbOkElements = aListElementsId.count();
+    buttonOk->setEnabled( myNbOkElements );
+    buttonApply->setEnabled( myNbOkElements );
+  }
+}
+
 //=================================================================================
 // function : isValid
 // purpose  :
@@ -1107,12 +1174,14 @@ bool SMESHGUI_TranslationDlg::isValid()
 // function : onDisplaySimulation
 // purpose  : Show/Hide preview
 //=================================================================================
-void SMESHGUI_TranslationDlg::onDisplaySimulation( bool toDisplayPreview ) {
-  if (myPreviewCheckBox->isChecked() && toDisplayPreview) {
-    
-    if (isValid() && myNbOkElements) {
+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());
@@ -1148,7 +1217,7 @@ void SMESHGUI_TranslationDlg::onDisplaySimulation( bool toDisplayPreview ) {
         }
         setSimulationPreview( aMeshPreviewStruct );
       } catch (...) {
-        
+
       }
     }
     else {
index 4ee72ab047f39cc851d3c28670458353924eaad0..cfd801c7a075cb6a05249b3d1909404f48e1b568 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -133,6 +133,7 @@ private:
 protected slots:
   virtual void           onDisplaySimulation( bool );
   virtual void           reject();
+  void                   onFilterAccepted();
    
 private slots:
   void                   ConstructorsClicked( int );
@@ -146,7 +147,10 @@ private slots:
   void                   onTextChange( const QString& );
   void                   onSelectMesh( bool );
   void                   onActionClicked( int );
+  void                   onOpenView();
+  void                   onCloseView();
   void                   setFilters();
+
 };
 
 #endif // SMESHGUI_TRANSLATIONDLG_H
index 6c13709434ae964a50a3a0068b71eddcb03a44e6..b747fcf8259cc434115bddacef8dd545e4971e23 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 91f13fc4161c1f9cbca9cfbdd147ce87780a3b3b..fee2324344a8f1b8833699037b07ffa2d10b0cc3 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index d539ac8a076aa8ef61c8ad14c94e343fb03f25e3..c8f22670819b90e199e4016b5fa38993dc5ac72c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -29,7 +29,7 @@
 #include "SMESHGUI.h"
 #include "SMESHGUI_Selection.h"
 #include "SMESH_Type.h"
-
+#include "SMESH_MeshAlgos.hxx"
 #include <SMDS_MeshNode.hxx>
 #include <SMDS_MeshFace.hxx>
 
 
 #include CORBA_SERVER_HEADER(SMESH_Group)
 
+//VSR: uncomment below macro to support unicode text properly in SALOME
+//     current commented out due to regressions
+//#define PAL22528_UNICODE
+
 namespace SMESH
 {
   SUIT_Desktop*
@@ -185,7 +189,7 @@ namespace SMESH
   }
 
   CORBA::Object_var SObjectToObject (_PTR(SObject) theSObject,
-                                     _PTR(Study)   theStudy)
+                                     _PTR(Study)   /*theStudy*/)
   {
     SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>
       (SUIT_Session::session()->activeApplication());
@@ -193,11 +197,11 @@ namespace SMESH
       _PTR(GenericAttribute) anAttr;
       if (theSObject->FindAttribute(anAttr, "AttributeIOR")) {
         _PTR(AttributeIOR) anIOR = anAttr;
-        CORBA::String_var aVal = anIOR->Value().c_str();
+        std::string aVal = anIOR->Value();
         // 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);
+        if ( aVal.size() > 0 )
+          return app->orb()->string_to_object( aVal.c_str() );
       }
     }
     return CORBA::Object::_nil();
@@ -205,7 +209,7 @@ namespace SMESH
 
   CORBA::Object_var SObjectToObject (_PTR(SObject) theSObject)
   {
-    _PTR(Study) aStudy = GetActiveStudyDocument();
+    _PTR(Study) aStudy;// = GetActiveStudyDocument(); -- aStudy is not used
     return SObjectToObject(theSObject,aStudy);
   }
 
@@ -294,19 +298,25 @@ namespace SMESH
     aPixmap->SetPixMap( pmName );
 
     _PTR(ChildIterator) anIter = aStudy->NewChildIterator(theSObject);
-    for (int i = 1; anIter->More(); anIter->Next(), i++) {
+    for ( ; anIter->More(); anIter->Next() ) {
       _PTR(SObject) aSObj = anIter->Value();
-      if (i >= 4) {
+      if ( aSObj->Tag() >= SMESH::Tag_FirstSubMesh )
+      {
         _PTR(ChildIterator) anIter1 = aStudy->NewChildIterator(aSObj);
         for ( ; anIter1->More(); anIter1->Next())
         {
           _PTR(SObject) aSObj1 = anIter1->Value();
+          _PTR(SObject) aSObjectRef;
+          if (aSObj1->ReferencedObject(aSObjectRef))
+            continue; // reference to an object
 
           anAttr = aBuilder->FindOrCreateAttribute(aSObj1, "AttributePixMap");
           aPixmap = anAttr;
 
           std::string entry = aSObj1->GetID();
           int objType = SMESHGUI_Selection::type( entry.c_str(), aStudy );
+          if ( objType == SMESH::HYPOTHESIS || objType == SMESH::ALGORITHM )
+            continue;
 
           SMESH::SMESH_IDSource_var idSrc = SObjectToInterface<SMESH::SMESH_IDSource>( aSObj1 );
           if ( !idSrc->_is_nil() )
@@ -316,7 +326,7 @@ namespace SMESH
             const bool isGroupOnFilter = !gof->_is_nil();
 
             bool isEmpty = false;
-            if ( !isGroupOnFilter ) // GetTypes() can be very long on isGroupOnFilter!
+            if ( !isGroupOnFilter ) // GetTypes() can be very long on GroupOnFilter!
             {
               SMESH::array_of_ElementType_var elemTypes = idSrc->GetTypes();
               isEmpty = ( elemTypes->length() == 0 );
@@ -330,7 +340,7 @@ namespace SMESH
             else
               aPixmap->SetPixMap( "ICON_SMESH_TREE_GROUP" );
           }
-          else
+          else // is it necessary?
           {
             if ( !theIsNotModif )
               aPixmap->SetPixMap( pmName );
@@ -369,26 +379,31 @@ namespace SMESH
   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;
+    SMESH_MeshAlgos::FaceNormal( theFace, n, /*normalized=*/true );
     return n;
   }
   
+  QString fromUtf8( const char* txt )
+  {
+#ifdef PAL22528_UNICODE
+    return QString::fromUtf8( txt );
+#else
+    return QString( txt );
+#endif
+  }
+
+  QString fromUtf8( const std::string& txt )
+  {
+    return fromUtf8( txt.c_str() );
+  }
+
+  toUtf8::toUtf8( const QString& txt )
+  {
+#ifdef PAL22528_UNICODE
+    assign( txt.toUtf8().constData() );
+#else
+    assign( txt.toLatin1().constData() );
+#endif
+  }
+
 } // end of namespace SMESH
index 5ac9ee97cfbd402878949c76a0e44dede4930078..6f024242ff497c850a79224551b766bff0efc3db 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -182,7 +182,7 @@ SMESHGUI_EXPORT
 
 
   // type to use instead of SMESH_IDSource_var for automatic UnRegister()
-  typedef SALOME::GenericObj_wrap<SMESH_IDSource> SMESH_IDSource_wrap;
+  typedef SALOME::GenericObj_wrap<SMESH_IDSource> IDSource_wrap;
 
   /*!
    * \brief Class usefull to convert a string returned from a CORBA call
@@ -195,7 +195,7 @@ SMESHGUI_EXPORT
   class toStrT : public _STRING {
     CORBA::String_var myStr;
   public:
-    toStrT( char* s ): myStr(s), _STRING( s )
+    toStrT( char* s ): _STRING( s ), myStr(s)
     {}
     operator const char*() const
     { return myStr.in(); }
@@ -208,6 +208,13 @@ SMESHGUI_EXPORT
     toStdStr( char* s ): toStrT< std::string >(s) {}
   };
 
+  QString fromUtf8( const char* txt );
+  QString fromUtf8( const std::string& txt );
+  struct toUtf8: public std::string
+  {
+    toUtf8( const QString& txt );
+    operator const char*() const { return c_str(); }
+  };
 }
 
 #endif // SMESHGUI_UTILS_H
index 7ca3e9395fa1940af4733b1a930b37d7f3624821..031335ee5128420f32877bbcfb8effb59c6b94d1 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 #include "SMESHGUI_VTKUtils.h"
 
 #include "SMESHGUI.h"
-#include "SMESHGUI_Utils.h"
 #include "SMESHGUI_Filter.h"
+#include "SMESHGUI_Utils.h"
+#include "SMDS_Mesh.hxx"
+#include "SMESH_Actor.h"
+#include "SMESH_ActorUtils.h"
+#include "SMESH_CellLabelActor.h"
 #include "SMESH_ControlsDef.hxx"
-
-#include <SMESH_Actor.h>
-#include <SMESH_ActorUtils.h>
 #include "SMESH_NodeLabelActor.h"
-#include "SMESH_CellLabelActor.h"
-#include <SMESH_ObjectDef.h>
-#include <SMDS_Mesh.hxx>
+#include "SMESH_ObjectDef.h"
 
 // SALOME GUI includes
 #include <SUIT_Desktop.h>
@@ -774,6 +773,7 @@ namespace SMESH
               anActor->SetVisibility(false);
               aStudy->setVisibilityState(theEntry, Qtx::HiddenState);
               break;
+            default:;
           }
         } else {
           switch (theAction) {
@@ -800,6 +800,7 @@ namespace SMESH
               }
               break;
             }
+          default:;
           }
         }
       }
@@ -809,16 +810,20 @@ namespace SMESH
   }
 
 
-  bool UpdateView(EDisplaing theAction, const char* theEntry){
+  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();
-    return UpdateView(aWnd,theAction,theEntry);
+    if ( SUIT_ViewManager* vm = app->activeViewManager() )
+    {
+      SUIT_ViewWindow *aWnd = vm->getActiveView();
+      return UpdateView(aWnd,theAction,theEntry);
+    }
+    return false;
   }
 
   void UpdateView(){
-    if(SVTK_ViewWindow* aWnd = SMESH::GetCurrentVtkView()){
+    if ( SVTK_ViewWindow* aWnd = SMESH::GetCurrentVtkView()) {
       LightApp_SelectionMgr* mgr = SMESHGUI::selectionMgr();
       SALOME_ListIO selected; mgr->selectedObjects( selected );
 
@@ -849,7 +854,7 @@ namespace SMESH
 
   bool Update(const Handle(SALOME_InteractiveObject)& theIO, bool theDisplay)
   {
-        MESSAGE("Update");
+    MESSAGE("Update");
     _PTR(Study) aStudy = GetActiveStudyDocument();
     CORBA::Long anId = aStudy->StudyId();
     if ( TVisualObjPtr aVisualObj = SMESH::GetVisualObj(anId,theIO->getEntry())) {
@@ -862,7 +867,7 @@ namespace SMESH
 
   bool UpdateNulData(const Handle(SALOME_InteractiveObject)& theIO, bool theDisplay)
   {
-        MESSAGE("UpdateNulData");
+    MESSAGE("UpdateNulData");
     _PTR(Study) aStudy = GetActiveStudyDocument();
     CORBA::Long anId = aStudy->StudyId();
     if ( TVisualObjPtr aVisualObj = SMESH::GetVisualObj(anId,theIO->getEntry(), true)) {
@@ -905,12 +910,12 @@ namespace SMESH
            aPreColor = mgr->colorValue( "SMESH", "highlight_color", Qt::cyan );
 
     int aElem0DSize = mgr->integerValue("SMESH", "elem0d_size", 5);
-    int aBallSize   = mgr->integerValue("SMESH", "ball_elem_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;
+  //  if (aBallSize > maxSize) maxSize = aBallSize;
 
     double SP1 = mgr->doubleValue( "SMESH", "selection_precision_node", 0.025 ),
            SP2 = mgr->doubleValue( "SMESH", "selection_precision_element", 0.001 ),
index 4fe56eef73bff4122f0ef9fb21dc826713d74e89..902eddbf2cde1366e4784ce8f0200654ed03999d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index cb27cf9b421b3ff4b497bf2ee6cf3a14e549bf23..d94b953029207e66d0278e842316b8cdebf1319c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 28203594cd551436ce69f1ba9eae7b6800b6770a..caa62c5f5d0e7dd754a7c2f4e3fa13650e6c5910 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 0638b5995f25d1a0cbf27d78fcfb3ba0b77d5512..010cce4b261ef86427cf5a79b2777f4452478b02 100755 (executable)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 7da6cad1a7362d4d7fe0578db2f06af2dd856bb9..a0c988e6c11c36ef49c160a5ad539f8f33255856 100644 (file)
             <source>ICON_COMPUTE</source>
             <translation>mesh_compute.png</translation>
         </message>
+        <message>
+            <source>ICON_EVALUATE</source>
+            <translation>mesh_evaluate.png</translation>
+        </message>
+        <message>
+            <source>ICON_MESH_ORDER</source>
+            <translation>mesh_order.png</translation>
+        </message>
         <message>
             <source>ICON_PRECOMPUTE</source>
             <translation>mesh_precompute.png</translation>
             <source>ICON_DLG_BIQUADRATIC_QUADRANGLE</source>
             <translation>mesh_biquad_quadrangle.png</translation>
         </message>
+        <message>
+            <source>ICON_DLG_QUADRATIC_POLYGON</source>
+            <translation>mesh_quad_polygon.png</translation>
+        </message>
         <message>
             <source>ICON_DLG_QUADRATIC_TETRAHEDRON</source>
             <translation>mesh_quad_tetrahedron.png</translation>
             <source>ICON_SPLIT_TO_TETRA</source>
             <translation>split_into_tetra.png</translation>
         </message>
+        <message>
+            <source>ICON_SPLIT_BIQUAD</source>
+            <translation>split_biquad.png</translation>
+        </message>
        <message>
             <source>ICON_MEASURE_LENGTH</source>
             <translation>mesh_measure_length.png</translation>
index 3f8a01c03908d1d8c3edb7e3a8b6b0faf5ff76d9..a235b9cc9dc8cac5118d807d583cb4f9e970029b 100644 (file)
     </message>
     <message>
         <source>MEN_MESH_ORDER</source>
-        <translation>Change submesh priority</translation>
+        <translation>Change sub-mesh priority</translation>
     </message>
     <message>
         <source>MEN_CREATE_GROUP</source>
         <source>MEN_POLYGON</source>
         <translation>Polygon</translation>
     </message>
+    <message>
+        <source>MEN_QUADRATIC_POLYGON</source>
+        <translation>Quadratic Polygon</translation>
+    </message>
     <message>
         <source>MEN_POLYHEDRON</source>
         <translation>Polyhedron</translation>
         <source>MEN_SHADE</source>
         <translation>Shading</translation>
     </message>
+    <message>
+        <source>MEN_SHOW_SCALAR_BAR</source>
+        <translation>Show Scalar Bar</translation>
+    </message>
     <message>
         <source>MEN_QUADRATIC_REPRESENT</source>
         <translation>2D Quadratic</translation>
     </message>
     <message>
         <source>MEN_UNDERLYING_ELEMS</source>
-        <translation>Group of underlying entities</translation>
+        <translation>Group based on nodes of other groups</translation>
     </message>
     <message>
         <source>MEN_UPDATE</source>
         <source>STB_SPLIT_TO_TETRA</source>
         <translation>Split Volumes</translation>
     </message>
+    <message>
+        <source>MEN_SPLIT_BIQUAD</source>
+        <translation>Split bi-quadratic into linear</translation>
+    </message>
+    <message>
+        <source>TOP_SPLIT_BIQUAD</source>
+        <translation>Split bi-quadratic into linear</translation>
+    </message>
+    <message>
+        <source>STB_SPLIT_BIQUAD</source>
+        <translation>Split bi-quadratic into linear</translation>
+    </message>
     <message>
         <source>MESHERS_FILE_CANT_OPEN</source>
         <translation>Can not open resource file</translation>
@@ -1123,8 +1143,13 @@ Please, select a mesh and try again</translation>
 Please enter a name of new group to be created or choose an existing one.</translation>
     </message>
     <message>
-        <source>MESH_STANDALONE_GRP_CHOSEN</source>
+        <source>MESH_GEOM_GRP_CHOSEN</source>
         <translation>Group on geometry is chosen: %1.
+Do you want to convert it to the standalone group?</translation>
+    </message>
+    <message>
+        <source>MESH_FILTER_GRP_CHOSEN</source>
+        <translation>Group on filter is chosen: %1.
 Do you want to convert it to the standalone group?</translation>
     </message>
     <message>
@@ -1221,6 +1246,14 @@ Please enter correct values and try again</translation>
         <source>SMESH_ADD_POLYGON_TITLE</source>
         <translation>Add Polygon</translation>
     </message>
+    <message>
+        <source>SMESH_ADD_QUADRATIC_POLYGON</source>
+        <translation>Add Quadratic polygon</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_QUADRATIC_POLYGON_TITLE</source>
+        <translation>Add Quadratic Polygon</translation>
+    </message>
     <message>
         <source>SMESH_ADD_PENTA</source>
         <translation>Add pentahedron</translation>
@@ -1287,7 +1320,7 @@ Please enter correct values and try again</translation>
     </message>
     <message>
         <source>SMESH_ADD_SUBMESH</source>
-        <translation>SubMesh Construction</translation>
+        <translation>Sub-mesh Construction</translation>
     </message>
     <message>
         <source>SMESH_ADD_TETRAS</source>
@@ -1693,6 +1726,10 @@ Do you want to continue ?</translation>
         <source>SMESH_EXTRUSION_ALONG_VECTOR</source>
         <translation>Extrusion Along Vector</translation>
     </message>
+    <message>
+        <source>SMESH_EXTRUSION_BY_NORMAL</source>
+        <translation>Extrusion By Normal</translation>
+    </message>
     <message>
         <source>SMESH_FACE</source>
         <translation>Face</translation>
@@ -1801,7 +1838,7 @@ add the exported data to its contents?</translation>
     </message>
     <message>
         <source>SMESH_HYP_10</source>
-        <translation>Hypothesis and submesh dimensions mismatch</translation>
+        <translation>Hypothesis and sub-mesh dimensions mismatch</translation>
     </message>
     <message>
         <source>SMESH_HYP_11</source>
@@ -1826,7 +1863,7 @@ Check algorithm documentation for supported geometry</translation>
     </message>
     <message>
         <source>SMESH_HYP_4</source>
-        <translation>Submesh is ignored as there is another algorithm of upper dimension generating %1D elements</translation>
+        <translation>Sub-mesh is ignored as there is another algorithm of upper dimension generating %1D elements</translation>
     </message>
     <message>
         <source>SMESH_HYP_5</source>
@@ -1850,19 +1887,23 @@ Check algorithm documentation for supported geometry</translation>
     </message>
     <message>
         <source>SMESH_ID_DIAGONAL</source>
-        <translation>Id Edges</translation>
+        <translation>Edges IDs</translation>
+    </message>
+    <message>
+        <source>SMESH_ID_EDGES</source>
+        <translation>Edge IDs</translation>
     </message>
     <message>
         <source>SMESH_ID_ELEMENTS</source>
-        <translation>Id Elements</translation>
+        <translation>Element IDs</translation>
     </message>
     <message>
         <source>SMESH_ID_FACES</source>
-        <translation>Id Faces</translation>
+        <translation>Face IDs</translation>
     </message>
     <message>
         <source>SMESH_ID_NODES</source>
-        <translation>Id Nodes</translation>
+        <translation>Node IDs</translation>
     </message>
     <message>
         <source>SMESH_INCORRECT_INPUT</source>
@@ -1934,23 +1975,23 @@ Check algorithm documentation for supported geometry</translation>
     </message>
     <message>
         <source>SMESH_MEN_SubMeshesOnCompound</source>
-        <translation>SubMeshes On Compound</translation>
+        <translation>Sub-meshes On Compound</translation>
     </message>
     <message>
         <source>SMESH_MEN_SubMeshesOnEdge</source>
-        <translation>SubMeshes On Edge</translation>
+        <translation>Sub-meshes On Edge</translation>
     </message>
     <message>
         <source>SMESH_MEN_SubMeshesOnFace</source>
-        <translation>SubMeshes On Face</translation>
+        <translation>Sub-meshes On Face</translation>
     </message>
     <message>
         <source>SMESH_MEN_SubMeshesOnSolid</source>
-        <translation>SubMeshes On Solid</translation>
+        <translation>Sub-meshes On Solid</translation>
     </message>
     <message>
         <source>SMESH_MEN_SubMeshesOnVertex</source>
-        <translation>SubMeshes On Vertex</translation>
+        <translation>Sub-meshes On Vertex</translation>
     </message>
     <message>
         <source>SMESH_AUTOMATIC</source>
@@ -2164,9 +2205,13 @@ Check algorithm documentation for supported geometry</translation>
         <source>SMESH_OBJECT_MESH</source>
         <translation>Mesh</translation>
     </message>
+    <message>
+        <source>SMESH_OBJECTS</source>
+        <translation>Objects</translation>
+    </message>
     <message>
         <source>SMESH_OBJECT_MESHorSUBMESH</source>
-        <translation>Mesh or SubMesh</translation>
+        <translation>Mesh or Sub-mesh</translation>
     </message>
     <message>
         <source>SMESH_OPERATION_FAILED</source>
@@ -2310,7 +2355,7 @@ Check algorithm documentation for supported geometry</translation>
     </message>
     <message>
         <source>PREF_NUMBERING_ELEM</source>
-        <translation>Edges: Color</translation>
+        <translation>Elements: Color</translation>
     </message>
     <message>
         <source>PREF_NUMBERING_FONT</source>
@@ -2573,6 +2618,10 @@ Check algorithm documentation for supported geometry</translation>
         <source>SMESH_SEWING</source>
         <translation>Sewing</translation>
     </message>
+    <message>
+        <source>SMESH_SHOW_SCALAR_BAR</source>
+        <translation>Show Scalar Bar</translation>
+    </message>
     <message>
         <source>SMESH_SMOOTHING</source>
         <translation>Smoothing</translation>
@@ -2583,11 +2632,11 @@ Check algorithm documentation for supported geometry</translation>
     </message>
     <message>
         <source>SMESH_SUBMESH</source>
-        <translation>SubMesh</translation>
+        <translation>Sub-mesh</translation>
     </message>
     <message>
         <source>SMESH_SUBMESH_SELECTED</source>
-        <translation>%1 SubMeshes</translation>
+        <translation>%1 Sub-meshes</translation>
     </message>
     <message>
         <source>SMESH_SYMMETRY</source>
@@ -2910,7 +2959,7 @@ Use Display Entity menu command to show them.
     </message>
     <message>
         <source>STB_MESH_ORDER</source>
-        <translation>Change submesh priority</translation>
+        <translation>Change sub-mesh priority</translation>
     </message>
     <message>
         <source>STB_CREATE_GROUP</source>
@@ -3208,6 +3257,10 @@ Use Display Entity menu command to show them.
         <source>STB_POLYGON</source>
         <translation>Polygon</translation>
     </message>
+    <message>
+        <source>STB_QUADRATIC_POLYGON</source>
+        <translation>Quadratic Polygon</translation>
+    </message>
     <message>
         <source>STB_POLYHEDRON</source>
         <translation>Polyhedron</translation>
@@ -3284,6 +3337,10 @@ Use Display Entity menu command to show them.
         <source>STB_SHOW_DISTRIBUTION</source>
         <translation>Show Distribution</translation>
     </message>
+    <message>
+        <source>STB_SHOW_SCALAR_BAR</source>
+        <translation>Show Scalar bar</translation>
+    </message>
     <message>
         <source>STB_REVOLUTION</source>
         <translation>Revolution</translation>
@@ -3394,7 +3451,7 @@ Use Display Entity menu command to show them.
     </message>
     <message>
         <source>STB_UNDERLYING_ELEMS</source>
-        <translation>Create groups of entities from existing groups of superior dimensions</translation>
+        <translation>Create groups of entities basing on nodes of other groups</translation>
     </message>
     <message>
         <source>STB_UPDATE</source>
@@ -3570,7 +3627,7 @@ Use Display Entity menu command to show them.
     </message>
     <message>
         <source>TOP_MESH_ORDER</source>
-        <translation>Change submesh priority</translation>
+        <translation>Change sub-mesh priority</translation>
     </message>
     <message>
         <source>TOP_CREATE_GROUP</source>
@@ -3860,6 +3917,10 @@ Use Display Entity menu command to show them.
         <source>TOP_POLYGON</source>
         <translation>Polygon</translation>
     </message>
+    <message>
+        <source>TOP_QUADRATIC_POLYGON</source>
+        <translation>Quadratic Polygon</translation>
+    </message>
     <message>
         <source>TOP_POLYHEDRON</source>
         <translation>Polyhedron</translation>
@@ -4046,7 +4107,7 @@ Use Display Entity menu command to show them.
     </message>
     <message>
         <source>TOP_UNDERLYING_ELEMS</source>
-        <translation>Create groups of entities from existing groups of superior dimensions</translation>
+        <translation>Create groups of entities basing on nodes of other groups</translation>
     </message>
     <message>
         <source>TOP_UPDATE</source>
@@ -4346,17 +4407,25 @@ Please, create VTK viewer and try again</translation>
         <translation>Display entity</translation>
     </message>
     <message>
-        <source>QUADRATIC_REPRESENT_MODE</source>
+        <source>QUADRATIC_REPRESENT_MODE_GROUP</source>
         <translation>Representation of the 2D quadratic elements</translation>
     </message>
+    <message>
+        <source>QUADRATIC_REPRESENT_MODE</source>
+        <translation>Default mode of the 2D quadratic elements</translation>
+    </message>
     <message>
         <source>MAX_ARC_ANGLE</source>
         <translation>Maximum angle</translation>
     </message>
     <message>
-        <source>PREF_DISPLAY_MODE</source>
+        <source>PREF_DISPLAY_MODE_GROUP</source>
         <translation>Display mode</translation>
     </message>
+    <message>
+        <source>PREF_DISPLAY_MODE</source>
+        <translation>Default display mode</translation>
+    </message>
     <message>
         <source>PREF_ELEMENTS</source>
         <translation>Elements</translation>
@@ -4567,7 +4636,7 @@ Please, create VTK viewer and try again</translation>
     </message>
     <message>
         <source>PREF_COLOR_0D</source>
-        <translation>0D elements</translation>
+        <translation>0D element color</translation>
     </message>
     <message>
         <source>PREF_SIZE_0D</source>
@@ -4575,7 +4644,11 @@ Please, create VTK viewer and try again</translation>
     </message>
     <message>
         <source>PREF_BALL_COLOR</source>
-        <translation>Balls</translation>
+        <translation>Ball color</translation>
+    </message>
+    <message>
+        <source>PREF_BALL_DIAMETER</source>
+        <translation>Default diameter of ball elements</translation>
     </message>
     <message>
         <source>PREF_BALL_SIZE</source>
@@ -4710,7 +4783,7 @@ Please, create VTK viewer and try again</translation>
     </message>
     <message>
         <source>CREATE_COMMON_GROUPS</source>
-        <translation>Create common groups for initial meshes</translation>
+        <translation>Create groups from input objects</translation>
     </message>
     <message>
         <source>MERGE_NODES_AND_ELEMENTS</source>
@@ -4718,7 +4791,7 @@ Please, create VTK viewer and try again</translation>
     </message>
     <message>
         <source>MESHES</source>
-        <translation>Meshes</translation>
+        <translation>Meshes, sub-meshes, groups</translation>
     </message>
     <message>
         <source>PROCESSING_IDENTICAL_GROUPS</source>
@@ -4829,9 +4902,7 @@ Please, create VTK viewer and try again</translation>
     <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>
+        <translation>Do you want to remove mesh entities generated during preview operation?</translation>
     </message>
     <message>
         <source>SMESH_WRN_NOTHING_PREVIEW</source>
@@ -4839,8 +4910,35 @@ Do you want to remove all these submeshes?</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>
+        <translation>The sub-mesh priority changed during preview operation.
+Do you want to restore original sub-mesh priority?</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_SplitBiQuadDlg</name>
+    <message>
+        <source>CAPTION</source>
+        <translation>Split bi-quadratic into linear</translation>
+    </message>
+    <message>
+        <source>MESH</source>
+        <translation>Mesh, Group or Sub-mesh</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_SplitBiQuadOp</name>
+    <message>
+        <source>MESH_IS_NOT_SELECTED</source>
+        <translation>No object to split is selected.
+Please specify it and try again</translation>
+    </message>
+    <message>
+        <source>REF_IS_NULL</source>
+        <translation>No valid mesh object selected</translation>
+    </message>
+    <message>
+        <source>DIFFERENT_MESHES</source>
+        <translation>Selected objects belong to different meshes</translation>
     </message>
 </context>
 <context>
@@ -4936,7 +5034,7 @@ Please verify validity of entered information</translation>
     </message>
     <message>
         <source>MESH_OR_SUBMESH</source>
-        <translation>Mesh or SubMesh</translation>
+        <translation>Mesh or Sub-mesh</translation>
     </message>
     <message>
         <source>PATTERN</source>
@@ -5024,8 +5122,12 @@ Please select a group and try again</translation>
         <translation>Detect</translation>
     </message>
     <message>
-        <source>EDIT_SELECTED_GROUP</source>
-        <translation>Edit selected group</translation>
+        <source>EDIT_SELECTED_NODE_GROUP</source>
+        <translation>Edit selected group of coincident nodes</translation>
+    </message>
+    <message>
+        <source>EDIT_SELECTED_ELEM_GROUP</source>
+        <translation>Edit selected group of coincident elements</translation>
     </message>
     <message>
         <source>SELECT_ALL</source>
@@ -5041,7 +5143,23 @@ Please select a group and try again</translation>
     </message>
     <message>
         <source>EXCLUDE_GROUPS</source>
-        <translation>Exclude Groups</translation>
+        <translation>Exclude groups from detection</translation>
+    </message>
+    <message>
+        <source>SEPARATE_CORNERS_AND_MEDIUM</source>
+        <translation>No merge of corner and medium nodes of quadratic cells</translation>
+    </message>
+    <message>
+        <source>KEEP_NODES</source>
+        <translation>Nodes to keep during the merge</translation>
+    </message>
+    <message>
+        <source>GROUP_SUBMESH</source>
+        <translation>Groups and sub-meshes</translation>
+    </message>
+    <message>
+        <source>SELECT</source>
+        <translation>Select: </translation>
     </message>
 </context>
 <context>
@@ -5100,7 +5218,7 @@ Please select a group and try again</translation>
     </message>
     <message>
         <source>SMESH_PATH_MESH</source>
-        <translation>Mesh or submesh</translation>
+        <translation>Mesh or sub-mesh</translation>
     </message>
     <message>
         <source>SMESH_PATH_SHAPE</source>
@@ -5141,6 +5259,14 @@ Please select a group and try again</translation>
         <source>EXTRUSION_ALONG_LINE</source>
         <translation>Extrusion along a line</translation>
     </message>
+    <message>
+        <source>BY_AVERAGE_NORMAL</source>
+        <translation>Along average normal</translation>
+    </message>
+    <message>
+        <source>USE_INPUT_ELEMS_ONLY</source>
+        <translation>Use only input elements</translation>
+    </message>
 </context>
 <context>
     <name>SMESHGUI_FilterDlg</name>
@@ -5151,7 +5277,7 @@ Please select valid object and try again</translation>
     </message>
     <message>
         <source>CURRENT_DIALOG</source>
-        <translation>Current Group</translation>
+        <translation>Current Dialog</translation>
     </message>
     <message>
         <source>EDGES_TLT</source>
@@ -5187,7 +5313,7 @@ Please select valid object and try again</translation>
     </message>
     <message>
         <source>SHAPE_IS_NOT_A_CYLINDER</source>
-        <translation>&quot;%1&quot; is not a cylinderical face
+        <translation>&quot;%1&quot; is not a cylindrical face
 Please select a cylindrical face and try again</translation>
     </message>
     <message>
@@ -5405,6 +5531,10 @@ Please check input data and try again</translation>
         <source>OVER_CONSTRAINED_FACE</source>
         <translation>Over-constrained faces</translation>
     </message>
+    <message>
+        <source>BELONG_TO_MESH_GROUP</source>
+        <translation>Belong to Mesh Group</translation>
+    </message>
     <message>
         <source>BELONG_TO_CYLINDER</source>
         <translation>Belong to Cylinder</translation>
@@ -5610,7 +5740,7 @@ Please enter correct value and try again</translation>
     </message>
     <message>
         <source>ELEMENTS</source>
-        <translation>Elements</translation>
+        <translation>All</translation>
     </message>
     <message>
         <source>ENTITY_TYPE</source>
@@ -5798,8 +5928,8 @@ Please specify non-empty name and try again</translation>
 Please specify them and try again</translation>
     </message>
     <message>
-        <source>NAME</source>
-        <translation>Name</translation>
+        <source>RESULT</source>
+        <translation>Result</translation>
     </message>
     <message>
         <source>OBJECT_1</source>
@@ -5811,7 +5941,7 @@ Please specify them and try again</translation>
     </message>
     <message>
         <source>RESULT_NAME</source>
-        <translation>Result name</translation>
+        <translation>Group name</translation>
     </message>
     <message>
         <source>TOOL_OBJECT</source>
@@ -5833,27 +5963,35 @@ Please specify them and try again</translation>
     <name>SMESHGUI_DimGroupDlg</name>
     <message>
         <source>CREATE_GROUP_OF_UNDERLYING_ELEMS</source>
-        <translation>Create group of underlying entities</translation>
+        <translation>Group based on nodes of other groups</translation>
     </message>
     <message>
         <source>ELEMENTS_TYPE</source>
         <translation>Elements type</translation>
     </message>
     <message>
-        <source>NODE</source>
-        <translation>Node</translation>
+        <source>UNDERLYING_ENTITIES_ONLY</source>
+        <translation>Include underlying entities only</translation>
     </message>
     <message>
-        <source>EDGE</source>
-        <translation>Edge</translation>
+        <source>NUMBER_OF_COMMON_NODES</source>
+        <translation>Number of common nodes</translation>
     </message>
     <message>
-        <source>FACE</source>
-        <translation>Face</translation>
+        <source>ALL</source>
+        <translation>All</translation>
     </message>
     <message>
-        <source>VOLUME</source>
-        <translation>Volume</translation>
+        <source>MAIN</source>
+        <translation>Main</translation>
+    </message>
+    <message>
+        <source>AT_LEAST_ONE</source>
+        <translation>At least one</translation>
+    </message>
+    <message>
+        <source>MAJORITY</source>
+        <translation>Majority</translation>
     </message>
 </context>
 <context>
@@ -6014,12 +6152,12 @@ Please specify them and try again</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>
+        <translation>A sub-mesh on the selected geometry already exists.
+ Do you want to edit this sub-mesh?</translation>
     </message>
     <message>
         <source>SUBMESH_NOT_ALLOWED</source>
-        <translation>No sense in creating a submesh ignored by global algorithm &quot;%1&quot;</translation>
+        <translation>No sense in creating a sub-mesh ignored by global algorithm &quot;%1&quot;</translation>
     </message>
     <message>
         <source>GEOMETRY_OBJECT_IS_NOT_DEFINED_MESH</source>
@@ -6088,7 +6226,7 @@ Please enter valid name and try again</translation>
     </message>
     <message>
         <source>NAME_OF_SUBMESH_IS_EMPTY</source>
-        <translation>Name of submesh is empty
+        <translation>Name of sub-mesh is empty
 Please enter valid name and try again</translation>
     </message>
     <message>
@@ -6395,8 +6533,8 @@ It is impossible to read point coordinates from file</translation>
         <translation>Preview</translation>
     </message>
     <message>
-        <source>REVOLUTION_1D</source>
-        <translation>Revolution of 1D elements</translation>
+        <source>REVOLUTION</source>
+        <translation>Revolution</translation>
     </message>
     <message>
         <source>REVOLUTION_2D</source>
@@ -6529,6 +6667,42 @@ It is impossible to read point coordinates from file</translation>
         <source>SIDE_2</source>
         <translation>Side 2</translation>
     </message>
+    <message>
+        <source>AUTO_SEWING</source>
+        <translation>Auto Sewing</translation>
+    </message>
+    <message>
+        <source>COINCIDENT_FREE_BORDERS</source>
+        <translation>Coincident Free Borders</translation>
+    </message>
+    <message>
+        <source>DETECT</source>
+        <translation>Detect</translation>
+    </message>
+    <message>
+        <source>SELECT_ALL</source>
+        <translation>Select all</translation>
+    </message>
+    <message>
+        <source>EDIT_SELECTED_GROUP</source>
+        <translation>Edit Selected Group</translation>
+    </message>
+    <message>
+        <source>STEP</source>
+        <translation>Step</translation>
+    </message>
+    <message>
+        <source>NO_BORDERS_TO_SEW</source>
+        <translation>No free borders to sew found</translation>
+    </message>
+    <message>
+        <source>NOT_ALL_BORDERS_SEWED</source>
+        <translation>%1 of %2 groups of borders sewed</translation>
+    </message>
+    <message>
+        <source>ALL_BORDERS_SEWED</source>
+        <translation>%1 group(s) of borders sewed</translation>
+    </message>
 </context>
 <context>
     <name>SMESHGUI_ShapeByMeshDlg</name>
@@ -6630,14 +6804,14 @@ It is impossible to read point coordinates from file</translation>
     <name>SMESHGUI_MeshOrderDlg</name>
     <message>
         <source>SMESH_MESHORDER_TITLE</source>
-        <translation>Order of submesh in meshing process</translation>
+        <translation>Order of sub-mesh in meshing process</translation>
     </message>
 </context>
 <context>
     <name>SMESHGUI_MeshOrderOp</name>
     <message>
         <source>SMESH_NO_CONCURENT_MESH</source>
-        <translation>No concurent submeshes detected</translation>
+        <translation>No concurent sub-meshes detected</translation>
     </message>
 </context>
 <context>
@@ -7090,6 +7264,10 @@ as they are of improper type:
         <source>GRAVITY_CENTER</source>
         <translation>Gravity Center</translation>
     </message>
+    <message>
+        <source>NORMAL_VECTOR</source>
+        <translation>Normal</translation>
+    </message>
     <message>
         <source>NODE</source>
         <translation>Node</translation>
index 91596f776723c9a9926310d58804c945bdba7e46..69a4022fb0ac4c39418f2aa36006d030769665ef 100755 (executable)
     </message>
     <message>
         <source>MEN_CHOOSE</source>
-        <translation type="unfinished">Choose...</translation>
+        <translation>Choisir...</translation>
     </message>
     <message>
         <source>MEN_EDIT</source>
         <source>MEN_POLYGON</source>
         <translation>Polygone</translation>
     </message>
+    <message>
+        <source>MEN_QUADRATIC_POLYGON</source>
+        <translation>Polygone quadratique</translation>
+    </message>
     <message>
         <source>MEN_POLYHEDRON</source>
         <translation>Polyèdre</translation>
         <source>MEN_SHADE</source>
         <translation>Ombrage</translation>
     </message>
+    <message>
+        <source>MEN_SHOW_SCALAR_BAR</source>
+        <translation>Afficher la barre d'échelle</translation>
+    </message>
     <message>
         <source>MEN_QUADRATIC_REPRESENT</source>
         <translation>Quadratique 2D</translation>
         <source>STB_SPLIT_TO_TETRA</source>
         <translation>Eclater en tétraèdres</translation>
     </message>
+    <message>
+        <source>MEN_SPLIT_BIQUAD</source>
+        <translation>Eclater les éléments bi-quadratiques en éléments linéaires</translation>
+    </message>
+    <message>
+        <source>TOP_SPLIT_BIQUAD</source>
+        <translation>Eclater les éléments bi-quadratiques en éléments linéaires</translation>
+    </message>
+    <message>
+        <source>STB_SPLIT_BIQUAD</source>
+        <translation>Eclater les éléments bi-quadratiques en éléments linéaire</translation>
+    </message>
     <message>
         <source>MESHERS_FILE_CANT_OPEN</source>
         <translation>Impossible d&apos;ouvrir le fichier de ressource</translation>
@@ -1123,8 +1143,13 @@ Choisissez un maillage et essayez de nouveau</translation>
 Indiquez le nom d&apos;un nouveau groupe à créer ou choisissez un groupe existant.</translation>
     </message>
     <message>
-        <source>MESH_STANDALONE_GRP_CHOSEN</source>
+        <source>MESH_GEOM_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>MESH_FILTER_GRP_CHOSEN</source>
+        <translation>Un groupe lié à un filtre est choisi: %1.
 Voulez-vous le convertir en un groupe autonome ?</translation>
     </message>
     <message>
@@ -1221,6 +1246,14 @@ Merci de les corriger, puis essayez de nouveau</translation>
         <source>SMESH_ADD_POLYGON_TITLE</source>
         <translation>Ajouter un polygone</translation>
     </message>
+    <message>
+        <source>SMESH_ADD_QUADRATIC_POLYGON</source>
+        <translation>Ajouter un polygone quadratique</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_QUADRATIC_POLYGON_TITLE</source>
+        <translation>Ajouter un polygone quadratique</translation>
+    </message>
     <message>
         <source>SMESH_ADD_PENTA</source>
         <translation>Ajouter un pentaèdre</translation>
@@ -1693,6 +1726,10 @@ Voulez-vous continuer ?</translation>
         <source>SMESH_EXTRUSION_ALONG_VECTOR</source>
         <translation>Extrusion le long du vecteur</translation>
     </message>
+    <message>
+        <source>SMESH_EXTRUSION_BY_NORMAL</source>
+        <translation>Extrusion par la normale</translation>
+    </message>
     <message>
         <source>SMESH_FACE</source>
         <translation>Face</translation>
@@ -1852,6 +1889,10 @@ Référez-vous à la documentation sur l&apos;algorithme et la géométrie suppo
         <source>SMESH_ID_DIAGONAL</source>
         <translation>IDs des arêtes</translation>
     </message>
+    <message>
+        <source>SMESH_ID_EDGES</source>
+        <translation>IDs des arêtes</translation>
+    </message>
     <message>
         <source>SMESH_ID_ELEMENTS</source>
         <translation>IDs des éléments</translation>
@@ -2164,6 +2205,10 @@ Référez-vous à la documentation sur l&apos;algorithme et la géométrie suppo
         <source>SMESH_OBJECT_MESH</source>
         <translation>Maillage</translation>
     </message>
+    <message>
+        <source>SMESH_OBJECTS</source>
+        <translation>Objets</translation>
+    </message>
     <message>
         <source>SMESH_OBJECT_MESHorSUBMESH</source>
         <translation>Maillage ou sous-maillage</translation>
@@ -2310,7 +2355,7 @@ Référez-vous à la documentation sur l&apos;algorithme et la géométrie suppo
     </message>
     <message>
         <source>PREF_NUMBERING_ELEM</source>
-        <translation>Arêtes: couleur</translation>
+        <translation>Éléments: couleur</translation>
     </message>
     <message>
         <source>PREF_NUMBERING_FONT</source>
@@ -2573,6 +2618,10 @@ Référez-vous à la documentation sur l&apos;algorithme et la géométrie suppo
         <source>SMESH_SEWING</source>
         <translation>Couture</translation>
     </message>
+    <message>
+        <source>SMESH_SHOW_SCALAR_BAR</source>
+        <translation>Afficher la barre d'échelle</translation>
+    </message>
     <message>
         <source>SMESH_SMOOTHING</source>
         <translation>Lissage</translation>
@@ -3209,6 +3258,10 @@ Utilisez le menu &quot;Visualiser une entité&quot; pour les afficher.
         <source>STB_POLYGON</source>
         <translation>Polygone</translation>
     </message>
+    <message>
+        <source>STB_QUADRATIC_POLYGON</source>
+        <translation>Polygone quadratique</translation>
+    </message>
     <message>
         <source>STB_POLYHEDRON</source>
         <translation>Polyèdre</translation>
@@ -3285,6 +3338,10 @@ Utilisez le menu &quot;Visualiser une entité&quot; pour les afficher.
         <source>STB_SHOW_DISTRIBUTION</source>
         <translation>Afficher la distribution</translation>
     </message>
+    <message>
+        <source>STB_SHOW_SCALAR_BAR</source>
+        <translation>Afficher la barre d'échelle</translation>
+    </message>
     <message>
         <source>STB_REVOLUTION</source>
         <translation>Révolution</translation>
@@ -3861,6 +3918,10 @@ Utilisez le menu &quot;Visualiser une entité&quot; pour les afficher.
         <source>TOP_POLYGON</source>
         <translation>Polygone</translation>
     </message>
+    <message>
+        <source>TOP_QUADRATIC_POLYGON</source>
+        <translation>Polygone quadratique</translation>
+    </message>
     <message>
         <source>TOP_POLYHEDRON</source>
         <translation>Polyèdre</translation>
@@ -4240,15 +4301,19 @@ Il ne peut pas être supprimé.</translation>
     <name>SMESHGUI_Dialog</name>
     <message>
         <source>DLG_MESH</source>
-        <translation>maillages</translation>
+        <translation>maillage(s)</translation>
     </message>
     <message>
         <source>DLG_HYPO</source>
-        <translation>hypothèses</translation>
+        <translation>hypothèse(s)</translation>
     </message>
     <message>
         <source>DLG_ALGO</source>
-        <translation>algorithmes</translation>
+        <translation>algorithme(s)</translation>
+    </message>
+    <message>
+        <source>DLG_GEOM</source>
+        <translation>objet(s)</translation>
     </message>
 </context>
 <context>
@@ -4342,6 +4407,10 @@ Ouvrez une fenêtre VTK et essayez de nouveau</translation>
         <source>PREF_DISPLAY_ENTITY</source>
         <translation>Eléments à visualiser</translation>
     </message>
+    <message>
+        <source>QUADRATIC_REPRESENT_MODE_GROUP</source>
+        <translation>Mode des éléments quadratiques 2D par défaut</translation>
+    </message>
     <message>
         <source>QUADRATIC_REPRESENT_MODE</source>
         <translation>Représentation des éléments quadratiques 2D</translation>
@@ -4351,9 +4420,13 @@ Ouvrez une fenêtre VTK et essayez de nouveau</translation>
         <translation>Angle maximal</translation>
     </message>
     <message>
-        <source>PREF_DISPLAY_MODE</source>
+        <source>PREF_DISPLAY_MODE_GROUP</source>
         <translation>Mode de visualisation</translation>
     </message>
+    <message>
+        <source>PREF_DISPLAY_MODE</source>
+        <translation>Mode de visualisation par défaut</translation>
+    </message>
     <message>
         <source>PREF_ELEMENTS</source>
         <translation>Eléments</translation>
@@ -4564,7 +4637,7 @@ Ouvrez une fenêtre VTK et essayez de nouveau</translation>
     </message>
     <message>
         <source>PREF_COLOR_0D</source>
-        <translation>Eléments 0D</translation>
+        <translation>Couleur d&apos;elément 0D</translation>
     </message>
     <message>
         <source>PREF_SIZE_0D</source>
@@ -4572,7 +4645,11 @@ Ouvrez une fenêtre VTK et essayez de nouveau</translation>
     </message>
     <message>
         <source>PREF_BALL_COLOR</source>
-        <translation>Particulaires</translation>
+        <translation>Couleur des particulaires</translation>
+    </message>
+    <message>
+        <source>PREF_BALL_DIAMETER</source>
+        <translation>Diamètre par défaut des éléments particulaires</translation>
     </message>
     <message>
         <source>PREF_BALL_SIZE</source>
@@ -4840,6 +4917,33 @@ Voulez-vous supprimer toutes ces sous-maillages ?</translation>
 Voulez-vous restaurer la priorité initiale ?</translation>
     </message>
 </context>
+<context>
+    <name>SMESHGUI_SplitBiQuadDlg</name>
+    <message>
+        <source>CAPTION</source>
+        <translation>Eclater les éléments bi-quadratiques en éléments linéaires</translation>
+    </message>
+    <message>
+        <source>MESH</source>
+        <translation>Maillage, groupe ou sous-maillage</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_SplitBiQuadOp</name>
+    <message>
+        <source>MESH_IS_NOT_SELECTED</source>
+        <translation>Pas d'éléments à éclater.
+Sélectionner des éléments et essayer encore</translation>
+    </message>
+    <message>
+        <source>REF_IS_NULL</source>
+        <translation>Aucun maillage valide n'a été sélectionné</translation>
+    </message>
+    <message>
+        <source>DIFFERENT_MESHES</source>
+        <translation>Les éléments sélectionnés appartiennent à différents maillages</translation>
+    </message>
+</context>
 <context>
     <name>SMESHGUI_ConvToQuadDlg</name>
     <message>
@@ -5021,8 +5125,12 @@ Choisissez un groupe et essayez de nouveau</translation>
         <translation>Détecter</translation>
     </message>
     <message>
-        <source>EDIT_SELECTED_GROUP</source>
-        <translation>Editer le groupe sélectionné</translation>
+        <source>EDIT_SELECTED_NODE_GROUP</source>
+        <translation>Editer le groupe sélectionné de noeuds coïncidents</translation>
+    </message>
+    <message>
+        <source>EDIT_SELECTED_ELEM_GROUP</source>
+        <translation>Editer le groupe sélectionné d'éléments coïncidents</translation>
     </message>
     <message>
         <source>SELECT_ALL</source>
@@ -5038,7 +5146,23 @@ Choisissez un groupe et essayez de nouveau</translation>
     </message>
     <message>
         <source>EXCLUDE_GROUPS</source>
-        <translation>Exclure les groupes</translation>
+        <translation>Exclure les groupes de la détection</translation>
+    </message>
+    <message>
+        <source>SEPARATE_CORNERS_AND_MEDIUM</source>
+        <translation>Pas de fusion du coin et des noeuds moyens des cellules quadratiques</translation>
+    </message>
+    <message>
+        <source>KEEP_NODES</source>
+        <translation>Les noeuds à conserver pendant la fusion</translation>
+    </message>
+    <message>
+        <source>GROUP_SUBMESH</source>
+        <translation>Groupes et sous-maillages</translation>
+    </message>
+    <message>
+        <source>SELECT</source>
+        <translation>Selectionner: </translation>
     </message>
 </context>
 <context>
@@ -5138,6 +5262,14 @@ Choisissez un groupe et essayez de nouveau</translation>
         <source>EXTRUSION_ALONG_LINE</source>
         <translation>Extrusion suivant une ligne</translation>
     </message>
+    <message>
+        <source>BY_AVERAGE_NORMAL</source>
+        <translation>Suivant une normale moyenne</translation>
+    </message>
+    <message>
+        <source>USE_INPUT_ELEMS_ONLY</source>
+        <translation>Use only input elements</translation>
+    </message>
 </context>
 <context>
     <name>SMESHGUI_FilterDlg</name>
@@ -5402,6 +5534,10 @@ Vérifiez la validité des informations données</translation>
         <source>OVER_CONSTRAINED_FACE</source>
         <translation>Faces sur-contraintes</translation>
     </message>
+    <message>
+        <source>BELONG_TO_MESH_GROUP</source>
+        <translation>Appartient au groupe du maillage</translation>
+    </message>
     <message>
         <source>BELONG_TO_CYLINDER</source>
         <translation>Appartient au cylindre</translation>
@@ -5795,8 +5931,8 @@ Indiquez un nom non-vide et essayez de nouveau</translation>
 Indiquez-les et essayez de nouveau</translation>
     </message>
     <message>
-        <source>NAME</source>
-        <translation>Nom</translation>
+        <source>RESULT</source>
+        <translation>Résultat</translation>
     </message>
     <message>
         <source>OBJECT_1</source>
@@ -5837,20 +5973,28 @@ Indiquez-les et essayez de nouveau</translation>
         <translation>Type d&apos;éléments </translation>
     </message>
     <message>
-        <source>NODE</source>
-        <translation>Nœud</translation>
+        <source>UNDERLYING_ENTITIES_ONLY</source>
+        <translation>Inclure les entités sous-jacentes uniquement</translation>
     </message>
     <message>
-        <source>EDGE</source>
-        <translation>Arête</translation>
+        <source>NUMBER_OF_COMMON_NODES</source>
+        <translation>Nombre de nœuds en commun</translation>
     </message>
     <message>
-        <source>FACE</source>
-        <translation>Face</translation>
+        <source>ALL</source>
+        <translation>Tout</translation>
     </message>
     <message>
-        <source>VOLUME</source>
-        <translation>Volume</translation>
+        <source>MAIN</source>
+        <translation>Principal</translation>
+    </message>
+    <message>
+        <source>AT_LEAST_ONE</source>
+        <translation>Au moins un</translation>
+    </message>
+    <message>
+        <source>MAJORITY</source>
+        <translation>La majorité</translation>
     </message>
 </context>
 <context>
@@ -6019,10 +6163,15 @@ Voulez-vous éditer ce sous-maillage?</translation>
         <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>
+        <source>GEOMETRY_OBJECT_IS_NOT_DEFINED_MESH</source>
         <translation>La géométrie n&apos;est pas définie.
 Voulez-vous créer un maillage vide
 sans algorithme ni hypothèse ? </translation>
+    </message>
+    <message>
+        <source>GEOMETRY_OBJECT_IS_NOT_DEFINED_SUBMESH</source>
+        <translation>L&apos;objet géométrique n&apos;est pas défini.
+Merci de le spécifier et essayer de nouveau</translation>
     </message>
     <message>
         <source>GEOMETRY_OBJECT_IS_NULL</source>
@@ -6088,6 +6237,14 @@ Indiquez un nom valide et essayez de nouveau</translation>
         <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>
+    <message>
+        <source>CONCURRENT_SUBMESH_APPEARS</source>
+        <translation> 
+L&apos;algorithme assigné a la même priorité que celui assigné à un
+sous-maillage adjacent; ainsi l'algorithme à utiliser pour mailler la
+frontière partagée par les deux sous-maillages n&apos;est pas défini.
+Voulez-vous définir l&apos;ordre de calcul des sous-maillages ?</translation>
+    </message>
 </context>
 <context>
     <name>SMESHGUI_MeshPatternDlg</name>
@@ -6250,6 +6407,14 @@ Il y a trop peu de points dans le fichier </translation>
         <source>NONE</source>
         <translation>&lt;None&gt;</translation>
     </message>
+    <message>
+        <source>DEFAULT</source>
+        <translation>&lt;Défaut&gt;</translation>
+    </message>
+    <message>
+        <source>SELECT</source>
+        <translation>&lt;Sélectionner&gt;</translation>
+    </message>
 </context>
 <context>
     <name>SMESHGUI_MultiEditDlg</name>
@@ -6371,7 +6536,7 @@ Il y a trop peu de points dans le fichier </translation>
         <translation>Prévisualiser</translation>
     </message>
     <message>
-        <source>REVOLUTION_1D</source>
+        <source>REVOLUTION</source>
         <translation>Révolution des éléments 1D</translation>
     </message>
     <message>
@@ -6505,6 +6670,42 @@ Il y a trop peu de points dans le fichier </translation>
         <source>SIDE_2</source>
         <translation>Bord 2</translation>
     </message>
+    <message>
+        <source>AUTO_SEWING</source>
+        <translation>Couture automatique</translation>
+    </message>
+    <message>
+        <source>COINCIDENT_FREE_BORDERS</source>
+        <translation>Frontières libres coïncidentes</translation>
+    </message>
+    <message>
+        <source>DETECT</source>
+        <translation>Détecter</translation>
+    </message>
+    <message>
+        <source>SELECT_ALL</source>
+        <translation>Sélectionner tous</translation>
+    </message>
+    <message>
+        <source>EDIT_SELECTED_GROUP</source>
+        <translation>Editer le groupe sélectionné</translation>
+    </message>
+    <message>
+        <source>STEP</source>
+        <translation>Pas</translation>
+    </message>
+    <message>
+        <source>NO_BORDERS_TO_SEW</source>
+        <translation>Pas de frontière libre à coudre</translation>
+    </message>
+    <message>
+        <source>NOT_ALL_BORDERS_SEWED</source>
+        <translation>%1 groupes sur %2 de frontières cousus</translation>
+    </message>
+    <message>
+        <source>ALL_BORDERS_SEWED</source>
+        <translation>%1 groupe(s) de frontières cousu(s)</translation>
+    </message>
 </context>
 <context>
     <name>SMESHGUI_ShapeByMeshDlg</name>
@@ -6737,6 +6938,10 @@ Il y a trop peu de points dans le fichier </translation>
         <source>DUPLICATION_ONLY_ELEMS</source>
         <translation>Avec duplication des éléments de frontière seulement</translation>
     </message>
+    <message>
+        <source>DUPLICATION_GROUP_BOUNDARY</source>
+        <translation>Avec duplication des nœuds des groupes de frontière</translation>
+    </message>
     <message>
         <source>GROUP_ELEMS_TO_DUPLICATE</source>
         <translation>Groupe des éléments à dupliquer</translation>
@@ -6761,6 +6966,14 @@ Il y a trop peu de points dans le fichier </translation>
         <source>CONSTRUCT_NEW_GROUP_ELEMENTS</source>
         <translation>Construire un groupe avec les éléments nouvellement créés</translation>
     </message>
+    <message>
+        <source>CREATE_JOINT_ELEMENTS</source>
+        <translation>Créer des éléments de joint</translation>
+    </message>
+    <message>
+        <source>ON_ALL_BOUNDARIES</source>
+        <translation>Sur toutes les frontières</translation>
+    </message>
 </context>
 <context>
     <name>SMESHGUI_Make2DFrom3DDlg</name>
@@ -7044,15 +7257,19 @@ en raison de leurs types incompatibles:
     </message>
     <message>
         <source>COORDINATES</source>
-        <translation>COORDONNÉES</translation>
+        <translation>Coordonnées</translation>
     </message>
     <message>
         <source>CONNECTIVITY</source>
-        <translation>CONNECTIVITÉ</translation>
+        <translation>Connectivité</translation>
     </message>
     <message>
         <source>GRAVITY_CENTER</source>
-        <translation>CENTRE DE GRAVITÉ</translation>
+        <translation>Centre de gravité</translation>
+    </message>
+    <message>
+        <source>NORMAL_VECTOR</source>
+        <translation>Normal</translation>
     </message>
     <message>
         <source>NODE</source>
@@ -7060,43 +7277,43 @@ en raison de leurs types incompatibles:
     </message>
     <message>
         <source>0D_ELEMENT</source>
-        <translation>ELÉMENTS 0D</translation>
+        <translation>Eléments 0d</translation>
     </message>
     <message>
         <source>0D_ELEMENTS</source>
-        <translation>ELÉMENTS 0D</translation>
+        <translation>Eléments 0d</translation>
     </message>
     <message>
         <source>BALL_ELEMENT</source>
-        <translation>ELEMENT PARTICULAIRE</translation>
+        <translation>Elément particulaire</translation>
     </message>
     <message>
         <source>BALL_ELEMENTS</source>
-        <translation>ELEMENTS PARTICULAIRES</translation>
+        <translation>Eléments particulaires</translation>
     </message>
     <message>
         <source>EDGE</source>
-        <translation>ARÊTE</translation>
+        <translation>Arête</translation>
     </message>
     <message>
         <source>EDGES</source>
-        <translation>ARÊTES</translation>
+        <translation>Arêtes</translation>
     </message>
     <message>
         <source>FACE</source>
-        <translation>FACE</translation>
+        <translation>Face</translation>
     </message>
     <message>
         <source>FACES</source>
-        <translation>FACES</translation>
+        <translation>Faces</translation>
     </message>
     <message>
         <source>VOLUME</source>
-        <translation>VOLUME</translation>
+        <translation>Volume</translation>
     </message>
     <message>
         <source>VOLUMES</source>
-        <translation>VOLUMES</translation>
+        <translation>Volumes</translation>
     </message>
     <message>
         <source>FREE_NODE</source>
@@ -7104,7 +7321,7 @@ en raison de leurs types incompatibles:
     </message>
     <message>
         <source>TYPE</source>
-        <translation>TYPE</translation>
+        <translation>Type</translation>
     </message>
     <message>
         <source>TRIANGLE</source>
@@ -7144,7 +7361,7 @@ en raison de leurs types incompatibles:
     </message>
     <message>
         <source>QUADRATIC</source>
-        <translation>QUADRATIQUE</translation>
+        <translation>Quadratique</translation>
     </message>
     <message>
         <source>YES</source>
@@ -7654,6 +7871,14 @@ en raison de leurs types incompatibles:
         <source>ORIENTATION</source>
         <translation>Orientation</translation>
     </message>
+    <message>
+        <source>VOLUMES</source>
+        <translation>Volumes</translation>
+    </message>
+    <message>
+        <source>OUTSIDE_VOLUME_NORMAL</source>
+        <translation>Normale de face en dehors du volume</translation>
+    </message>
 </context>
 <context>
     <name>SMESHGUI_ReorientFacesOp</name>
@@ -7661,10 +7886,18 @@ en raison de leurs types incompatibles:
         <source>NO_OBJECT_SELECTED</source>
         <translation>Aucun objet sélectionné</translation>
     </message>
+    <message>
+        <source>NO_VOLUME_OBJECT_SELECTED</source>
+        <translation>Aucun objet de volume sélectionné</translation>
+    </message>
     <message>
         <source>NO_FACES</source>
         <translation>L&apos;objet ne contient pas de faces</translation>
     </message>
+    <message>
+        <source>NO_VOLUMES</source>
+        <translation>L&apos;objet ne contient pas de volumes</translation>
+    </message>
     <message>
         <source>ZERO_SIZE_VECTOR</source>
         <translation>Vecteur de taille nulle</translation>
@@ -7761,7 +7994,7 @@ en raison de leurs types incompatibles:
     <name>SMESHGUI_DisplayEntitiesDlg</name>
     <message>
         <source>WRN_AT_LEAST_ONE</source>
-        <translation type="unfinished">At least one entity type should be chosen!</translation>
+        <translation>Au moins une entité devrait être choisie!</translation>
     </message>
 </context>
 </TS>
index 0332875cf11e700125f20139a3edf7302555e2e2..6b71493f4143573c303beb5919e265fc70d90bd7 100644 (file)
     </message>
     <message>
       <source>MEN_ASPECT</source>
-      <translation>ã\83¬ã\83\9dã\83¼ã\83\88 ã\83\95ã\82©ã\83¼ã\83 </translation>
+      <translation>ã\82¢ã\82¹ã\83\9aã\82¯ã\83\88æ¯\94</translation>
     </message>
     <message>
       <source>MEN_ASPECT_3D</source>
-      <translation>レポートの 3 D を形成</translation>
+      <translation>3Dアスペクト比</translation>
     </message>
     <message>
       <source>MEN_AUTO_COLOR</source>
       <translation>エッジ</translation>
     </message>
     <message>
-        <source>MEN_CHOOSE</source>
-        <translation type="unfinished">Choose...</translation>
+      <source>MEN_CHOOSE</source>
+      <translation>選択...</translation>
     </message>
     <message>
       <source>MEN_EDIT</source>
     </message>
     <message>
       <source>MEN_EXTRUSION</source>
-      <translation>Extrusion</translation>
+      <translation>押出し</translation>
     </message>
     <message>
       <source>MEN_EXTRUSION_ALONG</source>
     </message>
     <message>
       <source>MEN_EQUAL_NODE</source>
-      <translation>äº\8cé\87\8dã\83\8eã\83\83ã\83\88</translation>
+      <translation>äº\8cé\87\8dã\83\8eã\83¼ã\83\89</translation>
     </message>
     <message>
       <source>STB_EQUAL_NODE</source>
       <source>MEN_POLYGON</source>
       <translation>多角形</translation>
     </message>
+    <message>
+      <source>MEN_QUADRATIC_POLYGON</source>
+      <translation>2次ポリゴン</translation>
+    </message>
     <message>
       <source>MEN_POLYHEDRON</source>
       <translation>多面体</translation>
     </message>
     <message>
       <source>MEN_REVOLUTION</source>
-      <translation>Revolution</translation>
+      <translation>回転</translation>
     </message>
     <message>
       <source>MEN_ROT</source>
       <source>MEN_SHADE</source>
       <translation>網かけ</translation>
     </message>
+    <message>
+      <source>MEN_SHOW_SCALAR_BAR</source>
+      <translation>スカラバーの表示</translation>
+    </message>
     <message>
       <source>MEN_QUADRATIC_REPRESENT</source>
       <translation>二次 2D</translation>
     </message>
     <message>
       <source>MEN_TAPER</source>
-      <translation>Cone</translation>
+      <translation>抜き勾配</translation>
     </message>
     <message>
       <source>MEN_TETRA</source>
       <source>STB_SPLIT_TO_TETRA</source>
       <translation>四面体を爆発します。</translation>
     </message>
+    <message>
+      <source>MEN_SPLIT_BIQUAD</source>
+      <translation>線形に2次分割</translation>
+    </message>
+    <message>
+      <source>TOP_SPLIT_BIQUAD</source>
+      <translation>線形に2次分割</translation>
+    </message>
+    <message>
+      <source>STB_SPLIT_BIQUAD</source>
+      <translation>線形に2次分割</translation>
+    </message>
     <message>
       <source>MESHERS_FILE_CANT_OPEN</source>
       <translation>リソース ファイルを開くことができません。</translation>
       <translation>グループ名は表示されません。作成または既存のグループを選択して新しいグループの名前を指定します。</translation>
     </message>
     <message>
-      <source>MESH_STANDALONE_GRP_CHOSEN</source>
-      <translation>ジオメトリにリンクされているグループが選択されている: %1。スタンドアロン アレイに変換しますか。</translation>
+      <source>MESH_GEOM_GRP_CHOSEN</source>
+      <translation>ジオメトリグループは次のように選択されています: %1 それをスタンドアロングループに変換したいですか?</translation>
+    </message>
+    <message>
+      <source>MESH_FILTER_GRP_CHOSEN</source>
+      <translation>フィルタ上のグループは次のように選択されています: %1 それをスタンドアロングループに変換したいですか?</translation>
     </message>
     <message>
       <source>NODE_ID</source>
       <source>SMESH_ADD_POLYGON_TITLE</source>
       <translation>多角形を追加します。</translation>
     </message>
+    <message>
+      <source>SMESH_ADD_QUADRATIC_POLYGON</source>
+      <translation>2次ポリゴンの追加</translation>
+    </message>
+    <message>
+      <source>SMESH_ADD_QUADRATIC_POLYGON_TITLE</source>
+      <translation>2次ポリゴンの追加</translation>
+    </message>
     <message>
       <source>SMESH_ADD_PENTA</source>
       <translation>くさびを追加します。</translation>
       <source>SMESH_EXTRUSION_ALONG_VECTOR</source>
       <translation>押出、ベクトルに沿って</translation>
     </message>
+    <message>
+      <source>SMESH_EXTRUSION_BY_NORMAL</source>
+      <translation>標準押出</translation>
+    </message>
     <message>
       <source>SMESH_FACE</source>
       <translation>Face</translation>
       <translation>このようなディメンションの前提がジオメトリに既に割り当てられています。</translation>
     </message>
     <message>
-      <source>SMESH_ID_DIAGONAL</source>
-      <translation>エッジの Id</translation>
+      <source>SMESH_ID_EDGES</source>
+      <translation>エッジID</translation>
     </message>
     <message>
       <source>SMESH_ID_ELEMENTS</source>
       <source>SMESH_OBJECT_MESH</source>
       <translation>Mesh</translation>
     </message>
+    <message>
+      <source>SMESH_OBJECTS</source>
+      <translation>オブジェクト</translation>
+    </message>
     <message>
       <source>SMESH_OBJECT_MESHorSUBMESH</source>
       <translation>メッシュまたはサブメッシュ</translation>
       <source>SMESH_SEWING</source>
       <translation>つなぎ合わせ</translation>
     </message>
+    <message>
+      <source>SMESH_SHOW_SCALAR_BAR</source>
+      <translation>スカラバーの表示</translation>
+    </message>
     <message>
       <source>SMESH_SMOOTHING</source>
       <translation>スムージング</translation>
       <source>STB_POLYGON</source>
       <translation>多角形</translation>
     </message>
+    <message>
+      <source>STB_QUADRATIC_POLYGON</source>
+      <translation>2次ポリゴン</translation>
+    </message>
     <message>
       <source>STB_POLYHEDRON</source>
       <translation>多面体</translation>
       <source>STB_SHOW</source>
       <translation>表示</translation>
     </message>
+    <message>
+      <source>STB_SHOW_SCALAR_BAR</source>
+      <translation>スカラバーの表示</translation>
+    </message>
     <message>
       <source>STB_SHRINK</source>
       <translation>収縮</translation>
       <source>TOP_POLYGON</source>
       <translation>多角形</translation>
     </message>
+    <message>
+      <source>TOP_QUADRATIC_POLYGON</source>
+      <translation>2次ポリゴン</translation>
+    </message>
     <message>
       <source>TOP_POLYHEDRON</source>
       <translation>多面体</translation>
       <source>PREF_DISPLAY_ENTITY</source>
       <translation>表示する項目</translation>
     </message>
+    <message>
+      <source>QUADRATIC_REPRESENT_MODE_GROUP</source>
+      <translation>2D二次要素の表現</translation>
+    </message>
     <message>
       <source>QUADRATIC_REPRESENT_MODE</source>
       <translation>2 D の 2 次要素の表現</translation>
       <source>MAX_ARC_ANGLE</source>
       <translation>最大角度</translation>
     </message>
+    <message>
+      <source>PREF_DISPLAY_MODE_GROUP</source>
+      <translation>表示モード</translation>
+    </message>
     <message>
       <source>PREF_DISPLAY_MODE</source>
       <translation>表示モード</translation>
       <source>PREF_BALL_COLOR</source>
       <translation>粒子</translation>
     </message>
+    <message>
+      <source>PREF_BALL_DIAMETER</source>
+      <translation>ボール要素のデフォルト直径</translation>
+    </message>
     <message>
       <source>PREF_BALL_SIZE</source>
       <translation>粒子状のコンポーネントのサイズ</translation>
     <name>SMESHGUI_AddQuadraticElementDlg</name>
     <message>
       <source>SMESH_ADD_QUADRATIC_EDGE</source>
-      <translation>正方形のエッジを追加します。</translation>
+      <translation>2次エッジの追加</translation>
     </message>
     <message>
       <source>SMESH_ADD_QUADRATIC_HEXAHEDRON</source>
     </message>
     <message>
       <source>SMESH_ADD_QUADRATIC_PYRAMID</source>
-      <translation>四角錐を追加します。</translation>
+      <translation>二次ピラミッドの追加</translation>
     </message>
     <message>
       <source>SMESH_ADD_QUADRATIC_QUADRANGLE</source>
       <translation>サブメッシュの優先順位は、プレビュー時に変更されました。初期の優先度を復元しますか。</translation>
     </message>
   </context>
+  <context>
+    <name>SMESHGUI_SplitBiQuadDlg</name>
+    <message>
+      <source>CAPTION</source>
+      <translation>線形に2次分割</translation>
+    </message>
+    <message>
+      <source>MESH</source>
+      <translation>メッシュ、グループ、あるいはサブメッシュ</translation>
+    </message>
+  </context>
+  <context>
+    <name>SMESHGUI_SplitBiQuadOp</name>
+    <message>
+      <source>MESH_IS_NOT_SELECTED</source>
+      <translation>分割のためのオブジェクトは選択されていません。オブジェクトを指定してから再試行してください。</translation>
+    </message>
+    <message>
+      <source>REF_IS_NULL</source>
+      <translation>有効なメッシュオブジェクトは選択されていません</translation>
+    </message>
+    <message>
+      <source>DIFFERENT_MESHES</source>
+      <translation>異なるメッシュに属したオブジェクトが選択されています</translation>
+    </message>
+  </context>
   <context>
     <name>SMESHGUI_ConvToQuadDlg</name>
     <message>
       <source>EXCLUDE_GROUPS</source>
       <translation>グループを除外</translation>
     </message>
+    <message>
+      <source>SEPARATE_CORNERS_AND_MEDIUM</source>
+      <translation>2次セルのコーナ節点と中間節点をマージできません</translation>
+    </message>
+    <message>
+      <source>KEEP_NODES</source>
+      <translation>維持節点</translation>
+    </message>
+    <message>
+      <source>GROUP_SUBMESH</source>
+      <translation>グループとサブメッシュ</translation>
+    </message>
+    <message>
+      <source>SELECT</source>
+      <translation>Select: </translation>
+    </message>
   </context>
   <context>
     <name>SMESHGUI_ExtrusionAlongPathDlg</name>
       <source>EXTRUSION_ALONG_LINE</source>
       <translation>線に沿った押出し</translation>
     </message>
+    <message>
+      <source>BY_AVERAGE_NORMAL</source>
+      <translation>平均標準に従う</translation>
+    </message>
+    <message>
+      <source>USE_INPUT_ELEMS_ONLY</source>
+      <translation>入力要素のみ使用</translation>
+    </message>
   </context>
   <context>
     <name>SMESHGUI_FilterDlg</name>
       <source>OVER_CONSTRAINED_FACE</source>
       <translation>制約が多すぎるフェース</translation>
     </message>
+    <message>
+      <source>BELONG_TO_MESH_GROUP</source>
+      <translation>メッシュグループに所属</translation>
+    </message>
     <message>
       <source>BELONG_TO_CYLINDER</source>
       <translation>円筒に属する</translation>
       <translation>操作の引数されていないそれらを入力し、もう一度やり直してください</translation>
     </message>
     <message>
-      <source>NAME</source>
-      <translation>名前</translation>
+      <source>RESULT</source>
+      <translation>結果</translation>
     </message>
     <message>
       <source>OBJECT_1</source>
       <translation>要素の型</translation>
     </message>
     <message>
-      <source>NODE</source>
-      <translation>ノード</translation>
+      <source>UNDERLYING_ENTITIES_ONLY</source>
+      <translation>基本的なエンティティのみを含める</translation>
     </message>
     <message>
-      <source>EDGE</source>
-      <translation>Edge</translation>
+      <source>NUMBER_OF_COMMON_NODES</source>
+      <translation>共通節点数</translation>
     </message>
     <message>
-      <source>FACE</source>
-      <translation>Face</translation>
+      <source>ALL</source>
+      <translation>すべて</translation>
     </message>
     <message>
-      <source>VOLUME</source>
-      <translation>ボリューム</translation>
+      <source>MAIN</source>
+      <translation>メイン</translation>
+    </message>
+    <message>
+      <source>AT_LEAST_ONE</source>
+      <translation>少なくともひとつ</translation>
+    </message>
+    <message>
+      <source>MAJORITY</source>
+      <translation>多数</translation>
     </message>
   </context>
   <context>
       <translation>プレビュー</translation>
     </message>
     <message>
-      <source>REVOLUTION_1D</source>
-      <translation>1 D 要素の革命</translation>
+      <source>REVOLUTION</source>
+      <translation>回転押出</translation>
     </message>
     <message>
       <source>REVOLUTION_2D</source>
       <source>SIDE_2</source>
       <translation>エッジ 2</translation>
     </message>
+    <message>
+      <source>AUTO_SEWING</source>
+      <translation>自動縫合</translation>
+    </message>
+    <message>
+      <source>COINCIDENT_FREE_BORDERS</source>
+      <translation>一致フリー境界</translation>
+    </message>
+    <message>
+      <source>DETECT</source>
+      <translation>検出</translation>
+    </message>
+    <message>
+      <source>SELECT_ALL</source>
+      <translation>すべてを選択</translation>
+    </message>
+    <message>
+      <source>EDIT_SELECTED_GROUP</source>
+      <translation>選択グループを編集</translation>
+    </message>
+    <message>
+      <source>STEP</source>
+      <translation>Step</translation>
+    </message>
+    <message>
+      <source>NO_BORDERS_TO_SEW</source>
+      <translation>縫合できるフリー境界はみつかりません</translation>
+    </message>
+    <message>
+      <source>NOT_ALL_BORDERS_SEWED</source>
+      <translation>境界の %2 グループの%1を縫合しました</translation>
+    </message>
+    <message>
+      <source>ALL_BORDERS_SEWED</source>
+      <translation>境界の %1 グループを縫合しました。</translation>
+    </message>
   </context>
   <context>
     <name>SMESHGUI_ShapeByMeshDlg</name>
       <source>GRAVITY_CENTER</source>
       <translation>重心</translation>
     </message>
+    <message>
+      <source>NORMAL_VECTOR</source>
+      <translation>標準</translation>
+    </message>
     <message>
       <source>NODE</source>
       <translation>ノード</translation>
       <source>ORIENTATION</source>
       <translation>方向</translation>
     </message>
+    <message>
+      <source>VOLUMES</source>
+      <translation>ボリューム</translation>
+    </message>
+    <message>
+      <source>OUTSIDE_VOLUME_NORMAL</source>
+      <translation>標準外側ボリュームに面する</translation>
+    </message>
   </context>
   <context>
     <name>SMESHGUI_ReorientFacesOp</name>
       <source>NO_OBJECT_SELECTED</source>
       <translation>選択したオブジェクトがありません。</translation>
     </message>
+    <message>
+      <source>NO_VOLUME_OBJECT_SELECTED</source>
+      <translation>選択されたボリュームオブジェクトはありません</translation>
+    </message>
     <message>
       <source>NO_FACES</source>
       <translation>オブジェクトに顔が含まれていません。</translation>
     </message>
+    <message>
+      <source>NO_VOLUMES</source>
+      <translation>ボリュームオブジェクトはボリュームを含んでいません</translation>
+    </message>
     <message>
       <source>ZERO_SIZE_VECTOR</source>
       <translation>サイズがゼロのベクター</translation>
     <name>SMESHGUI_DisplayEntitiesDlg</name>
     <message>
       <source>WRN_AT_LEAST_ONE</source>
-      <translation type="unfinished">At least one entity type should be chosen!</translation>
+      <translation>少なくとも一つのエンティティタイプは選択する必要があります!</translation>
     </message>
   </context>
 </TS>
index 5261c5d7fdebc35f3684644b26186d9f6a66e4df..c79b29f2872ab9492ea6d30d827fb7586e42e349 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2012-2015  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
@@ -25,7 +25,6 @@ INCLUDE_DIRECTORIES(
   ${VTK_INCLUDE_DIRS}
   ${Boost_INCLUDE_DIRS}
   ${PROJECT_SOURCE_DIR}/src/SMDS
-  ${PROJECT_SOURCE_DIR}/src/SMESHDS
 )
 
 # additional preprocessor / compiler flags
@@ -38,12 +37,15 @@ ADD_DEFINITIONS(
 SET(_link_LIBRARIES
   ${CAS_TKShHealing}
   ${CAS_TKPrim}
+  ${CAS_TKernel}
+  ${CAS_TKBRep}
   ${CAS_TKG2d}
   ${CAS_TKG3d}
   ${CAS_TKGeomBase}
   ${CAS_TKGeomAlgo}
+  ${CAS_TKTopAlgo}
   ${Boost_LIBRARIES}
-  SMESHDS
+  SMDS
 )
 
 # --- headers ---
@@ -62,6 +64,7 @@ SET(SMESHUtils_HEADERS
   SMESH_Utils.hxx
   SMESH_TryCatch.hxx
   SMESH_MeshAlgos.hxx
+  SMESH_MAT2d.hxx
 )
 
 # --- sources ---
@@ -75,6 +78,8 @@ SET(SMESHUtils_SOURCES
   SMESH_TryCatch.cxx
   SMESH_File.cxx
   SMESH_MeshAlgos.cxx
+  SMESH_MAT2d.cxx
+  SMESH_FreeBorders.cxx
 )
 
 # --- rules ---
index 1b519201b4af6b5e487cedb78ae369d2881ad1ca..0d7eed4a74cd7c1dd1b4918d4920ea1405134eb9 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -166,7 +166,7 @@ void SMESH_Block::TFace::Set( const int          faceID,
   // pcurves
   vector< int > edgeIdVec;
   GetFaceEdgesIDs( faceID, edgeIdVec );
-  for ( int iE = 0; iE < edgeIdVec.size(); iE++ ) // loop on 4 edges
+  for ( size_t iE = 0; iE < edgeIdVec.size(); iE++ ) // loop on 4 edges
   {
     myCoordInd[ iE ] = GetCoordIndOnEdge( edgeIdVec[ iE ] );
     if ( myC2d[ iE ]) delete myC2d[ iE ];
@@ -596,6 +596,7 @@ Standard_Boolean SMESH_Block::Values(const math_Vector& theXYZ,
       if ( mag > DBL_MIN )
         dPi /= mag;
       drv[ iP - 1 ] = dPi;
+      // drv[ iP - 1 ] = dPi / 0.001;
     }
     for ( int iP = 0; iP < 3; iP++ ) {
 #if 1
@@ -725,7 +726,7 @@ bool SMESH_Block::ComputeParameters(const gp_Pnt& thePoint,
 
   bool hasHint = ( 0 <= theParamsHint.X() && theParamsHint.X() <= 1 &&
                    0 <= theParamsHint.Y() && theParamsHint.Y() <= 1 &&
-                   0 <= theParamsHint.Y() && theParamsHint.Y() <= 1 );
+                   0 <= theParamsHint.Z() && theParamsHint.Z() <= 1 );
   if ( !hasHint && !myGridComputed )
   {
     // define the first guess by thePoint projection on lines
@@ -1798,8 +1799,11 @@ bool SMESH_Block::FindBlockShapes(const TopoDS_Shell&         theShell,
     for (  ; eIt.More(); eIt.Next() ) {
       const TopoDS_Edge& e = TopoDS::Edge( eIt.Value() );
       TopoDS_Vertex v = TopExp::FirstVertex( e );
-      if ( v.IsSame( V000 ))
+      if ( v.IsSame( V000 )) {
         v = TopExp::LastVertex( e );
+        if ( v.IsSame( V000 ))
+          return false;
+      }
       val = dir001 * gp_Vec( p000, BRep_Tool::Pnt( v )).Normalized();
       if ( val > maxVal ) {
         V001 = v;
@@ -2079,7 +2083,7 @@ bool SMESH_Block::LoadFace(const TopoDS_Face& theFace,
   bool isForward[4];
   vector< int > edgeIdVec;
   GetFaceEdgesIDs( theFaceID, edgeIdVec );
-  for ( int iE = 0; iE < edgeIdVec.size(); iE++ ) // loop on 4 edges
+  for ( size_t iE = 0; iE < edgeIdVec.size(); iE++ ) // loop on 4 edges
   {
     if ( edgeIdVec[ iE ] > theShapeIDMap.Extent() )
       return false;
index 47de73b39ce8b146523cc4ddb8d57f69dbb0e160..d4efb16d67678849d5b72408fe4a81737b538e0c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 8e8db16d1530056acdd9b328e9ccb465d00c08a8..5e6420fda11f1dfb98d2f34f4d9612c64475893b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index b5e9965bb33585860a2bb7dfc37b6f502f553a29..8e90db5823b6d8e715235a703f7b668884dfc1bd 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index d4311bb71ef29464b7b926b689e2f1bbbc5dfa61..8d138b46cee114b2425be891aa87241073809f16 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index 0e7ccca52097dd656c794777871d589f078f8356..cf36b652b6806fac06beaa5a30ab048b823cf66c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
diff --git a/src/SMESHUtils/SMESH_FreeBorders.cxx b/src/SMESHUtils/SMESH_FreeBorders.cxx
new file mode 100644 (file)
index 0000000..5201817
--- /dev/null
@@ -0,0 +1,738 @@
+// Copyright (C) 2007-2015  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, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// 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_FreeBorders.cxx
+// Created   : Tue Sep  8 17:08:39 2015
+// Author    : Edward AGAPOV (eap)
+
+//================================================================================
+// Implementation of SMESH_MeshAlgos::FindCoincidentFreeBorders()
+//================================================================================
+
+#include "SMESH_MeshAlgos.hxx"
+
+#include "SMDS_LinearEdge.hxx"
+#include "SMDS_Mesh.hxx"
+#include "SMDS_SetIterator.hxx"
+
+#include <algorithm>
+#include <limits>
+#include <set>
+#include <vector>
+
+#include <NCollection_DataMap.hxx>
+#include <gp_Pnt.hxx>
+
+using namespace SMESH_MeshAlgos;
+
+namespace
+{
+  struct BEdge;
+
+  /*!
+   * \brief Node on a free border
+   */
+  struct BNode : public SMESH_TNodeXYZ
+  {
+    mutable std::vector< BEdge* > myLinkedEdges;
+    mutable std::vector< std::pair < BEdge*, double > > myCloseEdges; // edge & U
+
+    BNode(const SMDS_MeshNode * node): SMESH_TNodeXYZ( node ) {}
+    const SMDS_MeshNode * Node() const { return _node; }
+    void   AddLinked( BEdge* e ) const;
+    void   AddClose ( const BEdge* e, double u ) const;
+    BEdge* GetCloseEdge( size_t i ) const { return myCloseEdges[i].first; }
+    double GetCloseU( size_t i ) const { return myCloseEdges[i].second; }
+    BEdge* GetCloseEdgeOfBorder( int borderID, double * u = 0 ) const;
+    bool   HasCloseEdgeWithNode( const BNode* n ) const;
+    bool   IsCloseEdge( const BEdge*, double * u = 0 ) const;
+    bool operator<(const BNode& other) const { return Node()->GetID() < other.Node()->GetID(); }
+  };
+  /*!
+   * \brief Edge of a free border
+   */
+  struct BEdge : public SMDS_LinearEdge
+  {
+    const BNode*            myBNode1;
+    const BNode*            myBNode2;
+    int                     myBorderID;
+    int                     myID; // within a border
+    BEdge*                  myPrev;
+    BEdge*                  myNext;
+    const SMDS_MeshElement* myFace;
+    std::set< int >         myCloseBorders;
+    int                     myInGroup;
+
+    BEdge():SMDS_LinearEdge( 0, 0 ), myBorderID(-1), myID(-1), myPrev(0), myNext(0), myInGroup(-1) {}
+
+    void Set( const BNode *           node1,
+              const BNode *           node2,
+              const SMDS_MeshElement* face,
+              const int               ID)
+    {
+      myBNode1   = node1;
+      myBNode2   = node2;
+      myNodes[0] = node1->Node();
+      myNodes[1] = node2->Node();
+      myFace     = face;
+      setId( ID ); // mesh element ID
+    }
+    bool IsInGroup() const
+    {
+      return myInGroup >= 0;
+    }
+    bool Contains( const BNode* n ) const
+    {
+      return ( n == myBNode1 || n == myBNode2 );
+    }
+    void AddLinked( BEdge* e )
+    {
+      if ( e->Contains( myBNode1 )) myPrev = e;
+      else                          myNext = e;
+    }
+    void RemoveLinked( BEdge* e )
+    {
+      if ( myPrev == e ) myPrev = 0;
+      if ( myNext == e ) myNext = 0;
+    }
+    void Reverse()
+    {
+      std::swap( myBNode1, myBNode2 );
+      myNodes[0] = myBNode1->Node();
+      myNodes[1] = myBNode2->Node();
+    }
+    void Orient()
+    {
+      if (( myPrev && !myPrev->Contains( myBNode1 )) ||
+          ( myNext && !myNext->Contains( myBNode2 )))
+        std::swap( myPrev, myNext );
+      if ( myPrev && myPrev->myBNode2 != myBNode1 ) myPrev->Reverse();
+      if ( myNext && myNext->myBNode1 != myBNode2 ) myNext->Reverse();
+    }
+    void SetID( int id )
+    {
+      if ( myID < 0 )
+      {
+        myID = id;
+        if ( myNext )
+          myNext->SetID( id + 1 );
+      }
+    }
+    bool IsOut( const gp_XYZ& point, const double tol, double& u ) const
+    {
+      gp_XYZ  me = *myBNode2 - *myBNode1;
+      gp_XYZ n1p = point     - *myBNode1;
+      u = ( me * n1p ) / me.SquareModulus(); // param [0,1] on this
+      if ( u < 0. ) return ( n1p.SquareModulus() > tol * tol );
+      if ( u > 1. ) return ( ( point - *myBNode2 ).SquareModulus() > tol * tol );
+
+      gp_XYZ  proj = ( 1. - u ) * *myBNode1 + u * *myBNode2; // projection of the point on this
+      double dist2 = ( point - proj ).SquareModulus();
+      return ( dist2 > tol * tol );
+    }
+    bool IsOverlappingProjection( const BEdge* toE, const double u, bool is1st ) const
+    {
+      // is1st shows which end of toE is projected on this at u
+      double u2;
+      const double eps = 0.1;
+      if ( myBNode1->IsCloseEdge( toE, &u2 ) ||
+           myBNode2->IsCloseEdge( toE, &u2 ))
+        return (( 0 < u2 && u2 < 1 ) &&     // u2 is proj param of myBNode's on toE
+                ( Abs( u2 - int( !is1st )) > eps ));
+
+      const BNode* n = is1st ? toE->myBNode2 : toE->myBNode1;
+      if ( this == n->GetCloseEdgeOfBorder( this->myBorderID, &u2 ))
+        return Abs( u - u2 ) > eps;
+      return false;
+    }
+    bool GetRangeOfSameCloseBorders(BEdge* eRange[2], const std::set< int >& bordIDs)
+    {
+      if ( this->myCloseBorders != bordIDs )
+        return false;
+
+      if ( bordIDs.size() == 1 && bordIDs.count( myBorderID )) // border close to self
+      {
+        double u;
+        eRange[0] = this;
+        while ( eRange[0]->myBNode1->GetCloseEdgeOfBorder( myBorderID, &u ))
+        {
+          if ( eRange[0]->myPrev == this || u < 0 || u > 1 )
+            break;
+          eRange[0] = eRange[0]->myPrev;
+        }
+        eRange[1] = this;
+        while ( eRange[1]->myBNode2->GetCloseEdgeOfBorder( myBorderID, &u ))
+        {
+          if ( eRange[1]->myNext == this || u < 0 || u > 1 )
+            break;
+          eRange[1] = eRange[1]->myNext;
+        }
+      }
+      else
+      {
+        eRange[0] = this;
+        while ( eRange[0]->myPrev && eRange[0]->myPrev->myCloseBorders == bordIDs )
+        {
+          if ( eRange[0]->myPrev == this )
+            break;
+          eRange[0] = eRange[0]->myPrev;
+        }
+
+        eRange[1] = this;
+        if ( eRange[0]->myPrev != this ) // not closed border
+          while ( eRange[1]->myNext && eRange[1]->myNext->myCloseBorders == bordIDs )
+          {
+            if ( eRange[1]->myNext == this )
+              break;
+            eRange[1] = eRange[1]->myNext;
+          }
+      }
+
+      if ( eRange[0] == eRange[1] )
+      {
+        std::set<int>::iterator closeBord = eRange[0]->myCloseBorders.begin();
+        for ( ; closeBord != eRange[0]->myCloseBorders.end(); ++closeBord )
+        {
+          if ( BEdge* be = eRange[0]->myBNode1->GetCloseEdgeOfBorder( *closeBord ))
+            if ( be->myCloseBorders == eRange[0]->myCloseBorders )
+              return true;
+          if ( BEdge* be = eRange[0]->myBNode2->GetCloseEdgeOfBorder( *closeBord ))
+            if ( be->myCloseBorders == eRange[0]->myCloseBorders )
+              return true;
+        }
+        return false;
+      }
+      return true;
+    }
+  }; // class BEdge
+
+  void extendPart( BEdge* & e1, BEdge* & e2, const std::set< int >& bordIDs, int groupID )
+  {
+    if (( e1->myPrev == e2 ) ||
+        ( e1 == e2 && e1->myPrev && e1->myPrev->myInGroup == groupID ))
+      return; // full free border already
+
+    double u;
+    BEdge* be;
+    std::set<int>::const_iterator bord;
+    if ( e1->myPrev )
+    {
+      for ( bord = bordIDs.begin(); bord != bordIDs.end(); ++bord )
+        if ((( be = e1->myBNode1->GetCloseEdgeOfBorder( *bord, &u ))) &&
+            (  be->myInGroup == groupID ) &&
+            (  0 < u && u < 1 ) &&
+            (  be->IsOverlappingProjection( e1->myPrev, u, false )))
+        {
+          e1 = e1->myPrev;
+          break;
+        }
+      if ( bord == bordIDs.end() && // not extended
+           e1->myBNode1->HasCloseEdgeWithNode( e1->myPrev->myBNode1 ))
+      {
+        e1 = e1->myPrev;
+      }
+      e1->myInGroup = groupID;
+    }
+    if ( e2->myNext )
+    {
+      for ( bord = bordIDs.begin(); bord != bordIDs.end(); ++bord )
+        if ((( be = e2->myBNode2->GetCloseEdgeOfBorder( *bord, &u ))) &&
+            (  be->myInGroup == groupID ) &&
+            (  0 < u && u < 1 ) &&
+            (  be->IsOverlappingProjection( e2->myNext, u, true )))
+        {
+          e2 = e2->myNext;
+          break;
+        }
+      if ( bord == bordIDs.end() && // not extended
+           e2->myBNode2->HasCloseEdgeWithNode( e2->myNext->myBNode2 ))
+      {
+        e2 = e2->myNext;
+      }
+      e2->myInGroup = groupID;
+    }
+  }
+
+  void BNode::AddLinked( BEdge* e ) const
+  {
+    myLinkedEdges.reserve(2);
+    myLinkedEdges.push_back( e );
+    if ( myLinkedEdges.size() < 2 ) return;
+
+    if ( myLinkedEdges.size() == 2 )
+    {
+      myLinkedEdges[0]->AddLinked( myLinkedEdges[1] );
+      myLinkedEdges[1]->AddLinked( myLinkedEdges[0] );
+    }
+    else
+    {
+      for ( size_t i = 0; i < myLinkedEdges.size(); ++i )
+        for ( size_t j = 0; j < myLinkedEdges.size(); ++j )
+          if ( i != j )
+            myLinkedEdges[i]->RemoveLinked( myLinkedEdges[j] );
+    }
+  }
+  void BNode::AddClose ( const BEdge* e, double u ) const
+  {
+    if ( ! e->Contains( this ))
+      myCloseEdges.push_back( make_pair( const_cast< BEdge* >( e ), u ));
+  }
+  BEdge* BNode::GetCloseEdgeOfBorder( int borderID, double * uPtr ) const
+  {
+    BEdge* e = 0;
+    double u = 0;
+    for ( size_t i = 0; i < myCloseEdges.size(); ++i )
+      if ( borderID == GetCloseEdge( i )->myBorderID )
+      {
+        if ( e && Abs( u - 0.5 ) < Abs( GetCloseU( i ) - 0.5 ))
+          continue;
+        u = GetCloseU( i );
+        e = GetCloseEdge ( i );
+      }
+    if ( uPtr ) *uPtr = u;
+    return e;
+  }
+  bool BNode::HasCloseEdgeWithNode( const BNode* n ) const
+  {
+    for ( size_t i = 0; i < myCloseEdges.size(); ++i )
+      if ( GetCloseEdge( i )->Contains( n ) &&
+           0 < GetCloseU( i ) && GetCloseU( i ) < 1 )
+        return true;
+    return false;
+  }
+  bool BNode::IsCloseEdge( const BEdge* e, double * uPtr ) const
+  {
+    for ( size_t i = 0; i < myCloseEdges.size(); ++i )
+      if ( e == GetCloseEdge( i ) )
+      {
+        if ( uPtr ) *uPtr = GetCloseU( i );
+        return true;
+      }
+    return false;
+  }
+
+  /// Accessor to SMDS_MeshElement* inherited by BEdge
+  struct ElemAcess
+  {
+    static const SMDS_MeshElement* value( std::vector< BEdge >::const_iterator it)
+    {
+      return & (*it);
+    }
+  };
+  /// Iterator over a vector of BEdge's
+  static SMDS_ElemIteratorPtr getElemIterator( const std::vector< BEdge > & bedges )
+  {
+    typedef SMDS_SetIterator
+      < const SMDS_MeshElement*, std::vector< BEdge >::const_iterator, ElemAcess > BEIter;
+    return SMDS_ElemIteratorPtr( new BEIter( bedges.begin(), bedges.end() ));
+  }
+
+} // namespace
+
+//================================================================================
+/*
+ * Returns groups of TFreeBorder's coincident within the given tolerance.
+ * If the tolerance <= 0.0 then one tenth of an average size of elements adjacent
+ * to free borders being compared is used.
+ */
+//================================================================================
+
+void SMESH_MeshAlgos::FindCoincidentFreeBorders(SMDS_Mesh&              mesh,
+                                                double                  tolerance,
+                                                CoincidentFreeBorders & foundFreeBordes)
+{
+  // find free links
+  typedef NCollection_DataMap<SMESH_TLink, const SMDS_MeshElement*, SMESH_TLink > TLink2FaceMap;
+  TLink2FaceMap linkMap;
+  int nbSharedLinks = 0;
+  SMDS_FaceIteratorPtr faceIt = mesh.facesIterator();
+  while ( faceIt->more() )
+  {
+    const SMDS_MeshElement* face = faceIt->next();
+    if ( !face ) continue;
+
+    const SMDS_MeshNode*     n0 = face->GetNode( face->NbNodes() - 1 );
+    SMDS_NodeIteratorPtr nodeIt = face->interlacedNodesIterator();
+    while ( nodeIt->more() )
+    {
+      const SMDS_MeshNode* n1 = nodeIt->next();
+      SMESH_TLink link( n0, n1 );
+      if ( const SMDS_MeshElement** faceInMap = linkMap.ChangeSeek( link ))
+      {
+        nbSharedLinks += bool( *faceInMap );
+        *faceInMap = 0;
+      }
+      else
+      {
+        linkMap.Bind( link, face );
+      }
+      n0 = n1;
+    }
+  }
+  if ( linkMap.Extent() == nbSharedLinks )
+    return;
+
+  // form free borders
+  std::set   < BNode > bNodes;
+  std::vector< BEdge > bEdges( linkMap.Extent() - nbSharedLinks );
+
+  TLink2FaceMap::Iterator linkIt( linkMap );
+  for ( int iEdge = 0; linkIt.More(); linkIt.Next() )
+  {
+    if ( !linkIt.Value() ) continue;
+    const SMESH_TLink & link = linkIt.Key();
+    std::set< BNode >::iterator n1 = bNodes.insert( BNode( link.node1() )).first;
+    std::set< BNode >::iterator n2 = bNodes.insert( BNode( link.node2() )).first;
+    bEdges[ iEdge ].Set( &*n1, &*n2, linkIt.Value(), iEdge+1 );
+    n1->AddLinked( & bEdges[ iEdge ] );
+    n2->AddLinked( & bEdges[ iEdge ] );
+    ++iEdge;
+  }
+  linkMap.Clear();
+
+  // assign IDs to borders
+  std::vector< BEdge* > borders; // 1st of connected (via myPrev and myNext) edges
+  std::set< BNode >::iterator bn = bNodes.begin();
+  for ( ; bn != bNodes.end(); ++bn )
+  {
+    for ( size_t i = 0; i < bn->myLinkedEdges.size(); ++i )
+    {
+      if ( bn->myLinkedEdges[i]->myBorderID < 0 )
+      {
+        BEdge* be = bn->myLinkedEdges[i];
+        int borderID = borders.size();
+        borders.push_back( be );
+        for ( ; be && be->myBorderID < 0; be = be->myNext )
+        {
+          be->myBorderID = borderID;
+          be->Orient();
+        }
+        bool isClosed = ( be == bn->myLinkedEdges[i] );
+        be = bn->myLinkedEdges[i]->myPrev;
+        for ( ; be && be->myBorderID < 0; be = be->myPrev )
+        {
+          be->myBorderID = borderID;
+          be->Orient();
+        }
+        if ( !isClosed )
+          while ( borders.back()->myPrev )
+            borders.back() = borders.back()->myPrev;
+
+        borders.back()->SetID( 0 ); // set IDs to all edges of the border
+      }
+    }
+  }
+
+  // compute tolerance of each border
+  double maxTolerance = tolerance;
+  std::vector< double > bordToler( borders.size(), tolerance );
+  if ( maxTolerance < std::numeric_limits< double >::min() )
+  {
+    // no tolerance provided by the user; compute tolerance of each border
+    // as one tenth of an average size of faces adjacent to a border
+    for ( size_t i = 0; i < borders.size(); ++i )
+    {
+      double avgFaceSize = 0;
+      int    nbFaces     = 0;
+      BEdge* be = borders[ i ];
+      do {
+        double facePerimeter = 0;
+        gp_Pnt p0 = SMESH_TNodeXYZ( be->myFace->GetNode( be->myFace->NbNodes() - 1 ));
+        SMDS_NodeIteratorPtr nodeIt = be->myFace->interlacedNodesIterator();
+        while ( nodeIt->more() )
+        {
+          gp_Pnt p1 = SMESH_TNodeXYZ( nodeIt->next() );
+          facePerimeter += p0.Distance( p1 );
+          p0 = p1;
+        }
+        avgFaceSize += ( facePerimeter / be->myFace->NbCornerNodes() );
+        nbFaces++;
+
+        be = be->myNext;
+      }
+      while ( be && be != borders[i] );
+
+      bordToler[ i ] = 0.1 * avgFaceSize / nbFaces;
+      maxTolerance = Max( maxTolerance, bordToler[ i ]);
+    }
+  }
+
+  // for every border node find close border edges
+  SMESH_ElementSearcher* searcher =
+    GetElementSearcher( mesh, getElemIterator( bEdges ), maxTolerance );
+  SMESHUtils::Deleter< SMESH_ElementSearcher > searcherDeleter( searcher );
+  std::vector< const SMDS_MeshElement* > candidateEdges;
+  for ( bn = bNodes.begin(); bn != bNodes.end(); ++bn )
+  {
+    searcher->FindElementsByPoint( *bn, SMDSAbs_Edge, candidateEdges );
+    if ( candidateEdges.size() <= bn->myLinkedEdges.size() )
+      continue;
+
+    double nodeTol = 0, u;
+    for ( size_t i = 0; i < bn->myLinkedEdges.size(); ++i )
+      nodeTol = Max( nodeTol, bordToler[ bn->myLinkedEdges[ i ]->myBorderID ]);
+
+    for ( size_t i = 0; i < candidateEdges.size(); ++i )
+    {
+      const BEdge* be = static_cast< const BEdge* >( candidateEdges[ i ]);
+      double      tol = Max( nodeTol, bordToler[ be->myBorderID ]);
+      if ( !be->IsOut( *bn, tol, u ))
+        bn->AddClose( be, u );
+    }
+  }
+
+  // for every border edge find close borders
+
+  std::vector< BEdge* > closeEdges;
+  for ( size_t i = 0; i < bEdges.size(); ++i )
+  {
+    BEdge& be = bEdges[i];
+    if ( be.myBNode1->myCloseEdges.empty() ||
+         be.myBNode2->myCloseEdges.empty() )
+      continue;
+
+    closeEdges.clear();
+    for ( size_t iE1 = 0; iE1 < be.myBNode1->myCloseEdges.size(); ++iE1 )
+    {
+      // find edges of the same border close to both nodes of the edge
+      BEdge* closeE1 = be.myBNode1->GetCloseEdge( iE1 );
+      BEdge* closeE2 = be.myBNode2->GetCloseEdgeOfBorder( closeE1->myBorderID );
+      if ( !closeE2 )
+        continue;
+      // check that edges connecting closeE1 and closeE2 (if any) are also close to 'be'
+      if ( closeE1 != closeE2 )
+      {
+        bool coincide;
+        for ( int j = 0; j < 2; ++j ) // move closeE1 -> closeE2 or inversely
+        {
+          BEdge* ce = closeE1;
+          do {
+            coincide = ( ce->myBNode2->GetCloseEdgeOfBorder( be.myBorderID ));
+            ce       = ce->myNext;
+          } while ( coincide && ce && ce != closeE2 );
+
+          if ( coincide && ce == closeE2 )
+            break;
+          if ( j == 0 )
+            std::swap( closeE1, closeE2 );
+          coincide = false;
+        }
+        if ( !coincide )
+          continue;
+        closeEdges.push_back( closeE1 );
+        closeEdges.push_back( closeE2 );
+      }
+      else
+      {
+        closeEdges.push_back( closeE1 );
+      }
+      be.myCloseBorders.insert( closeE1->myBorderID );
+    }
+    if ( !closeEdges.empty() )
+    {
+      be.myCloseBorders.insert( be.myBorderID );
+      // for ( size_t iB = 0; iB < closeEdges.size(); ++iB )
+      //   closeEdges[ iB ]->myCloseBorders.insert( be.myCloseBorders.begin(),
+      //                                            be.myCloseBorders.end() );
+    }
+  }
+
+  // Fill in CoincidentFreeBorders
+
+  // save nodes of free borders
+  foundFreeBordes._borders.resize( borders.size() );
+  for ( size_t i = 0; i < borders.size(); ++i )
+  {
+    BEdge* be = borders[i];
+    foundFreeBordes._borders[i].push_back( be->myBNode1->Node() );
+    do {
+      foundFreeBordes._borders[i].push_back( be->myBNode2->Node() );
+      be = be->myNext;
+    }
+    while ( be && be != borders[i] );
+  }
+
+  // form groups of coincident parts of free borders
+
+  TFreeBorderPart  part;
+  TCoincidentGroup group;
+  vector< BEdge* > ranges; // couples of edges delimiting parts
+  BEdge* be = 0; // a current edge
+  int skipGroup = bEdges.size(); // a group ID used to avoid repeating treatment of edges
+
+  for ( int i = 0, nbBords = borders.size(); i < nbBords; i += bool(!be) )
+  {
+    if ( !be )
+      be = borders[i];
+
+    // look for an edge close to other borders
+    do {
+      if ( !be->IsInGroup() && !be->myCloseBorders.empty() )
+        break;
+      be = be->myNext;
+    } while ( be && be != borders[i] );
+
+    if ( !be || be->IsInGroup() || be->myCloseBorders.empty() )
+    {
+      be = 0;
+      continue; // all edges of a border are treated or non-coincident
+    }
+    group.clear();
+    ranges.clear();
+
+    // look for the 1st and last edge of a coincident group
+    BEdge* beRange[2];
+    if ( !be->GetRangeOfSameCloseBorders( beRange, be->myCloseBorders ))
+    {
+      be->myInGroup = skipGroup;
+      be = be->myNext;
+      continue;
+    }
+
+    ranges.push_back( beRange[0] );
+    ranges.push_back( beRange[1] );
+
+    int groupID = foundFreeBordes._coincidentGroups.size();
+    be = beRange[0];
+    be->myInGroup = groupID;
+    while ( be != beRange[1] )
+    {
+      be->myInGroup = groupID;
+      be = be->myNext;
+    }
+    beRange[1]->myInGroup = groupID;
+
+    // get starting edge of each close border
+    closeEdges.clear();
+    be = beRange[0];
+    if ( be->myCloseBorders.empty() )
+      be = beRange[0]->myNext;
+    std::set<int>::iterator closeBord = be->myCloseBorders.begin();
+    for ( ; closeBord != be->myCloseBorders.end(); ++closeBord )
+      if ( BEdge* e = be->myBNode2->GetCloseEdgeOfBorder( *closeBord ))
+        closeEdges.push_back( e );
+
+    for ( size_t iE = 0; iE < closeEdges.size(); ++iE )
+      if ( be->myCloseBorders != closeEdges[iE]->myCloseBorders )
+      {
+        closeBord = closeEdges[iE]->myCloseBorders.begin();
+        for ( ; closeBord != closeEdges[iE]->myCloseBorders.end(); ++closeBord )
+          if ( !be->myCloseBorders.count( *closeBord ))
+            if ( BEdge* e = closeEdges[iE]->myBNode2->GetCloseEdgeOfBorder( *closeBord ))
+              if ( std::find( closeEdges.begin(), closeEdges.end(), e ) == closeEdges.end() )
+                closeEdges.push_back( e );
+      }
+
+    // add parts of other borders
+
+    BEdge* be1st = beRange[0];
+    for ( size_t iE = 0; iE < closeEdges.size(); ++iE )
+    {
+      be = closeEdges[ iE ];
+      if ( !be ) continue;
+
+      bool ok = be->GetRangeOfSameCloseBorders( beRange, be->myCloseBorders );
+      // if ( !ok && be->myPrev )
+      //   ok = be->myPrev->GetRangeOfSameCloseBorders( beRange, be1st->myCloseBorders );
+      // if ( !ok && be->myNext )
+      //   ok = be->myNext->GetRangeOfSameCloseBorders( beRange, be1st->myCloseBorders );
+      if ( !ok )
+        continue;
+
+      be = beRange[0];
+
+      ranges.push_back( beRange[0] );
+      ranges.push_back( beRange[1] );
+
+      be->myInGroup = groupID;
+      while ( be != beRange[1] )
+      {
+        be->myInGroup = groupID;
+        be = be->myNext;
+      }
+      beRange[1]->myInGroup = groupID;
+    }
+
+    if ( ranges.size() > 2 )
+    {
+      for ( size_t iR = 1; iR < ranges.size(); iR += 2 )
+        extendPart( ranges[ iR-1 ], ranges[ iR ], be1st->myCloseBorders, groupID );
+
+      // fill in a group
+      beRange[0] = ranges[0];
+      beRange[1] = ranges[1];
+
+      part._border   = i;
+      part._node1    = beRange[0]->myID;
+      part._node2    = beRange[0]->myID + 1;
+      part._nodeLast = beRange[1]->myID + 1;
+      group.push_back( part );
+
+      be1st = beRange[0];
+      for ( size_t iR = 3; iR < ranges.size(); iR += 2 )
+      {
+        beRange[0] = ranges[iR-1];
+        beRange[1] = ranges[iR-0];
+
+        // find out mutual orientation of borders
+        double u1, u2;
+        be1st       ->IsOut( *beRange[ 0 ]->myBNode1, maxTolerance, u1 );
+        beRange[ 0 ]->IsOut( *be1st->myBNode1,        maxTolerance, u2 );
+        bool reverse = (( u1 < 0 || u1 > 1 ) && ( u2 < 0 || u2 > 1 ));
+
+        // fill in a group
+        part._border   = beRange[0]->myBorderID;
+        if ( reverse ) {
+          part._node1    = beRange[1]->myID + 1;
+          part._node2    = beRange[1]->myID;
+          part._nodeLast = beRange[0]->myID;
+        }
+        else  {
+          part._node1    = beRange[0]->myID;
+          part._node2    = beRange[0]->myID + 1;
+          part._nodeLast = beRange[1]->myID + 1;
+        }
+        // if ( group[0]._node2 != part._node2 )
+        group.push_back( part );
+      }
+      //if ( group.size() > 1 )
+        foundFreeBordes._coincidentGroups.push_back( group );
+    }
+    else
+    {
+      beRange[0] = ranges[0];
+      beRange[1] = ranges[1];
+
+      be = beRange[0];
+      be->myInGroup = skipGroup;
+      while ( be != beRange[1] )
+      {
+        be->myInGroup = skipGroup;
+        be = be->myNext;
+      }
+      beRange[1]->myInGroup = skipGroup;
+    }
+
+    be = ranges[1];
+
+  } // loop on free borders
+
+  return;
+
+} // SMESH_MeshAlgos::FindCoincidentFreeBorders()
+
diff --git a/src/SMESHUtils/SMESH_MAT2d.cxx b/src/SMESHUtils/SMESH_MAT2d.cxx
new file mode 100644 (file)
index 0000000..970d560
--- /dev/null
@@ -0,0 +1,2023 @@
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&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, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// 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_MAT2d.cxx
+// Created   : Thu May 28 17:49:53 2015
+// Author    : Edward AGAPOV (eap)
+
+#include "SMESH_MAT2d.hxx"
+
+#include <list>
+
+#include <BRepAdaptor_CompCurve.hxx>
+#include <BRepBuilderAPI_MakeEdge.hxx>
+#include <BRepBuilderAPI_MakeVertex.hxx>
+#include <BRep_Builder.hxx>
+#include <BRep_Tool.hxx>
+#include <Bnd_B2d.hxx>
+//#include <GCPnts_AbscissaPoint.hxx>
+#include <GCPnts_TangentialDeflection.hxx>
+// #include <GCPnts_UniformAbscissa.hxx>
+// #include <GCPnts_UniformDeflection.hxx>
+#include <Geom2d_Curve.hxx>
+//#include <GeomAdaptor_Curve.hxx>
+#include <Geom2dAdaptor_Curve.hxx>
+#include <Geom_Curve.hxx>
+#include <Geom_Surface.hxx>
+#include <TopExp.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <TopoDS_Wire.hxx>
+
+#ifdef _DEBUG_
+#define _MYDEBUG_
+#include "SMESH_File.hxx"
+#include "SMESH_Comment.hxx"
+#endif
+
+using namespace std;
+using boost::polygon::x;
+using boost::polygon::y;
+using SMESH_MAT2d::TVD;
+using SMESH_MAT2d::TVDEdge;
+using SMESH_MAT2d::TVDCell;
+using SMESH_MAT2d::TVDVertex;
+
+namespace
+{
+  // Input data for construct_voronoi()
+  // -------------------------------------------------------------------------------------
+
+  struct InPoint
+  {
+    int _a, _b;    // coordinates
+    double _param; // param on EDGE
+    InPoint(int x, int y, double param) : _a(x), _b(y), _param(param) {}
+    InPoint() : _a(0), _b(0), _param(0) {}
+
+    // working data
+    list< const TVDEdge* > _edges; // MA edges of a concave InPoint in CCW order
+
+    size_t index( const vector< InPoint >& inPoints ) const { return this - &inPoints[0]; }
+    bool operator==( const InPoint& other ) const { return _a == other._a && _b == other._b; }
+    bool operator==( const TVDVertex* v ) const { return ( Abs( _a - v->x() ) < 1. &&
+                                                           Abs( _b - v->y() ) < 1. ); }
+  };
+  // -------------------------------------------------------------------------------------
+
+  struct InSegment
+  {
+    InPoint * _p0;
+    InPoint * _p1;
+
+    // working data
+    size_t                 _geomEdgeInd; // EDGE index within the FACE
+    const TVDCell*         _cell;
+    list< const TVDEdge* > _edges; // MA edges in CCW order within _cell
+
+    InSegment( InPoint * p0, InPoint * p1, size_t iE)
+      : _p0(p0), _p1(p1), _geomEdgeInd(iE) {}
+    InSegment() : _p0(0), _p1(0), _geomEdgeInd(0) {}
+
+    const InPoint& point0() const { return *_p0; }
+    const InPoint& point1() const { return *_p1; }
+
+    inline bool isConnected( const TVDEdge* edge );
+
+    inline bool isExternal( const TVDEdge* edge );
+
+    static void setGeomEdgeToCell( const TVDCell* cell, size_t eID ) { cell->color( eID ); }
+
+    static size_t getGeomEdge( const TVDCell* cell ) { return cell->color(); }
+  };
+
+  // check  if a TVDEdge begins at my end or ends at my start
+  inline bool InSegment::isConnected( const TVDEdge* edge )
+  {
+    return (( edge->vertex0() && edge->vertex1() )
+            &&
+            ((Abs( edge->vertex0()->x() - _p1->_a ) < 1.&&
+              Abs( edge->vertex0()->y() - _p1->_b ) < 1.  ) ||
+             (Abs( edge->vertex1()->x() - _p0->_a ) < 1.&&
+              Abs( edge->vertex1()->y() - _p0->_b ) < 1.  )));
+  }
+
+  // check if a MA TVDEdge is outside of a domain
+  inline bool InSegment::isExternal( const TVDEdge* edge )
+  {
+    double dot = // x1*x2 + y1*y2;   (x1,y1) - internal normal of InSegment
+      ( _p0->_b - _p1->_b ) * ( 0.5 * ( edge->vertex0()->x() + edge->vertex1()->x() ) - _p0->_a ) +
+      ( _p1->_a - _p0->_a ) * ( 0.5 * ( edge->vertex0()->y() + edge->vertex1()->y() ) - _p0->_b );
+    return dot < 0.;
+  }
+
+  // // -------------------------------------------------------------------------------------
+  // const size_t theExternMA = 111; // to mark external MA edges
+
+  // bool isExternal( const TVDEdge* edge )
+  // {
+  //   return ( SMESH_MAT2d::Branch::getBndSegment( edge ) == theExternMA );
+  // }
+
+  // // mark external MA edges
+  // void markExternalEdges( const TVDEdge* edge )
+  // {
+  //   if ( isExternal( edge ))
+  //     return;
+  //   SMESH_MAT2d::Branch::setBndSegment( theExternMA, edge );
+  //   SMESH_MAT2d::Branch::setBndSegment( theExternMA, edge->twin() );
+  //   if ( edge->is_primary() && edge->vertex1() )
+  //   {
+  //     const TVDVertex * v = edge->vertex1();
+  //     edge = v->incident_edge();
+  //     do {
+  //       markExternalEdges( edge );
+  //       edge = edge->rot_next();
+  //     } while ( edge != v->incident_edge() );
+  //   }
+  // }
+
+  // -------------------------------------------------------------------------------------
+#ifdef _MYDEBUG_
+  // writes segments into a txt file readable by voronoi_visualizer
+  void inSegmentsToFile( vector< InSegment>& inSegments)
+  {
+    if ( inSegments.size() > 1000 )
+      return;
+    const char* fileName = "/misc/dn25/salome/eap/salome/misc/Code/C++/MAdebug.txt";
+    SMESH_File file(fileName, false );
+    file.remove();
+    file.openForWriting();
+    SMESH_Comment text;
+    text << "0\n"; // nb points
+    text << inSegments.size() << "\n"; // nb segments
+    for ( size_t i = 0; i < inSegments.size(); ++i )
+    {
+      text << inSegments[i]._p0->_a << " "
+           << inSegments[i]._p0->_b << " "
+           << inSegments[i]._p1->_a << " "
+           << inSegments[i]._p1->_b << "\n";
+    }
+    text << "\n";
+    file.write( text.c_str(), text.size() );
+    cout << "Write " << fileName << endl;
+  }
+  void dumpEdge( const TVDEdge* edge )
+  {
+    cout << "*Edge_" << edge;
+    if ( !edge->vertex0() )
+      cout << " ( INF, INF";
+    else
+      cout << " ( " << edge->vertex0()->x() << ", " << edge->vertex0()->y();
+    if ( !edge->vertex1() )
+      cout << ") -> ( INF, INF";
+    else
+      cout << ") -> ( " << edge->vertex1()->x() << ", " << edge->vertex1()->y();
+    cout << ")\t cell=" << edge->cell()
+         << " iBnd=" << edge->color()
+         << " twin=" << edge->twin()
+         << " twin_cell=" << edge->twin()->cell()
+         << " prev=" << edge->prev() << " next=" << edge->next()
+         << ( edge->is_primary() ? " MA " : " SCND" )
+         << ( edge->is_linear() ? " LIN " : " CURV" )
+         << endl;
+  }
+  void dumpCell( const TVDCell* cell )
+  {
+    cout << "**Cell_" << cell << " GEOM=" << cell->color() << " ";
+    cout << ( cell->contains_segment() ? " SEG " : " PNT " );
+    if ( cell-> is_degenerate() )
+      cout << " degen ";
+    else
+    {
+      cout << endl;
+      const TVDEdge* edge = cell->incident_edge();
+      size_t i = 0;
+      do {
+        edge = edge->next();
+        cout << "   - " << ++i << " ";
+        dumpEdge( edge );
+      } while (edge != cell->incident_edge());
+    }
+  }
+#else
+  void inSegmentsToFile( vector< InSegment>& inSegments) {}
+  void dumpEdge( const TVDEdge* edge ) {}
+  void dumpCell( const TVDCell* cell ) {}
+#endif
+}
+// -------------------------------------------------------------------------------------
+
+namespace boost {
+  namespace polygon {
+
+    template <>
+    struct geometry_concept<InPoint> {
+      typedef point_concept type;
+    };
+    template <>
+    struct point_traits<InPoint> {
+      typedef int coordinate_type;
+
+      static inline coordinate_type get(const InPoint& point, orientation_2d orient) {
+        return (orient == HORIZONTAL) ? point._a : point._b;
+      }
+    };
+
+    template <>
+    struct geometry_concept<InSegment> {
+      typedef segment_concept type;
+    };
+
+    template <>
+    struct segment_traits<InSegment> {
+      typedef int coordinate_type;
+      typedef InPoint point_type;
+
+      static inline point_type get(const InSegment& segment, direction_1d dir) {
+        return *(dir.to_int() ? segment._p1 : segment._p0);
+      }
+    };
+  }  // namespace polygon
+} // namespace boost
+  // -------------------------------------------------------------------------------------
+
+namespace
+{
+  const int    theNoBrachID = 0;
+  double       theScale[2]; // scale used in bndSegsToMesh()
+  const size_t theNoEdgeID = std::numeric_limits<size_t>::max() / 1000;
+
+  // -------------------------------------------------------------------------------------
+  /*!
+   * \brief Intermediate DS to create InPoint's
+   */
+  struct UVU
+  {
+    gp_Pnt2d _uv;
+    double   _u;
+    UVU( gp_Pnt2d uv, double u ): _uv(uv), _u(u) {}
+    InPoint getInPoint( double scale[2] )
+    {
+      return InPoint( int( _uv.X() * scale[0]), int( _uv.Y() * scale[1]), _u );
+    }
+  };
+  // -------------------------------------------------------------------------------------
+  /*!
+   * \brief Segment of EDGE, used to create BndPoints
+   */
+  struct BndSeg
+  {
+    InSegment*       _inSeg;
+    const TVDEdge*   _edge;
+    double           _uLast;
+    BndSeg*          _prev; // previous BndSeg in FACE boundary
+    int              _branchID; // negative ID means reverse direction
+
+    BndSeg( InSegment* seg, const TVDEdge* edge, double u ):
+      _inSeg(seg), _edge(edge), _uLast(u), _prev(0), _branchID( theNoBrachID ) {}
+
+    void setIndexToEdge( size_t id )
+    {
+      SMESH_MAT2d::Branch::setBndSegment( id, _edge );
+    }
+
+    int branchID() const { return Abs( _branchID ); }
+
+    size_t geomEdge() const { return _inSeg->_geomEdgeInd; }
+
+    static BndSeg* getBndSegOfEdge( const TVDEdge*              edge,
+                                    vector< vector< BndSeg > >& bndSegsPerEdge )
+    {
+      BndSeg* seg = 0;
+      if ( edge )
+      {
+        size_t oppSegIndex  = SMESH_MAT2d::Branch::getBndSegment( edge );
+        size_t oppEdgeIndex = SMESH_MAT2d::Branch::getGeomEdge  ( edge );
+        if ( oppEdgeIndex < bndSegsPerEdge.size() &&
+             oppSegIndex < bndSegsPerEdge[ oppEdgeIndex ].size() )
+        {
+          seg = & bndSegsPerEdge[ oppEdgeIndex ][ oppSegIndex ];
+        }
+      }
+      return seg;
+    }
+
+    void setBranch( int branchID, vector< vector< BndSeg > >& bndSegsPerEdge )
+    {
+      _branchID = branchID;
+
+      // pass branch to an opposite BndSeg
+      if ( _edge )
+        if ( BndSeg* oppSeg = getBndSegOfEdge( _edge->twin(), bndSegsPerEdge ))
+        {
+          if ( oppSeg->_branchID == theNoBrachID )
+            oppSeg->_branchID = -branchID;
+        }
+    }
+    bool hasOppositeEdge()
+    {
+      if ( !_edge ) return false;
+      return ( _inSeg->getGeomEdge( _edge->twin()->cell() ) != theNoEdgeID );
+    }
+
+    // check a next segment in CW order
+    bool isSameBranch( const BndSeg& seg2 )
+    {
+      if ( !_edge || !seg2._edge )
+        return true;
+
+      if ( _edge->twin() == seg2._edge )
+        return true;
+
+      const TVDCell* cell1 = this->_edge->twin()->cell();
+      const TVDCell* cell2 = seg2. _edge->twin()->cell();
+      if ( cell1 == cell2 )
+        return true;
+
+      const TVDEdge* edgeMedium1 = this->_edge->twin()->next();
+      const TVDEdge* edgeMedium2 = seg2. _edge->twin()->prev();
+
+      if ( edgeMedium1->is_secondary() && edgeMedium2->is_secondary() )
+      {
+        if ( edgeMedium1->twin() == edgeMedium2 )
+          return true;
+        // edgeMedium's are edges whose twin()->cell is built on an end point of inSegment
+        // and is located between cell1 and cell2
+        if ( edgeMedium1->twin() == edgeMedium2->twin() ) // is this possible???
+          return true;
+        if ( edgeMedium1->twin() == edgeMedium2->twin()->next() &&
+             edgeMedium1->twin()->cell()->contains_point() )
+          return true;
+      }
+      else if ( edgeMedium1->is_primary() && edgeMedium2->is_primary() )
+      {
+        if ( edgeMedium1->twin() == edgeMedium2 &&
+             SMESH_MAT2d::Branch::getGeomEdge( edgeMedium1 ) ==
+             SMESH_MAT2d::Branch::getGeomEdge( edgeMedium2 ))
+          // this is an ignored MA edge between inSegment's on one EDGE forming a convex corner
+          return true;
+      }
+
+      return false;
+    }
+  }; // struct BndSeg
+
+  // -------------------------------------------------------------------------------------
+  /*!
+   * \brief Iterator 
+   */
+  struct BranchIterator
+  {
+    int                                 _i, _size;
+    const std::vector<const TVDEdge*> & _edges;
+    bool                                _closed;
+
+    BranchIterator(const std::vector<const TVDEdge*> & edges, int i )
+      :_i( i ), _size( edges.size() ), _edges( edges )
+    {
+      _closed = ( edges[0]->vertex1() == edges.back()->vertex0() || // closed branch
+                  edges[0]->vertex0() == edges.back()->vertex1() );
+    }
+    const TVDEdge* operator++() { ++_i; return edge(); }
+    const TVDEdge* operator--() { --_i; return edge(); }
+    bool operator<( const BranchIterator& other ) { return _i < other._i; }
+    BranchIterator& operator=( const BranchIterator& other ) { _i = other._i; return *this; }
+    void set(int i) { _i = i; }
+    int  index() const { return _i; }
+    int  indexMod() const { return ( _i + _size ) % _size; }
+    const TVDEdge* edge() const {
+      return _closed ? _edges[ indexMod() ] : ( _i < 0 || _i >= _size ) ? 0 : _edges[ _i ];
+    }
+    const TVDEdge* edgePrev() { --_i; const TVDEdge* e = edge(); ++_i; return e; }
+    const TVDEdge* edgeNext() { ++_i; const TVDEdge* e = edge(); --_i; return e; }
+  };
+
+  //================================================================================
+  /*!
+   * \brief debug: to visually check found MA edges
+   */
+  //================================================================================
+
+  void bndSegsToMesh( const vector< vector< BndSeg > >& bndSegsPerEdge )
+  {
+#ifdef _MYDEBUG_
+    if ( !getenv("bndSegsToMesh")) return;
+    map< const TVDVertex *, int > v2Node;
+    map< const TVDVertex *, int >::iterator v2n;
+    set< const TVDEdge* > addedEdges;
+
+    const char* fileName = "/misc/dn25/salome/eap/salome/misc/Code/C++/MAedges.py";
+    SMESH_File file(fileName, false );
+    file.remove();
+    file.openForWriting();
+    SMESH_Comment text;
+    text << "import salome, SMESH\n";
+    text << "salome.salome_init()\n";
+    text << "from salome.smesh import smeshBuilder\n";
+    text << "smesh = smeshBuilder.New(salome.myStudy)\n";
+    text << "m=smesh.Mesh()\n";
+    for ( size_t iE = 0; iE < bndSegsPerEdge.size(); ++iE )
+    {
+      const vector< BndSeg >& bndSegs = bndSegsPerEdge[ iE ];
+      for ( size_t i = 0; i < bndSegs.size(); ++i )
+      {
+        if ( !bndSegs[i]._edge )
+          text << "# E=" << iE << " i=" << i << " NULL edge\n";
+        else if ( !bndSegs[i]._edge->vertex0() ||
+                  !bndSegs[i]._edge->vertex1() )
+          text << "# E=" << iE << " i=" << i << " INFINITE edge\n";
+        else if ( addedEdges.insert( bndSegs[i]._edge ).second &&
+                  addedEdges.insert( bndSegs[i]._edge->twin() ).second )
+        {
+          v2n = v2Node.insert( make_pair( bndSegs[i]._edge->vertex0(), v2Node.size() + 1 )).first;
+          int n0 = v2n->second;
+          if ( n0 == v2Node.size() )
+            text << "n" << n0 << " = m.AddNode( "
+                 << bndSegs[i]._edge->vertex0()->x() / theScale[0] << ", "
+                 << bndSegs[i]._edge->vertex0()->y() / theScale[1] << ", 0 )\n";
+
+          v2n = v2Node.insert( make_pair( bndSegs[i]._edge->vertex1(), v2Node.size() + 1 )).first;
+          int n1 = v2n->second;
+          if ( n1 == v2Node.size() )
+            text << "n" << n1 << " = m.AddNode( "
+                 << bndSegs[i]._edge->vertex1()->x() / theScale[0] << ", "
+                 << bndSegs[i]._edge->vertex1()->y() / theScale[1] << ", 0 )\n";
+
+          text << "e" << i << " = m.AddEdge([ n" << n0 << ", n" << n1 << " ])\n";
+        }
+      }
+    }
+    text << "\n";
+    file.write( text.c_str(), text.size() );
+    cout << "execfile( '" << fileName << "')" << endl;
+#endif
+  }
+
+  //================================================================================
+  /*!
+   * \brief Computes length of a TVDEdge
+   */
+  //================================================================================
+
+  double length( const TVDEdge* edge )
+  {
+    gp_XY d( edge->vertex0()->x() - edge->vertex1()->x(),
+             edge->vertex0()->y() - edge->vertex1()->y() );
+    return d.Modulus();
+  }
+
+  //================================================================================
+  /*!
+   * \brief Compute scale to have the same 2d proportions as in 3d
+   */
+  //================================================================================
+
+  void computeProportionScale( const TopoDS_Face& face,
+                               const Bnd_B2d&     uvBox,
+                               double             scale[2])
+  {
+    scale[0] = scale[1] = 1.;
+    if ( uvBox.IsVoid() ) return;
+
+    TopLoc_Location loc;
+    Handle(Geom_Surface) surface = BRep_Tool::Surface( face, loc );
+
+    const int nbDiv = 30;
+    gp_XY uvMin = uvBox.CornerMin(), uvMax = uvBox.CornerMax();
+    gp_XY uvMid = 0.5 * ( uvMin + uvMax );
+    double du = ( uvMax.X() - uvMin.X() ) / nbDiv;
+    double dv = ( uvMax.Y() - uvMin.Y() ) / nbDiv;
+
+    double uLen3d = 0, vLen3d = 0;
+    gp_Pnt uPrevP = surface->Value( uvMin.X(), uvMid.Y() );
+    gp_Pnt vPrevP = surface->Value( uvMid.X(), uvMin.Y() );
+    for (int i = 1; i <= nbDiv; i++)
+    {
+      double u = uvMin.X() + du * i;
+      double v = uvMin.Y() + dv * i;
+      gp_Pnt uP = surface->Value( u, uvMid.Y() );
+      gp_Pnt vP = surface->Value( uvMid.X(), v );
+      uLen3d += uP.Distance( uPrevP );
+      vLen3d += vP.Distance( vPrevP );
+      uPrevP = uP;
+      vPrevP = vP;
+    }
+    scale[0] = uLen3d / ( uvMax.X() - uvMin.X() );
+    scale[1] = vLen3d / ( uvMax.Y() - uvMin.Y() );
+  }
+
+  //================================================================================
+  /*!
+   * \brief Fill input data for construct_voronoi()
+   */
+  //================================================================================
+
+  bool makeInputData(const TopoDS_Face&                face,
+                     const std::vector< TopoDS_Edge >& edges,
+                     const double                      minSegLen,
+                     vector< InPoint >&                inPoints,
+                     vector< InSegment>&               inSegments,
+                     double                            scale[2])
+  {
+    const double theDiscrCoef = 0.5; // to decrease minSegLen for discretization
+    TopLoc_Location loc;
+
+    // discretize the EDGEs to get 2d points and segments
+
+    vector< vector< UVU > > uvuVec( edges.size() );
+    Bnd_B2d uvBox;
+    for ( size_t iE = 0; iE < edges.size(); ++iE )
+    {
+      vector< UVU > & points = uvuVec[ iE ];
+
+      double f,l;
+      Handle(Geom_Curve)   c3d = BRep_Tool::Curve         ( edges[ iE ], loc, f, l );
+      Handle(Geom2d_Curve) c2d = BRep_Tool::CurveOnSurface( edges[ iE ], face, f, l );
+      if ( c2d.IsNull() ) return false;
+
+      points.push_back( UVU( c2d->Value( f ), f ));
+      uvBox.Add( points.back()._uv );
+
+      Geom2dAdaptor_Curve c2dAdaptor (c2d, f,l );
+      double curDeflect = 0.3; //0.01;  //Curvature deflection
+      double angDeflect = 0.2; // 0.09; //Angular deflection
+
+      GCPnts_TangentialDeflection discret(c2dAdaptor, angDeflect, curDeflect);
+      // if ( discret.NbPoints() > 2 )
+      // {
+      //   cout << endl;
+      //   do
+      //   {
+      //     discret.Initialize( c2dAdaptor, 100, curDeflect );
+      //     cout << "C " << curDeflect << " " << discret.NbPoints() << endl;
+      //     curDeflect *= 1.5;
+      //   }
+      //   while ( discret.NbPoints() > 5 );
+      //   cout << endl;
+      //   do
+      //   {
+      //     discret.Initialize( c2dAdaptor, angDeflect, 100 );
+      //     cout << "A " << angDeflect << " " << discret.NbPoints() << endl;
+      //     angDeflect *= 1.5;
+      //   }
+      //   while ( discret.NbPoints() > 5 );
+      // }
+      gp_Pnt p, pPrev;
+      if ( !c3d.IsNull() )
+        pPrev = c3d->Value( f );
+      if ( discret.NbPoints() > 2 )
+        for ( int i = 2; i <= discret.NbPoints(); i++ ) // skip the 1st point
+        {
+          double u = discret.Parameter(i);
+          if ( !c3d.IsNull() )
+          {
+            p = c3d->Value( u );
+            int nbDiv = int( p.Distance( pPrev ) / minSegLen / theDiscrCoef );
+            double dU = ( u - points.back()._u ) / nbDiv;
+            for ( int iD = 1; iD < nbDiv; ++iD )
+            {
+              double uD = points.back()._u + dU;
+              points.push_back( UVU( c2d->Value( uD ), uD ));
+            }
+            pPrev = p;
+          }
+          points.push_back( UVU( c2d->Value( u ), u ));
+          uvBox.Add( points.back()._uv );
+        }
+      // if ( !c3d.IsNull() )
+      // {
+      //   vector<double> params;
+      //   GeomAdaptor_Curve c3dAdaptor( c3d,f,l );
+      //   if ( useDefl )
+      //   {
+      //     const double deflection = minSegLen * 0.1;
+      //     GCPnts_UniformDeflection discret( c3dAdaptor, deflection, f, l, true );
+      //     if ( !discret.IsDone() )
+      //       return false;
+      //     int nbP = discret.NbPoints();
+      //     for ( int i = 2; i < nbP; i++ ) // skip 1st and last points
+      //       params.push_back( discret.Parameter(i) );
+      //   }
+      //   else
+      //   {
+      //     double   eLen = GCPnts_AbscissaPoint::Length( c3dAdaptor );
+      //     int     nbSeg = Max( 1, int( eLen / minSegLen / theDiscrCoef ));
+      //     double segLen = eLen / nbSeg;
+      //     GCPnts_UniformAbscissa discret( c3dAdaptor, segLen, f, l );
+      //     int nbP = Min( discret.NbPoints(), nbSeg + 1 );
+      //     for ( int i = 2; i < nbP; i++ ) // skip 1st and last points
+      //       params.push_back( discret.Parameter(i) );
+      //   }
+      //   for ( size_t i = 0; i < params.size(); ++i )
+      //   {
+      //     points.push_back( UVU( c2d->Value( params[i] ), params[i] ));
+      //     uvBox.Add( points.back()._uv );
+      //   }
+      // }
+      if ( points.size() < 2 )
+      {
+        points.push_back( UVU( c2d->Value( l ), l ));
+        uvBox.Add( points.back()._uv );
+      }
+      if ( edges[ iE ].Orientation() == TopAbs_REVERSED )
+        std::reverse( points.begin(), points.end() );
+    }
+
+    // make connected EDGEs have same UV at shared VERTEX
+    TopoDS_Vertex vShared;
+    for ( size_t iE = 0; iE < edges.size(); ++iE )
+    {
+      size_t iE2 = (iE+1) % edges.size();
+      if ( !TopExp::CommonVertex( edges[iE], edges[iE2], vShared ))
+        continue;
+      if ( !vShared.IsSame( TopExp::LastVertex( edges[iE], true )))
+        return false;
+      vector< UVU > & points1 = uvuVec[ iE ];
+      vector< UVU > & points2 = uvuVec[ iE2 ];
+      gp_Pnt2d & uv1 = points1.back() ._uv;
+      gp_Pnt2d & uv2 = points2.front()._uv;
+      uv1 = uv2 = 0.5 * ( uv1.XY() + uv2.XY() );
+    }
+
+    // get scale to have the same 2d proportions as in 3d
+    computeProportionScale( face, uvBox, scale );
+
+    // make scale to have coordinates precise enough when converted to int
+
+    gp_XY uvMin = uvBox.CornerMin(), uvMax = uvBox.CornerMax();
+    uvMin.ChangeCoord(1) = uvMin.X() * scale[0];
+    uvMin.ChangeCoord(2) = uvMin.Y() * scale[1];
+    uvMax.ChangeCoord(1) = uvMax.X() * scale[0];
+    uvMax.ChangeCoord(2) = uvMax.Y() * scale[1];
+    double vMax[2] = { Max( Abs( uvMin.X() ), Abs( uvMax.X() )),
+                       Max( Abs( uvMin.Y() ), Abs( uvMax.Y() )) };
+    int iMax = ( vMax[0] > vMax[1] ) ? 0 : 1;
+    const double precision = 1e-5;
+    double preciScale = Min( vMax[iMax] / precision,
+                             std::numeric_limits<int>::max() / vMax[iMax] );
+    preciScale /= scale[iMax];
+    double roundedScale = 10; // to ease debug
+    while ( roundedScale * 10 < preciScale )
+      roundedScale *= 10.;
+    scale[0] *= roundedScale;
+    scale[1] *= roundedScale;
+
+    // create input points and segments
+
+    inPoints.clear();
+    inSegments.clear();
+    size_t nbPnt = 0;
+    for ( size_t iE = 0; iE < uvuVec.size(); ++iE )
+      nbPnt += uvuVec[ iE ].size();
+    inPoints.resize( nbPnt );
+    inSegments.reserve( nbPnt );
+
+    size_t iP = 0;
+    if ( face.Orientation() == TopAbs_REVERSED )
+    {
+      for ( int iE = uvuVec.size()-1; iE >= 0; --iE )
+      {
+        vector< UVU > & points = uvuVec[ iE ];
+        inPoints[ iP++ ] = points.back().getInPoint( scale );
+        for ( size_t i = points.size()-1; i >= 1; --i )
+        {
+          inPoints[ iP++ ] = points[i-1].getInPoint( scale );
+          inSegments.push_back( InSegment( & inPoints[ iP-2 ], & inPoints[ iP-1 ], iE ));
+        }
+      }
+    }
+    else
+    {
+      for ( size_t iE = 0; iE < uvuVec.size(); ++iE )
+      {
+        vector< UVU > & points = uvuVec[ iE ];
+        inPoints[ iP++ ] = points[0].getInPoint( scale );
+        for ( size_t i = 1; i < points.size(); ++i )
+        {
+          inPoints[ iP++ ] = points[i].getInPoint( scale );
+          inSegments.push_back( InSegment( & inPoints[ iP-2 ], & inPoints[ iP-1 ], iE ));
+        }
+      }
+    }
+    // debug
+    theScale[0] = scale[0];
+    theScale[1] = scale[1];
+
+    return true;
+  }
+
+  //================================================================================
+  /*!
+   * \brief Update a branch joined to another one
+   */
+  //================================================================================
+
+  void updateJoinedBranch( vector< const TVDEdge* > &   branchEdges,
+                           const size_t                 newID,
+                           vector< vector< BndSeg > > & bndSegs,
+                           const bool                   reverse)
+  {
+    BndSeg *seg1, *seg2;
+    if ( reverse )
+    {
+      for ( size_t i = 0; i < branchEdges.size(); ++i )
+      {
+        if (( seg1 = BndSeg::getBndSegOfEdge( branchEdges[i],         bndSegs )) &&
+            ( seg2 = BndSeg::getBndSegOfEdge( branchEdges[i]->twin(), bndSegs )))
+        {
+          seg1->_branchID /= seg1->branchID();
+          seg2->_branchID /= seg2->branchID();
+          seg1->_branchID *= -newID;
+          seg2->_branchID *= -newID;
+          branchEdges[i] = branchEdges[i]->twin();
+        }
+      }
+      std::reverse( branchEdges.begin(), branchEdges.end() );
+    }
+    else
+    {
+      for ( size_t i = 0; i < branchEdges.size(); ++i )
+      {
+        if (( seg1 = BndSeg::getBndSegOfEdge( branchEdges[i],         bndSegs )) &&
+            ( seg2 = BndSeg::getBndSegOfEdge( branchEdges[i]->twin(), bndSegs )))
+        {
+          seg1->_branchID /= seg1->branchID();
+          seg2->_branchID /= seg2->branchID();
+          seg1->_branchID *= newID;
+          seg2->_branchID *= newID;
+        }
+      }
+    }
+  }
+
+  //================================================================================
+  /*!
+   * \brief Create MA branches and FACE boundary data
+   *  \param [in] vd - voronoi diagram of \a inSegments
+   *  \param [in] inPoints - FACE boundary points
+   *  \param [in,out] inSegments - FACE boundary segments
+   *  \param [out] branch - MA branches to fill
+   *  \param [out] branchEnd - ends of MA branches to fill
+   *  \param [out] boundary - FACE boundary to fill
+   */
+  //================================================================================
+
+  void makeMA( const TVD&                               vd,
+               const bool                               ignoreCorners,
+               vector< InPoint >&                       inPoints,
+               vector< InSegment > &                    inSegments,
+               vector< SMESH_MAT2d::Branch >&           branch,
+               vector< const SMESH_MAT2d::BranchEnd* >& branchPnt,
+               SMESH_MAT2d::Boundary&                   boundary )
+  {
+    // Associate MA cells with geom EDGEs
+    for (TVD::const_cell_iterator it = vd.cells().begin(); it != vd.cells().end(); ++it)
+    {
+      const TVDCell* cell = &(*it);
+      if ( cell->contains_segment() )
+      {
+        InSegment& seg = inSegments[ cell->source_index() ];
+        seg._cell = cell;
+        seg.setGeomEdgeToCell( cell, seg._geomEdgeInd );
+      }
+      else
+      {
+        InSegment::setGeomEdgeToCell( cell, theNoEdgeID );
+      }
+    }
+
+    vector< bool > inPntChecked( inPoints.size(), false );
+
+    // Find MA edges of each inSegment
+
+    for ( size_t i = 0; i < inSegments.size(); ++i )
+    {
+      InSegment& inSeg = inSegments[i];
+
+      // get edges around the cell lying on MA
+      bool hasSecondary = false;
+      const TVDEdge* edge = inSeg._cell->incident_edge();
+      do {
+        edge = edge->next(); // Returns the CCW next edge within the cell.
+        if ( edge->is_primary() && !inSeg.isExternal( edge ) )
+          inSeg._edges.push_back( edge ); // edge equidistant from two InSegments
+        else
+          hasSecondary = true;
+      } while (edge != inSeg._cell->incident_edge());
+
+      // there can be several continuous MA edges but maEdges can begin in the middle of
+      // a chain of continuous MA edges. Make the chain continuous.
+      list< const TVDEdge* >& maEdges = inSeg._edges;
+      if ( maEdges.empty() )
+        continue;
+      if ( hasSecondary )
+        while ( maEdges.back()->next() == maEdges.front() )
+          maEdges.splice( maEdges.end(), maEdges, maEdges.begin() );
+
+      // remove maEdges equidistant from two neighbor InSegments of the same geom EDGE
+      list< const TVDEdge* >::iterator e = maEdges.begin();
+      while ( e != maEdges.end() )
+      {
+        const TVDCell* cell2 = (*e)->twin()->cell(); // cell on the other side of a MA edge
+        size_t         geoE2 = InSegment::getGeomEdge( cell2 );
+        bool        toRemove = ( inSeg._geomEdgeInd == geoE2 && inSeg.isConnected( *e ));
+        if ( toRemove )
+          e = maEdges.erase( e );
+        else
+          ++e;
+      }
+      if ( maEdges.empty() )
+        continue;
+
+      // add MA edges corresponding to concave InPoints
+      for ( int is2nd = 0; is2nd < 2; ++is2nd ) // loop on two ends of inSeg
+      {
+        InPoint& inPnt = *( is2nd ? inSeg._p1 : inSeg._p0 );
+        size_t    pInd = inPnt.index( inPoints );
+        if ( inPntChecked[ pInd ] )
+          continue;
+        if ( pInd > 0 &&
+             inPntChecked[ pInd-1 ] &&
+             inPoints[ pInd-1 ] == inPnt )
+          continue;
+        inPntChecked[ pInd ] = true;
+
+        const TVDEdge* maE = is2nd ? maEdges.front() : maEdges.back();
+        if ( inPnt == ( is2nd ? maE->vertex0() : maE->vertex1() ))
+          continue;
+        const TVDEdge* edge =  // a secondary TVDEdge connecting inPnt and maE
+          is2nd ? maE->prev() : maE->next();
+        while ( inSeg.isConnected( edge ))
+        {
+          if ( edge->is_primary() ) break; // this should not happen
+          const TVDEdge* edge2 = edge->twin(); // we are in a neighbor cell, add MA edges to inPnt
+          if ( inSeg.getGeomEdge( edge2->cell() ) != theNoEdgeID )
+            break; // cell of an InSegment
+          bool hasInfinite = false;
+          list< const TVDEdge* > pointEdges;
+          edge = edge2;
+          do
+          {
+            edge = edge->next(); // Returns the CCW next edge within the cell.
+            if ( edge->is_infinite() )
+              hasInfinite = true;
+            else if ( edge->is_primary() && !inSeg.isExternal( edge ))
+              pointEdges.push_back( edge );
+          }
+          while ( edge != edge2 && !hasInfinite );
+
+          if ( hasInfinite || pointEdges.empty() )
+            break;
+          inPnt._edges.splice( inPnt._edges.end(), pointEdges );
+          inSeg.setGeomEdgeToCell( edge->cell(), inSeg._geomEdgeInd );
+
+          edge = is2nd ? inPnt._edges.front()->prev() : inPnt._edges.back()->next();
+        }
+      } // add MA edges corresponding to concave InPoints
+
+    } // loop on inSegments to find corresponding MA edges
+
+
+    // -------------------------------------------
+    // Create Branches and BndPoints for each EDGE
+    // -------------------------------------------
+
+    if ( inPoints.front() == inPoints.back() /*&& !inPoints[0]._edges.empty()*/ )
+    {
+      inPntChecked[0] = false; // do not use the 1st point twice
+      //InSegment::setGeomEdgeToCell( inPoints[0]._edges.back()->cell(), theNoEdgeID );
+      inPoints[0]._edges.clear();
+    }
+
+    // Divide InSegment's into BndSeg's (so that each BndSeg corresponds to one MA edge)
+
+    vector< vector< BndSeg > > bndSegsPerEdge( boundary.nbEdges() ); // all BndSeg's
+    {
+      vector< BndSeg > bndSegs; // bndSeg's of a current EDGE
+      size_t prevGeomEdge = theNoEdgeID;
+
+      list< const TVDEdge* >::reverse_iterator e;
+      for ( size_t i = 0; i < inSegments.size(); ++i )
+      {
+        InSegment& inSeg = inSegments[i];
+
+        if ( inSeg._geomEdgeInd != prevGeomEdge )
+        {
+          if ( !bndSegs.empty() )
+            bndSegsPerEdge[ prevGeomEdge ].swap( bndSegs );
+          prevGeomEdge = inSeg._geomEdgeInd;
+        }
+
+        // segments around 1st concave point
+        size_t ip0 = inSeg._p0->index( inPoints );
+        if ( inPntChecked[ ip0 ] )
+          for ( e = inSeg._p0->_edges.rbegin(); e != inSeg._p0->_edges.rend(); ++e )
+            bndSegs.push_back( BndSeg( &inSeg, *e, inSeg._p0->_param ));
+        inPntChecked[ ip0 ] = false;
+
+        // segments of InSegment's
+        const size_t nbMaEdges = inSeg._edges.size();
+        switch ( nbMaEdges ) {
+        case 0: // "around" circle center
+          bndSegs.push_back( BndSeg( &inSeg, 0, inSeg._p1->_param )); break;
+        case 1:
+          bndSegs.push_back( BndSeg( &inSeg, inSeg._edges.back(), inSeg._p1->_param )); break;
+        default:
+          gp_XY inSegDir( inSeg._p1->_a - inSeg._p0->_a,
+                          inSeg._p1->_b - inSeg._p0->_b );
+          const double inSegLen2 = inSegDir.SquareModulus();
+          e = inSeg._edges.rbegin();
+          for ( size_t iE = 1; iE < nbMaEdges; ++e, ++iE )
+          {
+            gp_XY toMA( (*e)->vertex0()->x() - inSeg._p0->_a,
+                        (*e)->vertex0()->y() - inSeg._p0->_b );
+            double r = toMA * inSegDir / inSegLen2;
+            double u = r * inSeg._p1->_param + ( 1. - r ) * inSeg._p0->_param;
+            bndSegs.push_back( BndSeg( &inSeg, *e, u ));
+          }
+          bndSegs.push_back( BndSeg( &inSeg, *e, inSeg._p1->_param ));
+        }
+        // segments around 2nd concave point
+        size_t ip1 = inSeg._p1->index( inPoints );
+        if ( inPntChecked[ ip1 ] )
+          for ( e = inSeg._p1->_edges.rbegin(); e != inSeg._p1->_edges.rend(); ++e )
+            bndSegs.push_back( BndSeg( &inSeg, *e, inSeg._p1->_param ));
+        inPntChecked[ ip1 ] = false;
+      }
+      if ( !bndSegs.empty() )
+        bndSegsPerEdge[ prevGeomEdge ].swap( bndSegs );
+    }
+
+    // prepare to MA branch search
+    for ( size_t iE = 0; iE < bndSegsPerEdge.size(); ++iE )
+    {
+      // 1) make TVDEdge's know it's BndSeg to enable passing branchID to
+      // an opposite BndSeg in BndSeg::setBranch(); geom EDGE ID is known from TVDCell
+      // 2) connect bndSegs via BndSeg::_prev
+
+      vector< BndSeg >& bndSegs = bndSegsPerEdge[ iE ];
+      if ( bndSegs.empty() ) continue;
+
+      for ( size_t i = 1; i < bndSegs.size(); ++i )
+      {
+        bndSegs[i]._prev = & bndSegs[i-1];
+        bndSegs[i].setIndexToEdge( i );
+      }
+      // look for the last bndSeg of previous EDGE to set bndSegs[0]._prev
+      const InPoint& p0 = bndSegs[0]._inSeg->point0();
+      for ( size_t iE2 = 0; iE2 < bndSegsPerEdge.size(); ++iE2 )
+        if ( p0 == bndSegsPerEdge[ iE2 ].back()._inSeg->point1() )
+        {
+          bndSegs[0]._prev = & bndSegsPerEdge[ iE2 ].back();
+          break;
+        }
+      bndSegs[0].setIndexToEdge( 0 );
+    }
+
+    bndSegsToMesh( bndSegsPerEdge ); // debug: visually check found MA edges
+
+
+    // Find TVDEdge's of Branches and associate them with bndSegs
+
+    vector< vector<const TVDEdge*> > branchEdges;
+    branchEdges.reserve( boundary.nbEdges() * 4 );
+
+    map< const TVDVertex*, SMESH_MAT2d::BranchEndType > endType;
+
+    int branchID = 1; // we code orientation as branchID sign
+    branchEdges.resize( branchID );
+
+    for ( size_t iE = 0; iE < bndSegsPerEdge.size(); ++iE )
+    {
+      vector< BndSeg >& bndSegs = bndSegsPerEdge[ iE ];
+      for ( size_t i = 0; i < bndSegs.size(); ++i )
+      {
+        if ( bndSegs[i].branchID() )
+        {
+          if ( bndSegs[i]._prev &&
+               bndSegs[i]._branchID == -bndSegs[i]._prev->_branchID &&
+               bndSegs[i]._edge )
+          {
+            SMESH_MAT2d::BranchEndType type =
+              ( bndSegs[i]._inSeg->isConnected( bndSegs[i]._edge ) ?
+                SMESH_MAT2d::BE_ON_VERTEX :
+                SMESH_MAT2d::BE_END );
+            endType.insert( make_pair( bndSegs[i]._edge->vertex1(), type ));
+          }
+          continue;
+        }
+        if ( !bndSegs[i]._prev &&
+             !bndSegs[i].hasOppositeEdge() )
+          continue;
+
+        if ( !bndSegs[i]._prev ||
+             !bndSegs[i]._prev->isSameBranch( bndSegs[i] ))
+        {
+          branchEdges.resize(( branchID = branchEdges.size()) + 1 );
+          if ( bndSegs[i]._edge && bndSegs[i]._prev )
+            endType.insert( make_pair( bndSegs[i]._edge->vertex1(), SMESH_MAT2d::BE_BRANCH_POINT ));
+        }
+        else if ( bndSegs[i]._prev->_branchID )
+        {
+          branchID = bndSegs[i]._prev->_branchID;  // with sign
+        }
+        else if ( bndSegs[i]._edge ) // 1st bndSeg of a WIRE
+        {
+          branchEdges.resize(( branchID = branchEdges.size()) + 1 );
+          if ( bndSegs[i]._inSeg->isConnected( bndSegs[i]._edge ))
+          {
+            if ( bndSegs[i]._inSeg->point0() == bndSegs[i]._edge->vertex1() )
+              endType.insert( make_pair( bndSegs[i]._edge->vertex1(), SMESH_MAT2d::BE_ON_VERTEX ));
+            else
+              endType.insert( make_pair( bndSegs[i]._edge->vertex0(), SMESH_MAT2d::BE_ON_VERTEX ));
+          }
+        }
+
+        bndSegs[i].setBranch( branchID, bndSegsPerEdge ); // set to i-th and to the opposite bndSeg
+        if ( bndSegs[i].hasOppositeEdge() )
+          branchEdges[ bndSegs[i].branchID() ].push_back( bndSegs[i]._edge );
+      }
+    }
+
+    // join the 1st and the last branch edges if it is the same branch
+    // if ( bndSegs.back().branchID() != bndSegs.front().branchID() &&
+    //      bndSegs.back().isSameBranch( bndSegs.front() ))
+    // {
+    //   vector<const TVDEdge*> & br1 = branchEdges[ bndSegs.front().branchID() ];
+    //   vector<const TVDEdge*> & br2 = branchEdges[ bndSegs.back().branchID()  ];
+    //   br1.insert( br1.begin(), br2.begin(), br2.end() );
+    //   br2.clear();
+    // }
+
+    // remove branches ending at BE_ON_VERTEX
+
+    vector<bool> isBranchRemoved( branchEdges.size(), false );
+
+    if ( ignoreCorners && branchEdges.size() > 2 && !branchEdges[2].empty() )
+    {
+      // find branches to remove
+      map< const TVDVertex*, SMESH_MAT2d::BranchEndType >::iterator v2et;
+      for ( size_t iB = 1; iB < branchEdges.size(); ++iB )
+      {
+        if ( branchEdges[iB].empty() )
+          continue;
+        const TVDVertex* v0 = branchEdges[iB][0]->vertex1();
+        const TVDVertex* v1 = branchEdges[iB].back()->vertex0();
+        v2et = endType.find( v0 );
+        if ( v2et != endType.end() && v2et->second == SMESH_MAT2d::BE_ON_VERTEX )
+          isBranchRemoved[ iB ] = true;
+        v2et = endType.find( v1 );
+        if ( v2et != endType.end() && v2et->second == SMESH_MAT2d::BE_ON_VERTEX )
+          isBranchRemoved[ iB ] = true;
+      }
+      // try to join not removed branches into one
+      for ( size_t iB = 1; iB < branchEdges.size(); ++iB )
+      {
+        if ( branchEdges[iB].empty() || isBranchRemoved[iB] )
+          continue;
+        const TVDVertex* v0 = branchEdges[iB][0]->vertex1();
+        const TVDVertex* v1 = branchEdges[iB].back()->vertex0();
+        v2et = endType.find( v0 );
+        if ( v2et == endType.end() || v2et->second != SMESH_MAT2d::BE_BRANCH_POINT )
+          v0 = 0;
+        v2et = endType.find( v1 );
+        if ( v2et == endType.end() || v2et->second != SMESH_MAT2d::BE_BRANCH_POINT )
+          v1 = 0;
+        if ( !v0 && !v1 )
+          continue;
+
+        for ( int isV0 = 0; isV0 < 2; ++isV0 )
+        {
+          const TVDVertex* v = isV0 ? v0 : v1;
+          size_t iBrToJoin = 0;
+          for ( size_t iB2 = 1; iB2 < branchEdges.size(); ++iB2 )
+          {
+            if ( branchEdges[iB2].empty() || isBranchRemoved[iB2] || iB == iB2 )
+              continue;
+            const TVDVertex* v02 = branchEdges[iB2][0]->vertex1();
+            const TVDVertex* v12 = branchEdges[iB2].back()->vertex0();
+            if ( v == v02 || v == v12 )
+            {
+              if ( iBrToJoin > 0 )
+              {
+                iBrToJoin = 0;
+                break; // more than 2 not removed branches meat at a TVDVertex
+              }
+              iBrToJoin = iB2;
+            }
+          }
+          if ( iBrToJoin > 0 )
+          {
+            vector<const TVDEdge*>& branch = branchEdges[ iBrToJoin ];
+            const TVDVertex* v02 = branch[0]->vertex1();
+            const TVDVertex* v12 = branch.back()->vertex0();
+            updateJoinedBranch( branch, iB, bndSegsPerEdge, /*reverse=*/(v0 == v02 || v1 == v12 ));
+            if ( v0 == v02 || v0 == v12 )
+              branchEdges[iB].insert( branchEdges[iB].begin(), branch.begin(), branch.end() );
+            else
+              branchEdges[iB].insert( branchEdges[iB].end(),   branch.begin(), branch.end() );
+            branch.clear();
+          }
+        }
+      } // loop on branchEdges
+    } // if ( ignoreCorners )
+
+    // associate branchIDs and the input branch vector (arg)
+    vector< SMESH_MAT2d::Branch* > branchByID( branchEdges.size(), 0 );
+    int nbBranches = 0;
+    for ( size_t i = 0; i < branchEdges.size(); ++i )
+    {
+      nbBranches += ( !branchEdges[i].empty() );
+    }
+    branch.resize( nbBranches );
+    size_t iBr = 0;
+    for ( size_t brID = 1; brID < branchEdges.size(); ++brID ) // 1st - not removed
+    {
+      if ( !branchEdges[ brID ].empty() && !isBranchRemoved[ brID ])
+        branchByID[ brID ] = & branch[ iBr++ ];
+    }
+    for ( size_t brID = 1; brID < branchEdges.size(); ++brID ) // then - removed
+    {
+      if ( !branchEdges[ brID ].empty() && isBranchRemoved[ brID ])
+        branchByID[ brID ] = & branch[ iBr++ ];
+    }
+
+    // Fill in BndPoints of each EDGE of the boundary
+
+    //size_t iSeg = 0;
+    int edgeInd = -1, dInd = 0;
+    for ( size_t iE = 0; iE < bndSegsPerEdge.size(); ++iE )
+    {
+      vector< BndSeg >&          bndSegs = bndSegsPerEdge[ iE ];
+      SMESH_MAT2d::BndPoints & bndPoints = boundary.getPoints( iE );
+
+      // make TVDEdge know an index of bndSegs within BndPoints
+      for ( size_t i = 0; i < bndSegs.size(); ++i )
+        if ( bndSegs[i]._edge )
+          SMESH_MAT2d::Branch::setBndSegment( i, bndSegs[i]._edge );
+
+      // parameters on EDGE
+
+      bndPoints._params.reserve( bndSegs.size() + 1 );
+      bndPoints._params.push_back( bndSegs[ 0 ]._inSeg->_p0->_param );
+
+      for ( size_t i = 0; i < bndSegs.size(); ++i )
+        bndPoints._params.push_back( bndSegs[ i ]._uLast );
+
+      // MA edges
+
+      bndPoints._maEdges.reserve( bndSegs.size() );
+
+      for ( size_t i = 0; i < bndSegs.size(); ++i )
+      {
+        const size_t              brID = bndSegs[ i ].branchID();
+        const SMESH_MAT2d::Branch*  br = branchByID[ brID ];
+
+        if ( bndSegs[ i ]._edge && !branchEdges[ brID ].empty() )
+        {
+          edgeInd += dInd;
+
+          if (( edgeInd < 0 ||
+                edgeInd >= (int) branchEdges[ brID ].size() ) ||
+              ( branchEdges[ brID ][ edgeInd ]         != bndSegs[ i ]._edge &&
+                branchEdges[ brID ][ edgeInd ]->twin() != bndSegs[ i ]._edge ))
+          {
+            if ( bndSegs[ i ]._branchID < 0 )
+            {
+              dInd = -1;
+              for ( edgeInd = branchEdges[ brID ].size() - 1; edgeInd > 0; --edgeInd )
+                if ( branchEdges[ brID ][ edgeInd ]->twin() == bndSegs[ i ]._edge )
+                  break;
+            }
+            else // bndSegs[ i ]._branchID > 0
+            {
+              dInd = +1;
+              for ( edgeInd = 0; edgeInd < branchEdges[ brID ].size(); ++edgeInd )
+                if ( branchEdges[ brID ][ edgeInd ] == bndSegs[ i ]._edge )
+                  break;
+            }
+          }
+        }
+        else
+        {
+          // no MA edge, bndSeg corresponds to an end point of a branch
+          if ( bndPoints._maEdges.empty() )
+            edgeInd = 0;
+          else
+            edgeInd = branchEdges[ brID ].size();
+          dInd = bndSegs[ i ]._branchID > 0 ? +1 : -1;
+        }
+
+        bndPoints._maEdges.push_back( make_pair( br, ( 1 + edgeInd ) * dInd ));
+
+      } // loop on bndSegs of an EDGE
+    } // loop on all bndSegs to construct Boundary
+
+    // Initialize branches
+
+    // find a not removed branch
+    size_t iBrNorRemoved = 0;
+    for ( size_t brID = 1; brID < branchEdges.size(); ++brID )
+      if ( !branchEdges[brID].empty() && !isBranchRemoved[brID] )
+      {
+        iBrNorRemoved = brID;
+        break;
+      }
+    // fill the branches with MA edges
+    for ( size_t brID = 1; brID < branchEdges.size(); ++brID )
+      if ( !branchEdges[brID].empty() )
+      {
+        branchByID[ brID ]->init( branchEdges[brID], & boundary, endType );
+      }
+    // mark removed branches
+    for ( size_t brID = 1; brID < branchEdges.size(); ++brID )
+      if ( isBranchRemoved[brID] && iBrNorRemoved > 0 )
+      {
+        SMESH_MAT2d::Branch* branch     = branchByID[ brID ];
+        SMESH_MAT2d::Branch* mainBranch = branchByID[ iBrNorRemoved ];
+        bool is1stBrPnt = ( branch->getEnd(0)->_type == SMESH_MAT2d::BE_BRANCH_POINT );
+        const TVDVertex* branchVextex = 
+          is1stBrPnt ? branch->getEnd(0)->_vertex : branch->getEnd(1)->_vertex;
+        SMESH_MAT2d::BranchPoint bp = mainBranch->getPoint( branchVextex );
+        branch->setRemoved( bp );
+      }
+    // set branches to branch ends
+    for ( size_t i = 0; i < branch.size(); ++i )
+      if ( !branch[i].isRemoved() )
+        branch[i].setBranchesToEnds( branch );
+
+    // fill branchPnt arg
+    map< const TVDVertex*, const SMESH_MAT2d::BranchEnd* > v2end;
+    for ( size_t i = 0; i < branch.size(); ++i )
+    {
+      if ( branch[i].getEnd(0)->_branches.size() > 2 )
+        v2end.insert( make_pair( branch[i].getEnd(0)->_vertex, branch[i].getEnd(0) ));
+      if ( branch[i].getEnd(1)->_branches.size() > 2 )
+        v2end.insert( make_pair( branch[i].getEnd(1)->_vertex, branch[i].getEnd(1) ));
+    }
+    branchPnt.resize( v2end.size() );
+    map< const TVDVertex*, const SMESH_MAT2d::BranchEnd* >::iterator v2e = v2end.begin();
+    for ( size_t i = 0; v2e != v2end.end(); ++v2e, ++i )
+      branchPnt[ i ] = v2e->second;
+
+  } // makeMA()
+
+} // namespace
+
+//================================================================================
+/*!
+ * \brief MedialAxis constructor
+ *  \param [in] face - a face to create MA for
+ *  \param [in] edges - edges of the face (possibly not all) on the order they
+ *              encounter in the face boundary.
+ *  \param [in] minSegLen - minimal length of a mesh segment used to discretize
+ *              the edges. It is used to define precision of MA approximation
+ */
+//================================================================================
+
+SMESH_MAT2d::MedialAxis::MedialAxis(const TopoDS_Face&                face,
+                                    const std::vector< TopoDS_Edge >& edges,
+                                    const double                      minSegLen,
+                                    const bool                        ignoreCorners):
+  _face( face ), _boundary( edges.size() )
+{
+  // input to construct_voronoi()
+  vector< InPoint >  inPoints;
+  vector< InSegment> inSegments;
+  if ( !makeInputData( face, edges, minSegLen, inPoints, inSegments, _scale ))
+    return;
+
+  inSegmentsToFile( inSegments );
+
+  // build voronoi diagram
+  construct_voronoi( inSegments.begin(), inSegments.end(), &_vd );
+
+  // make MA data
+  makeMA( _vd, ignoreCorners, inPoints, inSegments, _branch, _branchPnt, _boundary );
+
+  // count valid branches
+  _nbBranches = _branch.size();
+  for ( size_t i = 0; i < _branch.size(); ++i )
+    if ( _branch[i].isRemoved() )
+      --_nbBranches;
+}
+
+//================================================================================
+/*!
+ * \brief Returns the i-th branch
+ */
+//================================================================================
+
+const SMESH_MAT2d::Branch* SMESH_MAT2d::MedialAxis::getBranch(size_t i) const
+{
+  return i < _nbBranches ? &_branch[i] : 0;
+}
+
+//================================================================================
+/*!
+ * \brief Return UVs of ends of MA edges of a branch
+ */
+//================================================================================
+
+void SMESH_MAT2d::MedialAxis::getPoints( const Branch*         branch,
+                                         std::vector< gp_XY >& points) const
+{
+  branch->getPoints( points, _scale );
+}
+
+//================================================================================
+/*!
+ * \brief Returns a BranchPoint corresponding to a given point on a geom EDGE
+ *  \param [in] iEdge - index of geom EDGE within a vector passed at MA construction
+ *  \param [in] u - parameter of the point on EDGE curve
+ *  \param [out] p - the found BranchPoint
+ *  \return bool - is OK
+ */
+//================================================================================
+
+bool SMESH_MAT2d::Boundary::getBranchPoint( const std::size_t iEdge,
+                                            double            u,
+                                            BranchPoint&      p ) const
+{
+  if ( iEdge >= _pointsPerEdge.size() || _pointsPerEdge[iEdge]._params.empty() )
+    return false;
+
+  const BndPoints& points = _pointsPerEdge[ iEdge ];
+  const bool  edgeReverse = ( points._params[0] > points._params.back() );
+
+  if ( u < ( edgeReverse ? points._params.back() : points._params[0] ))
+    u = edgeReverse ? points._params.back() : points._params[0];
+  else if ( u > ( edgeReverse ? points._params[0] : points._params.back()) )
+    u = edgeReverse ? points._params[0] : points._params.back();
+
+  double r = ( u - points._params[0] ) / ( points._params.back() - points._params[0] );
+  int    i = int( r * double( points._maEdges.size()-1 ));
+  if ( edgeReverse )
+  {
+    while ( points._params[i  ] < u ) --i;
+    while ( points._params[i+1] > u ) ++i;
+  }
+  else
+  {
+    while ( points._params[i  ] > u ) --i;
+    while ( points._params[i+1] < u ) ++i;
+  }
+
+  if ( points._params[i] == points._params[i+1] ) // coincident points at some end
+  {
+    int di = ( points._params[0] == points._params[i] ) ? +1 : -1;
+    while ( points._params[i] == points._params[i+1] )
+      i += di;
+    if ( i < 0 || i+1 >= points._params.size() )
+      i = 0;
+  }
+
+  double edgeParam = ( u - points._params[i] ) / ( points._params[i+1] - points._params[i] );
+
+  if ( !points._maEdges[ i ].second ) // no branch at the EDGE end, look for a closest branch
+  {
+    if ( i < points._maEdges.size() / 2 ) // near 1st point
+    {
+      while ( i < points._maEdges.size()-1 && !points._maEdges[ i ].second )
+        ++i;
+      edgeParam = edgeReverse;
+    }
+    else // near last point
+    {
+      while ( i > 0 && !points._maEdges[ i ].second )
+        --i;
+      edgeParam = !edgeReverse;
+    }
+  }
+  const std::pair< const Branch*, int >& maE = points._maEdges[ i ];
+  bool maReverse = ( maE.second < 0 );
+
+  p._branch    = maE.first;
+  p._iEdge     = ( maReverse ? -maE.second : maE.second ) - 1; // countered from 1 to store sign
+  p._edgeParam = ( maE.first && maReverse ) ? ( 1. - edgeParam ) : edgeParam;
+
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief Returns a BranchPoint corresponding to a given BoundaryPoint on a geom EDGE
+ *  \param [in] bp - the BoundaryPoint
+ *  \param [out] p - the found BranchPoint
+ *  \return bool - is OK
+ */
+//================================================================================
+
+bool SMESH_MAT2d::Boundary::getBranchPoint( const BoundaryPoint& bp,
+                                            BranchPoint&         p ) const
+{
+  return getBranchPoint( bp._edgeIndex, bp._param, p );
+}
+
+//================================================================================
+/*!
+ * \brief Check if a given boundary segment is a null-length segment on a concave
+ *        boundary corner.
+ *  \param [in] iEdge - index of a geom EDGE
+ *  \param [in] iSeg - index of a boundary segment
+ *  \return bool - true if the segment is on concave corner
+ */
+//================================================================================
+
+bool SMESH_MAT2d::Boundary::isConcaveSegment( std::size_t iEdge, std::size_t iSeg ) const
+{
+  if ( iEdge >= _pointsPerEdge.size() || _pointsPerEdge[iEdge]._params.empty() )
+    return false;
+
+  const BndPoints& points = _pointsPerEdge[ iEdge ];
+  if ( points._params.size() <= iSeg+1 )
+    return false;
+
+  return Abs( points._params[ iSeg ] - points._params[ iSeg+1 ]) < 1e-20;
+}
+
+//================================================================================
+/*!
+ * \brief Moves (changes _param) a given BoundaryPoint to a closest EDGE end
+ */
+//================================================================================
+
+bool SMESH_MAT2d::Boundary::moveToClosestEdgeEnd( BoundaryPoint& bp ) const
+{
+  if ( bp._edgeIndex >= _pointsPerEdge.size() )
+    return false;
+
+  const BndPoints& points = _pointsPerEdge[ bp._edgeIndex ];
+  if ( Abs( bp._param - points._params[0]) < Abs( points._params.back() - bp._param ))
+    bp._param = points._params[0];
+  else 
+    bp._param = points._params.back();
+
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief Creates a 3d curve corresponding to a Branch
+ *  \param [in] branch - the Branch
+ *  \return Adaptor3d_Curve* - the new curve the caller is to delete
+ */
+//================================================================================
+
+Adaptor3d_Curve* SMESH_MAT2d::MedialAxis::make3DCurve(const Branch& branch) const
+{
+  Handle(Geom_Surface) surface = BRep_Tool::Surface( _face );
+  if ( surface.IsNull() )
+    return 0;
+
+  vector< gp_XY > uv;
+  branch.getPoints( uv, _scale );
+  if ( uv.size() < 2 )
+    return 0;
+
+  vector< TopoDS_Vertex > vertex( uv.size() );
+  for ( size_t i = 0; i < uv.size(); ++i )
+    vertex[i] = BRepBuilderAPI_MakeVertex( surface->Value( uv[i].X(), uv[i].Y() ));
+
+  TopoDS_Wire aWire;
+  BRep_Builder aBuilder;
+  aBuilder.MakeWire(aWire);
+  for ( size_t i = 1; i < vertex.size(); ++i )
+  {
+    TopoDS_Edge edge = BRepBuilderAPI_MakeEdge( vertex[i-1], vertex[i] );
+    aBuilder.Add( aWire, edge );
+  }
+
+  // if ( myEdge.size() == 2 && FirstVertex().IsSame( LastVertex() ))
+  //   aWire.Closed(true); // issue 0021141
+
+  return new BRepAdaptor_CompCurve( aWire );
+}
+
+//================================================================================
+/*!
+ * \brief Copy points of an EDGE
+ */
+//================================================================================
+
+void SMESH_MAT2d::Branch::init( vector<const TVDEdge*>&                maEdges,
+                                const Boundary*                        boundary,
+                                map< const TVDVertex*, BranchEndType > endType )
+{
+  if ( maEdges.empty() ) return;
+
+  _boundary = boundary;
+  _maEdges.swap( maEdges );
+
+
+  _params.reserve( _maEdges.size() + 1 );
+  _params.push_back( 0. );
+  for ( size_t i = 0; i < _maEdges.size(); ++i )
+    _params.push_back( _params.back() + length( _maEdges[i] ));
+  
+  for ( size_t i = 1; i < _params.size(); ++i )
+    _params[i] /= _params.back();
+
+
+  _endPoint1._vertex = _maEdges.front()->vertex1();
+  _endPoint2._vertex = _maEdges.back ()->vertex0();
+
+  if ( endType.count( _endPoint1._vertex ))
+    _endPoint1._type = endType[ _endPoint1._vertex ];
+  if ( endType.count( _endPoint2._vertex ))
+    _endPoint2._type = endType[ _endPoint2._vertex ];
+}
+
+//================================================================================
+/*!
+ * \brief fills BranchEnd::_branches of its ends
+ */
+//================================================================================
+
+void SMESH_MAT2d::Branch::setBranchesToEnds( const vector< Branch >& branches )
+{
+  for ( size_t i = 0; i < branches.size(); ++i )
+  {
+    if ( this->_endPoint1._vertex == branches[i]._endPoint1._vertex ||
+         this->_endPoint1._vertex == branches[i]._endPoint2._vertex )
+      this->_endPoint1._branches.push_back( &branches[i] );
+
+    if ( this->_endPoint2._vertex == branches[i]._endPoint1._vertex ||
+         this->_endPoint2._vertex == branches[i]._endPoint2._vertex )
+      this->_endPoint2._branches.push_back( &branches[i] );
+  }
+}
+
+//================================================================================
+/*!
+ * \brief returns a BranchPoint corresponding to a TVDVertex
+ */
+//================================================================================
+
+SMESH_MAT2d::BranchPoint SMESH_MAT2d::Branch::getPoint( const TVDVertex* vertex ) const
+{
+  BranchPoint p;
+  p._branch = this;
+  p._iEdge  = 0;
+
+  if ( vertex == _maEdges[0]->vertex1() )
+  {
+    p._edgeParam = 0;
+  }
+  else
+  {
+    for ( ; p._iEdge < _maEdges.size(); ++p._iEdge )
+      if ( vertex == _maEdges[ p._iEdge ]->vertex0() )
+      {
+        p._edgeParam = _params[ p._iEdge ];
+        break;
+      }
+  }
+  return p;
+}
+
+//================================================================================
+/*!
+ * \brief Sets a proxy point for a removed branch
+ *  \param [in] proxyPoint - a point of another branch to which all points of this
+ *         branch are mapped
+ */
+//================================================================================
+
+void SMESH_MAT2d::Branch::setRemoved( const BranchPoint& proxyPoint )
+{
+  _proxyPoint = proxyPoint;
+}
+
+//================================================================================
+/*!
+ * \brief Returns points on two EDGEs, equidistant from a given point of this Branch
+ *  \param [in] param - [0;1] normalized param on the Branch
+ *  \param [out] bp1 - BoundaryPoint on EDGE with a lower index
+ *  \param [out] bp2 - BoundaryPoint on EDGE with a higher index
+ *  \return bool - true if the BoundaryPoint's found
+ */
+//================================================================================
+
+bool SMESH_MAT2d::Branch::getBoundaryPoints(double         param,
+                                            BoundaryPoint& bp1,
+                                            BoundaryPoint& bp2 ) const
+{
+  if ( param < _params[0] || param > _params.back() )
+    return false;
+
+  // look for an index of a MA edge by param
+  double ip = param * _params.size();
+  size_t  i = size_t( Min( int( _maEdges.size()-1), int( ip )));
+
+  while ( param < _params[i  ] ) --i;
+  while ( param > _params[i+1] ) ++i;
+
+  double r = ( param - _params[i] ) / ( _params[i+1] - _params[i] );
+
+  return getBoundaryPoints( i, r, bp1, bp2 );
+}
+
+//================================================================================
+/*!
+ * \brief Returns points on two EDGEs, equidistant from a given point of this Branch
+ *  \param [in] iMAEdge - index of a MA edge within this Branch
+ *  \param [in] maEdgeParam - [0;1] normalized param on the \a iMAEdge
+ *  \param [out] bp1 - BoundaryPoint on EDGE with a lower index
+ *  \param [out] bp2 - BoundaryPoint on EDGE with a higher index
+ *  \return bool - true if the BoundaryPoint's found
+ */
+//================================================================================
+
+bool SMESH_MAT2d::Branch::getBoundaryPoints(std::size_t    iMAEdge,
+                                            double         maEdgeParam,
+                                            BoundaryPoint& bp1,
+                                            BoundaryPoint& bp2 ) const
+{
+  if ( isRemoved() )
+    return _proxyPoint._branch->getBoundaryPoints( _proxyPoint, bp1, bp2 );
+
+  if ( iMAEdge > _maEdges.size() )
+    return false;
+  if ( iMAEdge == _maEdges.size() )
+    iMAEdge = _maEdges.size() - 1;
+
+  size_t iGeom1 = getGeomEdge( _maEdges[ iMAEdge ] );
+  size_t iGeom2 = getGeomEdge( _maEdges[ iMAEdge ]->twin() );
+  size_t iSeg1  = getBndSegment( _maEdges[ iMAEdge ] );
+  size_t iSeg2  = getBndSegment( _maEdges[ iMAEdge ]->twin() );
+
+  return ( _boundary->getPoint( iGeom1, iSeg1, maEdgeParam, bp1 ) &&
+           _boundary->getPoint( iGeom2, iSeg2, maEdgeParam, bp2 ));
+}
+
+//================================================================================
+/*!
+ * \brief Returns points on two EDGEs, equidistant from a given point of this Branch
+ */
+//================================================================================
+
+bool SMESH_MAT2d::Branch::getBoundaryPoints(const BranchPoint& p,
+                                            BoundaryPoint&     bp1,
+                                            BoundaryPoint&     bp2 ) const
+{
+  return ( p._branch ? p._branch : this )->getBoundaryPoints( p._iEdge, p._edgeParam, bp1, bp2 );
+}
+
+//================================================================================
+/*!
+ * \brief Return a parameter of a BranchPoint normalized within this Branch
+ */
+//================================================================================
+
+bool SMESH_MAT2d::Branch::getParameter(const BranchPoint & p, double & u ) const
+{
+  if ( this != p._branch && p._branch )
+    return p._branch->getParameter( p, u );
+
+  if ( isRemoved() )
+    return _proxyPoint._branch->getParameter( _proxyPoint, u );
+
+  if ( p._iEdge > _params.size()-1 )
+    return false;
+  if ( p._iEdge == _params.size()-1 )
+    return u = 1.;
+
+  u = ( _params[ p._iEdge   ] * ( 1 - p._edgeParam ) +
+        _params[ p._iEdge+1 ] * p._edgeParam );
+
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief Check type of both ends
+ */
+//================================================================================
+
+bool SMESH_MAT2d::Branch::hasEndOfType(BranchEndType type) const
+{
+  return ( _endPoint1._type == type || _endPoint2._type == type );
+}
+
+//================================================================================
+/*!
+ * \brief Returns MA points
+ *  \param [out] points - the 2d points
+ *  \param [in] scale - the scale that was used to scale the 2d space of MA
+ */
+//================================================================================
+
+void SMESH_MAT2d::Branch::getPoints( std::vector< gp_XY >& points,
+                                     const double          scale[2]) const
+{
+  points.resize( _maEdges.size() + 1 );
+
+  points[0].SetCoord( _maEdges[0]->vertex1()->x() / scale[0], // CCW order! -> vertex1 not vertex0
+                      _maEdges[0]->vertex1()->y() / scale[1] );
+
+  for ( size_t i = 0; i < _maEdges.size(); ++i )
+    points[i+1].SetCoord( _maEdges[i]->vertex0()->x() / scale[0],
+                          _maEdges[i]->vertex0()->y() / scale[1] );
+}
+
+//================================================================================
+/*!
+ * \brief Return indices of EDGEs equidistant from this branch
+ */
+//================================================================================
+
+void SMESH_MAT2d::Branch::getGeomEdges( std::vector< std::size_t >& edgeIDs1,
+                                        std::vector< std::size_t >& edgeIDs2 ) const
+{
+  edgeIDs1.push_back( getGeomEdge( _maEdges[0] ));
+  edgeIDs2.push_back( getGeomEdge( _maEdges[0]->twin() ));
+
+  for ( size_t i = 1; i < _maEdges.size(); ++i )
+  {
+    size_t ie1 = getGeomEdge( _maEdges[i] );
+    size_t ie2 = getGeomEdge( _maEdges[i]->twin() );
+
+    if ( edgeIDs1.back() != ie1 ) edgeIDs1.push_back( ie1 );
+    if ( edgeIDs2.back() != ie2 ) edgeIDs2.push_back( ie2 );
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Looks for a BranchPoint position around a concave VERTEX
+ */
+//================================================================================
+
+bool SMESH_MAT2d::Branch::addDivPntForConcaVertex( std::vector< std::size_t >&   edgeIDs1,
+                                                   std::vector< std::size_t >&   edgeIDs2,
+                                                   std::vector< BranchPoint >&   divPoints,
+                                                   const vector<const TVDEdge*>& maEdges,
+                                                   const vector<const TVDEdge*>& maEdgesTwin,
+                                                   int &                         i) const
+{
+  // if there is a concave vertex between EDGEs
+  // then position of a dividing BranchPoint is undefined, it is somewhere
+  // on an arc-shaped part of the Branch around the concave vertex.
+  // Chose this position by a VERTEX of the opposite EDGE, or put it in the middle
+  // of the arc if there is no opposite VERTEX.
+  // All null-length segments around a VERTEX belong to one of EDGEs.
+
+  BranchPoint divisionPnt;
+  divisionPnt._branch = this;
+
+  BranchIterator iCur( maEdges, i );
+
+  size_t ie1 = getGeomEdge( maEdges    [i] );
+  size_t ie2 = getGeomEdge( maEdgesTwin[i] );
+
+  size_t iSeg1  = getBndSegment( iCur.edgePrev() );
+  size_t iSeg2  = getBndSegment( iCur.edge() );
+  bool isConcaPrev = _boundary->isConcaveSegment( edgeIDs1.back(), iSeg1 );
+  bool isConcaNext = _boundary->isConcaveSegment( ie1,             iSeg2 );
+  if ( !isConcaNext && !isConcaPrev )
+    return false;
+
+  bool isConcaveV = false;
+
+  const TVDEdge* maE;
+  BranchIterator iPrev( maEdges, i ), iNext( maEdges, i );
+   --iPrev;
+  if ( isConcaNext ) // all null-length segments follow
+  {
+    // look for a VERTEX of the opposite EDGE
+    // iNext - next after all null-length segments
+    while ( maE = ++iNext )
+    {
+      iSeg2 = getBndSegment( maE );
+      if ( !_boundary->isConcaveSegment( ie1, iSeg2 ))
+        break;
+    }
+    bool vertexFound = false;
+    for ( ++iCur; iCur < iNext; ++iCur )
+    {
+      ie2 = getGeomEdge( maEdgesTwin[ iCur.indexMod() ] );
+      if ( ie2 != edgeIDs2.back() )
+      {
+        // opposite VERTEX found
+        divisionPnt._iEdge = iCur.indexMod();
+        divisionPnt._edgeParam = 0;
+        divPoints.push_back( divisionPnt );
+        edgeIDs1.push_back( ie1 );
+        edgeIDs2.push_back( ie2 );
+        vertexFound = true;
+      }
+    }
+    if ( vertexFound )
+    {
+      --iNext;
+      iPrev = iNext; // not to add a BP in the moddle
+      i = iNext.indexMod();
+      isConcaveV = true;
+    }
+  }
+  else if ( isConcaPrev )
+  {
+    // all null-length segments passed, find their beginning
+    while ( maE = iPrev.edgePrev() )
+    {
+      iSeg1 = getBndSegment( maE );
+      if ( _boundary->isConcaveSegment( edgeIDs1.back(), iSeg1 ))
+        --iPrev;
+      else
+        break;
+    }
+  }
+
+  if ( iPrev.index() < i-1 || iNext.index() > i )
+  {
+    // no VERTEX on the opposite EDGE, put the Branch Point in the middle
+    divisionPnt._iEdge = iPrev.indexMod();
+    ++iPrev;
+    double   par1 = _params[ iPrev.indexMod() ], par2 = _params[ iNext.indexMod() ];
+    double midPar = 0.5 * ( par1 + par2 );
+    for ( ; _params[ iPrev.indexMod() ] < midPar; ++iPrev )
+      divisionPnt._iEdge = iPrev.indexMod();
+    divisionPnt._edgeParam =
+      ( _params[ iPrev.indexMod() ] - midPar ) /
+      ( _params[ iPrev.indexMod() ] - _params[ divisionPnt._iEdge ] );
+    divPoints.push_back( divisionPnt );
+    isConcaveV = true;
+  }
+
+  return isConcaveV;
+}
+
+//================================================================================
+/*!
+ * \brief Return indices of opposite parts of EDGEs equidistant from this branch
+ *  \param [out] edgeIDs1 - EDGE index opposite to the edgeIDs2[i]-th EDGE
+ *  \param [out] edgeIDs2 - EDGE index opposite to the edgeIDs1[i]-th EDGE
+ *  \param [out] divPoints - BranchPoint's located between two successive unique
+ *         pairs of EDGE indices. A \a divPoints[i] can separate e.g. two following pairs
+ *         of EDGE indices < 0, 2 > and < 0, 1 >. Number of \a divPoints is one less
+ *         than number of \a edgeIDs
+ */
+//================================================================================
+
+void SMESH_MAT2d::Branch::getOppositeGeomEdges( std::vector< std::size_t >& edgeIDs1,
+                                                std::vector< std::size_t >& edgeIDs2,
+                                                std::vector< BranchPoint >& divPoints) const
+{
+  edgeIDs1.clear();
+  edgeIDs2.clear();
+  divPoints.clear();
+
+  std::vector<const TVDEdge*> twins( _maEdges.size() );
+  for ( size_t i = 0; i < _maEdges.size(); ++i )
+    twins[i] = _maEdges[i]->twin();
+
+  BranchIterator maIter ( _maEdges, 0 );
+  BranchIterator twIter ( twins, 0 );
+  // size_t lastConcaE1 = _boundary.nbEdges();
+  // size_t lastConcaE2 = _boundary.nbEdges();
+
+  // if ( maIter._closed ) // closed branch
+  // {
+  //   edgeIDs1.push_back( getGeomEdge( _maEdges.back() ));
+  //   edgeIDs2.push_back( getGeomEdge( _maEdges.back()->twin() ));
+  // }
+  // else
+  {
+    edgeIDs1.push_back( getGeomEdge( maIter.edge() ));
+    edgeIDs2.push_back( getGeomEdge( twIter.edge() ));
+  }
+
+  BranchPoint divisionPnt;
+  divisionPnt._branch = this;
+
+  for ( ++maIter, ++twIter; maIter.index() < _maEdges.size(); ++maIter, ++twIter )
+  {
+    size_t ie1 = getGeomEdge( maIter.edge() );
+    size_t ie2 = getGeomEdge( twIter.edge() );
+
+    bool otherE1 = ( edgeIDs1.back() != ie1 );
+    bool otherE2 = ( edgeIDs2.back() != ie2 );
+
+    if ( !otherE1 && !otherE2 && maIter._closed )
+    {
+      int iSegPrev1 = getBndSegment( maIter.edgePrev() );
+      int iSegCur1  = getBndSegment( maIter.edge() );
+      otherE1 = Abs( iSegPrev1 - iSegCur1 ) != 1;
+      int iSegPrev2 = getBndSegment( twIter.edgePrev() );
+      int iSegCur2  = getBndSegment( twIter.edge() );
+      otherE2 = Abs( iSegPrev2 - iSegCur2 ) != 1;
+    }
+
+    if ( otherE1 || otherE2 )
+    {
+      bool isConcaveV = false;
+      if ( otherE1 && !otherE2 )
+      {
+        isConcaveV = addDivPntForConcaVertex( edgeIDs1, edgeIDs2, divPoints,
+                                              _maEdges, twins, maIter._i );
+      }
+      if ( !otherE1 && otherE2 )
+      {
+        isConcaveV = addDivPntForConcaVertex( edgeIDs2, edgeIDs1, divPoints,
+                                              twins, _maEdges, maIter._i );
+      }
+
+      if ( isConcaveV )
+      {
+        ie1 = getGeomEdge( maIter.edge() );
+        ie2 = getGeomEdge( twIter.edge() );
+      }
+      if ( !isConcaveV || otherE1 || otherE2 )
+      {
+        edgeIDs1.push_back( ie1 );
+        edgeIDs2.push_back( ie2 );
+      }
+      if ( divPoints.size() < edgeIDs1.size() - 1 )
+      {
+        divisionPnt._iEdge = maIter.index();
+        divisionPnt._edgeParam = 0;
+        divPoints.push_back( divisionPnt );
+      }
+
+    } // if ( edgeIDs1.back() != ie1 || edgeIDs2.back() != ie2 )
+  } // loop on _maEdges
+}
+
+//================================================================================
+/*!
+ * \brief Store data of boundary segments in TVDEdge
+ */
+//================================================================================
+
+void SMESH_MAT2d::Branch::setGeomEdge( std::size_t geomIndex, const TVDEdge* maEdge )
+{
+  if ( maEdge ) maEdge->cell()->color( geomIndex );
+}
+std::size_t SMESH_MAT2d::Branch::getGeomEdge( const TVDEdge* maEdge )
+{
+  return maEdge ? maEdge->cell()->color() : std::string::npos;
+}
+void SMESH_MAT2d::Branch::setBndSegment( std::size_t segIndex, const TVDEdge* maEdge )
+{
+  if ( maEdge ) maEdge->color( segIndex );
+}
+std::size_t SMESH_MAT2d::Branch::getBndSegment( const TVDEdge* maEdge )
+{
+  return maEdge ? maEdge->color() : std::string::npos;
+}
+
+//================================================================================
+/*!
+ * \brief Returns a boundary point on a given EDGE
+ *  \param [in] iEdge - index of the EDGE within MedialAxis
+ *  \param [in] iSeg - index of a boundary segment within this Branch
+ *  \param [in] u - [0;1] normalized param within \a iSeg-th segment
+ *  \param [out] bp - the found BoundaryPoint
+ *  \return bool - true if the BoundaryPoint is found
+ */
+//================================================================================
+
+bool SMESH_MAT2d::Boundary::getPoint( std::size_t    iEdge,
+                                      std::size_t    iSeg,
+                                      double         u,
+                                      BoundaryPoint& bp ) const
+{
+  if ( iEdge >= _pointsPerEdge.size() )
+    return false;
+  if ( iSeg+1 >= _pointsPerEdge[ iEdge ]._params.size() )
+    return false;
+
+  // This method is called by Branch that can have an opposite orientation,
+  // hence u is inverted depending on orientation coded as a sign of _maEdge index
+  bool isReverse = ( _pointsPerEdge[ iEdge ]._maEdges[ iSeg ].second < 0 );
+  if ( isReverse )
+    u = 1. - u;
+
+  double p0 = _pointsPerEdge[ iEdge ]._params[ iSeg ];
+  double p1 = _pointsPerEdge[ iEdge ]._params[ iSeg+1 ];
+
+  bp._param = p0 * ( 1. - u ) + p1 * u;
+  bp._edgeIndex = iEdge;
+
+  return true;
+}
+
diff --git a/src/SMESHUtils/SMESH_MAT2d.hxx b/src/SMESHUtils/SMESH_MAT2d.hxx
new file mode 100644 (file)
index 0000000..618608e
--- /dev/null
@@ -0,0 +1,238 @@
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&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, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// 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_MAT2d.hxx
+// Created   : Thu May 28 17:49:53 2015
+// Author    : Edward AGAPOV (eap)
+
+#ifndef __SMESH_MAT2d_HXX__
+#define __SMESH_MAT2d_HXX__
+
+#include "SMESH_Utils.hxx"
+
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Edge.hxx>
+
+#include <vector>
+#include <map>
+
+#include <boost/polygon/polygon.hpp>
+#include <boost/polygon/voronoi.hpp>
+
+class Adaptor3d_Curve;
+
+// Medial Axis Transform 2D
+namespace SMESH_MAT2d
+{
+  class MedialAxis; // MedialAxis is the entry point
+  class Branch;
+  class BranchEnd;
+  class Boundary;
+  struct BoundaryPoint;
+
+  typedef boost::polygon::voronoi_diagram<double> TVD;
+  typedef TVD::cell_type                          TVDCell;
+  typedef TVD::edge_type                          TVDEdge;
+  typedef TVD::vertex_type                        TVDVertex;
+
+  //-------------------------------------------------------------------------------------
+  // type of Branch end point
+  enum BranchEndType { BE_UNDEF,
+                       BE_ON_VERTEX, // branch ends at a convex VRTEX
+                       BE_BRANCH_POINT, // branch meats 2 or more other branches
+                       BE_END // branch end equidistant from several adjacent segments
+  };
+  //-------------------------------------------------------------------------------------
+  /*!
+   * \brief End point of MA Branch
+   */
+  struct SMESHUtils_EXPORT BranchEnd
+  {
+    const TVDVertex*             _vertex;
+    BranchEndType                _type;
+    std::vector< const Branch* > _branches;
+
+    BranchEnd(): _vertex(0), _type( BE_UNDEF ) {}
+  };
+  //-------------------------------------------------------------------------------------
+  /*!
+   * \brief Point on MA Branch
+   */
+  struct SMESHUtils_EXPORT BranchPoint
+  {
+    const Branch* _branch;
+    std::size_t   _iEdge; // MA edge index within the branch
+    double        _edgeParam; // normalized param within the MA edge
+
+    BranchPoint( const Branch* b = 0, std::size_t e = 0, double u = -1 ):
+      _branch(b), _iEdge(e), _edgeParam(u) {}
+  };
+  //-------------------------------------------------------------------------------------
+  /*!
+   * \brief Branch is a set of MA edges enclosed between branch points and/or MA ends.
+   *        It's main feature is to return two BoundaryPoint's per a point on it.
+   *        Points on a Branch are defined by [0,1] parameter 
+   */
+  class SMESHUtils_EXPORT Branch
+  {
+  public:
+    bool getBoundaryPoints(double param, BoundaryPoint& bp1, BoundaryPoint& bp2 ) const;
+    bool getBoundaryPoints(std::size_t iMAEdge, double maEdgeParam,
+                           BoundaryPoint& bp1, BoundaryPoint& bp2 ) const;
+    bool getBoundaryPoints(const BranchPoint& p,
+                           BoundaryPoint& bp1, BoundaryPoint& bp2 ) const;
+    bool getParameter(const BranchPoint& p, double & u ) const;
+
+    std::size_t      nbEdges() const { return _maEdges.size(); }
+
+    const BranchEnd* getEnd(bool the2nd) const { return & ( the2nd ? _endPoint2 : _endPoint1 ); }
+
+    bool hasEndOfType(BranchEndType type) const;
+
+    void getPoints( std::vector< gp_XY >& points, const double scale[2]) const;
+
+    void getGeomEdges( std::vector< std::size_t >& edgeIDs1,
+                       std::vector< std::size_t >& edgeIDs2 ) const;
+
+    void getOppositeGeomEdges( std::vector< std::size_t >& edgeIDs1,
+                               std::vector< std::size_t >& edgeIDs2,
+                               std::vector< BranchPoint >& divPoints) const;
+
+    bool isRemoved() const { return _proxyPoint._branch; }
+
+  public: // internal: construction
+
+    void init( std::vector<const TVDEdge*>&                maEdges,
+               const Boundary*                             boundary,
+               std::map< const TVDVertex*, BranchEndType > endType);
+    void setBranchesToEnds( const std::vector< Branch >&   branches);
+    BranchPoint getPoint( const TVDVertex* vertex ) const;
+    void setRemoved( const BranchPoint& proxyPoint );
+
+    static void        setGeomEdge  ( std::size_t geomIndex, const TVDEdge* maEdge );
+    static std::size_t getGeomEdge  ( const TVDEdge* maEdge );
+    static void        setBndSegment( std::size_t segIndex, const TVDEdge* maEdge );
+    static std::size_t getBndSegment( const TVDEdge* maEdge );
+
+  private:
+
+    bool addDivPntForConcaVertex( std::vector< std::size_t >&        edgeIDs1,
+                                  std::vector< std::size_t >&        edgeIDs2,
+                                  std::vector< BranchPoint >&        divPoints,
+                                  const std::vector<const TVDEdge*>& maEdges,
+                                  const std::vector<const TVDEdge*>& maEdgesTwin,
+                                  int &                              i) const;
+
+    // association of _maEdges with boundary segments is stored in this way:
+    // index of an EDGE:           TVDEdge->cell()->color()
+    // index of a segment on EDGE: TVDEdge->color()
+    std::vector<const TVDEdge*> _maEdges; // MA edges ending at points located at _params
+    std::vector<double>  _params; // params of points on MA, normalized [0;1] within this branch
+    const Boundary*      _boundary; // face boundary
+    BranchEnd            _endPoint1;
+    BranchEnd            _endPoint2;
+    BranchPoint          _proxyPoint;
+  };
+
+  //-------------------------------------------------------------------------------------
+  /*!
+   * \brief Data of a discretized EDGE allowing to get a point on MA by a parameter on EDGE
+   */
+  struct BndPoints
+  {
+    std::vector< double > _params; // params of discretization points on an EDGE
+    std::vector< std::pair< const Branch*, int > > _maEdges; /* index of TVDEdge in branch;
+                                                                index sign means orientation;
+                                                                index == Branch->nbEdges() means
+                                                                end point of a Branch */
+  };
+  //-------------------------------------------------------------------------------------
+  /*!
+   * \brief Face boundary is discretized so that each its segment to correspond to
+   *        an edge of MA
+   */
+  class SMESHUtils_EXPORT Boundary
+  {
+  public:
+
+    Boundary( std::size_t nbEdges ): _pointsPerEdge( nbEdges ) {}
+    BndPoints&  getPoints( std::size_t iEdge ) { return _pointsPerEdge[ iEdge ]; }
+    std::size_t nbEdges() const { return _pointsPerEdge.size(); }
+
+    bool getPoint( std::size_t iEdge, std::size_t iSeg, double u, BoundaryPoint& bp ) const;
+
+    bool getBranchPoint( const std::size_t iEdge, double u, BranchPoint& p ) const;
+
+    bool getBranchPoint( const BoundaryPoint& bp, BranchPoint& p ) const;
+
+    bool isConcaveSegment( std::size_t iEdge, std::size_t iSeg ) const;
+
+    bool moveToClosestEdgeEnd( BoundaryPoint& bp ) const;
+
+  private:
+    std::vector< BndPoints > _pointsPerEdge;
+  };
+
+  //-------------------------------------------------------------------------------------
+  /*!
+   * \brief Point on FACE boundary
+   */
+  struct SMESHUtils_EXPORT BoundaryPoint
+  {
+    std::size_t _edgeIndex; // index of an EDGE in a sequence passed to MedialAxis()
+    double      _param;     // parameter of this EDGE
+  };
+  //-------------------------------------------------------------------------------------
+  /*!
+   * \brief Medial axis (MA) is defined as the loci of centres of locally
+   *        maximal balls inside 2D representation of a face. This class
+   *        implements a piecewise approximation of MA.
+   */
+  class SMESHUtils_EXPORT MedialAxis
+  {
+  public:
+    MedialAxis(const TopoDS_Face&                face,
+               const std::vector< TopoDS_Edge >& edges,
+               const double                      minSegLen,
+               const bool                        ignoreCorners = false );
+    std::size_t                            nbBranches() const { return _nbBranches; }
+    const Branch*                          getBranch(size_t i) const;
+    const std::vector< const BranchEnd* >& getBranchPoints() const { return _branchPnt; }
+    const Boundary&                        getBoundary() const { return _boundary; }
+
+    void getPoints( const Branch* branch, std::vector< gp_XY >& points) const;
+    Adaptor3d_Curve* make3DCurve(const Branch& branch) const;
+
+  private:
+
+  private:
+    TopoDS_Face                     _face;
+    TVD                             _vd;
+    std::vector< Branch >           _branch;
+    std::size_t                     _nbBranches; // removed branches ignored
+    std::vector< const BranchEnd* > _branchPnt;
+    Boundary                        _boundary;
+    double                          _scale[2];
+  };
+
+}
+
+#endif
index 957828474e306b0d3bb07286179f454aaf297c1c..c42f020236e096a1744df1235270a1d0f3d4661b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -168,6 +168,18 @@ struct SMESH_NodeSearcherImpl: public SMESH_NodeSearcher
     return closestNode;
   }
 
+  //---------------------------------------------------------------------
+  /*!
+   * \brief Finds nodes located within a tolerance near a point 
+   */
+  int FindNearPoint(const gp_Pnt&                        point,
+                    const double                         tolerance,
+                    std::vector< const SMDS_MeshNode* >& foundNodes)
+  {
+    myOctreeNode->NodesAround( point.Coord(), foundNodes, tolerance );
+    return foundNodes.size();
+  }
+
   //---------------------------------------------------------------------
   /*!
    * \brief Destructor
@@ -258,7 +270,7 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
 
   ElementBndBoxTree::~ElementBndBoxTree()
   {
-    for ( int i = 0; i < _elements.size(); ++i )
+    for ( size_t i = 0; i < _elements.size(); ++i )
       if ( --_elements[i]->_refCount <= 0 )
         delete _elements[i];
   }
@@ -272,7 +284,7 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
   Bnd_B3d* ElementBndBoxTree::buildRootBox()
   {
     Bnd_B3d* box = new Bnd_B3d;
-    for ( int i = 0; i < _elements.size(); ++i )
+    for ( size_t i = 0; i < _elements.size(); ++i )
       box->Add( *_elements[i] );
     return box;
   }
@@ -285,7 +297,7 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
 
   void ElementBndBoxTree::buildChildrenData()
   {
-    for ( int i = 0; i < _elements.size(); ++i )
+    for ( size_t i = 0; i < _elements.size(); ++i )
     {
       for (int j = 0; j < 8; j++)
       {
@@ -303,7 +315,7 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
     for (int j = 0; j < 8; j++)
     {
       ElementBndBoxTree* child = static_cast<ElementBndBoxTree*>( myChildren[j]);
-      if ( child->_elements.size() <= MaxNbElemsInLeaf )
+      if ((int) child->_elements.size() <= MaxNbElemsInLeaf )
         child->myIsLeaf = true;
 
       if ( child->_elements.capacity() - child->_elements.size() > 1000 )
@@ -325,7 +337,7 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
 
     if ( isLeaf() )
     {
-      for ( int i = 0; i < _elements.size(); ++i )
+      for ( size_t i = 0; i < _elements.size(); ++i )
         if ( !_elements[i]->IsOut( point.XYZ() ))
           foundElems.insert( _elements[i]->_element );
     }
@@ -350,7 +362,7 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
 
     if ( isLeaf() )
     {
-      for ( int i = 0; i < _elements.size(); ++i )
+      for ( size_t i = 0; i < _elements.size(); ++i )
         if ( !_elements[i]->IsOut( line ))
           foundElems.insert( _elements[i]->_element );
     }
@@ -376,7 +388,7 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
 
     if ( isLeaf() )
     {
-      for ( int i = 0; i < _elements.size(); ++i )
+      for ( size_t i = 0; i < _elements.size(); ++i )
         if ( !_elements[i]->IsOut( center, radius ))
           foundElems.insert( _elements[i]->_element );
     }
@@ -427,8 +439,10 @@ struct SMESH_ElementSearcherImpl: public SMESH_ElementSearcher
   bool                         _outerFacesFound;
   set<const SMDS_MeshElement*> _outerFaces; // empty means "no internal faces at all"
 
-  SMESH_ElementSearcherImpl( SMDS_Mesh& mesh, SMDS_ElemIteratorPtr elemIt=SMDS_ElemIteratorPtr())
-    : _mesh(&mesh),_meshPartIt(elemIt),_ebbTree(0),_nodeSearcher(0),_tolerance(-1),_outerFacesFound(false) {}
+  SMESH_ElementSearcherImpl( SMDS_Mesh&           mesh,
+                             double               tol=-1,
+                             SMDS_ElemIteratorPtr elemIt=SMDS_ElemIteratorPtr())
+    : _mesh(&mesh),_meshPartIt(elemIt),_ebbTree(0),_nodeSearcher(0),_tolerance(tol),_outerFacesFound(false) {}
   virtual ~SMESH_ElementSearcherImpl()
   {
     if ( _ebbTree )      delete _ebbTree;      _ebbTree      = 0;
@@ -696,21 +710,21 @@ FindElementsByPoint(const gp_Pnt&                      point,
     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
+    std::vector< const SMDS_MeshNode* > foundNodes;
+    _nodeSearcher->FindNearPoint( point, tolerance, foundNodes );
 
     if ( type == SMDSAbs_Node )
     {
-      foundElements.push_back( closeNode );
+      foundElements.assign( foundNodes.begin(), foundNodes.end() );
     }
     else
     {
-      SMDS_ElemIteratorPtr elemIt = closeNode->GetInverseElementIterator( type );
-      while ( elemIt->more() )
-        foundElements.push_back( elemIt->next() );
+      for ( size_t i = 0; i < foundNodes.size(); ++i )
+      {
+        SMDS_ElemIteratorPtr elemIt = foundNodes[i]->GetInverseElementIterator( type );
+        while ( elemIt->more() )
+          foundElements.push_back( elemIt->next() );
+      }
     }
   }
   // =================================================================================
@@ -1079,32 +1093,22 @@ bool SMESH_MeshAlgos::IsOut( const SMDS_MeshElement* element, const gp_Pnt& poin
 
   // get ordered nodes
 
-  vector< gp_XYZ > xyz;
-  vector<const SMDS_MeshNode*> nodeList;
+  vector< SMESH_TNodeXYZ > xyz;
 
-  SMDS_ElemIteratorPtr nodeIt = element->nodesIterator();
-  if ( element->IsQuadratic() ) {
-    nodeIt = element->interlacedNodesElemIterator();
-    // 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();
-  }
+  SMDS_ElemIteratorPtr nodeIt = element->interlacedNodesElemIterator();
   while ( nodeIt->more() )
   {
     SMESH_TNodeXYZ node = nodeIt->next();
     xyz.push_back( node );
-    nodeList.push_back(node._node);
   }
 
-  int i, nbNodes = (int) nodeList.size(); // central node of biquadratic is missing
+  int i, nbNodes = (int) xyz.size(); // central node of biquadratic is missing
 
   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]);
@@ -1117,7 +1121,7 @@ bool SMESH_MeshAlgos::IsOut( const SMDS_MeshElement* element, const gp_Pnt& poin
       // 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] );
+        SMDS_LinearEdge edge( xyz[i]._node, xyz[i+1]._node );
         if ( !IsOut( &edge, point, tol ))
           return false;
       }
@@ -1204,13 +1208,22 @@ bool SMESH_MeshAlgos::IsOut( const SMDS_MeshElement* element, const gp_Pnt& poin
     // (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 )
+      gp_Vec edge( xyz[i-1], xyz[i] );
+      gp_Vec n1p ( xyz[i-1], point  );
+      double u = ( edge * n1p ) / edge.SquareMagnitude(); // param [0,1] on the edge
+      if ( u <= 0. ) {
+        if ( n1p.SquareMagnitude() < tol * tol )
+          return false;
         continue;
-      gp_Vec n2p( xyz[i], point );
-      if ( fabs( edge.Magnitude() - n1p.Magnitude() - n2p.Magnitude()) > tol )
+      }
+      if ( u >= 1. ) {
+        if ( point.SquareDistance( xyz[i] ) < tol * tol )
+          return false;
+        continue;
+      }
+      gp_XYZ proj = ( 1. - u ) * xyz[i-1] + u * xyz[i]; // projection of the point on the edge
+      double dist2 = point.SquareDistance( proj );
+      if ( dist2 > tol * tol )
         continue;
       return false; // point is ON this part
     }
@@ -1219,7 +1232,7 @@ bool SMESH_MeshAlgos::IsOut( const SMDS_MeshElement* element, const gp_Pnt& poin
   // Node or 0D element -------------------------------------------------------------------------
   {
     gp_Vec n2p ( xyz[0], point );
-    return n2p.Magnitude() <= tol;
+    return n2p.SquareMagnitude() <= tol * tol;
   }
   return true;
 }
@@ -1312,6 +1325,7 @@ double SMESH_MeshAlgos::GetDistance( const SMDS_MeshElement* elem,
     return GetDistance( dynamic_cast<const SMDS_MeshEdge*>( elem ), point);
   case SMDSAbs_Node:
     return point.Distance( SMESH_TNodeXYZ( elem ));
+  default:;
   }
   return -1;
 }
@@ -1408,6 +1422,7 @@ double SMESH_MeshAlgos::GetDistance( const SMDS_MeshFace* face,
     // cout << distVec.Magnitude()  << " VERTEX " << face->GetNode(pos._index)->GetID() << endl;
     return distVec.Magnitude();
   }
+  default:;
   }
   return badDistance;
 }
@@ -1418,9 +1433,35 @@ double SMESH_MeshAlgos::GetDistance( const SMDS_MeshFace* face,
  */
 //=======================================================================
 
-double SMESH_MeshAlgos::GetDistance( const SMDS_MeshEdge* edge, const gp_Pnt& point )
+double SMESH_MeshAlgos::GetDistance( const SMDS_MeshEdge* seg, const gp_Pnt& point )
 {
-  throw SALOME_Exception(LOCALIZED("not implemented so far"));
+  double dist = Precision::Infinite();
+  if ( !seg ) return dist;
+
+  int i = 0, nbNodes = seg->NbNodes();
+
+  vector< SMESH_TNodeXYZ > xyz( nbNodes );
+  SMDS_ElemIteratorPtr nodeIt = seg->interlacedNodesElemIterator();
+  while ( nodeIt->more() )
+    xyz[ i++ ].Set( nodeIt->next() );
+
+  for ( i = 1; i < nbNodes; ++i )
+  {
+    gp_Vec edge( xyz[i-1], xyz[i] );
+    gp_Vec n1p ( xyz[i-1], point  );
+    double u = ( edge * n1p ) / edge.SquareMagnitude(); // param [0,1] on the edge
+    if ( u <= 0. ) {
+      dist = Min( dist, n1p.SquareMagnitude() );
+    }
+    else if ( u >= 1. ) {
+      dist = Min( dist, point.SquareDistance( xyz[i] ));
+    }
+    else {
+      gp_XYZ proj = ( 1. - u ) * xyz[i-1] + u * xyz[i]; // projection of the point on the edge
+      dist = Min( dist, point.SquareDistance( proj ));
+    }
+  }
+  return Sqrt( dist );
 }
 
 //=======================================================================
@@ -1524,14 +1565,12 @@ SMESH_MeshAlgos::FindFaceInSet(const SMDS_MeshNode*    n1,
                                int*                    n2ind)
 
 {
-  int i1, i2;
+  int i1 = 0, i2 = 0;
   const SMDS_MeshElement* face = 0;
 
   SMDS_ElemIteratorPtr invElemIt = n1->GetInverseElementIterator(SMDSAbs_Face);
-  //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.count( elem ))
       continue;
@@ -1550,9 +1589,6 @@ SMESH_MeshAlgos::FindFaceInSet(const SMDS_MeshNode*    n1,
     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 = elem->interlacedNodesElemIterator();
       const SMDS_MeshNode* prevN = static_cast<const SMDS_MeshNode*>( anIter->next() );
       for ( i1 = -1, i2 = 0; anIter->more() && !face; i1++, i2++ )
@@ -1587,7 +1623,7 @@ bool SMESH_MeshAlgos::FaceNormal(const SMDS_MeshElement* F, gp_XYZ& normal, bool
     return false;
 
   normal.SetCoord(0,0,0);
-  int nbNodes = F->IsQuadratic() ? F->NbNodes()/2 : F->NbNodes();
+  int nbNodes = F->NbCornerNodes();
   for ( int i = 0; i < nbNodes-2; ++i )
   {
     gp_XYZ p[3];
@@ -1638,9 +1674,10 @@ SMESH_NodeSearcher* SMESH_MeshAlgos::GetNodeSearcher(SMDS_Mesh& mesh)
  */
 //=======================================================================
 
-SMESH_ElementSearcher* SMESH_MeshAlgos::GetElementSearcher(SMDS_Mesh& mesh)
+SMESH_ElementSearcher* SMESH_MeshAlgos::GetElementSearcher(SMDS_Mesh& mesh,
+                                                           double     tolerance)
 {
-  return new SMESH_ElementSearcherImpl( mesh );
+  return new SMESH_ElementSearcherImpl( mesh, tolerance );
 }
 
 //=======================================================================
@@ -1650,7 +1687,8 @@ SMESH_ElementSearcher* SMESH_MeshAlgos::GetElementSearcher(SMDS_Mesh& mesh)
 //=======================================================================
 
 SMESH_ElementSearcher* SMESH_MeshAlgos::GetElementSearcher(SMDS_Mesh&           mesh,
-                                                           SMDS_ElemIteratorPtr elemIt)
+                                                           SMDS_ElemIteratorPtr elemIt,
+                                                           double               tolerance)
 {
-  return new SMESH_ElementSearcherImpl( mesh, elemIt );
+  return new SMESH_ElementSearcherImpl( mesh, tolerance, elemIt );
 }
index f1604572b2a83bba6922c0e95a5eae7bd8513f4f..9b860a6ab1150ef5169e25d1b81a6d89d27ba68b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -55,6 +55,9 @@ struct SMESHUtils_EXPORT SMESH_NodeSearcher
 {
   virtual const SMDS_MeshNode* FindClosestTo( const gp_Pnt& pnt ) = 0;
   virtual void MoveNode( const SMDS_MeshNode* node, const gp_Pnt& toPnt ) = 0;
+  virtual int  FindNearPoint(const gp_Pnt&                        point,
+                             const double                         tolerance,
+                             std::vector< const SMDS_MeshNode* >& foundNodes) = 0;
 };
 
 //=======================================================================
@@ -153,10 +156,45 @@ namespace SMESH_MeshAlgos
    * \brief Return SMESH_ElementSearcher. The caller is responsible for deleting it
    */
   SMESHUtils_EXPORT
-  SMESH_ElementSearcher* GetElementSearcher( SMDS_Mesh& mesh );
+  SMESH_ElementSearcher* GetElementSearcher( SMDS_Mesh& mesh,
+                                             double     tolerance=-1.);
   SMESHUtils_EXPORT
   SMESH_ElementSearcher* GetElementSearcher( SMDS_Mesh& mesh,
-                                             SMDS_ElemIteratorPtr elemIt );
-}
+                                             SMDS_ElemIteratorPtr elemIt,
+                                             double     tolerance=-1. );
+
+
+
+  typedef std::vector<const SMDS_MeshNode*> TFreeBorder;
+  typedef std::vector<TFreeBorder>          TFreeBorderVec;
+  struct TFreeBorderPart
+  {
+    int _border; // border index within a TFreeBorderVec
+    int _node1;  // node index within the border-th TFreeBorder
+    int _node2;
+    int _nodeLast;
+  };
+  typedef std::vector<TFreeBorderPart>  TCoincidentGroup;
+  typedef std::vector<TCoincidentGroup> TCoincidentGroupVec;
+  struct CoincidentFreeBorders
+  {
+    TFreeBorderVec      _borders;          // nodes of all free borders
+    TCoincidentGroupVec _coincidentGroups; // groups of coincident parts of borders
+  };
+
+  /*!
+   * Returns TFreeBorder's coincident within the given tolerance.
+   * If the tolerance <= 0.0 then one tenth of an average size of elements adjacent
+   * to free borders being compared is used.
+   *
+   * (Implemented in ./SMESH_FreeBorders.cxx)
+   */
+  SMESHUtils_EXPORT
+  void FindCoincidentFreeBorders(SMDS_Mesh&              mesh,
+                                 double                  tolerance,
+                                 CoincidentFreeBorders & foundFreeBordes);
+  
+
+} // SMESH_MeshAlgos
 
 #endif
index 45ceb21b32b0e829d4776aa47ee7ccfeab99237f..e7b049722399abd872d5a4fe6adb4eafe325f7a5 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index df25fd5739ef1717854a96f552108eaafae36caf..d21fa9d9e81be8333f70cce83e6799b83a28fd87 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index f23cac0cab8bc5e0804e03d2c6c93535e676487a..3c50fa8e703f7cb3801ea18d6fde7359951cb567 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -102,7 +102,7 @@ Bnd_B3d* SMESH_OctreeNode::buildRootBox()
     gp_XYZ p1( n1->X(), n1->Y(), n1->Z() );
     box->Add(p1);
   }
-  if ( myNodes.size() <= getMaxNbNodes() )
+  if ((int) myNodes.size() <= getMaxNbNodes() )
     myIsLeaf = true;
 
   return box;
@@ -151,7 +151,7 @@ void SMESH_OctreeNode::buildChildrenData()
   for (int i = 0; i < 8; i++)
   {
     SMESH_OctreeNode* myChild = dynamic_cast<SMESH_OctreeNode*> (myChildren[i]);
-    if ( myChild->myNodes.size() <= getMaxNbNodes() )
+    if ((int) myChild->myNodes.size() <= getMaxNbNodes() )
       myChild->myIsLeaf = true;
   }
 }
@@ -189,6 +189,7 @@ void SMESH_OctreeNode::NodesAround (const SMDS_MeshNode * Node,
 //================================================================================
 /*!
  * \brief Return in dist2Nodes nodes mapped to their square distance from Node
+ *        Tries to find a closest 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
@@ -241,6 +242,44 @@ bool SMESH_OctreeNode::NodesAround(const gp_XYZ &node,
   return false;
 }
 
+//================================================================================
+/*!
+ * \brief Return a list of nodes close to a point
+ *  \param [in] point - point
+ *  \param [out] nodes - found nodes
+ *  \param [in] precision - allowed distance from \a point
+ */
+//================================================================================
+
+void SMESH_OctreeNode::NodesAround(const gp_XYZ&                      point,
+                                   std::vector<const SMDS_MeshNode*>& nodes,
+                                   double                             precision)
+{
+  if ( isInside( point, precision ))
+  {
+    if ( isLeaf() && NbNodes() )
+    {
+      double minDist2 = precision * precision;
+      TIDSortedNodeSet::iterator nIt = myNodes.begin();
+      for ( ; nIt != myNodes.end(); ++nIt )
+      {
+        SMESH_TNodeXYZ p2( *nIt );
+        double dist2 = ( point - p2 ).SquareModulus();
+        if ( dist2 <= minDist2 )
+          nodes.push_back( p2._node );
+      }
+    }
+    else if ( myChildren )
+    {
+      for (int i = 0; i < 8; i++)
+      {
+        SMESH_OctreeNode* myChild = dynamic_cast<SMESH_OctreeNode*> (myChildren[i]);
+        myChild->NodesAround( point, nodes, precision);
+      }
+    }
+  }
+}
+
 //=============================
 /*!
  * \brief  Return in theGroupsOfNodes a list of group of nodes close to each other within theTolerance
@@ -275,42 +314,33 @@ void SMESH_OctreeNode::FindCoincidentNodes (TIDSortedNodeSet& theSetOfNodes,
  * \param theGroupsOfNodes - list of nodes closed to each other returned
  */
 //=============================
-void SMESH_OctreeNode::FindCoincidentNodes ( TIDSortedNodeSet* theSetOfNodes,
-                                             const double               theTolerance,
+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;
 
+  list<const SMDS_MeshNode*> ListOfCoincidentNodes;
+  TIDCompare idLess;
+
   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++)
+    if ( !ListOfCoincidentNodes.empty() )
     {
-      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 );
+      // We build a list {n1 + his neigbours} and add this list in theGroupsOfNodes
+      if ( idLess( n1, ListOfCoincidentNodes.front() )) ListOfCoincidentNodes.push_front( n1 );
+      else                                              ListOfCoincidentNodes.push_back ( n1 );
+      ListOfCoincidentNodes.sort( idLess );
+      theGroupsOfNodes->push_back( list<const SMDS_MeshNode*>() );
+      theGroupsOfNodes->back().splice( theGroupsOfNodes->back().end(), ListOfCoincidentNodes );
     }
-    if (groupPtr != 0)
-      groupPtr->sort();
 
     theSetOfNodes->erase(it1);
     it1 = theSetOfNodes->begin();
index dac8766ba7211b193800788ba07488b63c6adc76..2cd22a3c544d7230435f3c2184a447dc1bbed89e 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 #ifndef _SMESH_OCTREENODE_HXX_
 #define _SMESH_OCTREENODE_HXX_
 
-#include "SMESH_Utils.hxx"
+#include "SMDS_ElemIterator.hxx"
+#include "SMDS_MeshNode.hxx"
 #include "SMESH_Octree.hxx"
+#include "SMESH_Utils.hxx"
+
 #include <gp_Pnt.hxx>
-#include "SMDS_MeshNode.hxx"
 
 #include <list>
 #include <set>
 #include <map>
-
-#include "SMDS_ElemIterator.hxx"
+#include <vector>
 
 //forward declaration
 class SMDS_MeshNode;
@@ -49,34 +50,35 @@ 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:
+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
- */
-//=============================
+  // 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,
+  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,
+  bool               NodesAround(const gp_XYZ&                           point,
                                  std::map<double, const SMDS_MeshNode*>& dist2Nodes,
                                  double                                  precision);
 
+  // Return a list of Nodes close to a point
+  void               NodesAround(const gp_XYZ&                      point,
+                                 std::vector<const SMDS_MeshNode*>& nodes,
+                                 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,
index c5724304394c7a7a943ec0e4b9359b589f0a6e4b..b43fd02cb66636a3005a1921f98846c350cd902a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 59ede255d6b4a93977904bd8447be57730d42915..d1edb31a47daa623521cd2bbde10b471a77390a2 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 4c0e16a7ed0424901da5f22a6f7c3cf4269d861c..eb7b2b864886bdf06190f7816b44535eb287da82 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 0dd02ca13e185df64816016bc425571e4ce1a5d9..82ae51910c674ff9bb92b6b3d6ca8b012bfbc7d2 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 00fbcef584eddea00a5a4ed654ca53992264eaa4..bf2a8a73ccde9d99bf420b62c86a97a1acd7cf1d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index f5dedaec0ce38eb9bae6f96110417e96d25347e3..bd5f41d12f88764bef9c5dd1dea39fdbf3ba4882 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -80,8 +80,11 @@ namespace SMESHUtils
   struct Deleter
   {
     TOBJ* _obj;
-    Deleter( TOBJ* obj ): _obj( obj ) {}
+    explicit Deleter( TOBJ* obj = (TOBJ*)NULL ): _obj( obj ) {}
     ~Deleter() { delete _obj; _obj = 0; }
+    TOBJ& operator*()  const { return *_obj; }
+    TOBJ* operator->() const { return _obj; }
+    operator bool()    const { return _obj; }
   private:
     Deleter( const Deleter& );
   };
@@ -113,6 +116,16 @@ struct SMESH_TLink: public NLink
   { if ( first->GetID() < second->GetID() ) std::swap( first, second ); }
   const SMDS_MeshNode* node1() const { return first; }
   const SMDS_MeshNode* node2() const { return second; }
+
+  // methods for usage of SMESH_TLink as a hasher in NCollection maps
+  static int HashCode(const SMESH_TLink& link, int aLimit)
+  {
+    return ::HashCode( link.node1()->GetID() + link.node2()->GetID(), aLimit );
+  }
+  static Standard_Boolean IsEqual(const SMESH_TLink& l1, const SMESH_TLink& l2)
+  {
+    return ( l1.node1() == l2.node1() && l1.node2() == l2.node2() );
+  }
 };
 
 //=======================================================================
@@ -137,13 +150,20 @@ struct SMESH_TNodeXYZ : public gp_XYZ
 {
   const SMDS_MeshNode* _node;
   double               _xyz[3];
-  SMESH_TNodeXYZ( const SMDS_MeshElement* e=0):gp_XYZ(0,0,0),_node(0) {
+  SMESH_TNodeXYZ( const SMDS_MeshElement* e=0):gp_XYZ(0,0,0),_node(0)
+  {
+    Set(e);
+  }
+  bool Set( const SMDS_MeshElement* e=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] );
+      return true;
     }
+    return false;
   }
   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(); }
index 88a6a9305d2f344d81a0387428a6b1ec2257d412..6e3d7958a390a9c4642997e42a5510be55800967 100755 (executable)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 3643f0928f6fdc8c82bccaa8de9e0f4d6d30fc57..132a76546171f1e86ad09d9dad97c3aae79091b7 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2012-2015  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
index bd2a48bec483011754a3785428355cc2eede184c..5c92f1d192b2f8a3173ca536a23e8e45c69aa6ab 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index a97a169cca1161a5432fdf73809e82ce44e5850b..c6564719d45edbb303decb9b0dc44baf59a9f6f7 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index c401cd258281ebaf5d8a1163f5e30e77b6ad6568..180d43cf9ba87fced6ec8067ac018504d8ad8a68 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 7f7d1a4c3d2896e66651720cf22816d2012a0d9b..6ad832ca6a9da2abd459e6832249c4f41e07a733 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 107187977122d38bb0e19c7b0e4885841a99b957..391ecea8f3a8aa46e13394ee2eeda2245fbd55d8 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 92cb289b6d44561458e832ec091185e51ac9f179..7768d512ad49cc16004ea77cea7b5a6a8bd906ee 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index da442b4c1c6c223b9d9f5b8a562a4c3fa8cd055a..b1aabd92424a29226b7978898ac7ca09f3f88401 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 911375f68ea1e59894eb2f13e3fe41268377d9a2..2669db47bc92347b6f1c140764e55f18ad3176b7 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -306,6 +306,8 @@ namespace {
     //   - FT_EntityType            = 36
     // v 7.3.0: FT_Undefined == 46, new items:
     //   - FT_ConnectedElements     = 39
+    // v 7.6.0: FT_Undefined == 47, new items:
+    //   - FT_BelongToMeshGroup     = 22
     //
     // It's necessary to continue recording this history and to fill
     // undef2newItems (see below) accordingly.
@@ -326,6 +328,7 @@ namespace {
       undef2newItems[ 44 ].push_back( 37 );
       undef2newItems[ 45 ].push_back( 36 );
       undef2newItems[ 46 ].push_back( 39 );
+      undef2newItems[ 47 ].push_back( 22 );
 
       ASSERT( undef2newItems.rbegin()->first == SMESH::FT_Undefined );
     }
@@ -384,6 +387,7 @@ namespace {
         "ExtrusionSweepObjectMakeGroups","ExtrusionSweepObject0D",
         "ExtrusionSweepObject1D","ExtrusionSweepObject1DMakeGroups",
         "ExtrusionSweepObject2D","ExtrusionSweepObject2DMakeGroups",
+        "ExtrusionSweepObjects","RotationSweepObjects","ExtrusionAlongPathObjects",
         "Translate","TranslateMakeGroups","TranslateMakeMesh",
         "TranslateObject","TranslateObjectMakeGroups", "TranslateObjectMakeMesh",
         "ExtrusionAlongPathX","ExtrusionAlongPathObjX","SplitHexahedraIntoPrisms"
@@ -431,7 +435,8 @@ namespace {
         "ExportCGNS","ExportGMF",
         "Create0DElementsOnAllNodes","Reorient2D","QuadTo4Tri",
         "ScaleMakeGroups","Scale","ScaleMakeMesh",
-        "FindCoincidentNodesOnPartBut","DoubleElements"
+        "FindCoincidentNodesOnPartBut","DoubleElements",
+        "ExtrusionSweepObjects","RotationSweepObjects","ExtrusionAlongPathObjects"
         ,"" }; // <- mark of the end
       methodsAcceptingList.Insert( methodNames );
     }
@@ -687,6 +692,23 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand
   {
     //id_mesh->second->AddProcessedCmd( aCommand );
 
+    // Wrap Export*() into try-except
+    if ( aCommand->MethodStartsFrom("Export"))
+    {
+      _AString    tab = "\t";
+      _AString indent = aCommand->GetIndentation();
+      _AString tryStr = indent + "try:";
+      _AString newCmd = indent + tab + ( aCommand->GetString().ToCString() + indent.Length() );
+      _AString excStr = indent + "except:";
+      _AString msgStr = indent + "\tprint '"; msgStr += method + "() failed. Invalid file name?'";
+
+      myCommands.insert( --myCommands.end(), new _pyCommand( tryStr, myNbCommands ));
+      aCommand->Clear();
+      aCommand->GetString() = newCmd;
+      aCommand->SetOrderNb( ++myNbCommands );
+      myCommands.push_back( new _pyCommand( excStr, ++myNbCommands ));
+      myCommands.push_back( new _pyCommand( msgStr, ++myNbCommands ));
+    }
     // check for mesh editor object
     if ( aCommand->GetMethod() == "GetMeshEditor" ) { // MeshEditor creation
       _pyID editorID = aCommand->GetResultValue();
@@ -888,18 +910,22 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand
       if ( Type == "SMESH.FT_ElemGeomType" )
       {
         // set SMESH.GeometryType instead of a numerical Threshold
-        const int nbTypes = SMESH::Geom_BALL+1;
+        const int nbTypes = SMESH::Geom_LAST;
         const char* types[nbTypes] = {
           "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" };
         if ( -1 < iGeom && iGeom < nbTypes )
           Threshold = SMESH + types[ iGeom ];
+#ifdef _DEBUG_
+        // is types complete? (compilation failure mains that enum GeometryType changed)
+        int _assert[( sizeof(types) / sizeof(const char*) == nbTypes ) ? 1 : -1 ]; _assert[0]=1;
+#endif
       }
       if (Type == "SMESH.FT_EntityType")
       {
         // set SMESH.EntityType instead of a numerical Threshold
-        const int nbTypes = SMESH::Entity_Ball+1;
+        const int nbTypes = SMESH::Entity_Last;
         const char* types[nbTypes] = {
           "Entity_Node", "Entity_0D", "Entity_Edge", "Entity_Quad_Edge",
           "Entity_Triangle", "Entity_Quad_Triangle", "Entity_BiQuad_Triangle",
@@ -911,6 +937,10 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand
           "Entity_Polyhedra", "Entity_Quad_Polyhedra", "Entity_Ball" };
         if ( -1 < iGeom && iGeom < nbTypes )
           Threshold = SMESH + types[ iGeom ];
+#ifdef _DEBUG_
+        // is types complete? (compilation failure mains that enum EntityType changed)
+        int _assert[( sizeof(types) / sizeof(const char*) == nbTypes ) ? 1 : -1 ]; _assert[0]=1;
+#endif
       }
     }
     if ( ThresholdID.Length() != 2 ) // neither '' nor ""
@@ -1859,7 +1889,7 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand )
     }
   }
   // ----------------------------------------------------------------------
-  else if ( method == "GetSubMesh" ) { // collect submeshes of the mesh
+  else if ( method == "GetSubMesh" ) { // collect sub-meshes of the mesh
     Handle(_pySubMesh) subMesh = theGen->FindSubMesh( theCommand->GetResultValue() );
     if ( !subMesh.IsNull() ) {
       subMesh->SetCreator( this );
@@ -1867,6 +1897,10 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand )
     }
   }
   // ----------------------------------------------------------------------
+  else if ( method == "GetSubMeshes" ) { // clear as the command does nothing (0023156)
+    theCommand->Clear();
+  }
+  // ----------------------------------------------------------------------
   else if ( method == "AddHypothesis" ) { // mesh.AddHypothesis(geom, HYPO )
     myAddHypCmds.push_back( theCommand );
     // set mesh to hypo
@@ -1881,7 +1915,8 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand )
   // ----------------------------------------------------------------------
   else if ( method == "CreateGroup" ||
             method == "CreateGroupFromGEOM" ||
-            method == "CreateGroupFromFilter" )
+            method == "CreateGroupFromFilter" ||
+            method == "CreateDimGroup" )
   {
     Handle(_pyGroup) group = new _pyGroup( theCommand );
     myGroups.push_back( group );
@@ -1895,7 +1930,7 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand )
     TCollection_AsciiString grIDs = theCommand->GetResultValue();
     list< _pyID >          idList = theCommand->GetStudyEntries( grIDs );
     list< _pyID >::iterator  grID = idList.begin();
-    const int nbGroupsBefore = myGroups.size();
+    const size_t nbGroupsBefore = myGroups.size();
     Handle(_pyObject) obj;
     for ( ; grID != idList.end(); ++grID )
     {
@@ -2092,8 +2127,8 @@ bool _pyMesh::NeedMeshAccess( const Handle(_pyCommand)& theCommand )
   if ( sameMethods.empty() ) {
     const char * names[] =
       { "ExportDAT","ExportUNV","ExportSTL","ExportSAUV", "RemoveGroup","RemoveGroupWithContents",
-        "GetGroups","UnionGroups","IntersectGroups","CutGroups","GetLog","GetId","ClearLog",
-        "GetStudyId","HasDuplicatedGroupNamesMED","GetMEDMesh","NbNodes","NbElements",
+        "GetGroups","UnionGroups","IntersectGroups","CutGroups","CreateDimGroup","GetLog","GetId",
+        "ClearLog","GetStudyId","HasDuplicatedGroupNamesMED","GetMEDMesh","NbNodes","NbElements",
         "NbEdges","NbEdgesOfOrder","NbFaces","NbFacesOfOrder","NbTriangles",
         "NbTrianglesOfOrder","NbQuadrangles","NbQuadranglesOfOrder","NbPolygons","NbVolumes",
         "NbVolumesOfOrder","NbTetras","NbTetrasOfOrder","NbHexas","NbHexasOfOrder",
@@ -2394,11 +2429,13 @@ void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand)
       "ConvertToQuadratic","ConvertFromQuadratic","RenumberNodes","RenumberElements",
       "RotationSweep","RotationSweepObject","RotationSweepObject1D","RotationSweepObject2D",
       "ExtrusionSweep","AdvancedExtrusion","ExtrusionSweepObject","ExtrusionSweepObject1D",
-      "ExtrusionSweepObject2D","ExtrusionAlongPath","ExtrusionAlongPathObject",
+      "ExtrusionByNormal", "ExtrusionSweepObject2D","ExtrusionAlongPath","ExtrusionAlongPathObject",
       "ExtrusionAlongPathX","ExtrusionAlongPathObject1D","ExtrusionAlongPathObject2D",
+      "ExtrusionSweepObjects","RotationSweepObjects","ExtrusionAlongPathObjects",
       "Mirror","MirrorObject","Translate","TranslateObject","Rotate","RotateObject",
       "FindCoincidentNodes","MergeNodes","FindEqualElements",
       "MergeElements","MergeEqualElements","SewFreeBorders","SewConformFreeBorders",
+      "FindCoincidentFreeBorders", "SewCoincidentFreeBorders",
       "SewBorderToSide","SewSideElements","ChangeElemNodes","GetLastCreatedNodes",
       "GetLastCreatedElems",
       "MirrorMakeMesh","MirrorObjectMakeMesh","TranslateMakeMesh","TranslateObjectMakeMesh",
@@ -2777,7 +2814,7 @@ void _pyHypothesis::Process( const Handle(_pyCommand)& theCommand)
           myArgCommands.push_back( theCommand );
         usedCommand = true;
         while ( crMethod.myArgs.size() < i+1 )
-          crMethod.myArgs.push_back( "[]" );
+          crMethod.myArgs.push_back( "None" );
         crMethod.myArgs[ i ] = theCommand->GetArg( crMethod.myArgNb[i] );
       }
     }
@@ -3096,7 +3133,7 @@ void _pyHypothesis::setCreationArg( const int argNb, const _AString& arg )
 {
   if ( myCurCrMethod )
   {
-    while ( myCurCrMethod->myArgs.size() < argNb )
+    while ( (int) myCurCrMethod->myArgs.size() < argNb )
       myCurCrMethod->myArgs.push_back( "None" );
     if ( arg.IsEmpty() )
       myCurCrMethod->myArgs[ argNb-1 ] = "None";
@@ -3163,7 +3200,7 @@ void _pyComplexParamHypo::Process( const Handle(_pyCommand)& theCommand)
     for ( ; type2meth != myAlgoType2CreationMethod.end(); ++type2meth )
     {
       CreationMethod& crMethod = type2meth->second;
-        while ( crMethod.myArgs.size() < i+1 )
+      while ( (int) crMethod.myArgs.size() < i+1 )
           crMethod.myArgs.push_back( "[]" );
         crMethod.myArgs[ i ] = theCommand->GetArg( 1 ); // arg value
     }
@@ -3548,11 +3585,11 @@ void _pyCommand::SetBegPos( int thePartIndex, int thePosition )
 TCollection_AsciiString _pyCommand::GetIndentation()
 {
   int end = 1;
-  if ( GetBegPos( RESULT_IND ) == UNKNOWN )
-    GetWord( myString, end, true );
-  else
-    end = GetBegPos( RESULT_IND );
-  return myString.SubString( 1, Max( end - 1, 1 ));
+  //while ( end <= Length() && isblank( myString.Value( end )))
+  //ANA: isblank() function isn't provided in VC2010 compiler
+  while ( end <= Length() && ( myString.Value( end ) == ' ' || myString.Value( end ) == '\t') )
+    ++end;
+  return ( end == 1 ) ? _AString("") : myString.SubString( 1, end - 1 );
 }
 
 //================================================================================
@@ -3707,12 +3744,15 @@ const TCollection_AsciiString & _pyCommand::GetMethod()
   if ( GetBegPos( METHOD_IND ) == UNKNOWN )
   {
     // beginning
-    int begPos = GetBegPos( OBJECT_IND ) + myObj.Length();
+    int begPos = GetBegPos( OBJECT_IND );
     bool forward = true;
     if ( begPos < 1 ) {
       begPos = myString.Location( "(", 1, Length() ) - 1;
       forward = false;
     }
+    else {
+      begPos += myObj.Length();
+    }
     // store
     myMeth = GetWord( myString, begPos, forward );
     SetBegPos( METHOD_IND, begPos );
index 04352f24ca3b8c8ff8cb1cb420f7da9476f853f8..ca1f78337da2172d7152d79438c044b3940ba506 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -115,7 +115,7 @@ class _pyCommand: public Standard_Transient
 public:
   _pyCommand() {};
   _pyCommand( const _AString& theString, int theNb=-1 )
-    : myString( theString ), myOrderNb( theNb ) {};
+    : myOrderNb( theNb ), myString( theString ) {};
   _AString & GetString() { return myString; }
   int  GetOrderNb() const { return myOrderNb; }
   void SetOrderNb( int theNb ) { myOrderNb = theNb; }
index 178d906c8a7058d95a6ffe2bbe8617ebbf175a75..9bdcdd8c20bb5a8776a7fb9f6fd9ee6e6e1f7b0d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index a18bbab1b9fab96ca3b746221090196fe3ccb7fd..02ddc3f82dfecb76ddc5906f4ae4235a738d9fef 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 3001b765061969c1371fadf98e3f6b50ff50b54c..7fc7635adca7fc79ebb687e403f8ff60458dd101 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 70f041860edaacf217a4a38a62b624260497c407..af4471302eb435a044e46233a50f0e08fa63372c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 4289342dc1b83065d3918c7a358e7ab42a9ff9ea..187055df5a20356810254008776024dc9b31dc40 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -98,7 +98,7 @@ namespace SMESH
       myStream << "[ ";
       for ( size_t i = 1; i <= theVarValue.myVals.size(); ++i )
       {
-        if ( myVarsCounter < varIDs.size() && varIDs[ myVarsCounter ] >= 0 )
+        if ( myVarsCounter < (int)varIDs.size() && varIDs[ myVarsCounter ] >= 0 )
           myStream << TVar::Quote() << varIDs[ myVarsCounter ] << TVar::Quote();
         else
           myStream << theVarValue.myVals[i-1];
@@ -110,7 +110,7 @@ namespace SMESH
     }
     else
     {
-      if ( myVarsCounter < varIDs.size() && varIDs[ myVarsCounter ] >= 0 )
+      if ( myVarsCounter < (int)varIDs.size() && varIDs[ myVarsCounter ] >= 0 )
         myStream << TVar::Quote() << varIDs[ myVarsCounter ] << TVar::Quote();
       else
         myStream << theVarValue.myVals[0];
@@ -247,7 +247,7 @@ namespace SMESH
     else
     {
       theStream << "[ ";
-      for (int i = 1; i <= theArray.length(); i++) {
+      for (CORBA::ULong i = 1; i <= theArray.length(); i++) {
         theStream << theArray[i-1];
         if ( i < theArray.length() )
           theStream << ", ";
@@ -281,7 +281,7 @@ namespace SMESH
   TPythonDump::operator<<(const SMESH::string_array& theArray)
   {
     myStream << "[ ";
-    for (int i = 1; i <= theArray.length(); i++) {
+    for ( CORBA::ULong i = 1; i <= theArray.length(); i++ ) {
       myStream << "'" << theArray[i-1] << "'";
       if ( i < theArray.length() )
         myStream << ", ";
@@ -423,6 +423,7 @@ namespace SMESH
       case FT_MultiConnection2D:     myStream<< "aMultiConnection2D";     break;
       case FT_Length:                myStream<< "aLength";                break;
       case FT_Length2D:              myStream<< "aLength2D";              break;
+      case FT_BelongToMeshGroup:     myStream<< "aBelongToMeshGroup";     break;
       case FT_BelongToGeom:          myStream<< "aBelongToGeom";          break;
       case FT_BelongToPlane:         myStream<< "aBelongToPlane";         break;
       case FT_BelongToCylinder:      myStream<< "aBelongToCylinder";      break;
@@ -546,6 +547,39 @@ namespace SMESH
     DumpArray( theList, *this );
     return *this;
   }
+  TPythonDump& TPythonDump::operator<<(const SMESH::CoincidentFreeBorders& theCFB)
+  {
+    // dump CoincidentFreeBorders as a list of lists, each enclosed list
+    // contains node IDs of a group of coincident free borders where
+    // each consequent triple of IDs describe a free border: (n1, n2, nLast)
+    // For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes
+    // two groups of coincident free borders, each group including two borders
+
+    myStream << "[";
+    for ( CORBA::ULong i = 0; i < theCFB.coincidentGroups.length(); ++i )
+    {
+      const SMESH::FreeBordersGroup& aGRP = theCFB.coincidentGroups[ i ];
+      if ( i ) myStream << ",";
+      myStream << "[";
+      for ( CORBA::ULong iP = 0; iP < aGRP.length(); ++iP )
+      {
+        const SMESH::FreeBorderPart& aPART = aGRP[ iP ];
+        if ( 0 <= aPART.border && aPART.border < (CORBA::Long)theCFB.borders.length() )
+        {
+          if ( iP ) myStream << ", ";
+          const SMESH::FreeBorder& aBRD = theCFB.borders[ aPART.border ];
+          myStream << aBRD.nodeIDs[ aPART.node1    ] << ",";
+          myStream << aBRD.nodeIDs[ aPART.node2    ] << ",";
+          myStream << aBRD.nodeIDs[ aPART.nodeLast ];
+        }
+      }
+      myStream << "]";
+    }
+    myStream << "]";
+
+    return *this;
+  }
+
   const char* TPythonDump::NotPublishedObjectName()
   {
     return theNotPublishedObjectName;
@@ -1145,9 +1179,11 @@ TCollection_AsciiString SMESH_Gen_i::DumpPython_impl
   if ( importGeom && isMultiFile )
   {
     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");
+                 "import string, os, sys, re, inspect\n"
+                 "thisFile   = inspect.getfile( inspect.currentframe() )\n"
+                 "thisModule = os.path.splitext( os.path.basename( thisFile ))[0]\n"
+                 "sys.path.insert( 0, os.path.dirname( thisFile ))\n"
+                 "exec(\"from \"+re.sub(\"SMESH$\",\"GEOM\",thisModule)+\" import *\")\n\n");
   }
   // import python files corresponding to plugins if they are used in anUpdatedScript
   {
@@ -1173,7 +1209,7 @@ TCollection_AsciiString SMESH_Gen_i::DumpPython_impl
       initPart += importStr + "\n";
   }
 
-  if( isMultiFile )
+  if ( isMultiFile )
     initPart += "def RebuildData(theStudy):";
   initPart += "\n";
 
@@ -1237,8 +1273,18 @@ TCollection_AsciiString SMESH_Gen_i::DumpPython_impl
 
   anUpdatedScript += removeObjPart + '\n' + setNamePart + '\n' + visualPropertiesPart;
 
-  if( isMultiFile )
-    anUpdatedScript += "\n\tpass";
+  if ( isMultiFile )
+  {
+    anUpdatedScript +=
+      "\n\tpass"
+      "\n"
+      "\nif __name__ == '__main__':"
+      "\n\tSMESH_RebuildData = RebuildData"
+      "\n\texec('import '+re.sub('SMESH$','GEOM',thisModule)+' as GEOM_dump')"
+      "\n\tGEOM_dump.RebuildData( salome.myStudy )"
+      "\n\texec('from '+re.sub('SMESH$','GEOM',thisModule)+' import * ')"
+      "\n\tSMESH_RebuildData( salome.myStudy )";
+  }
   anUpdatedScript += "\n";
 
   // no need now as we use 'tab' and 'nt' variables depending on isMultiFile
index 3d7977cb6969fd9d92e157d5836622b427d78717..36808eed4afb03715767d29fe2b77b1c906f8ec1 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -31,6 +31,7 @@
 #include "SMDS_Mesh.hxx"
 #include "SMDS_MeshElement.hxx"
 #include "SMDS_MeshNode.hxx"
+#include "SMESHDS_GroupBase.hxx"
 #include "SMESHDS_Mesh.hxx"
 #include "SMESH_Gen_i.hxx"
 #include "SMESH_Group_i.hxx"
@@ -169,21 +170,21 @@ static TopoDS_Shape getShapeByID (const char* theID)
   return TopoDS_Shape();
 }
 
-static std::string getShapeNameByID (const char* 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_wrap aSObj = aStudy->FindObjectID(theID);
-      if ( !aSObj->_is_nil() ) {
-        CORBA::String_var name = aSObj->GetName();
-        return name.in();
-      }
-    }
-  }
-  return "";
-}
+// static std::string getShapeNameByID (const char* 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_wrap aSObj = aStudy->FindObjectID(theID);
+//       if ( !aSObj->_is_nil() ) {
+//         CORBA::String_var name = aSObj->GetName();
+//         return name.in();
+//       }
+//     }
+//   }
+//   return "";
+// }
 
 /*
                                 FUNCTORS
@@ -509,7 +510,6 @@ FunctorType Length2D_i::GetFunctorType()
 
 SMESH::Length2D::Values* Length2D_i::GetValues()
 {
-  INFOS("Length2D_i::GetValues");
   SMESH::Controls::Length2D::TValues aValues;
   (dynamic_cast<SMESH::Controls::Length2D*>(myFunctorPtr.get()))->GetValues( aValues );
 
@@ -529,7 +529,6 @@ SMESH::Length2D::Values* Length2D_i::GetValues()
     aValue.myPnt2 = aVal.myPntId[ 1 ];
   }
 
-  INFOS("Length2D_i::GetValuess~");
   return aResult._retn();
 }
 
@@ -580,7 +579,6 @@ FunctorType MultiConnection2D_i::GetFunctorType()
 
 SMESH::MultiConnection2D::Values* MultiConnection2D_i::GetValues()
 {
-  INFOS("MultiConnection2D_i::GetValues");
   SMESH::Controls::MultiConnection2D::MValues aValues;
   (dynamic_cast<SMESH::Controls::MultiConnection2D*>(myFunctorPtr.get()))->GetValues( aValues );
   
@@ -600,7 +598,6 @@ SMESH::MultiConnection2D::Values* MultiConnection2D_i::GetValues()
     aValue.myNbConnects = (*anIter).second;
   }
 
-  INFOS("Multiconnection2D_i::GetValuess~");
   return aResult._retn();
 }
 
@@ -722,6 +719,108 @@ FunctorType OverConstrainedFace_i::GetFunctorType()
   return SMESH::FT_OverConstrainedFace;
 }
 
+/*
+  Class       : BelongToMeshGroup_i
+  Description : Verify whether a mesh element is included into a mesh group
+*/
+BelongToMeshGroup_i::BelongToMeshGroup_i()
+{
+  myBelongToMeshGroup = Controls::BelongToMeshGroupPtr( new Controls::BelongToMeshGroup() );
+  myFunctorPtr = myPredicatePtr = myBelongToMeshGroup;
+}
+
+BelongToMeshGroup_i::~BelongToMeshGroup_i()
+{
+  SetGroup( SMESH::SMESH_GroupBase::_nil() );
+}
+
+void BelongToMeshGroup_i::SetGroup( SMESH::SMESH_GroupBase_ptr theGroup )
+{
+  if ( myGroup->_is_equivalent( theGroup ))
+    return;
+
+  if ( ! myGroup->_is_nil() )
+    myGroup->UnRegister();
+
+  myGroup = SMESH_GroupBase::_duplicate( theGroup );
+
+  myBelongToMeshGroup->SetGroup( 0 );
+  if ( SMESH_GroupBase_i* gr_i = SMESH::DownCast< SMESH_GroupBase_i* >( myGroup ))
+  {
+    myBelongToMeshGroup->SetGroup( gr_i->GetGroupDS() );
+    myGroup->Register();
+  }
+}
+
+void BelongToMeshGroup_i::SetGroupID( const char* theID ) // IOR or StoreName
+{
+  myID = theID;
+  if ( strncmp( "IOR:", myID.c_str(), 4 ) == 0 ) // transient mode, no GUI
+  {
+    CORBA::Object_var obj = SMESH_Gen_i::GetORB()->string_to_object( myID.c_str() );
+    SetGroup( SMESH::SMESH_GroupBase::_narrow( obj ));
+  }
+  else if ( strncmp( "0:", myID.c_str(), 2 ) == 0 ) // transient mode + GUI
+  {
+    SMESH_Gen_i* aSMESHGen     = SMESH_Gen_i::GetSMESHGen();
+    SALOMEDS::Study_var aStudy = aSMESHGen->GetCurrentStudy();
+    if ( !aStudy->_is_nil() ) {
+      SALOMEDS::SObject_wrap aSObj = aStudy->FindObjectID( myID.c_str() );
+      if ( !aSObj->_is_nil() ) {
+        CORBA::Object_var obj = aSObj->GetObject();
+        SetGroup( SMESH::SMESH_GroupBase::_narrow( obj ));
+      }
+    }
+  }
+  else if ( !myID.empty() ) // persistent mode
+  {
+    myBelongToMeshGroup->SetStoreName( myID );
+  }
+}
+
+std::string BelongToMeshGroup_i::GetGroupID()
+{
+  if ( myGroup->_is_nil() )
+    SMESH::SMESH_GroupBase_var( GetGroup() );
+
+  if ( !myGroup->_is_nil() )
+    myID = SMESH_Gen_i::GetORB()->object_to_string( myGroup );
+
+  return myID;
+}
+
+SMESH::SMESH_GroupBase_ptr BelongToMeshGroup_i::GetGroup()
+{
+  if ( myGroup->_is_nil() && myBelongToMeshGroup->GetGroup() )
+  {
+    // search for a group in a current study
+    SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
+    if ( StudyContext*  sc = aSMESHGen->GetCurrentStudyContext() )
+    {
+      int id = 1;
+      std::string ior;
+      while (true)
+      {
+        ior = sc->getIORbyId( id++ );
+        if ( ior.empty() ) break;
+        CORBA::Object_var obj = aSMESHGen->GetORB()->string_to_object( ior.c_str() );
+        if ( SMESH_GroupBase_i* g_i = SMESH::DownCast<SMESH_GroupBase_i*>( obj ))
+          if ( g_i->GetGroupDS() == myBelongToMeshGroup->GetGroup() )
+          {
+            SetGroup( g_i->_this() );
+            break;
+          }
+      }
+    }
+  }
+  return SMESH::SMESH_GroupBase::_duplicate( myGroup );
+}
+
+FunctorType BelongToMeshGroup_i::GetFunctorType()
+{
+  return SMESH::FT_BelongToMeshGroup;
+}
+
 /*
   Class       : BelongToGeom_i
   Description : Predicate for selection on geometrical support
@@ -736,8 +835,8 @@ BelongToGeom_i::BelongToGeom_i()
 
 BelongToGeom_i::~BelongToGeom_i()
 {
-  delete myShapeName;
-  delete myShapeID;
+  CORBA::string_free( myShapeName );
+  CORBA::string_free( myShapeID );
 }
 
 void BelongToGeom_i::SetGeom( GEOM::GEOM_Object_ptr theGeom )
@@ -756,7 +855,8 @@ void BelongToGeom_i::SetGeom( const TopoDS_Shape& theShape )
   myBelongToGeomPtr->SetGeom( theShape );
 }
 
-void BelongToGeom_i::SetElementType(ElementType theType){
+void BelongToGeom_i::SetElementType(ElementType theType)
+{
   myBelongToGeomPtr->SetType(SMDSAbs_ElementType(theType));
   TPythonDump()<<this<<".SetElementType("<<theType<<")";
 }
@@ -768,26 +868,33 @@ FunctorType BelongToGeom_i::GetFunctorType()
 
 void BelongToGeom_i::SetShapeName( const char* theName )
 {
-  delete myShapeName;
-  myShapeName = strdup( theName );
+  CORBA::string_free( myShapeName );
+  myShapeName = CORBA::string_dup( theName );
   myBelongToGeomPtr->SetGeom( getShapeByName( myShapeName ) );
   TPythonDump()<<this<<".SetShapeName('"<<theName<<"')";
 }
 
 void BelongToGeom_i::SetShape( const char* theID, const char* theName )
 {
-  delete myShapeName;
-  myShapeName = strdup( theName );
-  delete myShapeID;
-  if ( theID )
-    myShapeID = strdup( theID );
-  else
-    myShapeID = 0;
+  CORBA::string_free( myShapeName );
+  CORBA::string_free( myShapeID );
+  myShapeName = CORBA::string_dup( theName );
+  myShapeID   = CORBA::string_dup( theID );
+  bool hasName = ( theName && theName[0] );
+  bool hasID   = ( theID   && theID[0] );
 
-  if ( myShapeID && myShapeName == getShapeNameByID(myShapeID))
-    myBelongToGeomPtr->SetGeom( getShapeByID(myShapeID) );
+  TopoDS_Shape S;
+  if ( hasName && hasID )
+  {
+    S = getShapeByID( myShapeID );
+    if ( S.IsNull() )
+      S = getShapeByName( myShapeName );
+  }
   else
-    myBelongToGeomPtr->SetGeom( getShapeByName( myShapeName ) );
+  {
+    S = hasID ? getShapeByID( myShapeID ) : getShapeByName( myShapeName );
+  }
+  myBelongToGeomPtr->SetGeom( S );
 }
 
 char* BelongToGeom_i::GetShapeName()
@@ -826,8 +933,8 @@ BelongToSurface_i::BelongToSurface_i( const Handle(Standard_Type)& theSurfaceTyp
 
 BelongToSurface_i::~BelongToSurface_i()
 {
-  delete myShapeName;
-  delete myShapeID;
+  CORBA::string_free( myShapeName );
+  CORBA::string_free( myShapeID );
 }
 
 void BelongToSurface_i::SetSurface( GEOM::GEOM_Object_ptr theGeom, ElementType theType )
@@ -853,26 +960,33 @@ void BelongToSurface_i::SetSurface( GEOM::GEOM_Object_ptr theGeom, ElementType t
 
 void BelongToSurface_i::SetShapeName( const char* theName, ElementType theType )
 {
-  delete myShapeName;
-  myShapeName = strdup( theName );
+  CORBA::string_free( myShapeName );
+  myShapeName = CORBA::string_dup( theName );
   myElementsOnSurfacePtr->SetSurface( getShapeByName( myShapeName ), (SMDSAbs_ElementType)theType );
   TPythonDump()<<this<<".SetShapeName('"<<theName<<"',"<<theType<<")";
 }
 
 void BelongToSurface_i::SetShape( const char* theID,  const char* theName, ElementType theType )
 {
-  delete myShapeName;
-  myShapeName = strdup( theName );
-  delete myShapeID;
-  if ( theID )
-    myShapeID = strdup( theID );
-  else
-    myShapeID = 0;
-  
-  if ( myShapeID && myShapeName == getShapeNameByID(myShapeID))
-    myElementsOnSurfacePtr->SetSurface( getShapeByID(myShapeID), (SMDSAbs_ElementType)theType );
+  CORBA::string_free( myShapeName );
+  CORBA::string_free( myShapeID );
+  myShapeName = CORBA::string_dup( theName );
+  myShapeID   = CORBA::string_dup( theID );
+  bool hasName = ( theName && theName[0] );
+  bool hasID   = ( theID   && theID[0] );
+
+  TopoDS_Shape S;
+  if ( hasName && hasID )
+  {
+    S = getShapeByID( myShapeID );
+    if ( S.IsNull() )
+      S = getShapeByName( myShapeName );
+  }
   else
-    myElementsOnSurfacePtr->SetSurface( getShapeByName( myShapeName ), (SMDSAbs_ElementType)theType );
+  {
+    S = hasID ? getShapeByID( myShapeID ) : getShapeByName( myShapeName );
+  }
+  myElementsOnSurfacePtr->SetSurface( S, (SMDSAbs_ElementType)theType );
 }
 
 char* BelongToSurface_i::GetShapeName()
@@ -991,8 +1105,8 @@ LyingOnGeom_i::LyingOnGeom_i()
 
 LyingOnGeom_i::~LyingOnGeom_i()
 {
-  delete myShapeName;
-  delete myShapeID;
+  CORBA::string_free( myShapeName );
+  CORBA::string_free( myShapeID );
 }
 
 void LyingOnGeom_i::SetGeom( GEOM::GEOM_Object_ptr theGeom )
@@ -1023,26 +1137,33 @@ FunctorType LyingOnGeom_i::GetFunctorType()
 
 void LyingOnGeom_i::SetShapeName( const char* theName )
 {
-  delete myShapeName;
-  myShapeName = strdup( theName );
+  CORBA::string_free( myShapeName );
+  myShapeName = CORBA::string_dup( theName );
   myLyingOnGeomPtr->SetGeom( getShapeByName( myShapeName ) );
   TPythonDump()<<this<<".SetShapeName('"<<theName<<"')";
 }
 
 void LyingOnGeom_i::SetShape( const char* theID, const char* theName )
 {
-  delete myShapeName;
-  myShapeName = strdup( theName );
-  delete myShapeID;
-  if ( theID )
-    myShapeID = strdup( theID );
-  else
-    myShapeID = 0;
-  
-  if ( myShapeID && myShapeName == getShapeNameByID(myShapeID))
-    myLyingOnGeomPtr->SetGeom( getShapeByID(myShapeID) );
+  CORBA::string_free( myShapeName );
+  CORBA::string_free( myShapeID   );
+  myShapeName = CORBA::string_dup( theName );
+  myShapeID   = CORBA::string_dup( theID   );
+  bool hasName = ( theName && theName[0] );
+  bool hasID   = ( theID   && theID[0]   );
+
+  TopoDS_Shape S;
+  if ( hasName && hasID )
+  {
+    S = getShapeByID( myShapeID );
+    if ( S.IsNull() )
+      S = getShapeByName( myShapeName );
+  }
   else
-    myLyingOnGeomPtr->SetGeom( getShapeByName( myShapeName ) );
+  {
+    S = hasID ? getShapeByID( myShapeID ) : getShapeByName( myShapeName );
+  }
+  myLyingOnGeomPtr->SetGeom( S );
 }
 
 char* LyingOnGeom_i::GetShapeName()
@@ -1093,7 +1214,6 @@ FreeEdges_i::FreeEdges_i()
 
 SMESH::FreeEdges::Borders* FreeEdges_i::GetBorders()
 {
-  INFOS("FreeEdges_i::GetBorders");
   SMESH::Controls::FreeEdges::TBorders aBorders;
   myFreeEdgesPtr->GetBoreders( aBorders );
 
@@ -1112,8 +1232,6 @@ SMESH::FreeEdges::Borders* FreeEdges_i::GetBorders()
     aBorder.myPnt1 = aBord.myPntId[ 0 ];
     aBorder.myPnt2 = aBord.myPntId[ 1 ];
   }
-
-  INFOS("FreeEdges_i::GetBorders~");
   return aResult._retn();
 }
 
@@ -1712,9 +1830,9 @@ FunctorType EqualTo_i::GetFunctorType()
   Class       : LogicalNOT_i
   Description : Logical NOT predicate
 */
-LogicalNOT_i::LogicalNOT_i()
-: myPredicate( NULL ),
-  myLogicalNOTPtr( new Controls::LogicalNOT() )
+LogicalNOT_i::LogicalNOT_i():
+  myLogicalNOTPtr( new Controls::LogicalNOT() ),
+  myPredicate( NULL )
 {
   myFunctorPtr = myPredicatePtr = myLogicalNOTPtr;
 }
@@ -1750,6 +1868,7 @@ Predicate_i* LogicalNOT_i::GetPredicate_i()
 }
 
 
+
 /*
   Class       : LogicalBinary_i
   Description : Base class for binary logical predicate
@@ -2001,6 +2120,14 @@ BallDiameter_ptr FilterManager_i::CreateBallDiameter()
   return anObj._retn();
 }
 
+BelongToMeshGroup_ptr FilterManager_i::CreateBelongToMeshGroup()
+{
+  SMESH::BelongToMeshGroup_i* aServant = new SMESH::BelongToMeshGroup_i();
+  SMESH::BelongToMeshGroup_var anObj = aServant->_this();
+  TPythonDump()<<aServant<<" = "<<this<<".CreateBelongToMeshGroup()";
+  return anObj._retn();
+}
+
 BelongToGeom_ptr FilterManager_i::CreateBelongToGeom()
 {
   SMESH::BelongToGeom_i* aServant = new SMESH::BelongToGeom_i();
@@ -2317,7 +2444,8 @@ Filter_i::~Filter_i()
   if(!CORBA::is_nil(myMesh))
     myMesh->UnRegister();
 
-  //TPythonDump()<<this<<".UnRegister()";
+  myPredicate = 0;
+  FindBaseObjects();
 }
 
 //=======================================================================
@@ -2339,9 +2467,7 @@ void Filter_i::SetPredicate( Predicate_ptr thePredicate )
       myPredicate->GetPredicate()->SetMesh( aMesh );
     TPythonDump()<<this<<".SetPredicate("<<myPredicate<<")";
   }
-  std::list<TPredicateChangeWaiter*>::iterator i = myWaiters.begin();
-  for ( ; i != myWaiters.end(); ++i )
-    (*i)->PredicateChanged();
+  NotifyerAndWaiter::Modified();
 }
 
 //=======================================================================
@@ -2413,6 +2539,7 @@ GetElementsId( SMESH_Mesh_ptr theMesh )
 {
   SMESH::long_array_var anArray = new SMESH::long_array;
   if(!CORBA::is_nil(theMesh) && myPredicate){
+    theMesh->Load();
     Controls::Filter::TIdSequence aSequence;
     GetElementsId(myPredicate,theMesh,aSequence);
     long i = 0, iEnd = aSequence.size();
@@ -2517,27 +2644,45 @@ SMESH::SMESH_Mesh_ptr Filter_i::GetMesh()
   return SMESH_Mesh::_duplicate( myMesh );
 }
 
-//================================================================================
-/*!
- * \brief Stores an object to be notified on change of predicate
- */
-//================================================================================
+//=======================================================================
+//function : GetVtkUgStream
+//purpose  : Return data vtk unstructured grid (not implemented)
+//=======================================================================
 
-void Filter_i::AddWaiter( TPredicateChangeWaiter* waiter )
+SALOMEDS::TMPFile* Filter_i::GetVtkUgStream()
 {
-  if ( waiter )
-    myWaiters.push_back( waiter );
+  SALOMEDS::TMPFile_var SeqFile;
+  return SeqFile._retn();
 }
-
-//================================================================================
-/*!
- * \brief Removes an object to be notified on change of predicate
- */
-//================================================================================
-
-void Filter_i::RemoveWaiter( TPredicateChangeWaiter* waiter )
+//=======================================================================
+// name    : getCriteria
+// Purpose : Retrieve criterions from predicate
+//=======================================================================
+static inline void getPrediacates( Predicate_i*                thePred,
+                                   std::vector<Predicate_i*> & thePredVec )
 {
-  myWaiters.remove( waiter );
+  const int aFType = thePred->GetFunctorType();
+
+  switch ( aFType )
+  {
+  case FT_LogicalNOT:
+  {
+    Predicate_i* aPred = ( dynamic_cast<LogicalNOT_i*>( thePred ) )->GetPredicate_i();
+    getPrediacates( aPred, thePredVec );
+    break;
+  }
+  case FT_LogicalAND:
+  case FT_LogicalOR:
+  {
+    Predicate_i* aPred1 = ( dynamic_cast<LogicalBinary_i*>( thePred ) )->GetPredicate1_i();
+    Predicate_i* aPred2 = ( dynamic_cast<LogicalBinary_i*>( thePred ) )->GetPredicate2_i();
+    getPrediacates( aPred1, thePredVec );
+    getPrediacates( aPred2, thePredVec );
+    break;
+   }
+  default:;
+  }
+  thePredVec.push_back( thePred );
 }
 
 //=======================================================================
@@ -2547,7 +2692,7 @@ void Filter_i::RemoveWaiter( TPredicateChangeWaiter* waiter )
 static inline bool getCriteria( Predicate_i*                thePred,
                                 SMESH::Filter::Criteria_out theCriteria )
 {
-  int aFType = thePred->GetFunctorType();
+  const int aFType = thePred->GetFunctorType();
 
   switch ( aFType )
   {
@@ -2601,6 +2746,17 @@ static inline bool getCriteria( Predicate_i*                thePred,
     {
       return true;
     }
+  case FT_BelongToMeshGroup:
+    {
+      BelongToMeshGroup_i* aPred = dynamic_cast<BelongToMeshGroup_i*>( thePred );
+      SMESH::SMESH_GroupBase_var grp = aPred->GetGroup();
+      if ( !grp->_is_nil() )
+      {
+        theCriteria[ i ].ThresholdStr = grp->GetName();
+        theCriteria[ i ].ThresholdID  = aPred->GetGroupID().c_str();
+      }
+      return true;
+    }
   case FT_BelongToGeom:
     {
       BelongToGeom_i* aPred = dynamic_cast<BelongToGeom_i*>( thePred );
@@ -2839,6 +2995,13 @@ CORBA::Boolean Filter_i::SetCriteria( const SMESH::Filter::Criteria& theCriteria
       case SMESH::FT_EqualVolumes:
         aPredicate = aFilterMgr->CreateEqualVolumes();
         break;
+      case SMESH::FT_BelongToMeshGroup:
+        {
+          SMESH::BelongToMeshGroup_ptr tmpPred = aFilterMgr->CreateBelongToMeshGroup();
+          tmpPred->SetGroupID( aThresholdID );
+          aPredicate = tmpPred;
+        }
+        break;
       case SMESH::FT_BelongToGeom:
         {
           SMESH::BelongToGeom_ptr tmpPred = aFilterMgr->CreateBelongToGeom();
@@ -3102,6 +3265,75 @@ Predicate_ptr Filter_i::GetPredicate()
   }
 }
 
+//================================================================================
+/*!
+ * \brief Find groups it depends on
+ */
+//================================================================================
+
+void Filter_i::FindBaseObjects()
+{
+  // release current groups
+  for ( size_t i = 0; i < myBaseGroups.size(); ++i )
+    if ( myBaseGroups[i] )
+    {
+      myBaseGroups[i]->RemoveModifWaiter( this );
+      myBaseGroups[i]->UnRegister();
+    }
+
+  // remember new groups
+  myBaseGroups.clear();
+  if ( myPredicate )
+  {
+    std::vector<Predicate_i*> predicates;
+    getPrediacates( myPredicate, predicates );
+    for ( size_t i = 0; i < predicates.size(); ++i )
+      if ( BelongToMeshGroup_i* bmg = dynamic_cast< BelongToMeshGroup_i* >( predicates[i] ))
+      {
+        SMESH::SMESH_GroupBase_var g = bmg->GetGroup();
+        SMESH_GroupBase_i* g_i = SMESH::DownCast< SMESH_GroupBase_i*>( g );
+        if ( g_i )
+        {
+          g_i->AddModifWaiter( this );
+          g_i->Register();
+          myBaseGroups.push_back( g_i );
+        }
+      }
+  }
+}
+
+//================================================================================
+/*!
+ * \brief When notified on removal of myBaseGroups[i], remove a reference to a
+ *        group from a predicate
+ */
+//================================================================================
+
+void Filter_i::OnBaseObjModified(NotifyerAndWaiter* group, bool removed)
+{
+  if ( !removed )
+    return; // a GroupOnFilter holding this filter is notified automatically
+
+  if ( myPredicate )
+  {
+    std::vector<Predicate_i*> predicates;
+    getPrediacates( myPredicate, predicates );
+    for ( size_t i = 0; i < predicates.size(); ++i )
+      if ( BelongToMeshGroup_i* bmg = dynamic_cast< BelongToMeshGroup_i* >( predicates[i] ))
+      {
+        SMESH::SMESH_GroupBase_var g = bmg->GetGroup();
+        SMESH_GroupBase_i* g_i = SMESH::DownCast< SMESH_GroupBase_i*>( g );
+        if ( g_i == group )
+        {
+          bmg->SetGroup( SMESH::SMESH_GroupBase::_nil() );
+          bmg->SetGroupID( "" );
+        }
+      }
+  }
+
+  FindBaseObjects(); // release and update myBaseGroups;
+}
+
 /*
                             FILTER LIBRARY
 */
@@ -3161,50 +3393,51 @@ static inline LDOMString toString( CORBA::Long theType )
 {
   switch ( theType )
   {
-    case FT_AspectRatio     : return "Aspect ratio";
-    case FT_Warping         : return "Warping";
-    case FT_MinimumAngle    : return "Minimum angle";
-    case FT_Taper           : return "Taper";
-    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_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_Length          : return "Length";
-    case FT_Length2D        : return "Length 2D";
-    case FT_LessThan        : return "Less than";
-    case FT_MoreThan        : return "More than";
-    case FT_EqualTo         : return "Equal to";
-    case FT_LogicalNOT      : return "Not";
-    case FT_LogicalAND      : return "And";
-    case FT_LogicalOR       : return "Or";
-    case FT_GroupColor      : return "Color of Group";
-    case FT_LinearOrQuadratic : return "Linear or Quadratic";
-    case FT_ElemGeomType    : return "Element geomtry type";
-    case FT_EntityType      : return "Entity type";
-    case FT_Undefined       : return "";
-    default                 : return "";
+    case FT_AspectRatio           : return "Aspect ratio";
+    case FT_Warping               : return "Warping";
+    case FT_MinimumAngle          : return "Minimum angle";
+    case FT_Taper                 : return "Taper";
+    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_BelongToMeshGroup     : return "Belong to Mesh Group";
+    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_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_Length                : return "Length";
+    case FT_Length2D              : return "Length 2D";
+    case FT_LessThan              : return "Less than";
+    case FT_MoreThan              : return "More than";
+    case FT_EqualTo               : return "Equal to";
+    case FT_LogicalNOT            : return "Not";
+    case FT_LogicalAND            : return "And";
+    case FT_LogicalOR             : return "Or";
+    case FT_GroupColor            : return "Color of Group";
+    case FT_LinearOrQuadratic     : return "Linear or Quadratic";
+    case FT_ElemGeomType          : return "Element geomtry type";
+    case FT_EntityType            : return "Entity type";
+    case FT_Undefined             : return "";
+    default                       : return "";
   }
 }
 
@@ -3223,6 +3456,7 @@ static inline SMESH::FunctorType toFunctorType( const LDOMString& theStr )
   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 Mesh Group"         ) ) return FT_BelongToMeshGroup;
   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;
@@ -3431,7 +3665,7 @@ static LDOM_Element createFilterItem( const char*       theName,
 //=======================================================================
 FilterLibrary_i::FilterLibrary_i( const char* theFileName )
 {
-  myFileName = strdup( theFileName );
+  myFileName = CORBA::string_dup( theFileName );
   SMESH::FilterManager_i* aFilterMgr = new SMESH::FilterManager_i();
   myFilterMgr = aFilterMgr->_this();
 
@@ -3472,7 +3706,7 @@ FilterLibrary_i::FilterLibrary_i()
 
 FilterLibrary_i::~FilterLibrary_i()
 {
-  delete myFileName;
+  CORBA::string_free( myFileName );
   //TPythonDump()<<this<<".UnRegister()";
 }
 
@@ -3524,7 +3758,7 @@ Filter_ptr FilterLibrary_i::Copy( const char* theFilterName )
     {
       char a[ 255 ];
       sprintf( a, "%d", val );
-      aCriterion.ThresholdStr = strdup( a );
+      aCriterion.ThresholdStr = CORBA::string_dup( a );
     }
     else
       aCriterion.ThresholdStr = str.GetString();
@@ -3555,8 +3789,8 @@ Filter_ptr FilterLibrary_i::Copy( const char* theFilterName )
 //=======================================================================
 void FilterLibrary_i::SetFileName( const char* theFileName )
 {
-  delete myFileName;
-  myFileName = strdup( theFileName );
+  CORBA::string_free( myFileName );
+  myFileName = CORBA::string_dup( theFileName );
   TPythonDump()<<this<<".SetFileName('"<<theFileName<<"')";
 }
 
@@ -3779,7 +4013,7 @@ string_array* FilterLibrary_i::GetAllNames()
 
 static const char** getFunctNames()
 {
-  static const char* functName[ SMESH::FT_Undefined + 1 ] = {
+  static const char* functName[] = {
     // IT's necessary to update this array according to enum FunctorType (SMESH_Filter.idl)
     // The order is IMPORTANT !!!
     "FT_AspectRatio",
@@ -3804,6 +4038,7 @@ static const char** getFunctNames()
     "FT_MultiConnection2D",
     "FT_Length",
     "FT_Length2D",
+    "FT_BelongToMeshGroup",
     "FT_BelongToGeom",
     "FT_BelongToPlane",
     "FT_BelongToCylinder",
@@ -3829,6 +4064,13 @@ static const char** getFunctNames()
     "FT_LogicalAND",
     "FT_LogicalOR",
     "FT_Undefined"};
+
+#ifdef _DEBUG_
+  // check if functName is complete, compilation failure means that enum FunctorType changed
+  const int nbFunctors = sizeof(functName) / sizeof(const char*);
+  int _assert[( nbFunctors == SMESH::FT_Undefined + 1 ) ? 1 : -1 ]; _assert[0]=1;
+#endif
+
   return functName;
 }
 
@@ -3864,3 +4106,62 @@ SMESH::FunctorType SMESH::StringToFunctorType(const char* str)
 
   return SMESH::FunctorType( ft );
 }
+
+//================================================================================
+/*!
+ * \brief calls OnBaseObjModified(), if who != this, and myWaiters[i]->Modified(who)
+ */
+//================================================================================
+
+void NotifyerAndWaiter::Modified( bool removed, NotifyerAndWaiter* who )
+{
+  if ( who != 0 && who != this )
+    OnBaseObjModified( who, removed );
+  else
+    who = this;
+
+  std::list<NotifyerAndWaiter*> waiters = myWaiters; // myWaiters can be changed by Modified()
+  std::list<NotifyerAndWaiter*>::iterator i = waiters.begin();
+  for ( ; i != waiters.end(); ++i )
+    (*i)->Modified( removed, who );
+}
+
+//================================================================================
+/*!
+ * \brief Stores an object to be notified on change of predicate
+ */
+//================================================================================
+
+void NotifyerAndWaiter::AddModifWaiter( NotifyerAndWaiter* waiter )
+{
+  if ( waiter )
+    myWaiters.push_back( waiter );
+}
+
+//================================================================================
+/*!
+ * \brief Removes an object to be notified on change of predicate
+ */
+//================================================================================
+
+void NotifyerAndWaiter::RemoveModifWaiter( NotifyerAndWaiter* waiter )
+{
+  myWaiters.remove( waiter );
+}
+
+//================================================================================
+/*!
+ * \brief Checks if a waiter is among myWaiters, maybe nested
+ */
+//================================================================================
+
+bool NotifyerAndWaiter::ContainModifWaiter( NotifyerAndWaiter* waiter )
+{
+  bool is = ( waiter == this );
+
+  std::list<NotifyerAndWaiter*>::iterator w = myWaiters.begin();
+  for ( ; !is && w != myWaiters.end(); ++w )
+    is = (*w)->ContainModifWaiter( waiter );
+
+  return is;
+}
index 92c4618df1bc21d77a11d057c435f77639c83331..a629f6791deef1fba5f9eadbe3d6885475ab1054 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 
 #include <list>
 
+class SMESH_GroupBase_i;
+
+
 namespace SMESH
 {
+  /*!
+   * \brief Object notified on change of base objects and
+   *        notifying dependent objects in its turn.
+   *        This interface is used to track the following dependencies:
+   *        - GroupOnFiler depending on Filter predicates
+   *        - Filter depending on a Group via FT_BelongToMeshGroup predicate 
+   */
+  struct NotifyerAndWaiter
+  {
+    virtual void OnBaseObjModified(NotifyerAndWaiter* obj, bool removed) {};
+    // specific reaction on modification of a base object
+
+    void Modified( bool removed=false, NotifyerAndWaiter* who = 0);
+    // calls OnBaseObjModified(), if who != 0, and myWaiters[i]->Modified(who)
+
+    void AddModifWaiter    ( NotifyerAndWaiter* waiter ); // adds a dependent object to notify
+    void RemoveModifWaiter ( NotifyerAndWaiter* waiter ); // CALL IT when a waiter dies!!!
+    bool ContainModifWaiter( NotifyerAndWaiter* waiter );
+    std::list<NotifyerAndWaiter*> myWaiters;
+  };
   // ================================================================================
   /*
     FUNCTORS
@@ -370,6 +393,28 @@ namespace SMESH
     FunctorType                     GetFunctorType();
   };
 
+  /*
+    Class       : BelongToMeshGroup_i
+    Description : Verify whether a mesh element is included into a mesh group
+  */
+  class SMESH_I_EXPORT BelongToMeshGroup_i: public virtual POA_SMESH::BelongToMeshGroup,
+                                            public virtual Predicate_i
+  {
+    std::string                    myID; // IOR or StoreName
+    SMESH::SMESH_GroupBase_var     myGroup;
+    Controls::BelongToMeshGroupPtr myBelongToMeshGroup;
+  public:
+    BelongToMeshGroup_i();
+    ~BelongToMeshGroup_i();
+    void                       SetGroup( SMESH::SMESH_GroupBase_ptr theGroup );
+    void                       SetGroupID( const char* theID ); // IOR or StoreName
+    SMESH::SMESH_GroupBase_ptr GetGroup();
+
+    std::string                GetGroupID();
+    FunctorType                GetFunctorType();
+    //virtual void               SetMesh( SMESH_Mesh_ptr theMesh );
+  };
+
   /*
     Class       : BelongToGeom_i
     Description : Predicate for selection on geometrical support
@@ -896,7 +941,8 @@ 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 NotifyerAndWaiter
   {
   public:
     Filter_i();
@@ -943,6 +989,12 @@ namespace SMESH
 
     Predicate_i*     GetPredicate_i();
 
+    void FindBaseObjects();
+    // finds groups it depends on
+
+    virtual void OnBaseObjModified(NotifyerAndWaiter* group, bool removed);
+    // notified on change of myBaseGroups[i]
+
     // =========================
     // SMESH_IDSource interface
     // =========================
@@ -952,26 +1004,17 @@ namespace SMESH
     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 );
+    virtual SALOMEDS::TMPFile*           GetVtkUgStream();
 
   private:
     Controls::Filter myFilter;
     Predicate_i*     myPredicate;
     SMESH_Mesh_var   myMesh;
 
-    std::list<TPredicateChangeWaiter*> myWaiters;
+    std::vector< SMESH_GroupBase_i* > myBaseGroups;
   };
-  
-  
+
+
   /*
     FILTER LIBRARY
   */
@@ -1036,6 +1079,7 @@ namespace SMESH
     MultiConnection2D_ptr     CreateMultiConnection2D();
     BallDiameter_ptr          CreateBallDiameter();
     
+    BelongToMeshGroup_ptr     CreateBelongToMeshGroup();
     BelongToGeom_ptr          CreateBelongToGeom();
     BelongToPlane_ptr         CreateBelongToPlane();
     BelongToCylinder_ptr      CreateBelongToCylinder();
index cffb3d57308c54b7f11da79d15613033b745c64f..fe64ce7b7b945ae122c9834fc52d74f8f30d54a7 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 #include <BRep_Tool.hxx>
 #include <TCollection_AsciiString.hxx>
 #include <OSD.hxx>
+#include <BRepPrimAPI_MakeSphere.hxx>
+#include <BRepPrimAPI_MakeCylinder.hxx>
+#include <BRepPrimAPI_MakeBox.hxx>
+
 
 #ifdef WIN32
  #include <windows.h>
@@ -93,6 +97,7 @@
 #include "SMESH_Mesh_i.hxx"
 #include "SMESH_PreMeshInfo.hxx"
 #include "SMESH_PythonDump.hxx"
+#include "SMESH_ControlsDef.hxx"
 #include "SMESH_TryCatch.hxx" // to include after OCC headers!
 
 #include CORBA_SERVER_HEADER(SMESH_Group)
 #include <OpUtil.hxx>
 #include <SALOMEDS_Tool.hxx>
 #include <SALOME_Container_i.hxx>
-#include <SALOME_DataContainer_i.hxx>
 #include <SALOME_LifeCycleCORBA.hxx>
 #include <SALOME_NamingService.hxx>
 #include <Utils_CorbaException.hxx>
@@ -264,7 +268,6 @@ GEOM::GEOM_Gen_var SMESH_Gen_i::GetGeomEngine() {
 
 SMESH_Gen_i::SMESH_Gen_i()
 {
-  INFOS( "SMESH_Gen_i::SMESH_Gen_i : default constructor" );
 }
 
 //=============================================================================
@@ -296,9 +299,6 @@ SMESH_Gen_i::SMESH_Gen_i( CORBA::ORB_ptr            orb,
   myIsHistoricalPythonDump = true;
   myToForgetMeshDataOnHypModif = false;
 
-  myImportedStudyChanged = true;
-  myImportedStudyId      = 0;
-
   // set it in standalone mode only
   //OSD::SetSignal( true );
 
@@ -338,10 +338,17 @@ SMESH_Gen_i::~SMESH_Gen_i()
   MESSAGE( "SMESH_Gen_i::~SMESH_Gen_i" );
 
   // delete hypothesis creators
-  map<string, GenericHypothesisCreator_i*>::iterator itHyp;
+  map<string, GenericHypothesisCreator_i*>::iterator itHyp, itHyp2;
   for (itHyp = myHypCreatorMap.begin(); itHyp != myHypCreatorMap.end(); itHyp++)
   {
-    delete (*itHyp).second;
+    // same creator can be mapped under different names
+    GenericHypothesisCreator_i* creator = (*itHyp).second;
+    if ( !creator )
+      continue;
+    delete creator;
+    for (itHyp2 = itHyp; itHyp2 != myHypCreatorMap.end(); itHyp2++)
+      if ( creator == (*itHyp2).second )
+        (*itHyp2).second = 0;
   }
   myHypCreatorMap.clear();
 
@@ -474,8 +481,9 @@ SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::createHypothesis(const char* theHypName
   myHypothesis_i = aCreator->Create(myPoa, GetCurrentStudyID(), &myGen);
   if (myHypothesis_i)
   {
-    myHypothesis_i->SetLibName(aPlatformLibName.c_str()); // for persistency assurance
-    myHypCreatorMap[ myHypothesis_i->GetName() ] = aCreator;
+    myHypothesis_i->SetLibName( aPlatformLibName.c_str() ); // for persistency assurance
+    CORBA::String_var hypName = myHypothesis_i->GetName();
+    myHypCreatorMap[ hypName.in() ] = aCreator;
 
     // activate the CORBA servant of hypothesis
     hypothesis_i = myHypothesis_i->_this();
@@ -746,7 +754,7 @@ SMESH_Gen_i::GetHypothesisParameterValues (const char*           theHypType,
     return SMESH::SMESH_Hypothesis::_nil();
   ::SMESH_Mesh* mesh = meshServant ? &meshServant->GetImpl() : (::SMESH_Mesh*)0;
 
-  // create a temporary hypothesis to know its dimention
+  // create a temporary hypothesis to know its dimension
   SMESH::SMESH_Hypothesis_var tmpHyp = this->createHypothesis( theHypType, theLibName );
   SMESH_Hypothesis_i* hypServant = SMESH::DownCast<SMESH_Hypothesis_i*>( tmpHyp );
   if ( !hypServant )
@@ -932,7 +940,7 @@ void SMESH_Gen_i::SetOption(const char* name, const char* value)
 {
   if ( name && value && strlen( value ) > 0 )
   {
-    string msgToGUI; 
+    string msgToGUI;
     if ( strcmp(name, "historical_python_dump") == 0 )
     {
       myIsHistoricalPythonDump = ( value[0] == '1' || toupper(value[0]) == 'T' ); // 1 || true
@@ -945,6 +953,34 @@ void SMESH_Gen_i::SetOption(const char* name, const char* value)
       msgToGUI = "preferences/SMESH/forget_mesh_on_hyp_modif/";
       msgToGUI += myToForgetMeshDataOnHypModif ? "true" : "false";
     }
+    else if ( strcmp(name, "default_grp_color") == 0 )
+    {
+      vector<int> color;
+      string str = value;
+      // color must be presented as a string of next form:
+      if ( str.at(0) == '#' && str.length() == 7 ) { // hexadecimal color ("#ffaa00", for example)
+        str = str.substr(1);
+        for ( int i = 0; i < str.length()/2; i++ )
+          if ( str.at(i*2) >= '0' && str.at(i*2) <= 'f' && str.at(i*2+1) >= '0' && str.at(i*2+1) <= 'f' )
+            color.push_back( strtol( str.substr( i*2, 2 ).c_str(), NULL, 16 ) );
+      }
+      else { // rgb color ("255,170,0", for example)
+        char* tempValue = strdup( value );
+        char* colorValue = strtok( tempValue, "," );
+        while ( colorValue != NULL ) {
+          int c_value = atoi( colorValue );
+          if ( c_value >= 0 && c_value <= 255 )
+            color.push_back( c_value );
+          colorValue = strtok( NULL, "," );
+        }
+      }
+      if ( color.size() == 3 ) { // color must have three valid component
+        SMESHDS_GroupBase::SetDefaultColor( Quantity_Color( color[0]/255., color[1]/255., color[2]/255., Quantity_TOC_RGB ) );
+        myDefaultGroupColor = value;
+        msgToGUI = "preferences/SMESH/default_grp_color/";
+        msgToGUI += value;
+      }
+    }
 
     // update preferences in case if SetOption() is invoked from python console
     if ( !msgToGUI.empty() )
@@ -975,6 +1011,10 @@ char* SMESH_Gen_i::GetOption(const char* name)
     {
       return CORBA::string_dup( myToForgetMeshDataOnHypModif ? "true" : "false" );
     }
+    if ( strcmp(name, "default_grp_color") == 0 )
+    {
+      return CORBA::string_dup( myDefaultGroupColor.c_str() );
+    }
   }
   return CORBA::string_dup( "" );
 }
@@ -1196,7 +1236,7 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMEDorSAUV( const char* theFileNa
   aPythonDump << "], status) = " << this << "." << theCommandNameForPython << "(r'" << theFileNameForPython << "')";
   }
   // Dump creation of groups
-  for ( int i = 0; i < aResult->length(); ++i )
+  for ( CORBA::ULong  i = 0; i < aResult->length(); ++i )
     SMESH::ListOfGroups_var groups = aResult[ i ]->GetGroups();
 
   return aResult._retn();
@@ -1374,7 +1414,7 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromCGNS( const char* theFileName,
     aPythonDump << "], status) = " << this << ".CreateMeshesFromCGNS(r'" << theFileName << "')";
   }
   // Dump creation of groups
-  for ( int i = 0; i < aResult->length(); ++i )
+  for ( CORBA::ULong 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);
@@ -1769,9 +1809,10 @@ 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 )
-     throw ( SALOME::SALOME_Exception )
+SMESH::long_array*
+SMESH_Gen_i::GetSubShapesId( GEOM::GEOM_Object_ptr      theMainShapeObject,
+                             const SMESH::object_array& theListOfSubShapeObject )
+  throw ( SALOME::SALOME_Exception )
 {
   Unexpect aCatch(SALOME_SalomeException);
   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::GetSubShapesId" );
@@ -1780,58 +1821,57 @@ SMESH::long_array* SMESH_Gen_i::GetSubShapesId( GEOM::GEOM_Object_ptr theMainSha
   set<int> setId;
 
   if ( CORBA::is_nil( theMainShapeObject ) )
-    THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference",
-                                  SALOME::BAD_PARAM );
+    THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", SALOME::BAD_PARAM );
 
   try
-    {
-      TopoDS_Shape myMainShape = GeomObjectToShape(theMainShapeObject);
-      TopTools_IndexedMapOfShape myIndexToShape;
-      TopExp::MapShapes(myMainShape,myIndexToShape);
+  {
+    TopoDS_Shape myMainShape = GeomObjectToShape(theMainShapeObject);
+    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));
-            }
-        }
-      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++;
-        }
+    for ( CORBA::ULong 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));
+      }
     }
-  catch (SALOME_Exception& S_ex)
+    shapesId->length(setId.size());
+    set<int>::iterator iind;
+    int i=0;
+    for (iind = setId.begin(); iind != setId.end(); iind++)
     {
-      THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
+      if(MYDEBUG) SCRUTE((*iind));
+      shapesId[i] = (*iind);
+      if(MYDEBUG) SCRUTE(shapesId[i]);
+      i++;
     }
+  }
+  catch (SALOME_Exception& S_ex)
+  {
+    THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
+  }
 
   return shapesId._retn();
 }
@@ -1867,9 +1907,9 @@ 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 ) {
+      meshServant->Load();
       // NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation"
       meshServant->CheckGeomModif();
       // get local TopoDS_Shape
@@ -2148,6 +2188,7 @@ SMESH::long_array* SMESH_Gen_i::Evaluate(SMESH::SMESH_Mesh_ptr theMesh,
     SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( theMesh ).in() );
     ASSERT( meshServant );
     if ( meshServant ) {
+      meshServant->Load();
       // NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation"
       meshServant->CheckGeomModif();
       // get local TopoDS_Shape
@@ -2163,13 +2204,13 @@ SMESH::long_array* SMESH_Gen_i::Evaluate(SMESH::SMESH_Mesh_ptr theMesh,
       MapShapeNbElemsItr anIt = aResMap.begin();
       for(; anIt!=aResMap.end(); anIt++) {
         const vector<int>& aVec = (*anIt).second;
-        for(i = SMESH::Entity_Node; i < aVec.size(); i++) {
+        for ( i = SMESH::Entity_Node; i < (int)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_subMesh*            sm = anIt->first;
             SMESH_ComputeErrorPtr& error = sm->GetComputeError();
-            const SMESH_Algo* algo = myGen.GetAlgo( myLocMesh, sm->GetSubShape());
+            const SMESH_Algo*       algo = sm->GetAlgo();
             if ( (algo && !error.get()) || error->IsOK() )
               error.reset( new SMESH_ComputeError( COMPERR_ALGO_FAILED,"Failed to evaluate",algo));
           }
@@ -2344,10 +2385,11 @@ 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)
+SMESH::SMESH_Mesh_ptr
+SMESH_Gen_i::Concatenate(const SMESH::ListOfIDSources& theMeshesArray,
+                         CORBA::Boolean                theUniteIdenticalGroups,
+                         CORBA::Boolean                theMergeNodesAndElements,
+                         CORBA::Double                 theMergeTolerance)
   throw ( SALOME::SALOME_Exception )
 {
   return ConcatenateCommon(theMeshesArray,
@@ -2367,10 +2409,10 @@ 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::Double            theMergeTolerance)
+SMESH_Gen_i::ConcatenateWithGroups(const SMESH::ListOfIDSources& theMeshesArray,
+                                   CORBA::Boolean                theUniteIdenticalGroups,
+                                   CORBA::Boolean                theMergeNodesAndElements,
+                                   CORBA::Double                 theMergeTolerance)
   throw ( SALOME::SALOME_Exception )
 {
   return ConcatenateCommon(theMeshesArray,
@@ -2389,17 +2431,15 @@ 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::Double            theMergeTolerance,
-                               CORBA::Boolean           theCommonGroups)
+SMESH_Gen_i::ConcatenateCommon(const SMESH::ListOfIDSources& theMeshesArray,
+                               CORBA::Boolean                theUniteIdenticalGroups,
+                               CORBA::Boolean                theMergeNodesAndElements,
+                               CORBA::Double                 theMergeTolerance,
+                               CORBA::Boolean                theCommonGroups)
   throw ( SALOME::SALOME_Exception )
 {
-  typedef map<int, int> TIDsMap;
   typedef list<SMESH::SMESH_Group_var> TListOfNewGroups;
   typedef map< pair<string, SMESH::ElementType>, TListOfNewGroups > TGroupsMap;
-  typedef std::set<SMESHDS_GroupBase*> TGroups;
 
   TPythonDump* pPythonDump = new TPythonDump;
   TPythonDump& aPythonDump = *pPythonDump; // prevent dump of called methods
@@ -2407,303 +2447,248 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray,
   // 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();
-      aNewMeshDS = aLocMesh.GetMeshDS();
-
-      TGroupsMap aGroupsMap;
-      TListOfNewGroups aListOfNewGroups;
-      SMESH_MeshEditor aNewEditor = ::SMESH_MeshEditor(&aLocMesh);
-      SMESH::ListOfGroups_var aListOfGroups = new SMESH::ListOfGroups();
-
-      // 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();
-            aInitLocMesh.Load();
-            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() );
-            }
+  if ( aNewMesh->_is_nil() )
+    return aNewMesh._retn();
 
-            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
+  SMESH_Mesh_i* aNewImpl = SMESH::DownCast<SMESH_Mesh_i*>( aNewMesh );
+  if ( !aNewImpl )
+    return aNewMesh._retn();
 
-            // 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();
-              }
-            }
+  ::SMESH_Mesh& aLocMesh = aNewImpl->GetImpl();
+  SMESHDS_Mesh* aNewMeshDS = aLocMesh.GetMeshDS();
 
+  TGroupsMap aGroupsMap;
+  TListOfNewGroups aListOfNewGroups;
+  ::SMESH_MeshEditor aNewEditor(&aLocMesh);
+  SMESH::ListOfGroups_var aListOfGroups;
 
-            aListOfGroups = anInitImpl->GetGroups();
-            SMESH::SMESH_GroupBase_ptr aGroup;
+  ::SMESH_MeshEditor::ElemFeatures  elemType;
+  std::vector<const SMDS_MeshNode*> aNodesArray;
 
-            // 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;
+  // loop on sub-meshes
+  for ( CORBA::ULong i = 0; i < theMeshesArray.length(); i++)
+  {
+    if ( CORBA::is_nil( theMeshesArray[i] )) continue;
+    SMESH::SMESH_Mesh_var anInitMesh = theMeshesArray[i]->GetMesh();
+    if ( anInitMesh->_is_nil() ) continue;
+    SMESH_Mesh_i* anInitImpl = SMESH::DownCast<SMESH_Mesh_i*>( anInitMesh );
+    if ( !anInitImpl ) continue;
+    anInitImpl->Load();
+
+    //::SMESH_Mesh& aInitLocMesh = anInitImpl->GetImpl();
+    //SMESHDS_Mesh* anInitMeshDS = aInitLocMesh.GetMeshDS();
+
+    // remember nb of elements before filling in
+    SMESH::long_array_var prevState =  aNewMesh->GetNbElementsByType();
+
+    typedef std::map<const SMDS_MeshElement*, const SMDS_MeshElement*, TIDCompare > TEEMap;
+    TEEMap elemsMap, nodesMap;
+
+    // loop on elements of a sub-mesh
+    SMDS_ElemIteratorPtr itElems = anInitImpl->GetElements( theMeshesArray[i], SMESH::ALL );
+    const SMDS_MeshElement* anElem;
+    const SMDS_MeshElement* aNewElem;
+    const SMDS_MeshNode*    aNode;
+    const SMDS_MeshNode*    aNewNode;
+    int anElemNbNodes;
+
+    while ( itElems->more() )
+    {
+      anElem = itElems->next();
+      anElemNbNodes = anElem->NbNodes();
+      aNodesArray.resize( anElemNbNodes );
 
-            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_wrap aMeshSObj = ObjectToSObject( myCurrentStudy, anInitMesh );
-                if(aMeshSObj)
-                  str += aMeshSObj->GetName();
-                str += "_";
+      // loop on nodes of an element
+      SMDS_ElemIteratorPtr itNodes = anElem->nodesIterator();
+      for ( int k = 0; itNodes->more(); k++)
+      {
+        aNode = static_cast<const SMDS_MeshNode*>( itNodes->next() );
+        TEEMap::iterator n2nnIt = nodesMap.find( aNode );
+        if ( n2nnIt == nodesMap.end() )
+        {
+          aNewNode = aNewMeshDS->AddNode(aNode->X(), aNode->Y(), aNode->Z());
+          nodesMap.insert( make_pair( aNode, aNewNode ));
+        }
+        else
+        {
+          aNewNode = static_cast<const SMDS_MeshNode*>( n2nnIt->second );
+        }
+        aNodesArray[k] = aNewNode;
+      }
 
-                int anLen = 0;
+      // creates a corresponding element on existent nodes in new mesh
+      if ( anElem->GetType() == SMDSAbs_Node )
+        aNewElem = 0;
+      else
+        aNewElem =
+          aNewEditor.AddElement( aNodesArray, elemType.Init( anElem, /*basicOnly=*/false ));
 
-                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 ( aNewElem )
+        elemsMap.insert( make_pair( anElem, aNewElem ));
 
-                if(anLen) {
-                  aGroupName = str.c_str();
+    } //elems loop
 
-                  // add a new group in the mesh
-                  aNewGroup = aNewImpl->CreateGroup(aGroupType, aGroupName);
+    aNewEditor.ClearLastCreated(); // forget the history
 
-                  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 ));
-                }
+    // create groups of just added elements
+    SMESH::SMESH_Group_var aNewGroup;
+    SMESH::ElementType aGroupType;
+    if ( theCommonGroups )
+    {
+      SMESH::long_array_var curState = aNewMesh->GetNbElementsByType();
+
+      for( aGroupType = SMESH::NODE;
+           aGroupType < SMESH::NB_ELEMENT_TYPES;
+           aGroupType = (SMESH::ElementType)( aGroupType + 1 ))
+      {
+        if ( curState[ aGroupType ] <= prevState[ aGroupType ])
+          continue;
+
+        // make a group name
+        const char* typeNames[] = { "All","Nodes","Edges","Faces","Volumes","0DElems","Balls" };
+        { // check of typeNames, compilation failure mains that NB_ELEMENT_TYPES changed:
+          const int nbNames = sizeof(typeNames) / sizeof(const char*);
+          int _assert[( nbNames == SMESH::NB_ELEMENT_TYPES ) ? 1 : -1 ]; _assert[0]=0;
+        }
+        string groupName = "Gr";
+        SALOMEDS::SObject_wrap aMeshSObj = ObjectToSObject( myCurrentStudy, theMeshesArray[i] );
+        if ( aMeshSObj ) {
+          CORBA::String_var name = aMeshSObj->GetName();
+          groupName += name;
+        }
+        groupName += "_";
+        groupName += typeNames[ aGroupType ];
+
+        // make and fill a group
+        TEEMap & e2neMap = ( aGroupType == SMESH::NODE ) ? nodesMap : elemsMap;
+        aNewGroup = aNewImpl->CreateGroup( aGroupType, groupName.c_str() );
+        if ( SMESH_Group_i* grp_i = SMESH::DownCast<SMESH_Group_i*>( aNewGroup ))
+        {
+          if ( SMESHDS_Group* grpDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() ))
+          {
+            TEEMap::iterator e2neIt = e2neMap.begin();
+            for ( ; e2neIt != e2neMap.end(); ++e2neIt )
+            {
+              aNewElem = e2neIt->second;
+              if ( aNewElem->GetType() == grpDS->GetType() )
+              {
+                grpDS->Add( aNewElem );
+
+                if ( prevState[ aGroupType ]++ >= curState[ aGroupType ] )
+                  break;
               }
             }
+          }
+        }
+        aListOfNewGroups.clear();
+        aListOfNewGroups.push_back(aNewGroup);
+        aGroupsMap.insert(make_pair( make_pair(groupName, aGroupType), aListOfNewGroups ));
+      }
+    }
 
-            // check that current group name and type don't have identical ones in union mesh
-            for (int iG = 0; iG < aListOfGroups->length(); iG++) {
-              aGroup = aListOfGroups[iG];
-              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;
-                }
+    if ( SMESH_Mesh_i* anSrcImpl = SMESH::DownCast<SMESH_Mesh_i*>( theMeshesArray[i] ))
+    {
+      // copy orphan nodes
+      if ( anSrcImpl->NbNodes() > (int)nodesMap.size() )
+      {
+        SMDS_ElemIteratorPtr itNodes = anInitImpl->GetElements( theMeshesArray[i], SMESH::NODE );
+        while ( itNodes->more() )
+        {
+          const SMDS_MeshNode* aNode = static_cast< const SMDS_MeshNode* >( itNodes->next() );
+          if ( aNode->NbInverseElements() == 0 )
+          {
+            aNewNode = aNewMeshDS->AddNode(aNode->X(), aNode->Y(), aNode->Z());
+            nodesMap.insert( make_pair( aNode, aNewNode ));
+          }
+        }
+      }
 
-              // 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 );
+      // copy groups
 
-                aListOfNewGroups.push_back(aNewGroup);
-                aGroupsMap.insert(make_pair( make_pair(aGroupName, aGroupType), aListOfNewGroups ));
-              }
+      SMESH::SMESH_GroupBase_ptr aGroup;
+      CORBA::String_var aGroupName;
+      SMESH::long_array_var anNewIDs = new SMESH::long_array();
 
-              else if ( theUniteIdenticalGroups ) {
-                // unite identical groups
-                TListOfNewGroups& aNewGroups = anIter->second;
-                aNewGroups.front()->Add( anNewIDs );
-              }
+      // loop on groups of a source mesh
+      aListOfGroups = anSrcImpl->GetGroups();
+      for ( CORBA::ULong iG = 0; iG < aListOfGroups->length(); iG++ )
+      {
+        aGroup = aListOfGroups[iG];
+        aGroupType = aGroup->GetType();
+        aGroupName = aGroup->GetName();
+        string aName = aGroupName.in();
+
+        // convert a list of IDs
+        anNewIDs->length( aGroup->Size() );
+        TEEMap & e2neMap = ( aGroupType == SMESH::NODE ) ? nodesMap : elemsMap;
+        SMDS_ElemIteratorPtr itGrElems = anSrcImpl->GetElements( aGroup, SMESH::ALL );
+        int iElem = 0;
+        while ( itGrElems->more() )
+        {
+          anElem = itGrElems->next();
+          TEEMap::iterator e2neIt = e2neMap.find( anElem );
+          if ( e2neIt != e2neMap.end() )
+            anNewIDs[ iElem++ ] = e2neIt->second->GetID();
+        }
+        anNewIDs->length( iElem );
+
+        // check a current group name and type don't have identical ones in final mesh
+        aListOfNewGroups.clear();
+        TGroupsMap::iterator anIter = aGroupsMap.find( make_pair( aName, aGroupType ));
+        if ( anIter == aGroupsMap.end() ) {
+          // add a new group in the mesh
+          aNewGroup = aNewImpl->CreateGroup( aGroupType, aGroupName.in() );
+          // add elements into new group
+          aNewGroup->Add( anNewIDs );
+
+          aListOfNewGroups.push_back(aNewGroup);
+          aGroupsMap.insert(make_pair( make_pair(aName, aGroupType), aListOfNewGroups ));
+        }
 
-              else {
-                // rename identical groups
-                aNewGroup = aNewImpl->CreateGroup(aGroupType, aGroupName);
-                aNewGroup->Add( anNewIDs );
+        else if ( theUniteIdenticalGroups ) {
+          // unite identical groups
+          TListOfNewGroups& aNewGroups = anIter->second;
+          aNewGroups.front()->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
+        else {
+          // rename identical groups
+          aNewGroup = aNewImpl->CreateGroup(aGroupType, aGroupName.in());
+          aNewGroup->Add( anNewIDs );
+
+          TListOfNewGroups& aNewGroups = anIter->second;
+          string aNewGroupName;
+          if (aNewGroups.size() == 1) {
+            aNewGroupName = aName + "_1";
+            aNewGroups.front()->SetName(aNewGroupName.c_str());
           }
+          char aGroupNum[128];
+          sprintf(aGroupNum, "%u", (unsigned int)aNewGroups.size()+1);
+          aNewGroupName = aName + "_" + string(aGroupNum);
+          aNewGroup->SetName(aNewGroupName.c_str());
+          aNewGroups.push_back(aNewGroup);
         }
-      }//meshes loop
-
-      if (theMergeNodesAndElements) {
-        // merge nodes
-        TIDSortedNodeSet aMeshNodes; // no input nodes
-        SMESH_MeshEditor::TListOfListOfNodes aGroupsOfNodes;
-        aNewEditor.FindCoincidentNodes( aMeshNodes, theMergeTolerance, aGroupsOfNodes );
-        aNewEditor.MergeNodes( aGroupsOfNodes );
-        // merge elements
-        aNewEditor.MergeEqualElements();
-      }
-    }
+      } //groups loop
+    } // if an IDSource is a mesh
+  } //meshes loop
+
+  if (theMergeNodesAndElements) // merge nodes
+  {
+    TIDSortedNodeSet aMeshNodes; // no input nodes
+    SMESH_MeshEditor::TListOfListOfNodes aGroupsOfNodes;
+    aNewEditor.FindCoincidentNodes( aMeshNodes, theMergeTolerance, aGroupsOfNodes,
+                                    /*SeparateCornersAndMedium=*/ false );
+    aNewEditor.MergeNodes( aGroupsOfNodes );
+    // merge elements
+    aNewEditor.MergeEqualElements();
   }
 
   // Update Python script
-  aPythonDump << aNewMesh << " = " << this;
-  if( !theCommonGroups )
-    aPythonDump << ".Concatenate(";
-  else
-    aPythonDump << ".ConcatenateWithGroups(";
-  aPythonDump << "[";
-  for ( int i = 0; i < theMeshesArray.length(); i++) {
+  aPythonDump << aNewMesh << " = " << this << "."
+              << ( theCommonGroups ? "ConcatenateWithGroups" : "Concatenate" )
+              << "([";
+  for ( CORBA::ULong i = 0; i < theMeshesArray.length(); i++) {
     if (i > 0) aPythonDump << ", ";
     aPythonDump << theMeshesArray[i];
   }
@@ -2726,6 +2711,7 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray,
 
   if (aNewMeshDS)
     aNewMeshDS->Modified();
+
   return aNewMesh._retn();
 }
 
@@ -2775,6 +2761,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CopyMesh(SMESH::SMESH_IDSource_ptr meshPart,
   }
   SMESHDS_Mesh* newMeshDS = newMesh_i->GetImpl().GetMeshDS();
   ::SMESH_MeshEditor editor( &newMesh_i->GetImpl() );
+  ::SMESH_MeshEditor::ElemFeatures elemType;
 
   // 3. Get elements to copy
 
@@ -2792,13 +2779,13 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CopyMesh(SMESH::SMESH_IDSource_ptr meshPart,
     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++)
+      for ( CORBA::ULong 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++)
+      for ( CORBA::ULong i = 0; i < ids->length(); i++ )
         if ( const SMDS_MeshElement * elem = srcMeshDS->FindElement( ids[i] ))
           srcElems.insert( elem );
     }
@@ -2846,30 +2833,12 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CopyMesh(SMESH::SMESH_IDSource_ptr meshPart,
     // add elements
     if ( elem->GetType() != SMDSAbs_Node )
     {
-      int ID = toKeepIDs ? elem->GetID() : 0;
-      const SMDS_MeshElement * newElem;
-      switch ( elem->GetEntityType() ) {
-      case SMDSEntity_Polyhedra:
-        if ( toKeepIDs )
-          newElem = editor.GetMeshDS()->
-            AddPolyhedralVolumeWithID( nodes,
-                                       static_cast<const SMDS_VtkVolume*>(elem)->GetQuantities(),
-                                       ID);
-        else
-          newElem = editor.GetMeshDS()->
-            AddPolyhedralVolume( nodes,
-                                 static_cast<const SMDS_VtkVolume*>(elem)->GetQuantities());
-        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);
+      elemType.Init( elem, /*basicOnly=*/false );
+      if ( toKeepIDs ) elemType.SetID( elem->GetID() );
 
+      const SMDS_MeshElement * newElem = editor.AddElement( nodes, elemType );
       if ( toCopyGroups && !toKeepIDs )
         e2eMapByType[ elem->GetType() ].insert( make_pair( elem, newElem ));
-      }
     }
   } // while ( srcElemIt->more() )
 
@@ -3029,8 +2998,6 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
                                       const char*              theURL,
                                       bool                     isMultiFile )
 {
-  INFOS( "SMESH_Gen_i::Save" );
-
   //  ASSERT( theComponent->GetStudy()->StudyId() == myCurrentStudy->StudyId() )
   // san -- in case <myCurrentStudy> differs from theComponent's study,
   // use that of the component
@@ -3109,7 +3076,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
             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 )
+            for ( CORBA::ULong i = 0; i < groups->length(); ++i )
             {
               SMESH_GroupBase_i* grImpl = SMESH::DownCast<SMESH_GroupBase_i*>( groups[i]);
               if ( grImpl )
@@ -3755,7 +3722,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
                         myWriter.AddGroup( aGeomGrp );
                       }
                     }
-                    else if ( SMESH_GroupOnFilter_i* aFilterGrp_i = 
+                    else if ( SMESH_GroupOnFilter_i* aFilterGrp_i =
                               dynamic_cast<SMESH_GroupOnFilter_i*>( myGroupImpl ))
                     {
                       std::string str = aFilterGrp_i->FilterToString();
@@ -3972,7 +3939,6 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
   if ( !isMultiFile )
     SALOMEDS_Tool::RemoveTemporaryFiles( tmpDir.ToCString(), aFileSeq.in(), true );
 
-  INFOS( "SMESH_Gen_i::Save() completed" );
   return aStreamFile._retn();
 }
 
@@ -4039,8 +4005,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
                         const char*              theURL,
                         bool                     isMultiFile )
 {
-  INFOS( "SMESH_Gen_i::Load" );
-
   if ( theComponent->GetStudy()->StudyId() != GetCurrentStudyID() )
     SetCurrentStudy( theComponent->GetStudy() );
 
@@ -4057,11 +4021,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
   TCollection_AsciiString tmpDir =
     ( char* )( isMultiFile ? theURL : SALOMEDS_Tool::GetTmpDir().c_str() );
 
-  INFOS( "THE URL++++++++++++++" );
-  INFOS( theURL );
-  INFOS( "THE TMP PATH+++++++++" );
-  INFOS( tmpDir );
-
   // Convert the stream into sequence of files to process
   SALOMEDS::ListOfFileNames_var aFileSeq = SALOMEDS_Tool::PutStreamToFiles( theStream,
                                                                             tmpDir.ToCString(),
@@ -4111,6 +4070,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
 
   list< pair< SMESH_Hypothesis_i*, string > >    hypDataList;
   list< pair< SMESH_Mesh_i*,       HDFgroup* > > meshGroupList;
+  list< SMESH::Filter_var >                      filters;
 
   // get total number of top-level groups
   int aNbGroups = aFile->nInternalObjects();
@@ -4753,6 +4713,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
                 if ( strlen( persistStr ) > 0 ) {
                   filter = SMESH_GroupOnFilter_i::StringToFilter( persistStr );
                   predicate = SMESH_GroupOnFilter_i::GetPredicate( filter );
+                  filters.push_back( filter );
                 }
               }
 
@@ -4799,11 +4760,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
                 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 );
             }
           }
           aGroup->CloseOnDisk();
@@ -4862,6 +4818,13 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
         ComputeStateEngine (SMESH_subMesh::SUBMESH_RESTORED);
     }
 
+    // let filters detect dependency on mesh groups via FT_BelongToMeshGroup predicate (22877)
+    list< SMESH::Filter_var >::iterator f = filters.begin();
+    for ( ; f != filters.end(); ++f )
+      if ( SMESH::Filter_i * fi = SMESH::DownCast< SMESH::Filter_i*>( *f ))
+        fi->FindBaseObjects();
+
+
     // close mesh group
     if(aTopGroup)
       aTopGroup->CloseOnDisk();
@@ -4898,13 +4861,12 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
   if ( !useCaseBuilder->IsUseCaseNode( theComponent ) ) {
     useCaseBuilder->SetRootCurrent();
     useCaseBuilder->Append( theComponent ); // component object is added as the top level item
-    SALOMEDS::ChildIterator_wrap it = study->NewChildIterator( theComponent ); 
+    SALOMEDS::ChildIterator_wrap it = study->NewChildIterator( theComponent );
     for (it->InitEx(true); it->More(); it->Next()) {
       useCaseBuilder->AppendTo( it->Value()->GetFather(), it->Value() );
     }
   }
 
-  INFOS( "SMESH_Gen_i::Load completed" );
   return true;
 }
 
@@ -5053,8 +5015,6 @@ int SMESH_Gen_i::RegisterObject(CORBA::Object_ptr theObject)
 {
   StudyContext* myStudyContext = GetCurrentStudyContext();
   if ( myStudyContext && !CORBA::is_nil( theObject )) {
-    if (GetCurrentStudyID() == myImportedStudyId)
-      myImportedStudyChanged = true;
     CORBA::String_var iorString = GetORB()->object_to_string( theObject );
     return myStudyContext->addObject( string( iorString.in() ) );
   }
@@ -5115,12 +5075,12 @@ char* SMESH_Gen_i::getVersion()
 
 //=================================================================================
 // function : Move()
-// purpose  : Moves objects to the specified position. 
+// purpose  : Moves objects to the specified position.
 //            Is used in the drag-n-drop functionality.
 //=================================================================================
 void SMESH_Gen_i::Move( const SMESH::sobject_list& what,
-                        SALOMEDS::SObject_ptr where,
-                        CORBA::Long row )
+                        SALOMEDS::SObject_ptr      where,
+                        CORBA::Long                row )
 {
   if ( CORBA::is_nil( where ) ) return;
 
@@ -5130,7 +5090,7 @@ void SMESH_Gen_i::Move( const SMESH::sobject_list& what,
   SALOMEDS::SComponent_var father = where->GetFatherComponent();
   std::string dataType = father->ComponentDataType();
   if ( dataType != "SMESH" ) return; // not a SMESH component
-  
+
   SALOMEDS::SObject_var objAfter;
   if ( row >= 0 && useCaseBuilder->HasChildren( where ) ) {
     // insert at given row -> find insertion position
@@ -5141,8 +5101,8 @@ void SMESH_Gen_i::Move( const SMESH::sobject_list& what,
       objAfter = useCaseIt->Value();
     }
   }
-  
-  for ( int i = 0; i < what.length(); i++ ) {
+
+  for ( CORBA::ULong i = 0; i < what.length(); i++ ) {
     SALOMEDS::SObject_var sobj = what[i];
     if ( CORBA::is_nil( sobj ) ) continue; // skip bad object
     // insert the object to the use case tree
@@ -5178,8 +5138,7 @@ CORBA::Boolean SMESH_Gen_i::IsApplicable ( const char*           theAlgoType,
   if (aCreator)
   {
     TopoDS_Shape shape = GeomObjectToShape( theGeomObject );
-    if ( !shape.IsNull() )
-      return aCreator->IsApplicable( shape, toCheckAll );
+    return shape.IsNull() || aCreator->IsApplicable( shape, toCheckAll );
   }
   else
   {
@@ -5187,144 +5146,201 @@ CORBA::Boolean SMESH_Gen_i::IsApplicable ( const char*           theAlgoType,
   }
 
   SMESH_CATCH( SMESH::doNothing );
+
+#ifdef _DEBUG_
+  cout << "SMESH_Gen_i::IsApplicable(): exception in " << ( theAlgoType ? theAlgoType : "") << endl;
+#endif
   return true;
 }
 
 //=================================================================================
-// function : importData
-// purpose  : imports mesh data file (the med one) into the SMESH internal data structure
+// function : GetInsideSphere
+// purpose  : Collect indices of elements, which are located inside the sphere
 //=================================================================================
-Engines::ListOfIdentifiers* SMESH_Gen_i::importData(CORBA::Long                   studyId,
-                                                    Engines::DataContainer_ptr    data,
-                                                    const Engines::ListOfOptions& options)
+SMESH::long_array* SMESH_Gen_i::GetInsideSphere( SMESH::SMESH_IDSource_ptr meshPart,
+                                                 SMESH::ElementType     theElemType,
+                                                 CORBA::Double         theX,
+                                                 CORBA::Double         theY,
+                                                 CORBA::Double         theZ,
+                                                 CORBA::Double         theR)
 {
-  Engines::ListOfIdentifiers_var aResultIds = new Engines::ListOfIdentifiers;
-  list<string> aResultList;
-
-  CORBA::Object_var aSMObject = myNS->Resolve( "/myStudyManager" );
-  SALOMEDS::StudyManager_var aStudyManager = SALOMEDS::StudyManager::_narrow( aSMObject );
-  SALOMEDS::Study_var aStudy = aStudyManager->GetStudyByID( studyId );
-  SetCurrentStudy(aStudy);
-
-  // load and store temporary imported file
-  string aFileName = Kernel_Utils::GetTmpFileName();
-  aFileName += string(".") + data->extension();
-  Engines::TMPFile* aFileStream = data->get();
-  const char *aBuffer = (const char*)aFileStream->NP_data();
-#ifdef WIN32
-  std::ofstream aFile(aFileName.c_str(), std::ios::binary);
-#else
-  std::ofstream aFile(aFileName.c_str());
-#endif
-  aFile.write(aBuffer, aFileStream->length());
-  aFile.close();
+  SMESH::long_array_var aResult = new SMESH::long_array();
+  if ( meshPart->_is_nil() )
+    return aResult._retn();
 
-  // Retrieve mesh names from the file
-  DriverMED_R_SMESHDS_Mesh aReader;
-  aReader.SetFile( aFileName );
-  aReader.SetMeshId(-1);
-  Driver_Mesh::Status aStatus;
-  list<string> aNames = aReader.GetMeshNames(aStatus);
-  SMESH::mesh_array_var aResult = new SMESH::mesh_array();
-  SMESH::DriverMED_ReadStatus aStatus2 = (SMESH::DriverMED_ReadStatus)aStatus;
-  if (aStatus2 == SMESH::DRS_OK) {
-    // Iterate through all meshes and create mesh objects
-    for ( list<string>::iterator it = aNames.begin(); it != aNames.end(); it++ ) {
-      // create mesh
-      SMESH::SMESH_Mesh_var mesh = createMesh();
+  // 1. Create geometrical object
+  gp_Pnt aP( theX, theY, theZ );
+  TopoDS_Shape aShape = BRepPrimAPI_MakeSphere( aP, theR ).Shape();
 
-      // publish mesh in the study
-      SALOMEDS::SObject_var aSO;
-      if (CanPublishInStudy(mesh)) {
-        aSO = PublishMesh(aStudy, mesh.in(), (*it).c_str());
-        aResultList.push_back(aSO->GetID());
-      }
-      // Read mesh data (groups are published automatically by ImportMEDFile())
-      SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( mesh ).in() );
-      ASSERT( meshServant );
-      meshServant->ImportMEDFile( aFileName.c_str(), (*it).c_str() );
-      //meshServant->GetImpl().GetMeshDS()->Modified();
+  std::vector<long> lst =_GetInside(meshPart, theElemType, aShape);
+
+  if ( lst.size() > 0 ) {
+    aResult->length( lst.size() );
+    for ( size_t i = 0; i < lst.size(); i++ ) {
+      aResult[i] = lst[i];
     }
-  } else {
-    MESSAGE("Opening MED file problems "<<aFileName.c_str())
-    return aResultIds._retn();
   }
+  return aResult._retn();
+}
 
-  // remove temporary file 
-#ifdef WIN32
-  DeleteFileA(aFileName.c_str());
-#else
-  unlink(aFileName.c_str());
-#endif
+SMESH::long_array* SMESH_Gen_i::GetInsideBox( SMESH::SMESH_IDSource_ptr meshPart,
+                                              SMESH::ElementType        theElemType,
+                                              CORBA::Double             theX1,
+                                              CORBA::Double             theY1,
+                                              CORBA::Double             theZ1,
+                                              CORBA::Double             theX2,
+                                              CORBA::Double             theY2,
+                                              CORBA::Double             theZ2) {
+  SMESH::long_array_var aResult = new SMESH::long_array();
+  if( meshPart->_is_nil() )
+    return aResult._retn();
 
-  if (!aResultList.empty()) {
-    aResultIds->length(aResultList.size());
-    list<string>::iterator aListIter = aResultList.begin();
-    for(int a = 0; aListIter != aResultList.end(); aListIter++, a++)
-      aResultIds[a] = aListIter->c_str();
-  }
-  
-  myImportedStudyId = studyId;
-  myImportedStudyChanged = false;
+  TopoDS_Shape aShape = BRepPrimAPI_MakeBox( gp_Pnt( theX1, theY1, theZ1 ), gp_Pnt( theX2, theY2, theZ2 ) ).Shape();
+
+  std::vector<long> lst =_GetInside(meshPart, theElemType, aShape);
 
-  return aResultIds._retn();
+  if( lst.size() > 0 ) {
+    aResult->length( lst.size() );
+    for ( size_t i = 0; i < lst.size(); i++ ) {
+      aResult[i] = lst[i];
+    }
+  }
+  return aResult._retn();
 }
 
-//=================================================================================
-// function : getModifiedData
-// purpose  : exports all geometry of this GEOM module into one BRep file
-//=================================================================================
-Engines::ListOfData* SMESH_Gen_i::getModifiedData(CORBA::Long studyId)
-{
-  Engines::ListOfData_var aResult = new Engines::ListOfData;
-  
-  if (!myImportedStudyChanged) {
-    INFOS("SMESH module data was not changed")
+SMESH::long_array* SMESH_Gen_i::GetInsideCylinder( SMESH::SMESH_IDSource_ptr meshPart,
+                                                   SMESH::ElementType        theElemType,
+                                                   CORBA::Double             theX,
+                                                   CORBA::Double             theY,
+                                                   CORBA::Double             theZ,
+                                                   CORBA::Double             theDX,
+                                                   CORBA::Double             theDY,
+                                                   CORBA::Double             theDZ,
+                                                   CORBA::Double             theH,
+                                                   CORBA::Double             theR ){
+  SMESH::long_array_var aResult = new SMESH::long_array();
+  if( meshPart->_is_nil() )
     return aResult._retn();
+
+  gp_Pnt aP( theX, theY, theZ );
+  gp_Vec aV( theDX, theDY, theDZ );
+  gp_Ax2 anAxes (aP, aV);
+
+  TopoDS_Shape aShape = BRepPrimAPI_MakeCylinder(anAxes, theR, Abs(theH)).Shape();
+
+  std::vector<long> lst =_GetInside(meshPart, theElemType, aShape);
+
+  if( lst.size() > 0 ) {
+    aResult->length( lst.size() );
+    for ( size_t i = 0; i < lst.size(); i++ ) {
+      aResult[i] = lst[i];
+    }
   }
+  return aResult._retn();
+}
 
-  CORBA::Object_var aSMObject = myNS->Resolve("/myStudyManager");
-  SALOMEDS::StudyManager_var aStudyManager = SALOMEDS::StudyManager::_narrow(aSMObject);
-  SALOMEDS::Study_var aStudy = aStudyManager->GetStudyByID(studyId);
-  SetCurrentStudy(aStudy);
-  SALOMEDS::SComponent_var aComponent = aStudy->FindComponent("SMESH");
-  
-  if (CORBA::is_nil(aComponent))
+SMESH::long_array* SMESH_Gen_i::GetInside( SMESH::SMESH_IDSource_ptr meshPart,
+                                           SMESH::ElementType        theElemType,
+                                           GEOM::GEOM_Object_ptr     theGeom,
+                                           CORBA::Double             theTolerance ) {
+  SMESH::long_array_var aResult = new SMESH::long_array();
+  if( meshPart->_is_nil() || theGeom->_is_nil() )
     return aResult._retn();
 
-  std::string aFullPath(Kernel_Utils::GetTmpFileName());
-  aFullPath += ".med";
-  StudyContext* myStudyContext = GetCurrentStudyContext();
+  TopoDS_Shape aShape = GeomObjectToShape( theGeom );
 
-  SALOMEDS::ChildIterator_var anIter = aStudy->NewChildIterator(aComponent); // check only published meshes
-  int aNumMeshes = 0; // number of meshes in result
-  for(; anIter->More(); anIter->Next()) {
-    SALOMEDS::SObject_var aSO = anIter->Value();
-    CORBA::Object_var anObj = aSO->GetObject();
-    if (!CORBA::is_nil(anObj)) {
-      SMESH::SMESH_Mesh_var aCORBAMesh = SMESH::SMESH_Mesh::_narrow(anObj);
-      if(!aCORBAMesh->_is_nil()) {
-        SMESH_Mesh_i* myImpl = dynamic_cast<SMESH_Mesh_i*>(GetServant(aCORBAMesh).in());
-        if (myImpl) {
-          myImpl->Load();
-          SMESH_Mesh& aMesh = myImpl->GetImpl();
-          CORBA::String_var objName = aSO->GetName();
-          aMesh.ExportMED(aFullPath.c_str(), objName.in(), false, MED::eV2_2, 0);
-          aNumMeshes++;
+  std::vector<long> lst =_GetInside(meshPart, theElemType, aShape, &theTolerance);
+
+  if( lst.size() > 0 ) {
+    aResult->length( lst.size() );
+    for ( size_t i = 0; i < lst.size(); i++ ) {
+      aResult[i] = lst[i];
+    }
+  }
+  return aResult._retn();
+}
+
+
+
+std::vector<long> SMESH_Gen_i::_GetInside( SMESH::SMESH_IDSource_ptr meshPart,
+                                           SMESH::ElementType theElemType,
+                                           TopoDS_Shape& aShape,
+                                           double* theTolerance) {
+
+  std::vector<long> res;
+  SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
+
+  if ( mesh->_is_nil() )
+    return res;
+
+  SMESH_Mesh_i* anImpl = dynamic_cast<SMESH_Mesh_i*>( GetServant( mesh ).in() );
+  if ( !anImpl )
+    return res;
+
+  const SMDS_Mesh* meshDS = anImpl->GetImpl().GetMeshDS();
+
+  if ( !meshDS )
+    return res;
+
+  SMDSAbs_ElementType aType = SMDSAbs_ElementType(theElemType);
+  SMESH::Controls::ElementsOnShape* anElementsOnShape = new SMESH::Controls::ElementsOnShape();
+  anElementsOnShape->SetAllNodes( true );
+  anElementsOnShape->SetMesh( meshDS );
+  anElementsOnShape->SetShape( aShape, aType );
+
+  if(theTolerance)
+    anElementsOnShape->SetTolerance(*theTolerance);
+
+  SMESH::SMESH_Mesh_var msource = SMESH::SMESH_Mesh::_narrow(meshPart);
+  if ( !msource->_is_nil() ) { // Mesh case
+    SMDS_ElemIteratorPtr elemIt = meshDS->elementsIterator( aType );
+    if ( elemIt ) {
+      while ( elemIt->more() ) {
+        const SMDS_MeshElement* anElem = elemIt->next();
+        long anId = anElem->GetID();
+        if ( anElementsOnShape->IsSatisfy( anId ) )
+          res.push_back( anId );
+      }
+    }
+  }
+  SMESH::SMESH_Group_var gsource = SMESH::SMESH_Group::_narrow(meshPart);
+  if ( !gsource->_is_nil() ) {
+    if(theElemType == SMESH::NODE) {
+      SMESH::long_array_var nodes = gsource->GetNodeIDs();
+      for ( CORBA::ULong i = 0; i < nodes->length(); ++i ) {
+        if ( const SMDS_MeshNode* node = meshDS->FindNode( nodes[i] )) {
+          long anId = node->GetID();
+          if ( anElementsOnShape->IsSatisfy( anId ) )
+            res.push_back( anId );
+        }
+      }
+    } else if (gsource->GetType() == theElemType || theElemType == SMESH::ALL ) {
+      SMESH::long_array_var elems = gsource->GetListOfID();
+      for ( CORBA::ULong i = 0; i < elems->length(); ++i ) {
+        if ( const SMDS_MeshElement* elem = meshDS->FindElement( elems[i] )) {
+          long anId = elem->GetID();
+          if ( anElementsOnShape->IsSatisfy( anId ) )
+            res.push_back( anId );
         }
       }
     }
   }
-  if (aNumMeshes > 0) { // prepare a container to store files
-    INFOS("Write "<<aNumMeshes<<" meshes to "<<aFullPath.c_str());
-    aResult->length(1);
-    Engines::DataContainer_var aData = (new Engines_DataContainer_i(
-                    aFullPath.c_str(), "", "", true))->_this();
-    aResult[0] = aData;
+  SMESH::SMESH_subMesh_var smsource = SMESH::SMESH_subMesh::_narrow(meshPart);
+  if ( !smsource->_is_nil() ) {
+    SMESH::long_array_var elems = smsource->GetElementsByType( theElemType );
+    for ( CORBA::ULong i = 0; i < elems->length(); ++i ) {
+      const SMDS_MeshElement* elem = ( theElemType == SMESH::NODE ) ? meshDS->FindNode( elems[i] ) : meshDS->FindElement( elems[i] );
+      if (elem) {
+        long anId = elem->GetID();
+        if ( anElementsOnShape->IsSatisfy( anId ) )
+          res.push_back( anId );
+      }
+    }
   }
-  return aResult._retn();
+  return res;
 }
 
+
 //=============================================================================
 /*!
  *  SMESHEngine_factory
index ba4ed98b54d82430bb766ba2ce18efe56e74a8f1..e2be6042d64755912c884bd8cbd906028fcf0615 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -356,26 +356,26 @@ public:
     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::ListOfIDSources& meshesArray,
+                                          CORBA::Boolean                uniteIdenticalGroups,
+                                          CORBA::Boolean                mergeNodesAndElements,
+                                          CORBA::Double                 mergeTolerance,
+                                          CORBA::Boolean                commonGroups)
     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::ListOfIDSources& meshesArray,
+                                    CORBA::Boolean                uniteIdenticalGroups,
+                                    CORBA::Boolean                mergeNodesAndElements,
+                                    CORBA::Double                 mergeTolerance)
     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::ListOfIDSources& meshesArray,
+                                              CORBA::Boolean                uniteIdenticalGroups,
+                                              CORBA::Boolean                mergeNodesAndElements,
+                                              CORBA::Double                 mergeTolerance)
     throw ( SALOME::SALOME_Exception );
 
   // Get MED version of the file by its name
@@ -491,13 +491,6 @@ public:
 
   void CleanPythonTrace (int theStudyID);
 
-  // SIMAN-related functions (check out/check in) : import data to study
-  virtual Engines::ListOfIdentifiers* importData(CORBA::Long studyId,
-                                                 Engines::DataContainer_ptr data,
-                                                 const Engines::ListOfOptions& options);
-  // SIMAN-related functions (check out/check in) : get modified data
-  virtual Engines::ListOfData* getModifiedData(CORBA::Long studyId);
-
   // *****************************************
   // Internal methods
   // *****************************************
@@ -602,11 +595,44 @@ public:
   void Move( const SMESH::sobject_list& what,
              SALOMEDS::SObject_ptr where,
              CORBA::Long row );
+
   CORBA::Boolean IsApplicable ( const char*           theAlgoType,
                                 const char*           theLibName,
                                 GEOM::GEOM_Object_ptr theShapeObject,
                                 CORBA::Boolean        toCheckAll);
 
+  SMESH::long_array* GetInsideSphere( SMESH::SMESH_IDSource_ptr meshPart,
+                                      SMESH::ElementType        theElemType,
+                                      CORBA::Double             theX,
+                                      CORBA::Double             theY,
+                                      CORBA::Double             theZ,
+                                      CORBA::Double             theR);
+
+  SMESH::long_array* GetInsideBox( SMESH::SMESH_IDSource_ptr meshPart,
+                                   SMESH::ElementType        theElemType,
+                                   CORBA::Double             theX1,
+                                   CORBA::Double             theY1,
+                                   CORBA::Double             theZ1,
+                                   CORBA::Double             theX2,
+                                   CORBA::Double             theY2,
+                                   CORBA::Double             theZ2);
+
+  SMESH::long_array* GetInsideCylinder( SMESH::SMESH_IDSource_ptr meshPart,
+                                        SMESH::ElementType        theElemType,
+                                        CORBA::Double             theX,
+                                        CORBA::Double             theY,
+                                        CORBA::Double             theZ,
+                                        CORBA::Double             theDX,
+                                        CORBA::Double             theDY,
+                                        CORBA::Double             theDZ,
+                                        CORBA::Double             theH,
+                                        CORBA::Double             theR );
+
+  SMESH::long_array* GetInside( SMESH::SMESH_IDSource_ptr meshPart,
+                                SMESH::ElementType        theElemType,
+                                GEOM::GEOM_Object_ptr     theGeom,
+                                CORBA::Double             theTolerance );
+
 private:
   // Get hypothesis creator
   GenericHypothesisCreator_i* getHypothesisCreator( const char*  theHypName,
@@ -630,6 +656,11 @@ private:
   void setCurrentStudy( SALOMEDS::Study_ptr theStudy,
                         bool                theStudyIsBeingClosed=false);
 
+  std::vector<long> _GetInside(SMESH::SMESH_IDSource_ptr meshPart,
+                               SMESH::ElementType     theElemType,
+                               TopoDS_Shape& aShape,
+                               double* theTolerance = NULL);
+
 private:
   static GEOM::GEOM_Gen_var      myGeomGen;
   static CORBA::ORB_var          myOrb;         // ORB reference
@@ -648,6 +679,9 @@ private:
   SALOMEDS::Study_var       myCurrentStudy;     // Current study
   CORBA::Boolean            myIsEmbeddedMode;   // Current mode
 
+  // Default color of groups
+  std::string myDefaultGroupColor;
+
   // To load full mesh data from study at hyp modification or not
   bool myToForgetMeshDataOnHypModif;
 
@@ -657,8 +691,6 @@ private:
   std::vector< int >                                       myLastParamIndex;
   std::vector< std::string >                               myLastParameters;
   std::string                                              myLastObj;
-  int                                                      myImportedStudyId;      // SIMAN: identifier of the imported in importData study to keep no-modifiection flag for getModifiedData method
-  int                                                      myImportedStudyChanged; // SIMAN: flag that indicates that the imported study has been changed (by creation of the additional mesh)
 };
 
 
index b59479fce561d0c5a843b181968fc5604a4b7b76..66422047da112e36a94284f0613a112c62d60e27 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -265,31 +265,29 @@ static SALOMEDS::SObject_ptr publish(SALOMEDS::Study_ptr   theStudy,
   SALOMEDS::StudyBuilder_var     aStudyBuilder = theStudy->NewBuilder();
   SALOMEDS::UseCaseBuilder_wrap useCaseBuilder = theStudy->GetUseCaseBuilder();
   SALOMEDS::SObject_wrap objAfter;
+  bool isNewSO = false;
   if ( SO->_is_nil() )
   {
     if ( theTag == 0 ) {
       SO = aStudyBuilder->NewObject( theFatherObject );
+      isNewSO = true;
     }
     else if ( !theFatherObject->FindSubObject( theTag, SO.inout() ))
     {
       SO = aStudyBuilder->NewObjectToTag( theFatherObject, theTag );
+      isNewSO = true;
 
       // define the next tag after given one in the data tree to insert SObject
-      std::string anEntry;
-      int last2Pnt_pos = -1;
-      int tagAfter = -1;
-      CORBA::String_var entry;
       SALOMEDS::SObject_wrap curObj;
-      SALOMEDS::UseCaseIterator_wrap anUseCaseIter = useCaseBuilder->GetUseCaseIterator(theFatherObject);
-      for ( ; anUseCaseIter->More(); anUseCaseIter->Next() ) {
-        curObj = anUseCaseIter->Value();
-        entry = curObj->GetID();
-        anEntry = entry.in();
-        last2Pnt_pos = anEntry.rfind( ":" );
-        tagAfter = atoi( anEntry.substr( last2Pnt_pos+1 ).c_str() );
-        if ( tagAfter > theTag  ) {
-          objAfter = curObj;
-          break;
+      if ( theFatherObject->GetLastChildTag() > theTag )
+      {
+        SALOMEDS::UseCaseIterator_wrap anUseCaseIter = useCaseBuilder->GetUseCaseIterator(theFatherObject);
+        for ( ; anUseCaseIter->More(); anUseCaseIter->Next() ) {
+          curObj = anUseCaseIter->Value();
+          if ( curObj->Tag() > theTag  ) {
+            objAfter = curObj;
+            break;
+          }
         }
       }
     }
@@ -319,18 +317,19 @@ static SALOMEDS::SObject_ptr publish(SALOMEDS::Study_ptr   theStudy,
 
   // add object to the use case tree
   // (to support tree representation customization and drag-n-drop)
-  if ( !CORBA::is_nil( objAfter ) ) {
-    useCaseBuilder->InsertBefore( SO, objAfter );    // insert at given tag
-  } else if ( !useCaseBuilder->IsUseCaseNode( SO ) ) {
-    useCaseBuilder->AppendTo( theFatherObject, SO ); // append to the end of list
+  if ( isNewSO )
+  {
+    if ( !CORBA::is_nil( objAfter ) )
+      useCaseBuilder->InsertBefore( SO, objAfter );    // insert at given tag
+    else if ( !useCaseBuilder->IsUseCaseNode( SO ) )
+      useCaseBuilder->AppendTo( theFatherObject, SO ); // append to the end of list
   }
-
   return SO._retn();
 }
 
 //=======================================================================
 //function : setName
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 void SMESH_Gen_i::SetName(SALOMEDS::SObject_ptr theSObject,
@@ -420,14 +419,21 @@ static void addReference (SALOMEDS::Study_ptr   theStudy,
         theTag = tag;
     }
     if ( !theSObject->FindSubObject( theTag, aReferenceSO.inout() ))
-    {
       aReferenceSO = aStudyBuilder->NewObjectToTag( theSObject, theTag );
-      // add reference to the use case tree
-      // (to support tree representation customization and drag-n-drop)
-      SALOMEDS::UseCaseBuilder_wrap useCaseBuilder = theStudy->GetUseCaseBuilder();
-      useCaseBuilder->AppendTo( aReferenceSO->GetFather(), aReferenceSO );
-    }
+
     aStudyBuilder->Addreference( aReferenceSO, aToObjSO );
+
+    // add reference to the use case tree
+    // (to support tree representation customization and drag-n-drop)
+    SALOMEDS::UseCaseBuilder_wrap  useCaseBuilder = theStudy->GetUseCaseBuilder();
+    SALOMEDS::UseCaseIterator_wrap    useCaseIter = useCaseBuilder->GetUseCaseIterator(theSObject);
+    for ( ; useCaseIter->More(); useCaseIter->Next() )
+    {
+      SALOMEDS::SObject_wrap curSO = useCaseIter->Value();
+      if ( curSO->Tag() == theTag )
+        return;
+    }
+    useCaseBuilder->AppendTo( theSObject, aReferenceSO );
   }
 }
 
@@ -534,32 +540,6 @@ SALOMEDS::SComponent_ptr SMESH_Gen_i::PublishComponent(SALOMEDS::Study_ptr theSt
   return father._retn();
 }
 
-//=============================================================================
-/*!
- *  findMaxChildTag [ static internal ]
- *
- *  Finds maximum child tag for the given object
- */
-//=============================================================================
-
-static long findMaxChildTag( SALOMEDS::SObject_ptr theSObject )
-{
-  long aTag = 0;
-  if ( !theSObject->_is_nil() ) {
-    SALOMEDS::Study_var aStudy = theSObject->GetStudy();
-    if ( !aStudy->_is_nil() ) {
-      SALOMEDS::ChildIterator_wrap anIter = aStudy->NewChildIterator( theSObject );
-      for ( ; anIter->More(); anIter->Next() ) {
-        SALOMEDS::SObject_wrap anSO = anIter->Value();
-        long nTag = anSO->Tag();
-        if ( nTag > aTag )
-          aTag = nTag;
-      }
-    }
-  }
-  return aTag;
-}
-
 //=======================================================================
 //function : PublishMesh
 //purpose  : 
@@ -584,7 +564,7 @@ SALOMEDS::SObject_ptr SMESH_Gen_i::PublishMesh (SALOMEDS::Study_ptr   theStudy,
       return aMeshSO._retn();
 
     // Find correct free tag
-    long aTag = findMaxChildTag( father.in() );
+    long aTag = father->GetLastChildTag();
     if ( aTag <= GetAlgorithmsRootTag() )
       aTag = GetAlgorithmsRootTag() + 1;
     else
@@ -605,7 +585,7 @@ SALOMEDS::SObject_ptr SMESH_Gen_i::PublishMesh (SALOMEDS::Study_ptr   theStudy,
     // Publish global hypotheses
 
     SMESH::ListOfHypothesis_var hypList = theMesh->GetHypothesisList( aShapeObject );
-    for ( int i = 0; i < hypList->length(); i++ )
+    for ( CORBA::ULong i = 0; i < hypList->length(); i++ )
     {
       SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( hypList[ i ]);
       SALOMEDS::SObject_wrap so = PublishHypothesis( theStudy, aHyp );
@@ -730,7 +710,7 @@ SALOMEDS::SObject_ptr SMESH_Gen_i::PublishSubMesh (SALOMEDS::Study_ptr      theS
   // Publish hypothesis
 
   SMESH::ListOfHypothesis_var hypList = theMesh->GetHypothesisList( theShapeObject );
-  for ( int i = 0; i < hypList->length(); i++ ) {
+  for ( CORBA::ULong i = 0; i < hypList->length(); i++ ) {
     SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( hypList[ i ]);
     SALOMEDS::SObject_wrap so = PublishHypothesis( theStudy, aHyp );
     AddHypothesisToShape( theStudy, theMesh, theShapeObject, aHyp );
@@ -762,7 +742,7 @@ SALOMEDS::SObject_ptr SMESH_Gen_i::PublishGroup (SALOMEDS::Study_ptr    theStudy
       if ( aMeshSO->_is_nil())
         return SALOMEDS::SObject::_nil();
     }
-    int aType = (int)theGroup->GetType();
+    size_t aType = (int)theGroup->GetType();
     const char* aRootNames[] = {
       "Compound Groups", "Groups of Nodes", "Groups of Edges",
       "Groups of Faces", "Groups of Volumes", "Groups of 0D Elements",
@@ -791,9 +771,14 @@ SALOMEDS::SObject_ptr SMESH_Gen_i::PublishGroup (SALOMEDS::Study_ptr    theStudy
       }
       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() );
+        if ( theGroup->GetType() == SMESH::NODE )
+          isEmpty = ( theMesh->NbNodes() == 0 );
+        else
+        {
+          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() );
     }
@@ -971,7 +956,7 @@ bool SMESH_Gen_i::RemoveHypothesisFromShape(SALOMEDS::Study_ptr         theStudy
 
   CORBA::String_var hypEntry = aHypSO->GetID();
 
-  // Find a mesh or submesh refering to theShape
+  // Find a mesh or sub-mesh referring to theShape
   SALOMEDS::SObject_wrap aMeshOrSubMesh =
     GetMeshOrSubmeshByShape( theStudy, theMesh, theShape );
   if ( aMeshOrSubMesh->_is_nil() )
index d55846adebfc7455bb74af7b3ca29083cb5a9b42..9d3b3ee021016c8152d2542ca1f3b325bc5609b9 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -55,11 +55,11 @@ 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 ),
+  myPreMeshInfo(NULL),
   myNbNodes(-1),
   myGroupDSTic(0),
-  myPreMeshInfo(NULL)
+  myMeshServant( theMeshServant ), 
+  myLocalID( theLocalID )
 {
   // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i,
   // servant activation is performed by SMESH_Mesh_i::createGroup()
@@ -69,8 +69,8 @@ SMESH_GroupBase_i::SMESH_GroupBase_i( PortableServer::POA_ptr thePOA,
 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 )
+  : SALOME::GenericObj_i( thePOA ),
+    SMESH_GroupBase_i( thePOA, theMeshServant, theLocalID )
 {
   //MESSAGE("SMESH_Group_i; this = "<<this );
 }
@@ -78,8 +78,8 @@ SMESH_Group_i::SMESH_Group_i( PortableServer::POA_ptr thePOA,
 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 )
+  : SALOME::GenericObj_i( thePOA ),
+    SMESH_GroupBase_i( thePOA, theMeshServant, theLocalID )
 {
   //MESSAGE("SMESH_GroupOnGeom_i; this = "<<this );
 }
@@ -244,6 +244,21 @@ CORBA::Boolean SMESH_GroupBase_i::IsEmpty()
   return true;
 }
 
+//=============================================================================
+/*
+ * Returns \c true if \c this group depends on the \a other via
+ * FT_BelongToMeshGroup predicate or vice versa
+ */
+//=============================================================================
+
+bool SMESH_GroupBase_i::IsInDependency( SMESH::SMESH_GroupBase_ptr other )
+{
+  if ( NotifyerAndWaiter* nw = SMESH::DownCast< NotifyerAndWaiter* >( other ))
+    return ( nw->ContainModifWaiter( this ) || this->ContainModifWaiter( nw ));
+
+  return false;
+}
+
 //=============================================================================
 /*!
  *  
@@ -264,6 +279,8 @@ void SMESH_Group_i::Clear()
     aGroupDS->Clear();
     return;
   }
+  Modified(); // notify dependent Filter with FT_BelongToMeshGroup criterion
+
   MESSAGE("attempt to clear a vague group");
 }
 
@@ -303,11 +320,13 @@ CORBA::Long SMESH_Group_i::Add( const SMESH::long_array& theIDs )
   SMESHDS_Group* aGroupDS = dynamic_cast<SMESHDS_Group*>( GetGroupDS() );
   if (aGroupDS) {
     int nbAdd = 0;
-    for (int i = 0; i < theIDs.length(); i++) {
+    for ( CORBA::ULong i = 0; i < theIDs.length(); i++) {
       int anID = (int) theIDs[i];
-      if (aGroupDS->Add(anID))
+      if ( aGroupDS->Add( anID ))
         nbAdd++;
     }
+    if ( nbAdd )
+      Modified(); // notify dependent Filter with FT_BelongToMeshGroup criterion
     return nbAdd;
   }
   MESSAGE("attempt to add elements to a vague group");
@@ -316,7 +335,7 @@ CORBA::Long SMESH_Group_i::Add( const SMESH::long_array& theIDs )
 
 //=============================================================================
 /*!
- *  
+ *
  */
 //=============================================================================
 
@@ -333,11 +352,13 @@ CORBA::Long SMESH_Group_i::Remove( const SMESH::long_array& theIDs )
   SMESHDS_Group* aGroupDS = dynamic_cast<SMESHDS_Group*>( GetGroupDS() );
   if (aGroupDS) {
     int nbDel = 0;
-    for (int i = 0; i < theIDs.length(); i++) {
+    for ( CORBA::ULong i = 0; i < theIDs.length(); i++ ) {
       int anID = (int) theIDs[i];
-      if (aGroupDS->Remove(anID))
+      if ( aGroupDS->Remove( anID ))
         nbDel++;
     }
+    if ( nbDel )
+      Modified(); // notify dependent Filter with FT_BelongToMeshGroup criterion
     return nbDel;
   }
   MESSAGE("attempt to remove elements from a vague group");
@@ -346,7 +367,7 @@ CORBA::Long SMESH_Group_i::Remove( const SMESH::long_array& theIDs )
 
 //=============================================================================
 /*!
- *  
+ *
  */
 //=============================================================================
 
@@ -355,6 +376,7 @@ typedef bool (SMESHDS_Group::*TFunChangeGroup)(const int);
 CORBA::Long 
 ChangeByPredicate( SMESH::Predicate_i* thePredicate,
                    SMESHDS_GroupBase*  theGroupBase,
+                   NotifyerAndWaiter*  theGroupImpl,
                    TFunChangeGroup     theFun)
 {
   CORBA::Long aNb = 0;
@@ -367,6 +389,8 @@ ChangeByPredicate( SMESH::Predicate_i* thePredicate,
     for(; i < iEnd; i++)
       if((aGroupDS->*theFun)(aSequence[i]))
         aNb++;
+    if ( aNb )
+      theGroupImpl->Modified();
     return aNb;
   }
   return aNb;
@@ -382,7 +406,7 @@ AddByPredicate( SMESH::Predicate_ptr thePredicate )
   if(SMESH::Predicate_i* aPredicate = SMESH::GetPredicate(thePredicate)){
     TPythonDump() << SMESH::SMESH_Group_var(_this())
                   << ".AddByPredicate( " << aPredicate << " )";
-    return ChangeByPredicate( aPredicate, GetGroupDS(), &SMESHDS_Group::Add );
+    return ChangeByPredicate( aPredicate, GetGroupDS(), this, &SMESHDS_Group::Add );
   }
   return 0;
 }
@@ -397,7 +421,7 @@ RemoveByPredicate( SMESH::Predicate_ptr thePredicate )
   if(SMESH::Predicate_i* aPredicate = SMESH::GetPredicate(thePredicate)){
     TPythonDump() << SMESH::SMESH_Group_var(_this())
                   << ".RemoveByPredicate( " << aPredicate << " )";
-    return ChangeByPredicate(aPredicate,GetGroupDS(),&SMESHDS_Group::Remove);
+    return ChangeByPredicate(aPredicate,GetGroupDS(),this, &SMESHDS_Group::Remove);
   }
   return 0;
 }
@@ -419,12 +443,15 @@ CORBA::Long SMESH_Group_i::AddFrom( SMESH::SMESH_IDSource_ptr theSource )
   // Update Python script
   pd << "nbAdd = " << SMESH::SMESH_Group_var(_this()) << ".AddFrom( " << theSource << " )";
 
-  return prevNb - Size();
+  if ( prevNb != Size() )
+    Modified(); // notify dependent Filter with FT_BelongToMeshGroup criterion
+
+  return Size() - prevNb;
 }
 
 //=============================================================================
 /*!
- *  
+ *
  */
 //=============================================================================
 
@@ -681,7 +708,7 @@ SMESH::long_array* SMESH_GroupBase_i::GetMeshInfo()
 
   if ( SMESHDS_GroupBase* g = GetGroupDS())
   {
-    if ( g->GetType() == SMDSAbs_Node || ( myNbNodes > -1 && g->GetTic() == myGroupDSTic))
+    if ( g->GetType() == SMDSAbs_Node /*|| ( myNbNodes > -1 && g->GetTic() == myGroupDSTic)*/)
       aRes[ SMDSEntity_Node ] = GetNumberOfNodes();
 
     if ( g->GetType() != SMDSAbs_Node )
@@ -749,6 +776,17 @@ bool SMESH_GroupBase_i::IsMeshInfoCorrect()
   return myPreMeshInfo ? myPreMeshInfo->IsMeshInfoCorrect() : true;
 }
 
+//=======================================================================
+//function : GetVtkUgStream
+//purpose  : Return data vtk unstructured grid (not implemented)
+//=======================================================================
+
+SALOMEDS::TMPFile* SMESH_GroupBase_i::GetVtkUgStream()
+{
+  SALOMEDS::TMPFile_var SeqFile;
+  return SeqFile._retn();
+}
+
 //================================================================================
 /*!
  * \brief Retrieves the predicate from the filter
@@ -773,6 +811,7 @@ SMESH_PredicatePtr SMESH_GroupOnFilter_i::GetPredicate( SMESH::Filter_ptr filter
 //================================================================================
 
 void SMESH_GroupOnFilter_i::SetFilter(SMESH::Filter_ptr theFilter)
+  throw (SALOME::SALOME_Exception)
 {
   if ( myFilter->_is_equivalent( theFilter ))
     return;
@@ -785,17 +824,34 @@ void SMESH_GroupOnFilter_i::SetFilter(SMESH::Filter_ptr theFilter)
 
   myFilter = SMESH::Filter::_duplicate( theFilter );
 
-  if ( SMESHDS_GroupOnFilter* grDS = dynamic_cast< SMESHDS_GroupOnFilter*>( GetGroupDS() ))
-    grDS->SetPredicate( GetPredicate( myFilter ));
+  if ( !myFilter->_is_nil() )
+  {
+    myFilter->Register();
 
-  TPythonDump()<< SMESH::SMESH_GroupOnFilter_var(_this()) <<".SetFilter( "<<theFilter<<" )";
+    if ( SMESH::Filter_i* f = SMESH::DownCast< SMESH::Filter_i* >( myFilter ))
+    {
+      // make filter notify me about change of either a predicate or a base group
+      f->FindBaseObjects();
+
+      if ( f->ContainModifWaiter( this ) ||
+           this->ContainModifWaiter( f ))
+      {
+        SetFilter( SMESH::Filter::_nil() );
+        THROW_SALOME_CORBA_EXCEPTION( "Cyclic dependency between Groups on Filter",
+                                      SALOME::BAD_PARAM );
+      }
+      f->AddModifWaiter( this );
+    }
+    myFilter->SetMesh( SMESH::SMESH_Mesh::_nil() ); // to UnRegister() the mesh
+  }
 
-  if ( myFilter )
+  if ( SMESHDS_GroupOnFilter* grDS = dynamic_cast< SMESHDS_GroupOnFilter*>( GetGroupDS() ))
   {
-    myFilter->SetMesh( SMESH::SMESH_Mesh::_nil() ); // to UnRegister() the mesh
-    myFilter->Register();
-    SMESH::DownCast< SMESH::Filter_i* >( myFilter )->AddWaiter( this );
+    grDS->SetPredicate( GetPredicate( myFilter ));
+    Modified(); // notify dependent Filter with FT_BelongToMeshGroup criterion
   }
+
+  TPythonDump()<< SMESH::SMESH_GroupOnFilter_var(_this()) <<".SetFilter( "<<theFilter<<" )";
 }
 
 //================================================================================
@@ -857,7 +913,7 @@ SMESH::long_array* SMESH_GroupOnFilter_i::GetMeshInfo()
 
   if ( SMESHDS_GroupBase* g = GetGroupDS())
   {
-    if ( g->GetType() == SMDSAbs_Node || ( myNbNodes > -1 && g->GetTic() == myGroupDSTic))
+    if ( g->GetType() == SMDSAbs_Node /*|| ( myNbNodes > -1 && g->GetTic() == myGroupDSTic)*/)
       aRes[ SMDSEntity_Node ] = GetNumberOfNodes();
 
     if ( g->GetType() != SMDSAbs_Node )
@@ -889,9 +945,18 @@ std::string SMESH_GroupOnFilter_i::FilterToString() const
     result << criteria->length() << SEPAR;
     for ( unsigned i = 0; i < criteria->length(); ++i )
     {
+      SMESH::Filter::Criterion& crit = criteria[ i ];
+
+      if ( SMESH::FunctorType( crit.Type ) == SMESH::FT_BelongToMeshGroup &&
+           crit.ThresholdID.in() && crit.ThresholdID.in()[0] )
+      {
+        CORBA::Object_var obj = SMESH_Gen_i::GetORB()->string_to_object( crit.ThresholdID );
+        if ( SMESH_GroupBase_i * g = SMESH::DownCast< SMESH_GroupBase_i*>( obj ))
+          if ( SMESHDS_GroupBase* gDS = g->GetGroupDS() )
+            crit.ThresholdID = gDS->GetStoreName();
+      }
       // 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;
@@ -976,22 +1041,22 @@ SMESH_GroupOnFilter_i::~SMESH_GroupOnFilter_i()
 {
   if ( ! myFilter->_is_nil() )
   {
-    SMESH::DownCast< SMESH::Filter_i* >( myFilter )->RemoveWaiter( this );
+    SMESH::DownCast< SMESH::Filter_i* >( myFilter )->RemoveModifWaiter( this );
     myFilter->UnRegister();
   }
 }
 
 //================================================================================
 /*!
- * \brief Method calleds when a predicate of myFilter changes
+ * \brief Method called when a predicate of myFilter changes
  */
 //================================================================================
 
-void SMESH_GroupOnFilter_i::PredicateChanged()
+void SMESH_GroupOnFilter_i::OnBaseObjModified(NotifyerAndWaiter* filter, bool /*removed*/)
 {
   if ( myPreMeshInfo )
     myPreMeshInfo->FullLoadFromFile();
 
   if ( SMESHDS_GroupOnFilter* grDS = dynamic_cast< SMESHDS_GroupOnFilter*>( GetGroupDS() ))
-    grDS->SetPredicate( GetPredicate( myFilter ));
+    grDS->SetPredicate( GetPredicate( myFilter )); // group resets its cache
 }
index f08e51b2440772c3d89ebf24d132797766a2b968..867ae56ebe54c17466fbe9ed0f95a25edf2f5235 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -48,7 +48,8 @@ class SMESH_PreMeshInfo;
 // ===========
 class SMESH_I_EXPORT SMESH_GroupBase_i:
   public virtual POA_SMESH::SMESH_GroupBase,
-  public virtual SALOME::GenericObj_i
+  public virtual SALOME::GenericObj_i,
+  public SMESH::NotifyerAndWaiter // defined in SMESH_Filter_i.hxx
 {
  public:
   SMESH_GroupBase_i(PortableServer::POA_ptr thePOA,
@@ -95,6 +96,17 @@ class SMESH_I_EXPORT SMESH_GroupBase_i:
    * happen if mesh data is not yet fully loaded from the file of study.
    */
   virtual bool IsMeshInfoCorrect();
+  /*!
+   * Returns mesh unstructed grid information.
+   */
+  virtual SALOMEDS::TMPFile* GetVtkUgStream();
+
+  /*!
+   * Returns \c true if \c this group depends on the \a other via
+   * FT_BelongToMeshGroup predicate or vice versa
+   */
+  virtual CORBA::Boolean IsInDependency( SMESH::SMESH_GroupBase_ptr other );
+
 
   // Internal C++ interface
   int GetLocalID() const { return myLocalID; }
@@ -169,8 +181,7 @@ class SMESH_I_EXPORT SMESH_GroupOnGeom_i:
 
 class SMESH_I_EXPORT SMESH_GroupOnFilter_i:
   public virtual POA_SMESH::SMESH_GroupOnFilter,
-  public SMESH_GroupBase_i,
-  public SMESH::Filter_i::TPredicateChangeWaiter
+  public SMESH_GroupBase_i
 {
  public:
   SMESH_GroupOnFilter_i( PortableServer::POA_ptr thePOA,
@@ -185,13 +196,13 @@ class SMESH_I_EXPORT SMESH_GroupOnFilter_i:
   static SMESH_PredicatePtr GetPredicate( SMESH::Filter_ptr );
 
   // CORBA interface implementation
-  void SetFilter(SMESH::Filter_ptr theFilter);
+  void SetFilter(SMESH::Filter_ptr theFilter) throw (SALOME::SALOME_Exception);
   SMESH::Filter_ptr GetFilter();
   virtual SMESH::long_array* GetListOfID();
   virtual SMESH::long_array* GetMeshInfo();
 
-  // method of SMESH::Filter_i::TPredicateChangeWaiter
-  virtual void PredicateChanged();
+  // method of SMESH::NotifyerAndWaiter to update self when myFilter changes
+  virtual void OnBaseObjModified(NotifyerAndWaiter* filter, bool);
 
  private:
   SMESH::Filter_var myFilter;
index 96460dd6fd324357d9bdcad702d288b19936fb86..1f0517f3ab13a40b4db646a438489a74f8e3435f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -237,6 +237,19 @@ void SMESH_Hypothesis_i::setOldParameters (const char* theParameters)
   return myBaseImpl;
 }
 
+//================================================================================
+/*!
+ * \brief Return true if a hypothesis has parameters
+ */
+//================================================================================
+
+CORBA::Boolean SMESH_Hypothesis_i::HasParameters()
+{
+  std::ostringstream os;
+  myBaseImpl->SaveTo( os );
+  return ( !os.str().empty() );
+}
+
 //=============================================================================
 /*!
  *  SMESH_Hypothesis_i::SaveTo
index 5cc8e54d961ecf6c7a29b7c7da6c042eedc8c49a..55c1e2779908af93fe5c241e4c3f5f1b85b94bfc 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -59,31 +59,34 @@ public:
   virtual ~SMESH_Hypothesis_i();
 
   // Get type name of hypothesis
-  char* GetName();
+  virtual char* GetName();
 
   // Get plugin library name of hypothesis
-  char* GetLibName();
+  virtual char* GetLibName();
 
   // Set plugin library name of hypothesis
   void SetLibName( const char* theLibName );
 
   // Get unique id of hypothesis
-  CORBA::Long GetId();
-  
+  virtual CORBA::Long GetId();
+
+  // Return true if a hypothesis has parameters
+  virtual CORBA::Boolean HasParameters();
+
   // Set the variable parameter (a variable name or a parameter value); \a 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);
+  virtual void SetVarParameter (const char* parameter, const char* method);
 
   // Return the variable parameter used at Hypothesis Creation by the name of method
   // setting this parameter. The returned variable name is used at Hypothesis Edition.
-  char* GetVarParameter (const char* methodName);
+  virtual char* GetVarParameter (const char* methodName);
 
   // Store a hypothesis wrapping this not published one. This hyp, which has
   // no own parameters but is published, is used to store variables defining parameters
   // of this hypothesis. This method is to be called before setting parameters
   // of this hypothesis.
-  void SetHolderHypothesis(const SMESH::SMESH_Hypothesis_ptr hyp);
+  virtual void SetHolderHypothesis(const SMESH::SMESH_Hypothesis_ptr hyp);
 
   //Return true if hypothesis was published in study
   bool IsPublished();
index d0de81b916b93c0c121ba2421b941aa40ed7af13..b17fc6c4ac4775b4098b14a088a0f78e1451ab87 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -132,7 +132,8 @@ static bool isNodeType (SMESH::array_of_ElementType_var theTypes)
   return theTypes->length() > 0 && theTypes[0] == SMESH::NODE;
 }
 
-static double getNumericalValue(SMESH::SMESH_IDSource_ptr theSource, SMESH::Controls::NumericalFunctorPtr theFunctor)
+static double getNumericalValue(SMESH::SMESH_IDSource_ptr            theSource,
+                                SMESH::Controls::NumericalFunctorPtr theFunctor)
 {
   double value = 0;
 
@@ -142,7 +143,7 @@ static double getNumericalValue(SMESH::SMESH_IDSource_ptr theSource, SMESH::Cont
       theFunctor->SetMesh( aMesh );
       
       SMESH::long_array_var anElementsId = theSource->GetIDs();
-      for (int i = 0; i < anElementsId->length(); i++) {
+      for ( CORBA::ULong i = 0; i < anElementsId->length(); i++) {
         value += theFunctor->GetValue( anElementsId[i] );
       }
     }
index 127017c5a6370848d7f26b37e710b51c44077b92..66d28f1875a65d25af9af1d79d4752ab627f0e61 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 763f976e4e758859ae76dff901ed5877fb8bd8c2..0b927273c4ada665a02e6ea1013ad3285fcf220a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -114,8 +114,6 @@ namespace MeshEditor_I {
       _myMeshDS  = new SMESHDS_Mesh( _id, true );
       myPreviewType = previewElements;
     }
-    //!< Destructor
-    virtual ~TPreviewMesh() { delete _myMeshDS; _myMeshDS = 0; }
     //!< Copy a set of elements
     void Copy(const TIDSortedElemSet & theElements,
               TIDSortedElemSet&        theCopyElements,
@@ -156,20 +154,11 @@ namespace MeshEditor_I {
       }
 
       // creates a corresponding element on copied nodes
-      SMDS_MeshElement* anElemCopy = 0;
-      if ( anElem->IsPoly() && anElem->GetType() == SMDSAbs_Volume )
-      {
-        const SMDS_VtkVolume* ph =
-          dynamic_cast<const SMDS_VtkVolume*> (anElem);
-        if ( ph )
-          anElemCopy = _myMeshDS->AddPolyhedralVolumeWithID
-            (anElemNodesID, ph->GetQuantities(),anElem->GetID());
-      }
-      else {
-        anElemCopy = ::SMESH_MeshEditor(this).AddElement( anElemNodesID,
-                                                          anElem->GetType(),
-                                                          anElem->IsPoly() );
-      }
+      ::SMESH_MeshEditor::ElemFeatures elemType;
+      elemType.Init( anElem, /*basicOnly=*/false );
+      elemType.SetID( anElem->GetID() );
+      SMDS_MeshElement* anElemCopy =
+        ::SMESH_MeshEditor(this).AddElement( anElemNodesID, elemType );
       return anElemCopy;
     }
     //!< Copy a node
@@ -182,6 +171,12 @@ namespace MeshEditor_I {
     {
       GetMeshDS()->ClearMesh();
     }
+    void Remove( SMDSAbs_ElementType type )
+    {
+      SMDS_ElemIteratorPtr eIt = GetMeshDS()->elementsIterator( type );
+      while ( eIt->more() )
+        GetMeshDS()->RemoveFreeElement( eIt->next(), /*sm=*/0, /*fromGroups=*/false );
+    }
   };// struct TPreviewMesh
 
   static SMESH_NodeSearcher *    theNodeSearcher    = 0;
@@ -302,65 +297,7 @@ namespace MeshEditor_I {
           aMap.insert( aMap.end(), elem );
       }
   }
-  //================================================================================
-  /*!
-   * \brief Retrieve elements of given type from SMESH_IDSource
-   */
-  //================================================================================
-
-  enum IDSource_Error { IDSource_OK, IDSource_INVALID, IDSource_EMPTY };
-
-  bool idSourceToSet(SMESH::SMESH_IDSource_ptr  theIDSource,
-                     const SMESHDS_Mesh*        theMeshDS,
-                     TIDSortedElemSet&          theElemSet,
-                     const SMDSAbs_ElementType  theType,
-                     const bool                 emptyIfIsMesh = false,
-                     IDSource_Error*            error = 0)
-
-  {
-    if ( error ) *error = IDSource_OK;
 
-    if ( CORBA::is_nil( theIDSource ) )
-    {
-      if ( error ) *error = IDSource_INVALID;
-      return false;
-    }
-    if ( emptyIfIsMesh && SMESH::DownCast<SMESH_Mesh_i*>( theIDSource ))
-    {
-      if ( error && theMeshDS->GetMeshInfo().NbElements( theType ) == 0 )
-        *error = IDSource_EMPTY;
-      return true;
-    }
-    SMESH::long_array_var anIDs = theIDSource->GetIDs();
-    if ( anIDs->length() == 0 )
-    {
-      if ( error ) *error = IDSource_EMPTY;
-      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
-      {
-        if ( error ) *error = IDSource_INVALID;
-        return false;
-      }
-    }
-    else
-    {
-      arrayToSet( anIDs, theMeshDS, theElemSet, theType);
-      if ( bool(anIDs->length()) != bool(theElemSet.size()))
-      {
-        if ( error ) *error = IDSource_INVALID;
-        return false;
-      }
-    }
-    return true;
-  }
   //================================================================================
   /*!
    * \brief Retrieve nodes from SMESH_IDSource
@@ -418,7 +355,8 @@ namespace MeshEditor_I {
     if ( !sameElemType )
       elemType = SMDSAbs_All;
 
-    TIDSortedElemSet visitedNodes;
+    vector<bool> isNodeChecked( theMeshDS->NbNodes(), false );
+
     TIDSortedElemSet::const_iterator elemIt = theElements.begin();
     for ( ; elemIt != theElements.end(); ++elemIt )
     {
@@ -427,8 +365,9 @@ namespace MeshEditor_I {
       while ( --i != -1 )
       {
         const SMDS_MeshNode* n = e->GetNode( i );
-        if ( visitedNodes.insert( n ).second )
+        if ( !isNodeChecked[ n->GetID() ])
         {
+          isNodeChecked[ n->GetID() ] = true;
           SMDS_ElemIteratorPtr invIt = n->GetInverseElementIterator(elemType);
           while ( invIt->more() )
           {
@@ -495,6 +434,17 @@ SMESH_MeshEditor_i::~SMESH_MeshEditor_i()
   delete myPreviewEditor; myPreviewEditor = 0;
 }
 
+//================================================================================
+/*!
+ * \brief Returns the mesh
+ */
+//================================================================================
+
+SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::GetMesh()
+{
+  return myMesh_i->_this();
+}
+
 //================================================================================
 /*!
  * \brief Clear members
@@ -511,14 +461,14 @@ void SMESH_MeshEditor_i::initData(bool deleteSearchers)
       TSearchersDeleter::Delete();
   }
   getEditor().GetError().reset();
-  getEditor().CrearLastCreated();
+  getEditor().ClearLastCreated();
 }
 
 //================================================================================
 /*!
  * \brief Increment mesh modif time and optionally record that the performed
  *        modification may influence futher mesh re-compute.
- *  \param [in] isReComputeSafe - true if the modification does not infulence
+ *  \param [in] isReComputeSafe - true if the modification does not influence
  *              futher mesh re-compute
  */
 //================================================================================
@@ -576,7 +526,7 @@ TPreviewMesh * SMESH_MeshEditor_i::getPreviewMesh(SMDSAbs_ElementType previewEle
 
 SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
   throw (SALOME::SALOME_Exception)
-{ 
+{
   SMESH_TRY;
   const bool hasBadElems = ( getEditor().GetError() && getEditor().GetError()->HasBadElems() );
 
@@ -598,7 +548,7 @@ SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
     myPreviewData = new SMESH::MeshPreviewStruct();
     myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
 
-    
+
     SMDSAbs_ElementType previewType = SMDSAbs_All;
     if ( !hasBadElems )
       if (TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( getEditor().GetMesh() )) {
@@ -618,7 +568,10 @@ SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
 
     while ( itMeshElems->more() ) {
       const SMDS_MeshElement* aMeshElem = itMeshElems->next();
-      SMDS_NodeIteratorPtr itElemNodes = aMeshElem->nodeIterator();
+      SMDS_NodeIteratorPtr itElemNodes = 
+        (( aMeshElem->GetEntityType() == SMDSEntity_Quad_Polygon ) ?
+         aMeshElem->interlacedNodesIterator() :
+         aMeshElem->nodeIterator() );
       while ( itElemNodes->more() ) {
         const SMDS_MeshNode* aMeshNode = itElemNodes->next();
         int aNodeID = aMeshNode->GetID();
@@ -710,7 +663,7 @@ SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
 void SMESH_MeshEditor_i::ClearLastCreated() throw (SALOME::SALOME_Exception)
 {
   SMESH_TRY;
-  getEditor().CrearLastCreated();
+  getEditor().ClearLastCreated();
   SMESH_CATCH( SMESH::throwCorbaException );
 }
 
@@ -779,21 +732,22 @@ struct SMESH_MeshEditor_i::_IDSource : public virtual POA_SMESH::SMESH_IDSource,
     }
     return types._retn();
   }
+  SALOMEDS::TMPFile* GetVtkUgStream()
+  {
+    SALOMEDS::TMPFile_var SeqFile;
+    return SeqFile._retn();
+  }
 };
 
 SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_array& ids,
                                                            SMESH::ElementType       type)
 {
-  // if ( myAuxIDSources.size() > 10 ) {
-  //   delete myAuxIDSources.front();
-  //   myAuxIDSources.pop_front();
-  // }
-
   _IDSource* idSrc = new _IDSource;
   idSrc->_mesh = myMesh_i->_this();
   idSrc->_ids  = ids;
   idSrc->_type = type;
-  //myAuxIDSources.push_back( idSrc );
+  if ( type == SMESH::ALL && ids.length() > 0 )
+    idSrc->_type = myMesh_i->GetElementType( ids[0], true );
 
   SMESH::SMESH_IDSource_var anIDSourceVar = idSrc->_this();
 
@@ -1099,6 +1053,7 @@ CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
  *  AddPolygonalFace
  */
 //=============================================================================
+
 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
   throw (SALOME::SALOME_Exception)
 {
@@ -1108,7 +1063,8 @@ CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsO
   int NbNodes = IDsOfNodes.length();
   std::vector<const SMDS_MeshNode*> nodes (NbNodes);
   for (int i = 0; i < NbNodes; i++)
-    nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
+    if ( ! ( nodes[i] = getMeshDS()->FindNode( IDsOfNodes[i] )))
+      return 0;
 
   const SMDS_MeshElement* elem = getMeshDS()->AddPolygonalFace(nodes);
 
@@ -1122,6 +1078,35 @@ CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsO
   return 0;
 }
 
+//=============================================================================
+/*!
+ *  AddQuadPolygonalFace
+ */
+//=============================================================================
+
+CORBA::Long SMESH_MeshEditor_i::AddQuadPolygonalFace (const SMESH::long_array & IDsOfNodes)
+  throw (SALOME::SALOME_Exception)
+{
+  SMESH_TRY;
+  initData();
+
+  int NbNodes = IDsOfNodes.length();
+  std::vector<const SMDS_MeshNode*> nodes (NbNodes);
+  for (int i = 0; i < NbNodes; i++)
+    nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
+
+  const SMDS_MeshElement* elem = getMeshDS()->AddQuadPolygonalFace(nodes);
+
+  // Update Python script
+  TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
+
+  declareMeshModified( /*isReComputeSafe=*/false );
+  return elem ? elem->GetID() : 0;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
+}
+
 //=============================================================================
 /*!
  * Create volume, either linear and quadratic (this is determed
@@ -1282,7 +1267,6 @@ SMESH_MeshEditor_i::Create0DElementsOnAllNodes(SMESH::SMESH_IDSource_ptr theObje
   TPythonDump pyDump;
 
   TIDSortedElemSet elements, elems0D;
-  prepareIdSource( theObject );
   if ( idSourceToSet( theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
     getEditor().Create0DElementsOnAllNodes( elements, elems0D );
 
@@ -1667,7 +1651,6 @@ CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup,
   initData(/*deleteSearchers=*/false);
 
   TIDSortedElemSet elements;
-  prepareIdSource( the2Dgroup );
   IDSource_Error error;
   idSourceToSet( the2Dgroup, getMeshDS(), elements, SMDSAbs_Face, /*emptyIfIsMesh=*/1, &error );
   if ( error == IDSource_EMPTY )
@@ -1752,7 +1735,6 @@ CORBA::Long SMESH_MeshEditor_i::Reorient2DBy3D(const SMESH::ListOfIDSources& fac
   initData();
 
   TIDSortedElemSet volumes;
-  prepareIdSource( volumeGroup );
   IDSource_Error volsError;
   idSourceToSet( volumeGroup, getMeshDS(), volumes, SMDSAbs_Volume, /*emptyIfMesh=*/1, &volsError);
 
@@ -1760,7 +1742,6 @@ CORBA::Long SMESH_MeshEditor_i::Reorient2DBy3D(const SMESH::ListOfIDSources& fac
   for ( size_t i = 0; i < faceGroups.length(); ++i )
   {
     SMESH::SMESH_IDSource_ptr faceGrp = faceGroups[i].in();
-    prepareIdSource( faceGrp );
 
     TIDSortedElemSet faces;
     IDSource_Error error;
@@ -1958,7 +1939,6 @@ void SMESH_MeshEditor_i::QuadTo4Tri (SMESH::SMESH_IDSource_ptr theObject)
   initData();
 
   TIDSortedElemSet faces;
-  prepareIdSource( theObject );
   if ( !idSourceToSet( theObject, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/true ) &&
        faces.empty() )
     THROW_SALOME_CORBA_EXCEPTION("No faces given", SALOME::BAD_PARAM);
@@ -2079,7 +2059,6 @@ void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
 {
   SMESH_TRY;
   initData();
-  prepareIdSource( elems );
 
   ::SMESH_MeshEditor::TFacetOfElem elemSet;
   const int noneFacet = -1;
@@ -2108,7 +2087,7 @@ void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
  */
 //================================================================================
 
-void SMESH_MeshEditor_i::SplitHexahedraIntoPrisms (SMESH::SMESH_IDSource_ptr  elems,
+void SMESH_MeshEditor_i::SplitHexahedraIntoPrismsSMESH::SMESH_IDSource_ptr  elems,
                                                    const SMESH::PointStruct & startHexPoint,
                                                    const SMESH::DirStruct&    facetToSplitNormal,
                                                    CORBA::Short               methodFlags,
@@ -2160,6 +2139,44 @@ void SMESH_MeshEditor_i::SplitHexahedraIntoPrisms (SMESH::SMESH_IDSource_ptr  el
   SMESH_CATCH( SMESH::throwCorbaException );
 }
 
+//================================================================================
+/*!
+ * \brief Split bi-quadratic elements into linear ones without creation of additional nodes:
+ *   - bi-quadratic triangle will be split into 3 linear quadrangles;
+ *   - bi-quadratic quadrangle will be split into 4 linear quadrangles;
+ *   - tri-quadratic hexahedron will be split into 8 linear hexahedra.
+ *   Quadratic elements of lower dimension  adjacent to the split bi-quadratic element
+ *   will be split in order to keep the mesh conformal.
+ *  \param elems - elements to split
+ */
+//================================================================================
+
+void SMESH_MeshEditor_i::SplitBiQuadraticIntoLinear(const SMESH::ListOfIDSources& theElems)
+  throw (SALOME::SALOME_Exception)
+{
+  SMESH_TRY;
+  initData();
+
+  TIDSortedElemSet elemSet;
+  for ( size_t i = 0; i < theElems.length(); ++i )
+  {
+    SMESH::SMESH_IDSource_ptr elems = theElems[i].in();
+    SMESH::SMESH_Mesh_var      mesh = elems->GetMesh();
+    if ( mesh->GetId() != myMesh_i->GetId() )
+      THROW_SALOME_CORBA_EXCEPTION("Wrong mesh of IDSource", SALOME::BAD_PARAM);
+
+    idSourceToSet( elems, getMeshDS(), elemSet, SMDSAbs_All );
+  }
+  getEditor().SplitBiQuadraticIntoLinear( elemSet );
+
+  declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
+
+  TPythonDump() << this << ".SplitBiQuadraticIntoLinear( "
+                << theElems << " )";
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+}
+
 //=======================================================================
 //function : Smooth
 //purpose  :
@@ -2382,1448 +2399,543 @@ SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupID
 }
 
 //=======================================================================
-//function : rotationSweep
+//function : RotationSweepObjects
 //purpose  :
 //=======================================================================
 
 SMESH::ListOfGroups*
-SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements,
-                                  const SMESH::AxisStruct & theAxis,
-                                  CORBA::Double             theAngleInRadians,
-                                  CORBA::Long               theNbOfSteps,
-                                  CORBA::Double             theTolerance,
-                                  const bool                theMakeGroups,
-                                  const SMDSAbs_ElementType theElementType)
+SMESH_MeshEditor_i::RotationSweepObjects(const SMESH::ListOfIDSources & theNodes,
+                                         const SMESH::ListOfIDSources & theEdges,
+                                         const SMESH::ListOfIDSources & theFaces,
+                                         const SMESH::AxisStruct &      theAxis,
+                                         CORBA::Double                  theAngleInRadians,
+                                         CORBA::Long                    theNbOfSteps,
+                                         CORBA::Double                  theTolerance,
+                                         const bool                     theMakeGroups)
   throw (SALOME::SALOME_Exception)
 {
   SMESH_TRY;
   initData();
 
-  TIDSortedElemSet inElements, copyElements;
-  arrayToSet(theIDsOfElements, getMeshDS(), inElements, theElementType);
+  TIDSortedElemSet elemsNodes[2];
+  for ( int i = 0, nb = theNodes.length(); i < nb; ++i ) {
+    SMDS_ElemIteratorPtr nIt = myMesh_i->GetElements( theNodes[i], SMESH::NODE );
+    while ( nIt->more() ) elemsNodes[1].insert( nIt->next() );
+  }
+  for ( int i = 0, nb = theEdges.length(); i < nb; ++i )
+    idSourceToSet( theEdges[i], getMeshDS(), elemsNodes[0], SMDSAbs_Edge );
+  for ( int i = 0, nb = theFaces.length(); i < nb; ++i )
+    idSourceToSet( theFaces[i], getMeshDS(), elemsNodes[0], SMDSAbs_Face );
 
-  TIDSortedElemSet* workElements = & inElements;
+  TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2];
   bool              makeWalls=true;
   if ( myIsPreviewMode )
   {
     SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
-    getPreviewMesh( SMDSAbs_Face )->Copy( inElements, copyElements, select, avoid );
-    workElements = & copyElements;
-    //makeWalls = false;
+    TPreviewMesh * tmpMesh = getPreviewMesh();
+    tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid );
+    tmpMesh->Copy( elemsNodes[1], copyElements[1], select, avoid );
+    workElements = & copyElements[0];
+    //makeWalls = false; -- faces are needed for preview
   }
 
+  TPythonDump aPythonDump; // it is here to prevent dump of getGroups()
+
   gp_Ax1 Ax1 (gp_Pnt( theAxis.x,  theAxis.y,  theAxis.z ),
               gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
 
   ::SMESH_MeshEditor::PGroupIDs groupIds =
-      getEditor().RotationSweep (*workElements, Ax1, theAngleInRadians,
+      getEditor().RotationSweep (workElements, Ax1, theAngleInRadians,
                                  theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
 
+  SMESH::ListOfGroups * aGroups = theMakeGroups ? getGroups( groupIds.get()) : 0;
+
   declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
 
-  return theMakeGroups ? getGroups(groupIds.get()) : 0;
+  if ( !myIsPreviewMode )
+  {
+    dumpGroupsList( aPythonDump, aGroups );
+    aPythonDump << this<< ".RotationSweepObjects( "
+                << theNodes                  << ", "
+                << theEdges                  << ", "
+                << theFaces                  << ", "
+                << theAxis                   << ", "
+                << TVar( theAngleInRadians ) << ", "
+                << TVar( theNbOfSteps      ) << ", "
+                << TVar( theTolerance      ) << ", "
+                << theMakeGroups             << " )";
+  }
+  else
+  {
+    getPreviewMesh()->Remove( SMDSAbs_Volume );
+  }
+
+  return aGroups ? aGroups : new SMESH::ListOfGroups;
 
   SMESH_CATCH( SMESH::throwCorbaException );
   return 0;
 }
 
-//=======================================================================
-//function : RotationSweep
-//purpose  :
-//=======================================================================
-
-void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElements,
-                                       const SMESH::AxisStruct & theAxis,
-                                       CORBA::Double             theAngleInRadians,
-                                       CORBA::Long               theNbOfSteps,
-                                       CORBA::Double             theTolerance)
-  throw (SALOME::SALOME_Exception)
+namespace MeshEditor_I
 {
-  if ( !myIsPreviewMode ) {
-    TPythonDump() << this << ".RotationSweep( "
-                  << theIDsOfElements          << ", "
-                  << theAxis                   << ", "
-                  << TVar( theAngleInRadians ) << ", "
-                  << TVar( theNbOfSteps      ) << ", "
-                  << TVar( theTolerance      ) << " )";
-  }
-  rotationSweep(theIDsOfElements,
-                theAxis,
-                theAngleInRadians,
-                theNbOfSteps,
-                theTolerance,
-                false);
+  /*!
+   * \brief Structure used to pass extrusion parameters to ::SMESH_MeshEditor
+   */
+  struct ExtrusionParams : public ::SMESH_MeshEditor::ExtrusParam
+  {
+    bool myIsExtrusionByNormal;
+
+    static int makeFlags( CORBA::Boolean MakeGroups,
+                          CORBA::Boolean ByAverageNormal = false,
+                          CORBA::Boolean UseInputElemsOnly = false,
+                          CORBA::Long    Flags = 0,
+                          CORBA::Boolean MakeBoundary = true )
+    {
+      if ( MakeGroups       ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_GROUPS;
+      if ( ByAverageNormal  ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_BY_AVG_NORMAL;
+      if ( UseInputElemsOnly) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY;
+      if ( MakeBoundary     ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_BOUNDARY;
+      return Flags;
+    }
+    // standard params
+    ExtrusionParams(const SMESH::DirStruct &  theDir,
+                    CORBA::Long               theNbOfSteps,
+                    CORBA::Boolean            theMakeGroups):
+      ::SMESH_MeshEditor::ExtrusParam ( gp_Vec( theDir.PS.x,
+                                                theDir.PS.y,
+                                                theDir.PS.z ),
+                                        theNbOfSteps,
+                                        makeFlags( theMakeGroups )),
+      myIsExtrusionByNormal( false )
+    {
+    }
+    // advanced params
+    ExtrusionParams(const SMESH::DirStruct &  theDir,
+                    CORBA::Long               theNbOfSteps,
+                    CORBA::Boolean            theMakeGroups,
+                    CORBA::Long               theExtrFlags,
+                    CORBA::Double             theSewTolerance):
+      ::SMESH_MeshEditor::ExtrusParam ( gp_Vec( theDir.PS.x,
+                                                theDir.PS.y,
+                                                theDir.PS.z ),
+                                        theNbOfSteps,
+                                        makeFlags( theMakeGroups, false, false,
+                                                   theExtrFlags, false ),
+                                        theSewTolerance ),
+      myIsExtrusionByNormal( false )
+    {
+    }
+    // params for extrusion by normal
+    ExtrusionParams(CORBA::Double  theStepSize,
+                    CORBA::Long    theNbOfSteps,
+                    CORBA::Short   theDim,
+                    CORBA::Boolean theByAverageNormal,
+                    CORBA::Boolean theUseInputElemsOnly,
+                    CORBA::Boolean theMakeGroups ):
+      ::SMESH_MeshEditor::ExtrusParam ( theStepSize, 
+                                        theNbOfSteps,
+                                        makeFlags( theMakeGroups,
+                                                   theByAverageNormal, theUseInputElemsOnly ),
+                                        theDim),
+      myIsExtrusionByNormal( true )
+    {
+    }
+
+    void SetNoGroups()
+    {
+      Flags() &= ~(::SMESH_MeshEditor::EXTRUSION_FLAG_GROUPS);
+    }
+  };
 }
 
 //=======================================================================
-//function : RotationSweepMakeGroups
-//purpose  :
+/*!
+ * \brief Generate dim+1 elements by extrusion of elements along vector
+ *  \param [in] edges - edges to extrude: a list including groups, sub-meshes or a mesh
+ *  \param [in] faces - faces to extrude: a list including groups, sub-meshes or a mesh
+ *  \param [in] nodes - nodes to extrude: a list including groups, sub-meshes or a mesh
+ *  \param [in] stepVector - vector giving direction and distance of an extrusion step
+ *  \param [in] nbOfSteps - number of elements to generate from one element
+ *  \param [in] toMakeGroups - if true, new elements will be included into new groups
+ *              corresponding to groups the input elements included in.
+ *  \return ListOfGroups - new groups craeted if \a toMakeGroups is true
+ */
 //=======================================================================
 
 SMESH::ListOfGroups*
-SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
-                                            const SMESH::AxisStruct& theAxis,
-                                            CORBA::Double            theAngleInRadians,
-                                            CORBA::Long              theNbOfSteps,
-                                            CORBA::Double            theTolerance)
+SMESH_MeshEditor_i::ExtrusionSweepObjects(const SMESH::ListOfIDSources & theNodes,
+                                          const SMESH::ListOfIDSources & theEdges,
+                                          const SMESH::ListOfIDSources & theFaces,
+                                          const SMESH::DirStruct &       theStepVector,
+                                          CORBA::Long                    theNbOfSteps,
+                                          CORBA::Boolean                 theToMakeGroups)
   throw (SALOME::SALOME_Exception)
 {
-  TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
+  SMESH_TRY;
+  initData();
 
-  SMESH::ListOfGroups *aGroups = rotationSweep(theIDsOfElements,
-                                               theAxis,
-                                               theAngleInRadians,
-                                               theNbOfSteps,
-                                               theTolerance,
-                                               true);
-  if (!myIsPreviewMode) {
-    dumpGroupsList(aPythonDump, aGroups);
-    aPythonDump << this << ".RotationSweepMakeGroups( "
-                << theIDsOfElements        << ", "
-                << theAxis                   << ", "
-                << TVar( theAngleInRadians ) << ", "
-                << TVar( theNbOfSteps      ) << ", "
-                << TVar( theTolerance      ) << " )";
+  ExtrusionParams params( theStepVector, theNbOfSteps, theToMakeGroups );
+
+  TIDSortedElemSet elemsNodes[2];
+  for ( int i = 0, nb = theNodes.length(); i < nb; ++i ) {
+    SMDS_ElemIteratorPtr nIt = myMesh_i->GetElements( theNodes[i], SMESH::NODE );
+    while ( nIt->more() ) elemsNodes[1].insert( nIt->next() );
   }
-  return aGroups;
-}
+  for ( int i = 0, nb = theEdges.length(); i < nb; ++i )
+    idSourceToSet( theEdges[i], getMeshDS(), elemsNodes[0], SMDSAbs_Edge );
+  for ( int i = 0, nb = theFaces.length(); i < nb; ++i )
+    idSourceToSet( theFaces[i], getMeshDS(), elemsNodes[0], SMDSAbs_Face );
 
-//=======================================================================
-//function : RotationSweepObject
-//purpose  :
-//=======================================================================
+  TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2];
+  SMDSAbs_ElementType previewType = SMDSAbs_All; //SMDSAbs_Face;
+  if ( myIsPreviewMode )
+  {
+    // if ( (*elemsNodes.begin())->GetType() == SMDSAbs_Node )
+    //   previewType = SMDSAbs_Edge;
 
-void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject,
-                                             const SMESH::AxisStruct & theAxis,
-                                             CORBA::Double             theAngleInRadians,
-                                             CORBA::Long               theNbOfSteps,
-                                             CORBA::Double             theTolerance)
-  throw (SALOME::SALOME_Exception)
-{
-  if ( !myIsPreviewMode ) {
-    TPythonDump() << this << ".RotationSweepObject( "
-                  << theObject << ", "
-                  << theAxis << ", "
-                  << theAngleInRadians << ", "
-                  << theNbOfSteps << ", "
-                  << theTolerance << " )";
+    SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
+    TPreviewMesh * tmpMesh = getPreviewMesh( previewType );
+    tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid );
+    tmpMesh->Copy( elemsNodes[1], copyElements[1], select, avoid );
+    workElements = & copyElements[0];
+
+    params.SetNoGroups();
   }
-  prepareIdSource( theObject );
-  SMESH::long_array_var anElementsId = theObject->GetIDs();
-  rotationSweep(anElementsId,
-                theAxis,
-                theAngleInRadians,
-                theNbOfSteps,
-                theTolerance,
-                false);
-}
+  TPythonDump aPythonDump; // it is here to prevent dump of getGroups()
 
-//=======================================================================
-//function : RotationSweepObject1D
-//purpose  :
-//=======================================================================
+  ::SMESH_MeshEditor::TTElemOfElemListMap aHistory;
+  ::SMESH_MeshEditor::PGroupIDs groupIds =
+      getEditor().ExtrusionSweep( workElements, params, aHistory );
 
-void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
-                                               const SMESH::AxisStruct & theAxis,
-                                               CORBA::Double             theAngleInRadians,
-                                               CORBA::Long               theNbOfSteps,
-                                               CORBA::Double             theTolerance)
-  throw (SALOME::SALOME_Exception)
-{
-  if ( !myIsPreviewMode ) {
-    TPythonDump() << this << ".RotationSweepObject1D( "
-                  << theObject                 << ", "
-                  << theAxis                   << ", "
-                  << TVar( theAngleInRadians ) << ", "
-                  << TVar( theNbOfSteps      ) << ", "
-                  << TVar( theTolerance      ) << " )";
-  }
-  prepareIdSource( theObject );
-  SMESH::long_array_var anElementsId = theObject->GetIDs();
-  rotationSweep(anElementsId,
-                theAxis,
-                theAngleInRadians,
-                theNbOfSteps,
-                theTolerance,
-                false,
-                SMDSAbs_Edge);
-}
+  SMESH::ListOfGroups * aGroups = theToMakeGroups ? getGroups( groupIds.get()) : 0;
 
-//=======================================================================
-//function : RotationSweepObject2D
-//purpose  :
-//=======================================================================
+  declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
 
-void SMESH_MeshEditor_i::RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
-                                               const SMESH::AxisStruct & theAxis,
-                                               CORBA::Double             theAngleInRadians,
-                                               CORBA::Long               theNbOfSteps,
-                                               CORBA::Double             theTolerance)
-  throw (SALOME::SALOME_Exception)
-{
-  if ( !myIsPreviewMode ) {
-    TPythonDump() << this << ".RotationSweepObject2D( "
-                  << theObject                 << ", "
-                  << theAxis                   << ", "
-                  << TVar( theAngleInRadians ) << ", "
-                  << TVar( theNbOfSteps      ) << ", "
-                  << TVar( theTolerance      ) << " )";
+  if ( !myIsPreviewMode )
+  {
+    dumpGroupsList( aPythonDump, aGroups );
+    aPythonDump << this<< ".ExtrusionSweepObjects( "
+                << theNodes             << ", "
+                << theEdges             << ", "
+                << theFaces             << ", "
+                << theStepVector        << ", "
+                << TVar( theNbOfSteps ) << ", "
+                << theToMakeGroups      << " )";
   }
-  prepareIdSource( theObject );
-  SMESH::long_array_var anElementsId = theObject->GetIDs();
-  rotationSweep(anElementsId,
-                theAxis,
-                theAngleInRadians,
-                theNbOfSteps,
-                theTolerance,
-                false,
-                SMDSAbs_Face);
+  else
+  {
+    getPreviewMesh( previewType )->Remove( SMDSAbs_Volume );
+  }
+
+  return aGroups ? aGroups : new SMESH::ListOfGroups;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=======================================================================
-//function : RotationSweepObjectMakeGroups
+//function : ExtrusionByNormal
 //purpose  :
 //=======================================================================
 
 SMESH::ListOfGroups*
-SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
-                                                  const SMESH::AxisStruct&  theAxis,
-                                                  CORBA::Double             theAngleInRadians,
-                                                  CORBA::Long               theNbOfSteps,
-                                                  CORBA::Double             theTolerance)
+SMESH_MeshEditor_i::ExtrusionByNormal(const SMESH::ListOfIDSources& objects,
+                                      CORBA::Double                 stepSize,
+                                      CORBA::Long                   nbOfSteps,
+                                      CORBA::Boolean                byAverageNormal,
+                                      CORBA::Boolean                useInputElemsOnly,
+                                      CORBA::Boolean                makeGroups,
+                                      CORBA::Short                  dim)
   throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
+  initData();
+
   TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
 
-  prepareIdSource( theObject );
-  SMESH::long_array_var anElementsId = theObject->GetIDs();
-  SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
-                                               theAxis,
-                                               theAngleInRadians,
-                                               theNbOfSteps,
-                                               theTolerance,
-                                               true);
-  if (!myIsPreviewMode) {
-    dumpGroupsList(aPythonDump, aGroups);
-    aPythonDump << this << ".RotationSweepObjectMakeGroups( "
-                << theObject << ", "
-                << theAxis << ", "
-                << theAngleInRadians << ", "
-                << theNbOfSteps << ", "
-                << theTolerance << " )";
+  ExtrusionParams params( stepSize, nbOfSteps, dim,
+                          byAverageNormal, useInputElemsOnly, makeGroups );
+
+  SMDSAbs_ElementType elemType = ( dim == 1 ? SMDSAbs_Edge : SMDSAbs_Face );
+  if ( objects.length() > 0 && !SMESH::DownCast<SMESH_Mesh_i*>( objects[0] ))
+  {
+    SMESH::array_of_ElementType_var elemTypes = objects[0]->GetTypes();
+    if (( elemTypes->length() == 1 ) &&
+        ( elemTypes[0] == SMESH::EDGE || elemTypes[0] == SMESH::FACE ))
+      elemType = ( SMDSAbs_ElementType ) elemTypes[0];
   }
-  return aGroups;
-}
 
-//=======================================================================
-//function : RotationSweepObject1DMakeGroups
-//purpose  :
-//=======================================================================
+  TIDSortedElemSet elemsNodes[2];
+  for ( int i = 0, nb = objects.length(); i < nb; ++i )
+    idSourceToSet( objects[i], getMeshDS(), elemsNodes[0], elemType );
 
-SMESH::ListOfGroups*
-SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
-                                                    const SMESH::AxisStruct&  theAxis,
-                                                    CORBA::Double             theAngleInRadians,
-                                                    CORBA::Long               theNbOfSteps,
-                                                    CORBA::Double             theTolerance)
-  throw (SALOME::SALOME_Exception)
-{
-  TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
+  TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2];
+  SMDSAbs_ElementType previewType = SMDSAbs_Face;
+  if ( myIsPreviewMode )
+  {
+    SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
+    TPreviewMesh * tmpMesh = getPreviewMesh( previewType );
+    tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid );
+    workElements = & copyElements[0];
+
+    params.SetNoGroups();
+  }
+
+  ::SMESH_MeshEditor::TTElemOfElemListMap aHistory;
+  ::SMESH_MeshEditor::PGroupIDs groupIds =
+      getEditor().ExtrusionSweep( workElements, params, aHistory );
+
+  SMESH::ListOfGroups * aGroups = makeGroups ? getGroups( groupIds.get()) : 0;
 
-  prepareIdSource( theObject );
-  SMESH::long_array_var anElementsId = theObject->GetIDs();
-  SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
-                                               theAxis,
-                                               theAngleInRadians,
-                                               theNbOfSteps,
-                                               theTolerance,
-                                               true,
-                                               SMDSAbs_Edge);
   if (!myIsPreviewMode) {
     dumpGroupsList(aPythonDump, aGroups);
-    aPythonDump << this << ".RotationSweepObject1DMakeGroups( "
-                << theObject                 << ", "
-                << theAxis                   << ", "
-                << TVar( theAngleInRadians ) << ", "
-                << TVar( theNbOfSteps )      << ", "
-                << TVar( theTolerance )      << " )";
+    aPythonDump << this << ".ExtrusionByNormal( " << objects
+                << ", " << TVar( stepSize )
+                << ", " << TVar( nbOfSteps )
+                << ", " << byAverageNormal
+                << ", " << useInputElemsOnly
+                << ", " << makeGroups
+                << ", " << dim
+                << " )";
   }
-  return aGroups;
+  else
+  {
+    getPreviewMesh( previewType )->Remove( SMDSAbs_Volume );
+  }
+
+  declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
+
+  return aGroups ? aGroups : new SMESH::ListOfGroups;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //=======================================================================
-//function : RotationSweepObject2DMakeGroups
+//function : AdvancedExtrusion
 //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)
+SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
+                                      const SMESH::DirStruct &  theStepVector,
+                                      CORBA::Long               theNbOfSteps,
+                                      CORBA::Long               theExtrFlags,
+                                      CORBA::Double             theSewTolerance,
+                                      CORBA::Boolean            theMakeGroups)
   throw (SALOME::SALOME_Exception)
 {
-  TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
-
-  prepareIdSource( theObject );
-  SMESH::long_array_var anElementsId = theObject->GetIDs();
-  SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
-                                               theAxis,
-                                               theAngleInRadians,
-                                               theNbOfSteps,
-                                               theTolerance,
-                                               true,
-                                               SMDSAbs_Face);
-  if (!myIsPreviewMode) {
-    dumpGroupsList(aPythonDump, aGroups);
-    aPythonDump << this << ".RotationSweepObject2DMakeGroups( "
-                << theObject                 << ", "
-                << theAxis                   << ", "
-                << TVar( theAngleInRadians ) << ", "
-                << TVar( theNbOfSteps      ) << ", "
-                << TVar( theTolerance      ) << " )";
-  }
-  return aGroups;
-}
+  SMESH_TRY;
+  initData();
 
+  TPythonDump aPythonDump; // it is here to prevent dump of getGroups()
 
-//=======================================================================
-//function : extrusionSweep
-//purpose  :
-//=======================================================================
-
-SMESH::ListOfGroups*
-SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements,
-                                   const SMESH::DirStruct &  theStepVector,
-                                   CORBA::Long               theNbOfSteps,
-                                   bool                      theMakeGroups,
-                                   const SMDSAbs_ElementType theElementType)
-  throw (SALOME::SALOME_Exception)
-{
-  SMESH_TRY;
-  initData();
+  ExtrusionParams params( theStepVector, theNbOfSteps, theMakeGroups,
+                          theExtrFlags, theSewTolerance );
 
-  TIDSortedElemSet elements, copyElements;
-  arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
+  TIDSortedElemSet elemsNodes[2];
+  arrayToSet( theIDsOfElements, getMeshDS(), elemsNodes[0] );
 
-  const SMESH::PointStruct * P = &theStepVector.PS;
-  gp_Vec stepVec( P->x, P->y, P->z );
-
-  TIDSortedElemSet* workElements = & elements;
-
-  SMDSAbs_ElementType aType = SMDSAbs_Face;
-  if (theElementType == SMDSAbs_Node)
-  {
-    aType = SMDSAbs_Edge;
-  }
-  if ( myIsPreviewMode ) {
-    SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
-    getPreviewMesh( aType )->Copy( elements, copyElements, select, avoid );
-    workElements = & copyElements;
-    theMakeGroups = false;
-  }
+  ::SMESH_MeshEditor::TTElemOfElemListMap aHistory;
+  ::SMESH_MeshEditor::PGroupIDs groupIds =
+      getEditor().ExtrusionSweep( elemsNodes, params, aHistory );
 
-  ::SMESH_MeshEditor::TTElemOfElemListMap aHystory;
-  ::SMESH_MeshEditor::PGroupIDs groupIds = 
-      getEditor().ExtrusionSweep (*workElements, stepVec, theNbOfSteps, aHystory, theMakeGroups);
+  SMESH::ListOfGroups * aGroups = theMakeGroups ? getGroups( groupIds.get()) : 0;
 
   declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
 
-  return theMakeGroups ? getGroups(groupIds.get()) : 0;
-
-  SMESH_CATCH( SMESH::throwCorbaException );
-  return 0;
-}
-
-//=======================================================================
-//function : ExtrusionSweep
-//purpose  :
-//=======================================================================
-
-void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements,
-                                        const SMESH::DirStruct &  theStepVector,
-                                        CORBA::Long               theNbOfSteps)
-  throw (SALOME::SALOME_Exception)
-{
-  extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false );
-  if (!myIsPreviewMode) {
-    TPythonDump() << this << ".ExtrusionSweep( "
-                  << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps) << " )";
-  }
-}
-
-//=======================================================================
-//function : ExtrusionSweep0D
-//purpose  :
-//=======================================================================
-
-void SMESH_MeshEditor_i::ExtrusionSweep0D(const SMESH::long_array & theIDsOfElements,
-                                          const SMESH::DirStruct &  theStepVector,
-                                          CORBA::Long               theNbOfSteps)
-  throw (SALOME::SALOME_Exception)
-{
-  extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
-  if (!myIsPreviewMode) {
-    TPythonDump() << this << ".ExtrusionSweep0D( "
-                  << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps)<< " )";
-  }
-}
-
-//=======================================================================
-//function : ExtrusionSweepObject
-//purpose  :
-//=======================================================================
-
-void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
-                                              const SMESH::DirStruct &  theStepVector,
-                                              CORBA::Long               theNbOfSteps)
-  throw (SALOME::SALOME_Exception)
-{
-  prepareIdSource( theObject );
-  SMESH::long_array_var anElementsId = theObject->GetIDs();
-  extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false );
-  if (!myIsPreviewMode) {
-    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)
-  throw (SALOME::SALOME_Exception)
-{
-  prepareIdSource( theObject );
-  SMESH::long_array_var anElementsId = theObject->GetIDs();
-  extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
-  if ( !myIsPreviewMode ) {
-    TPythonDump() << this << ".ExtrusionSweepObject0D( "
-                  << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
-  }
-}
-
-//=======================================================================
-//function : ExtrusionSweepObject1D
-//purpose  :
-//=======================================================================
-
-void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
-                                                const SMESH::DirStruct &  theStepVector,
-                                                CORBA::Long               theNbOfSteps)
-  throw (SALOME::SALOME_Exception)
-{
-  prepareIdSource( theObject );
-  SMESH::long_array_var anElementsId = theObject->GetIDs();
-  extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Edge );
-  if ( !myIsPreviewMode ) {
-    TPythonDump() << this << ".ExtrusionSweepObject1D( "
-                  << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
-  }
-}
-
-//=======================================================================
-//function : ExtrusionSweepObject2D
-//purpose  :
-//=======================================================================
-
-void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
-                                                const SMESH::DirStruct &  theStepVector,
-                                                CORBA::Long               theNbOfSteps)
-  throw (SALOME::SALOME_Exception)
-{
-  prepareIdSource( theObject );
-  SMESH::long_array_var anElementsId = theObject->GetIDs();
-  extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Face );
   if ( !myIsPreviewMode ) {
-    TPythonDump() << this << ".ExtrusionSweepObject2D( "
-                  << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
-  }
-}
-
-//=======================================================================
-//function : ExtrusionSweepMakeGroups
-//purpose  :
-//=======================================================================
-
-SMESH::ListOfGroups*
-SMESH_MeshEditor_i::ExtrusionSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
-                                             const SMESH::DirStruct&  theStepVector,
-                                             CORBA::Long              theNbOfSteps)
-  throw (SALOME::SALOME_Exception)
-{
-  TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
-
-  SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true);
-
-  if (!myIsPreviewMode) {
     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)
-  throw (SALOME::SALOME_Exception)
-{
-  TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
-
-  SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true,SMDSAbs_Node);
-
-  if (!myIsPreviewMode) {
-    dumpGroupsList(aPythonDump, aGroups);
-    aPythonDump << this << ".ExtrusionSweepMakeGroups0D( " << theIDsOfElements
-                << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
-  }
-  return aGroups;
-}
-
-//=======================================================================
-//function : ExtrusionSweepObjectMakeGroups
-//purpose  :
-//=======================================================================
-
-SMESH::ListOfGroups*
-SMESH_MeshEditor_i::ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
-                                                   const SMESH::DirStruct&   theStepVector,
-                                                   CORBA::Long               theNbOfSteps)
-  throw (SALOME::SALOME_Exception)
-{
-  TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
-
-  prepareIdSource( theObject );
-  SMESH::long_array_var anElementsId = theObject->GetIDs();
-  SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, theNbOfSteps, true);
-
-  if (!myIsPreviewMode) {
-    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)
-  throw (SALOME::SALOME_Exception)
-{
-  TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
-
-  prepareIdSource( theObject );
-  SMESH::long_array_var anElementsId = theObject->GetIDs();
-  SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
-                                                 theNbOfSteps, true, SMDSAbs_Node);
-  if (!myIsPreviewMode) {
-    dumpGroupsList(aPythonDump, aGroups);
-    aPythonDump << this << ".ExtrusionSweepObject0DMakeGroups( " << theObject
-                << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
-  }
-  return aGroups;
-}
-
-//=======================================================================
-//function : ExtrusionSweepObject1DMakeGroups
-//purpose  :
-//=======================================================================
-
-SMESH::ListOfGroups*
-SMESH_MeshEditor_i::ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
-                                                     const SMESH::DirStruct&   theStepVector,
-                                                     CORBA::Long               theNbOfSteps)
-  throw (SALOME::SALOME_Exception)
-{
-  TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
-
-  prepareIdSource( theObject );
-  SMESH::long_array_var anElementsId = theObject->GetIDs();
-  SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
-                                                 theNbOfSteps, true, SMDSAbs_Edge);
-  if (!myIsPreviewMode) {
-    dumpGroupsList(aPythonDump, aGroups);
-    aPythonDump << this << ".ExtrusionSweepObject1DMakeGroups( " << theObject
-                << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
+    aPythonDump << this << ".AdvancedExtrusion( "
+                << theIDsOfElements << ", "
+                << theStepVector << ", "
+                << theNbOfSteps << ", "
+                << theExtrFlags << ", "
+                << theSewTolerance << ", "
+                << theMakeGroups << " )";
   }
-  return aGroups;
-}
-
-//=======================================================================
-//function : ExtrusionSweepObject2DMakeGroups
-//purpose  :
-//=======================================================================
-
-SMESH::ListOfGroups*
-SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
-                                                     const SMESH::DirStruct&   theStepVector,
-                                                     CORBA::Long               theNbOfSteps)
-  throw (SALOME::SALOME_Exception)
-{
-  TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
-
-  prepareIdSource( theObject );
-  SMESH::long_array_var anElementsId = theObject->GetIDs();
-  SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
-                                                 theNbOfSteps, true, SMDSAbs_Face);
-  if (!myIsPreviewMode) {
-    dumpGroupsList(aPythonDump, aGroups);
-    aPythonDump << this << ".ExtrusionSweepObject2DMakeGroups( " << theObject
-                << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
+  else
+  {
+    getPreviewMesh()->Remove( SMDSAbs_Volume );
   }
-  return aGroups;
-}
 
-
-//=======================================================================
-//function : advancedExtrusion
-//purpose  :
-//=======================================================================
-
-SMESH::ListOfGroups*
-SMESH_MeshEditor_i::advancedExtrusion(const SMESH::long_array & theIDsOfElements,
-                                      const SMESH::DirStruct &  theStepVector,
-                                      CORBA::Long               theNbOfSteps,
-                                      CORBA::Long               theExtrFlags,
-                                      CORBA::Double             theSewTolerance,
-                                      const bool                theMakeGroups)
-  throw (SALOME::SALOME_Exception)
-{
-  SMESH_TRY;
-  initData();
-
-  TIDSortedElemSet elements;
-  arrayToSet(theIDsOfElements, getMeshDS(), elements);
-
-  const SMESH::PointStruct * P = &theStepVector.PS;
-  gp_Vec stepVec( P->x, P->y, P->z );
-
-  ::SMESH_MeshEditor::TTElemOfElemListMap aHystory;
-  ::SMESH_MeshEditor::PGroupIDs groupIds =
-      getEditor().ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory,
-                                  theMakeGroups, theExtrFlags, theSewTolerance);
-
-  declareMeshModified( /*isReComputeSafe=*/true );
-
-  return theMakeGroups ? getGroups(groupIds.get()) : 0;
+  return aGroups ? aGroups : new SMESH::ListOfGroups;
 
   SMESH_CATCH( SMESH::throwCorbaException );
   return 0;
 }
 
-//=======================================================================
-//function : AdvancedExtrusion
-//purpose  :
-//=======================================================================
-
-void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
-                                           const SMESH::DirStruct &  theStepVector,
-                                           CORBA::Long               theNbOfSteps,
-                                           CORBA::Long               theExtrFlags,
-                                           CORBA::Double             theSewTolerance)
-  throw (SALOME::SALOME_Exception)
-{
-  if ( !myIsPreviewMode ) {
-    TPythonDump() << "stepVector = " << theStepVector;
-    TPythonDump() << this << ".AdvancedExtrusion("
-                  << theIDsOfElements
-                  << ", stepVector, "
-                  << theNbOfSteps << ","
-                  << theExtrFlags << ", "
-                  << theSewTolerance <<  " )";
-  }
-  advancedExtrusion( theIDsOfElements,
-                     theStepVector,
-                     theNbOfSteps,
-                     theExtrFlags,
-                     theSewTolerance,
-                     false);
-}
-
-//=======================================================================
-//function : AdvancedExtrusionMakeGroups
-//purpose  :
-//=======================================================================
-SMESH::ListOfGroups*
-SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsOfElements,
-                                                const SMESH::DirStruct&  theStepVector,
-                                                CORBA::Long              theNbOfSteps,
-                                                CORBA::Long              theExtrFlags,
-                                                CORBA::Double            theSewTolerance)
-  throw (SALOME::SALOME_Exception)
-{
-  if (!myIsPreviewMode) {
-    TPythonDump() << "stepVector = " << theStepVector;
-  }
-  TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
-
-  SMESH::ListOfGroups * aGroups = advancedExtrusion( theIDsOfElements,
-                                                     theStepVector,
-                                                     theNbOfSteps,
-                                                     theExtrFlags,
-                                                     theSewTolerance,
-                                                     true);
-
-  if (!myIsPreviewMode) {
-    dumpGroupsList(aPythonDump, aGroups);
-    aPythonDump << this << ".AdvancedExtrusionMakeGroups("
-                << theIDsOfElements
-                << ", stepVector, "
-                << theNbOfSteps << ","
-                << theExtrFlags << ", "
-                << theSewTolerance <<  " )";
-  }
-  return aGroups;
-}
-
-
 //================================================================================
 /*!
  * \brief Convert extrusion error to IDL enum
  */
 //================================================================================
 
+namespace
+{
 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
 
-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 );
+  SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( ::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 );
+    }
+    return SMESH::SMESH_MeshEditor::EXTR_OK;
   }
-  return SMESH::SMESH_MeshEditor::EXTR_OK;
 }
 
-
 //=======================================================================
 //function : extrusionAlongPath
 //purpose  :
 //=======================================================================
 SMESH::ListOfGroups*
-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,
-                                       const bool                  theMakeGroups,
-                                       SMESH::SMESH_MeshEditor::Extrusion_Error & theError,
-                                       const SMDSAbs_ElementType   theElementType)
-  throw (SALOME::SALOME_Exception)
-{
-  SMESH_TRY;
-  MESSAGE("extrusionAlongPath");
-  initData();
-
-  if ( thePathMesh->_is_nil() || thePathShape->_is_nil() ) {
-    theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
-    return 0;
-  }
-  SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
-
-  TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
-  SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
-
-  if ( !aSubMesh || !aSubMesh->GetSubMeshDS()) {
-    theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
-    return 0;
-  }
-
-  SMDS_MeshNode* nodeStart = (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
-  if ( !nodeStart ) {
-    theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
-    return 0;
-  }
-
-  TIDSortedElemSet elements;
-  arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
-
-  list<double> angles;
-  for (int i = 0; i < theAngles.length(); i++) {
-    angles.push_back( theAngles[i] );
-  }
-
-  gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
-
-  int nbOldGroups = myMesh->NbGroup();
-
-  ::SMESH_MeshEditor::Extrusion_Error error =
-      getEditor().ExtrusionAlongTrack( elements, aSubMesh, nodeStart,
-                                    theHasAngles, angles, false,
-                                    theHasRefPoint, refPnt, theMakeGroups );
-
-  declareMeshModified( /*isReComputeSafe=*/true );
-  theError = convExtrError( error );
-
-  if ( theMakeGroups ) {
-    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 0;
-
-  SMESH_CATCH( SMESH::throwCorbaException );
-  return 0;
-}
-
-//=======================================================================
-//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_MeshEditor_i::ExtrusionAlongPathObjects(const SMESH::ListOfIDSources & theNodes,
+                                              const SMESH::ListOfIDSources & theEdges,
+                                              const SMESH::ListOfIDSources & theFaces,
+                                              SMESH::SMESH_IDSource_ptr      thePathMesh,
+                                              GEOM::GEOM_Object_ptr          thePathShape,
+                                              CORBA::Long                    theNodeStart,
+                                              CORBA::Boolean                 theHasAngles,
+                                              const SMESH::double_array &    theAngles,
+                                              CORBA::Boolean                 theLinearVariation,
+                                              CORBA::Boolean                 theHasRefPoint,
+                                              const SMESH::PointStruct &     theRefPoint,
+                                              bool                           theMakeGroups,
+                                              SMESH::SMESH_MeshEditor::Extrusion_Error& theError)
   throw (SALOME::SALOME_Exception)
 {
   SMESH_TRY;
-  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;
-
-  if ( myIsPreviewMode )
-  {
-    SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
-    getPreviewMesh( SMDSAbs_Face )->Copy( elements, copyElements, select, avoid );
-    workElements = & copyElements;
-    MakeGroups = false;
-  }
+  SMESH::ListOfGroups_var aGroups = new SMESH::ListOfGroups;
 
-  ::SMESH_MeshEditor::Extrusion_Error error;
+  theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
+  if ( thePathMesh->_is_nil() )
+    return aGroups._retn();
 
-  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 = getEditor().ExtrusionAlongTrack( *workElements, &(aMeshImp->GetImpl()), aNodeStart,
-                                             HasAngles, angles, LinearVariation,
-                                             HasRefPoint, refPnt, MakeGroups );
-    declareMeshModified( /*isReComputeSafe=*/true );
-  }
-  else if ( SMESH_subMesh_i* aSubMeshImp = SMESH::DownCast<SMESH_subMesh_i*>( Path ))
+  // get a sub-mesh
+  SMESH_subMesh* aSubMesh = 0;
+  SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
+  if ( thePathShape->_is_nil() )
   {
-    // 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;
+    // thePathMesh should be either a sub-mesh or a mesh with 1D elements only
+    if ( SMESH_subMesh_i* sm = SMESH::DownCast<SMESH_subMesh_i*>( thePathMesh ))
+    {
+      SMESH::SMESH_Mesh_var mesh = thePathMesh->GetMesh();
+      aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
+      if ( !aMeshImp ) return aGroups._retn();
+      aSubMesh = aMeshImp->GetImpl().GetSubMeshContaining( sm->GetId() );
+      if ( !aSubMesh ) return aGroups._retn();
     }
-    SMESH_subMesh* aSubMesh =
-      aMeshImp->GetImpl().GetSubMeshContaining(aSubMeshImp->GetId());
-    error = getEditor().ExtrusionAlongTrack( *workElements, aSubMesh, aNodeStart,
-                                             HasAngles, angles, LinearVariation,
-                                             HasRefPoint, refPnt, MakeGroups );
-    declareMeshModified( /*isReComputeSafe=*/true );
-  }
-  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;
-  }
-
-  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;
-
-  SMESH_CATCH( SMESH::throwCorbaException );
-  return 0;
-}
-
-//=======================================================================
-//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)
-  throw (SALOME::SALOME_Exception)
-{
-  MESSAGE("ExtrusionAlongPath");
-  if ( !myIsPreviewMode ) {
-    TPythonDump() << "error = " << this << ".ExtrusionAlongPath( "
-                  << theIDsOfElements << ", "
-                  << thePathMesh      << ", "
-                  << thePathShape     << ", "
-                  << theNodeStart     << ", "
-                  << theHasAngles     << ", "
-                  << theAngles        << ", "
-                  << theHasRefPoint   << ", "
-                  << "SMESH.PointStruct( "
-                  << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
-                  << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
-                  << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
-  }
-  SMESH::SMESH_MeshEditor::Extrusion_Error anError;
-  extrusionAlongPath( theIDsOfElements,
-                      thePathMesh,
-                      thePathShape,
-                      theNodeStart,
-                      theHasAngles,
-                      theAngles,
-                      theHasRefPoint,
-                      theRefPoint,
-                      false,
-                      anError);
-  return anError;
-}
-
-//=======================================================================
-//function : ExtrusionAlongPathObject
-//purpose  :
-//=======================================================================
-
-SMESH::SMESH_MeshEditor::Extrusion_Error
-SMESH_MeshEditor_i::ExtrusionAlongPathObject(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)
-  throw (SALOME::SALOME_Exception)
-{
-  if ( !myIsPreviewMode ) {
-    TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject( "
-                  << theObject        << ", "
-                  << thePathMesh      << ", "
-                  << thePathShape     << ", "
-                  << theNodeStart     << ", "
-                  << theHasAngles     << ", "
-                  << theAngles        << ", "
-                  << theHasRefPoint   << ", "
-                  << "SMESH.PointStruct( "
-                  << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
-                  << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
-                  << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
-  }
-  SMESH::SMESH_MeshEditor::Extrusion_Error anError;
-  prepareIdSource( theObject );
-  SMESH::long_array_var anElementsId = theObject->GetIDs();
-  extrusionAlongPath( anElementsId,
-                      thePathMesh,
-                      thePathShape,
-                      theNodeStart,
-                      theHasAngles,
-                      theAngles,
-                      theHasRefPoint,
-                      theRefPoint,
-                      false,
-                      anError);
-  return anError;
-}
-
-//=======================================================================
-//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)
-  throw (SALOME::SALOME_Exception)
-{
-  if ( !myIsPreviewMode ) {
-    TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject1D( "
-                  << theObject        << ", "
-                  << thePathMesh      << ", "
-                  << thePathShape     << ", "
-                  << theNodeStart     << ", "
-                  << theHasAngles     << ", "
-                  << theAngles        << ", "
-                  << theHasRefPoint   << ", "
-                  << "SMESH.PointStruct( "
-                  << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
-                  << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
-                  << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
-  }
-  SMESH::SMESH_MeshEditor::Extrusion_Error anError;
-  prepareIdSource( theObject );
-  SMESH::long_array_var anElementsId = theObject->GetIDs();
-  extrusionAlongPath( anElementsId,
-                      thePathMesh,
-                      thePathShape,
-                      theNodeStart,
-                      theHasAngles,
-                      theAngles,
-                      theHasRefPoint,
-                      theRefPoint,
-                      false,
-                      anError,
-                      SMDSAbs_Edge);
-  return anError;
-}
-
-//=======================================================================
-//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)
-  throw (SALOME::SALOME_Exception)
-{
-  if ( !myIsPreviewMode ) {
-    TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject2D( "
-                  << theObject        << ", "
-                  << thePathMesh      << ", "
-                  << thePathShape     << ", "
-                  << theNodeStart     << ", "
-                  << theHasAngles     << ", "
-                  << theAngles        << ", "
-                  << theHasRefPoint   << ", "
-                  << "SMESH.PointStruct( "
-                  << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
-                  << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
-                  << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
-  }
-  SMESH::SMESH_MeshEditor::Extrusion_Error anError;
-  prepareIdSource( theObject );
-  SMESH::long_array_var anElementsId = theObject->GetIDs();
-  extrusionAlongPath( anElementsId,
-                      thePathMesh,
-                      thePathShape,
-                      theNodeStart,
-                      theHasAngles,
-                      theAngles,
-                      theHasRefPoint,
-                      theRefPoint,
-                      false,
-                      anError,
-                      SMDSAbs_Face);
-  return anError;
-}
-
-
-//=======================================================================
-//function : ExtrusionAlongPathMakeGroups
-//purpose  :
-//=======================================================================
-
-SMESH::ListOfGroups*
-SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(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::SMESH_MeshEditor::Extrusion_Error& Error)
-  throw (SALOME::SALOME_Exception)
-{
-  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 (!myIsPreviewMode) {
-    bool isDumpGroups = aGroups && aGroups->length() > 0;
-    if (isDumpGroups)
-      aPythonDump << "(" << aGroups << ", error)";
-    else
-      aPythonDump <<"error";
-
-    aPythonDump<<" = "<< this << ".ExtrusionAlongPathMakeGroups( "
-               << theIDsOfElements << ", "
-               << thePathMesh      << ", "
-               << thePathShape     << ", "
-               << theNodeStart     << ", "
-               << theHasAngles     << ", "
-               << theAngles        << ", "
-               << theHasRefPoint   << ", "
-               << "SMESH.PointStruct( "
-               << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
-               << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
-               << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
-  }
-  return aGroups;
-}
-
-//=======================================================================
-//function : ExtrusionAlongPathObjectMakeGroups
-//purpose  :
-//=======================================================================
-
-SMESH::ListOfGroups* SMESH_MeshEditor_i::
-ExtrusionAlongPathObjectMakeGroups(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)
-  throw (SALOME::SALOME_Exception)
-{
-  TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
-
-  prepareIdSource( theObject );
-  SMESH::long_array_var anElementsId = theObject->GetIDs();
-  SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
-                                                      thePathMesh,
-                                                      thePathShape,
-                                                      theNodeStart,
-                                                      theHasAngles,
-                                                      theAngles,
-                                                      theHasRefPoint,
-                                                      theRefPoint,
-                                                      true,
-                                                      Error);
-
-  if (!myIsPreviewMode) {
-    bool isDumpGroups = aGroups && aGroups->length() > 0;
-    if (isDumpGroups)
-      aPythonDump << "(" << aGroups << ", error)";
-    else
-      aPythonDump <<"error";
-
-    aPythonDump << " = " << this << ".ExtrusionAlongPathObjectMakeGroups( "
-                << theObject << ", "
-                << thePathMesh      << ", "
-                << thePathShape     << ", "
-                << theNodeStart     << ", "
-                << theHasAngles     << ", "
-                << theAngles        << ", "
-                << theHasRefPoint   << ", "
-                << "SMESH.PointStruct( "
-                << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
-                << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
-                << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
-  }
-  return aGroups;
-}
-
-//=======================================================================
-//function : ExtrusionAlongPathObject1DMakeGroups
-//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)
-  throw (SALOME::SALOME_Exception)
-{
-  TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
-
-  prepareIdSource( theObject );
-  SMESH::long_array_var anElementsId = theObject->GetIDs();
-  SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
-                                                      thePathMesh,
-                                                      thePathShape,
-                                                      theNodeStart,
-                                                      theHasAngles,
-                                                      theAngles,
-                                                      theHasRefPoint,
-                                                      theRefPoint,
-                                                      true,
-                                                      Error,
-                                                      SMDSAbs_Edge);
-
-  if (!myIsPreviewMode) {
-    bool isDumpGroups = aGroups && aGroups->length() > 0;
-    if (isDumpGroups)
-      aPythonDump << "(" << aGroups << ", error)";
-    else
-      aPythonDump << "error";
-
-    aPythonDump << " = " << this << ".ExtrusionAlongPathObject1DMakeGroups( "
-                << theObject << ", "
-                << thePathMesh      << ", "
-                << thePathShape     << ", "
-                << theNodeStart     << ", "
-                << theHasAngles     << ", "
-                << theAngles        << ", "
-                << theHasRefPoint   << ", "
-                << "SMESH.PointStruct( "
-                << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
-                << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
-                << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
-  }
-  return aGroups;
-}
-
-//=======================================================================
-//function : ExtrusionAlongPathObject2DMakeGroups
-//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)
-  throw (SALOME::SALOME_Exception)
-{
-  TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
-
-  prepareIdSource( theObject );
-  SMESH::long_array_var anElementsId = theObject->GetIDs();
-  SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
-                                                      thePathMesh,
-                                                      thePathShape,
-                                                      theNodeStart,
-                                                      theHasAngles,
-                                                      theAngles,
-                                                      theHasRefPoint,
-                                                      theRefPoint,
-                                                      true,
-                                                      Error,
-                                                      SMDSAbs_Face);
+    else if ( !aMeshImp ||
+              aMeshImp->NbEdges() != aMeshImp->NbElements() )
+    {
+      return aGroups._retn();
+    }
+  }
+  else
+  {
+    if ( !aMeshImp ) return aGroups._retn();
+    TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
+    aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
+    if ( !aSubMesh /*|| !aSubMesh->GetSubMeshDS()*/ )
+      return aGroups._retn();
+  }
 
-  if (!myIsPreviewMode) {
-    bool isDumpGroups = aGroups && aGroups->length() > 0;
-    if (isDumpGroups)
-      aPythonDump << "(" << aGroups << ", error)";
-    else
-      aPythonDump << "error";
+  SMDS_MeshNode* nodeStart =
+    (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
+  if ( !nodeStart ) {
+    theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
+    return aGroups._retn();
+  }
 
-    aPythonDump << " = " << this << ".ExtrusionAlongPathObject2DMakeGroups( "
-                << theObject << ", "
-                << thePathMesh      << ", "
-                << thePathShape     << ", "
-                << theNodeStart     << ", "
-                << theHasAngles     << ", "
-                << theAngles        << ", "
-                << theHasRefPoint   << ", "
-                << "SMESH.PointStruct( "
-                << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
-                << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
-                << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
+  TIDSortedElemSet elemsNodes[2];
+  for ( int i = 0, nb = theNodes.length(); i < nb; ++i ) {
+    SMDS_ElemIteratorPtr nIt = myMesh_i->GetElements( theNodes[i], SMESH::NODE );
+    while ( nIt->more() ) elemsNodes[1].insert( nIt->next() );
   }
-  return aGroups;
-}
+  for ( int i = 0, nb = theEdges.length(); i < nb; ++i )
+    idSourceToSet( theEdges[i], getMeshDS(), elemsNodes[0], SMDSAbs_Edge );
+  for ( int i = 0, nb = theFaces.length(); i < nb; ++i )
+    idSourceToSet( theFaces[i], getMeshDS(), elemsNodes[0], SMDSAbs_Face );
 
-//=======================================================================
-//function : ExtrusionAlongPathObjX
-//purpose  :
-//=======================================================================
+  list<double> angles;
+  for (int i = 0; i < theAngles.length(); i++) {
+    angles.push_back( theAngles[i] );
+  }
 
-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)
-  throw (SALOME::SALOME_Exception)
-{
-  TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
+  gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
 
-  prepareIdSource( Object );
-  SMESH::long_array_var anElementsId = Object->GetIDs();
-  SMESH::ListOfGroups * aGroups = extrusionAlongPathX(anElementsId,
-                                                      Path,
-                                                      NodeStart,
-                                                      HasAngles,
-                                                      Angles,
-                                                      LinearVariation,
-                                                      HasRefPoint,
-                                                      RefPoint,
-                                                      MakeGroups,
-                                                      (SMDSAbs_ElementType)ElemType,
-                                                      Error);
+  int nbOldGroups = myMesh->NbGroup();
 
-  if (!myIsPreviewMode) {
-    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 << " )";
+  TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2];
+  if ( myIsPreviewMode )
+  {
+    SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
+    TPreviewMesh * tmpMesh = getPreviewMesh();
+    tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid );
+    tmpMesh->Copy( elemsNodes[1], copyElements[1], select, avoid );
+    workElements = & copyElements[0];
+    theMakeGroups = false;
   }
-  return aGroups;
-}
 
-//=======================================================================
-//function : ExtrusionAlongPathX
-//purpose  :
-//=======================================================================
+  ::SMESH_MeshEditor::Extrusion_Error error;
+  if ( !aSubMesh )
+    error = getEditor().ExtrusionAlongTrack( workElements, &(aMeshImp->GetImpl()), nodeStart,
+                                             theHasAngles, angles, theLinearVariation,
+                                             theHasRefPoint, refPnt, theMakeGroups );
+  else
+    error = getEditor().ExtrusionAlongTrack( workElements, aSubMesh, nodeStart,
+                                             theHasAngles, angles, theLinearVariation,
+                                             theHasRefPoint, refPnt, theMakeGroups );
 
-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)
-  throw (SALOME::SALOME_Exception)
-{
-  TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
+  declareMeshModified( /*isReComputeSafe=*/true );
+  theError = convExtrError( error );
 
-  SMESH::ListOfGroups * aGroups = extrusionAlongPathX(IDsOfElements,
-                                                      Path,
-                                                      NodeStart,
-                                                      HasAngles,
-                                                      Angles,
-                                                      LinearVariation,
-                                                      HasRefPoint,
-                                                      RefPoint,
-                                                      MakeGroups,
-                                                      (SMDSAbs_ElementType)ElemType,
-                                                      Error);
+  TPythonDump aPythonDump; // it is here to prevent dump of getGroups()
+  if ( theMakeGroups ) {
+    list<int> groupIDs = myMesh->GetGroupIds();
+    list<int>::iterator newBegin = groupIDs.begin();
+    std::advance( newBegin, nbOldGroups ); // skip old groups
+    groupIDs.erase( groupIDs.begin(), newBegin );
+    aGroups = getGroups( & groupIDs );
+    if ( ! &aGroups.in() ) aGroups = new SMESH::ListOfGroups;
+  }
 
-  if (!myIsPreviewMode) {
-    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     << ", "
+  if ( !myIsPreviewMode ) {
+    aPythonDump << "(" << aGroups << ", error) = "
+                << this << ".ExtrusionAlongPathObjects( "
+                << theNodes            << ", "
+                << theEdges            << ", "
+                << theFaces            << ", "
+                << thePathMesh         << ", "
+                << thePathShape        << ", "
+                << theNodeStart        << ", "
+                << theHasAngles        << ", "
+                << theAngles           << ", "
+                << theLinearVariation  << ", "
+                << theHasRefPoint      << ", "
                 << "SMESH.PointStruct( "
-                << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
-                << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
-                << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
-                << MakeGroups << ", "
-                << ElemType << " )";
+                << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
+                << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
+                << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ), "
+                << theMakeGroups       << " )";
   }
-  return aGroups;
+  else
+  {
+    getPreviewMesh()->Remove( SMDSAbs_Volume );
+  }
+
+  return aGroups._retn();
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
 }
 
 //================================================================================
@@ -4018,7 +3130,6 @@ void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr           theObj
 
   bool emptyIfIsMesh = myIsPreviewMode ? false : true;
 
-  prepareIdSource( theObject );
   if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
     mirror(elements, theAxis, theMirrorType, theCopy, false);
 }
@@ -4068,7 +3179,6 @@ SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr           t
 
   SMESH::ListOfGroups * aGroups = 0;
   TIDSortedElemSet elements;
-  prepareIdSource( theObject );
   if ( idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
     aGroups = mirror(elements, theMirror, theMirrorType, true, true);
 
@@ -4154,7 +3264,6 @@ SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr           the
     mesh = makeMesh( theMeshName );
     mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
     TIDSortedElemSet elements;
-    prepareIdSource( theObject );
     if ( mesh_i &&
          idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
     {
@@ -4282,8 +3391,7 @@ void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
   TIDSortedElemSet elements;
 
   bool emptyIfIsMesh = myIsPreviewMode ? false : true;
-  
-  prepareIdSource( theObject );
+
   if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
     translate(elements, theVector, theCopy, false);
 }
@@ -4329,7 +3437,6 @@ SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObjec
 
   SMESH::ListOfGroups * aGroups = 0;
   TIDSortedElemSet elements;
-  prepareIdSource( theObject );
   if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
     aGroups = translate(elements, theVector, true, true);
 
@@ -4412,9 +3519,8 @@ SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
     mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
 
     TIDSortedElemSet elements;
-    prepareIdSource( theObject );
     if ( mesh_i &&
-      idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
+         idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
     {
       translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl());
       mesh_i->CreateGroupServants();
@@ -4540,7 +3646,6 @@ void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
   }
   TIDSortedElemSet elements;
   bool emptyIfIsMesh = myIsPreviewMode ? false : true;
-  prepareIdSource( theObject );
   if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
     rotate(elements,theAxis,theAngle,theCopy,false);
 }
@@ -4590,7 +3695,6 @@ SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
 
   SMESH::ListOfGroups * aGroups = 0;
   TIDSortedElemSet elements;
-  prepareIdSource( theObject );
   if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
     aGroups = rotate(elements, theAxis, theAngle, true, true);
 
@@ -4682,7 +3786,6 @@ SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
     mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
 
     TIDSortedElemSet elements;
-    prepareIdSource( theObject );
     if (mesh_i &&
         idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
     {
@@ -4735,7 +3838,6 @@ SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr  theObject,
     theCopy = false;
 
   TIDSortedElemSet elements;
-  prepareIdSource( theObject );
   bool emptyIfIsMesh = myIsPreviewMode ? false : true;
   if ( !idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
     return 0;
@@ -4745,14 +3847,23 @@ SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr  theObject,
     (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[1],
     (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[2],
   };
-  double tol = std::numeric_limits<double>::max();
   gp_Trsf aTrsf;
 
 #if OCC_VERSION_LARGE > 0x06070100
-  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]) );
+  // fight against orthogonalization
+  // 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]) );
+  aTrsf.SetScale( gp::Origin(), 1.0 ); // set form which is used to make group names
+  gp_XYZ & loc = ( gp_XYZ& ) aTrsf.TranslationPart();
+  gp_Mat & M   = ( gp_Mat& ) aTrsf.HVectorialPart();
+  loc.SetCoord( thePoint.x * (1-S[0]),
+                thePoint.y * (1-S[1]),
+                thePoint.z * (1-S[2]));
+  M.SetDiagonal( S[0], S[1], S[2] );
+
 #else
+  double tol = std::numeric_limits<double>::max();
   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);
@@ -4880,25 +3991,24 @@ SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr  theObject,
 
 
 //=======================================================================
-//function : FindCoincidentNodes
+//function : findCoincidentNodes
 //purpose  :
 //=======================================================================
 
-void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double                  Tolerance,
-                                              SMESH::array_of_long_array_out GroupsOfNodes)
-  throw (SALOME::SALOME_Exception)
+void SMESH_MeshEditor_i::
+findCoincidentNodes (TIDSortedNodeSet &             Nodes,
+                     CORBA::Double                  Tolerance,
+                     SMESH::array_of_long_array_out GroupsOfNodes,
+                     CORBA::Boolean                 SeparateCornersAndMedium)
 {
-  SMESH_TRY;
-  initData();
-
   ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
-  TIDSortedNodeSet nodes; // no input nodes
-  getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
+  getEditor().FindCoincidentNodes( Nodes, Tolerance, aListOfListOfNodes, SeparateCornersAndMedium );
 
   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++ ) {
+  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 ];
@@ -4906,8 +4016,28 @@ void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double                  Tol
     for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
       aGroup[ j ] = (*lIt)->GetID();
   }
+}
+
+//=======================================================================
+//function : FindCoincidentNodes
+//purpose  :
+//=======================================================================
+
+void SMESH_MeshEditor_i::
+FindCoincidentNodes (CORBA::Double                  Tolerance,
+                     SMESH::array_of_long_array_out GroupsOfNodes,
+                     CORBA::Boolean                 SeparateCornersAndMedium)
+  throw (SALOME::SALOME_Exception)
+{
+  SMESH_TRY;
+  initData();
+
+  TIDSortedNodeSet nodes; // no input nodes
+  findCoincidentNodes( nodes, Tolerance, GroupsOfNodes, SeparateCornersAndMedium );
+
   TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
-                << Tolerance << " )";
+                << Tolerance << ", "
+                << SeparateCornersAndMedium << " )";
 
   SMESH_CATCH( SMESH::throwCorbaException );
 }
@@ -4917,37 +4047,25 @@ void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double                  Tol
 //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::
+FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr      theObject,
+                          CORBA::Double                  Tolerance,
+                          SMESH::array_of_long_array_out GroupsOfNodes,
+                          CORBA::Boolean                 SeparateCornersAndMedium)
   throw (SALOME::SALOME_Exception)
 {
   SMESH_TRY;
   initData();
 
   TIDSortedNodeSet nodes;
-  prepareIdSource( theObject );
   idSourceToNodeSet( theObject, getMeshDS(), nodes );
 
-  ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
-  if(!nodes.empty())
-    getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
+  findCoincidentNodes( nodes, Tolerance, GroupsOfNodes, SeparateCornersAndMedium );
 
-  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 << " )";
+                << theObject <<", "
+                << Tolerance << ", "
+                << SeparateCornersAndMedium << " )";
 
   SMESH_CATCH( SMESH::throwCorbaException );
 }
@@ -4963,44 +4081,30 @@ void SMESH_MeshEditor_i::
 FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr      theObject,
                              CORBA::Double                  theTolerance,
                              SMESH::array_of_long_array_out theGroupsOfNodes,
-                             const SMESH::ListOfIDSources&  theExceptSubMeshOrGroups)
+                             const SMESH::ListOfIDSources&  theExceptSubMeshOrGroups,
+                             CORBA::Boolean                 theSeparateCornersAndMedium)
   throw (SALOME::SALOME_Exception)
 {
   SMESH_TRY;
   initData();
 
   TIDSortedNodeSet nodes;
-  prepareIdSource( theObject );
   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 );
+    SMDS_ElemIteratorPtr nodeIt = myMesh_i->GetElements( theExceptSubMeshOrGroups[i],
+                                                         SMESH::NODE );
+    while ( nodeIt->more() )
+      nodes.erase( cast2Node( nodeIt->next() ));
   }
-  ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
-  if(!nodes.empty())
-    getEditor().FindCoincidentNodes( nodes, theTolerance, aListOfListOfNodes );
+  findCoincidentNodes( nodes, theTolerance, theGroupsOfNodes, theSeparateCornersAndMedium );
 
-  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 << " )";
+                << theExceptSubMeshOrGroups << ", "
+                << theSeparateCornersAndMedium << " )";
 
   SMESH_CATCH( SMESH::throwCorbaException );
 }
@@ -5010,7 +4114,8 @@ FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr      theObject,
 //purpose  :
 //=======================================================================
 
-void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
+void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes,
+                                     const SMESH::ListOfIDSources&     NodesToKeep)
   throw (SALOME::SALOME_Exception)
 {
   SMESH_TRY;
@@ -5020,6 +4125,16 @@ void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfN
 
   TPythonDump aTPythonDump;
   aTPythonDump << this << ".MergeNodes([";
+
+  TIDSortedNodeSet setOfNodesToKeep;
+  for ( int i = 0; i < NodesToKeep.length(); ++i )
+  {
+    prepareIdSource( NodesToKeep[i] );
+    SMDS_ElemIteratorPtr nodeIt = myMesh_i->GetElements( NodesToKeep[i], SMESH::NODE );
+    while ( nodeIt->more() )
+      setOfNodesToKeep.insert( setOfNodesToKeep.end(), cast2Node( nodeIt->next() ));
+  }
+
   ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
   for (int i = 0; i < GroupsOfNodes.length(); i++)
   {
@@ -5029,9 +4144,13 @@ void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfN
     for ( int j = 0; j < aNodeGroup.length(); j++ )
     {
       CORBA::Long index = aNodeGroup[ j ];
-      const SMDS_MeshNode * node = aMesh->FindNode(index);
-      if ( node )
-        aListOfNodes.push_back( node );
+      if ( const SMDS_MeshNode * node = aMesh->FindNode( index ))
+      {
+        if ( setOfNodesToKeep.count( node ))
+          aListOfNodes.push_front( node );
+        else
+          aListOfNodes.push_back( node );
+      }
     }
     if ( aListOfNodes.size() < 2 )
       aListOfListOfNodes.pop_back();
@@ -5039,9 +4158,10 @@ void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfN
     if ( i > 0 ) aTPythonDump << ", ";
     aTPythonDump << aNodeGroup;
   }
+
   getEditor().MergeNodes( aListOfListOfNodes );
 
-  aTPythonDump <<  "])";
+  aTPythonDump << "], " << NodesToKeep << ")";
 
   declareMeshModified( /*isReComputeSafe=*/false );
 
@@ -5064,7 +4184,6 @@ void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr      theObj
   if ( !(!group->_is_nil() && group->GetType() == SMESH::NODE) )
   {
     TIDSortedElemSet elems;
-    prepareIdSource( theObject );
     idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true);
 
     ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
@@ -5453,6 +4572,225 @@ static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Se
   return SMESH::SMESH_MeshEditor::SEW_OK;
 }
 
+//=======================================================================
+/*!
+ * Returns groups of FreeBorder's coincident within the given tolerance.
+ * If the tolerance <= 0.0 then one tenth of an average size of elements adjacent
+ * to free borders being compared is used.
+ */
+//=======================================================================
+
+SMESH::CoincidentFreeBorders*
+SMESH_MeshEditor_i::FindCoincidentFreeBorders(CORBA::Double tolerance)
+{
+  SMESH::CoincidentFreeBorders_var aCFB = new SMESH::CoincidentFreeBorders;
+
+  SMESH_TRY;
+
+  SMESH_MeshAlgos::CoincidentFreeBorders cfb;
+  SMESH_MeshAlgos::FindCoincidentFreeBorders( *getMeshDS(), tolerance, cfb );
+
+  // copy free borders
+  aCFB->borders.length( cfb._borders.size() );
+  for ( size_t i = 0; i < cfb._borders.size(); ++i )
+  {
+    SMESH_MeshAlgos::TFreeBorder& nodes = cfb._borders[i];
+    SMESH::FreeBorder&             aBRD = aCFB->borders[i];
+    aBRD.nodeIDs.length( nodes.size() );
+    for ( size_t iN = 0; iN < nodes.size(); ++iN )
+      aBRD.nodeIDs[ iN ] = nodes[ iN ]->GetID();
+  }
+
+  // copy coincident parts
+  aCFB->coincidentGroups.length( cfb._coincidentGroups.size() );
+  for ( size_t i = 0; i < cfb._coincidentGroups.size(); ++i )
+  {
+    SMESH_MeshAlgos::TCoincidentGroup& grp = cfb._coincidentGroups[i];
+    SMESH::FreeBordersGroup&          aGRP = aCFB->coincidentGroups[i];
+    aGRP.length( grp.size() );
+    for ( size_t iP = 0; iP < grp.size(); ++iP )
+    {
+      SMESH_MeshAlgos::TFreeBorderPart& part = grp[ iP ];
+      SMESH::FreeBorderPart&           aPART = aGRP[ iP ];
+      aPART.border   = part._border;
+      aPART.node1    = part._node1;
+      aPART.node2    = part._node2;
+      aPART.nodeLast = part._nodeLast;
+    }
+  }
+  SMESH_CATCH( SMESH::doNothing );
+
+  TPythonDump() << "CoincidentFreeBorders = "
+                << this << ".FindCoincidentFreeBorders( " << tolerance << " )";
+
+  return aCFB._retn();
+}
+
+//=======================================================================
+/*!
+ * Sew FreeBorder's of each group
+ */
+//=======================================================================
+
+CORBA::Short SMESH_MeshEditor_i::
+SewCoincidentFreeBorders(const SMESH::CoincidentFreeBorders& freeBorders,
+                         CORBA::Boolean                      createPolygons,
+                         CORBA::Boolean                      createPolyhedra)
+  throw (SALOME::SALOME_Exception)
+{
+  CORBA::Short nbSewed = 0;
+
+  SMESH_MeshAlgos::TFreeBorderVec groups;
+  SMESH_MeshAlgos::TFreeBorder    borderNodes; // triples of nodes for every FreeBorderPart
+
+  // check the input and collect nodes
+  for ( CORBA::ULong i = 0; i < freeBorders.coincidentGroups.length(); ++i )
+  {
+    borderNodes.clear();
+    const SMESH::FreeBordersGroup& aGRP = freeBorders.coincidentGroups[ i ];
+    for ( CORBA::ULong iP = 0; iP < aGRP.length(); ++iP )
+    {
+      const SMESH::FreeBorderPart& aPART = aGRP[ iP ];
+      if ( aPART.border < 0 || aPART.border >= freeBorders.borders.length() )
+        THROW_SALOME_CORBA_EXCEPTION("Invalid FreeBorderPart::border index", SALOME::BAD_PARAM);
+
+      const SMESH::FreeBorder& aBRD = freeBorders.borders[ aPART.border ];
+
+      if ( aPART.node1 < 0 || aPART.node1 > aBRD.nodeIDs.length() )
+        THROW_SALOME_CORBA_EXCEPTION("Invalid FreeBorderPart::node1", SALOME::BAD_PARAM);
+      if ( aPART.node2 < 0 || aPART.node2 > aBRD.nodeIDs.length() )
+        THROW_SALOME_CORBA_EXCEPTION("Invalid FreeBorderPart::node2", SALOME::BAD_PARAM);
+      if ( aPART.nodeLast < 0 || aPART.nodeLast > aBRD.nodeIDs.length() )
+        THROW_SALOME_CORBA_EXCEPTION("Invalid FreeBorderPart::nodeLast", SALOME::BAD_PARAM);
+
+      // do not keep these nodes for further sewing as nodes can be removed by the sewing
+      const SMDS_MeshNode* n1 = getMeshDS()->FindNode( aBRD.nodeIDs[ aPART.node1    ]);
+      const SMDS_MeshNode* n2 = getMeshDS()->FindNode( aBRD.nodeIDs[ aPART.node2    ]);
+      const SMDS_MeshNode* n3 = getMeshDS()->FindNode( aBRD.nodeIDs[ aPART.nodeLast ]);
+      if ( !n1)
+        THROW_SALOME_CORBA_EXCEPTION("Nonexistent FreeBorderPart::node1", SALOME::BAD_PARAM);
+      if ( !n2 )
+        THROW_SALOME_CORBA_EXCEPTION("Nonexistent FreeBorderPart::node2", SALOME::BAD_PARAM);
+      if ( !n3 )
+        THROW_SALOME_CORBA_EXCEPTION("Nonexistent FreeBorderPart::nodeLast", SALOME::BAD_PARAM);
+
+      borderNodes.push_back( n1 );
+      borderNodes.push_back( n2 );
+      borderNodes.push_back( n3 );
+    }
+    groups.push_back( borderNodes );
+  }
+
+  // SewFreeBorder() can merge nodes, thus nodes stored in 'groups' can become dead;
+  // to get nodes that replace other nodes during merge we create 0D elements
+  // on each node and MergeNodes() will replace underlying nodes of 0D elements by
+  // new ones.
+
+  vector< const SMDS_MeshElement* > tmp0Delems;
+  for ( size_t i = 0; i < groups.size(); ++i )
+  {
+    SMESH_MeshAlgos::TFreeBorder& nodes = groups[i];
+    for ( size_t iN = 0; iN < nodes.size(); ++iN )
+    {
+      SMDS_ElemIteratorPtr it0D = nodes[iN]->GetInverseElementIterator(SMDSAbs_0DElement);
+      if ( it0D->more() )
+        tmp0Delems.push_back( it0D->next() );
+      else
+        tmp0Delems.push_back( getMeshDS()->Add0DElement( nodes[iN] ));
+    }
+  }
+
+  // cout << endl << "INIT" << endl;
+  // for ( size_t i = 0; i < tmp0Delems.size(); ++i )
+  // {
+  //   cout << i << " ";
+  //   if ( i % 3 == 0 ) cout << "^ ";
+  //   tmp0Delems[i]->GetNode(0)->Print( cout );
+  // }
+
+  SMESH_TRY;
+
+  ::SMESH_MeshEditor::Sew_Error res, ok = ::SMESH_MeshEditor::SEW_OK;
+  int i0D = 0;
+  for ( size_t i = 0; i < groups.size(); ++i )
+  {
+    bool isBordToBord = true;
+    bool   groupSewed = false;
+    SMESH_MeshAlgos::TFreeBorder& nodes = groups[i];
+    for ( size_t iN = 3; iN+2 < nodes.size(); iN += 3 )
+    {
+      const SMDS_MeshNode* n0 = tmp0Delems[ i0D + 0 ]->GetNode( 0 );
+      const SMDS_MeshNode* n1 = tmp0Delems[ i0D + 1 ]->GetNode( 0 );
+      const SMDS_MeshNode* n2 = tmp0Delems[ i0D + 2 ]->GetNode( 0 );
+
+      const SMDS_MeshNode* n3 = tmp0Delems[ i0D + 0 + iN ]->GetNode( 0 );
+      const SMDS_MeshNode* n4 = tmp0Delems[ i0D + 1 + iN ]->GetNode( 0 );
+      const SMDS_MeshNode* n5 = tmp0Delems[ i0D + 2 + iN ]->GetNode( 0 );
+
+      if ( !n0 || !n1 || !n2 || !n3 || !n4 || !n5 )
+        continue;
+
+      // TIDSortedElemSet emptySet, avoidSet;
+      // if ( !SMESH_MeshAlgos::FindFaceInSet( n0, n1, emptySet, avoidSet))
+      // {
+      //   cout << "WRONG 2nd 1" << endl;
+      //   n0->Print( cout );
+      //   n1->Print( cout );
+      // }
+      // if ( !SMESH_MeshAlgos::FindFaceInSet( n3, n4, emptySet, avoidSet))
+      // {
+      //   cout << "WRONG 2nd 2" << endl;
+      //   n3->Print( cout );
+      //   n4->Print( cout );
+      // }
+
+      if ( !isBordToBord )
+      {
+        n1 = n2; // at border-to-side sewing only last side node (n1) is needed
+        n2 = 0;  //  and n2 is not used
+      }
+      // 1st border moves to 2nd
+      res = getEditor().SewFreeBorder( n3, n4, n5 ,// 1st
+                                       n0 ,n1 ,n2 ,// 2nd
+                                       /*2ndIsFreeBorder=*/ isBordToBord,
+                                       createPolygons, createPolyhedra);
+      groupSewed = ( res == ok );
+
+      isBordToBord = false;
+      // cout << endl << "SEWED GROUP " << i << " PART " << iN / 3 << endl;
+      // for ( size_t t = 0; t < tmp0Delems.size(); ++t )
+      // {
+      //   cout << t << " ";
+      //   if ( t % 3 == 0 ) cout << "^ ";
+      //   tmp0Delems[t]->GetNode(0)->Print( cout );
+      // }
+    }
+    i0D += nodes.size();
+    nbSewed += groupSewed;
+  }
+
+  TPythonDump() << "nbSewed = " << this << ".SewCoincidentFreeBorders( "
+                << freeBorders     << ", "
+                << createPolygons  << ", "
+                << createPolyhedra << " )";
+
+  SMESH_CATCH( SMESH::doNothing );
+
+  declareMeshModified( /*isReComputeSafe=*/false );
+
+  // remove tmp 0D elements
+  SMESH_TRY;
+  set< const SMDS_MeshElement* > removed0D;
+  for ( size_t i = 0; i < tmp0Delems.size(); ++i )
+  {
+    if ( removed0D.insert( tmp0Delems[i] ).second )
+      getMeshDS()->RemoveFreeElement( tmp0Delems[i], /*sm=*/0, /*fromGroups=*/false );
+  }
+  SMESH_CATCH( SMESH::throwCorbaException );
+
+  return nbSewed;
+}
+
 //=======================================================================
 //function : SewFreeBorders
 //purpose  :
@@ -5502,14 +4840,14 @@ SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
 
   SMESH::SMESH_MeshEditor::Sew_Error error =
     convError( getEditor().SewFreeBorder (aBorderFirstNode,
-                                       aBorderSecondNode,
-                                       aBorderLastNode,
-                                       aSide2FirstNode,
-                                       aSide2SecondNode,
-                                       aSide2ThirdNode,
-                                       true,
-                                       CreatePolygons,
-                                       CreatePolyedrs) );
+                                          aBorderSecondNode,
+                                          aBorderLastNode,
+                                          aSide2FirstNode,
+                                          aSide2SecondNode,
+                                          aSide2ThirdNode,
+                                          true,
+                                          CreatePolygons,
+                                          CreatePolyedrs) );
 
 
   declareMeshModified( /*isReComputeSafe=*/false );
@@ -5562,13 +4900,13 @@ SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
 
   SMESH::SMESH_MeshEditor::Sew_Error error =
     convError( getEditor().SewFreeBorder (aBorderFirstNode,
-                                       aBorderSecondNode,
-                                       aBorderLastNode,
-                                       aSide2FirstNode,
-                                       aSide2SecondNode,
-                                       aSide2ThirdNode,
-                                       true,
-                                       false, false) );
+                                          aBorderSecondNode,
+                                          aBorderLastNode,
+                                          aSide2FirstNode,
+                                          aSide2SecondNode,
+                                          aSide2ThirdNode,
+                                          true,
+                                          false, false) );
 
   declareMeshModified( /*isReComputeSafe=*/false );
   return error;
@@ -5624,14 +4962,14 @@ SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
 
   SMESH::SMESH_MeshEditor::Sew_Error error =
     convError( getEditor().SewFreeBorder (aBorderFirstNode,
-                                       aBorderSecondNode,
-                                       aBorderLastNode,
-                                       aSide2FirstNode,
-                                       aSide2SecondNode,
-                                       aSide2ThirdNode,
-                                       false,
-                                       CreatePolygons,
-                                       CreatePolyedrs) );
+                                          aBorderSecondNode,
+                                          aBorderLastNode,
+                                          aSide2FirstNode,
+                                          aSide2SecondNode,
+                                          aSide2ThirdNode,
+                                          false,
+                                          CreatePolygons,
+                                          CreatePolyedrs) );
 
   declareMeshModified( /*isReComputeSafe=*/false );
   return error;
@@ -5754,11 +5092,12 @@ void SMESH_MeshEditor_i::convertToQuadratic(CORBA::Boolean            theForce3d
   throw (SALOME::SALOME_Exception)
 {
   SMESH_TRY;
+  initData();
+
   TIDSortedElemSet elems;
   bool elemsOK;
   if ( !( elemsOK = CORBA::is_nil( theObject )))
   {
-    prepareIdSource( theObject );
     elemsOK =  idSourceToSet( theObject, getMeshDS(), elems,
                               SMDSAbs_All, /*emptyIfIsMesh=*/true );
   }
@@ -5784,10 +5123,16 @@ void SMESH_MeshEditor_i::convertToQuadratic(CORBA::Boolean            theForce3d
 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
   throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
+  initData();
+
   CORBA::Boolean isDone = getEditor().ConvertFromQuadratic();
   TPythonDump() << this << ".ConvertFromQuadratic()";
   declareMeshModified( /*isReComputeSafe=*/!isDone );
   return isDone;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return false;
 }
 
 //=======================================================================
@@ -5840,11 +5185,11 @@ void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr th
   throw (SALOME::SALOME_Exception)
 {
   SMESH_TRY;
+  initData();
 
   TPythonDump pyDump;
 
   TIDSortedElemSet elems;
-  prepareIdSource( theObject );
   if ( idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
   {
     if ( elems.empty() )
@@ -5944,10 +5289,68 @@ void SMESH_MeshEditor_i::prepareIdSource(SMESH::SMESH_IDSource_ptr theObject)
     filter->SetMesh( mesh );
   }
 }
+//================================================================================
+/*!
+ * \brief Retrieve elements of given type from SMESH_IDSource
+ */
+//================================================================================
+
+bool SMESH_MeshEditor_i::idSourceToSet(SMESH::SMESH_IDSource_ptr  theIDSource,
+                                       const SMESHDS_Mesh*        theMeshDS,
+                                       TIDSortedElemSet&          theElemSet,
+                                       const SMDSAbs_ElementType  theType,
+                                       const bool                 emptyIfIsMesh,
+                                       IDSource_Error*            error)
+
+{
+  if ( error ) *error = IDSource_OK;
+
+  if ( CORBA::is_nil( theIDSource ) )
+  {
+    if ( error ) *error = IDSource_INVALID;
+    return false;
+  }
+  if ( emptyIfIsMesh && SMESH::DownCast<SMESH_Mesh_i*>( theIDSource ))
+  {
+    if ( error && getMeshDS()->GetMeshInfo().NbElements( theType ) == 0 )
+      *error = IDSource_EMPTY;
+    return true;
+  }
+  prepareIdSource( theIDSource );
+  SMESH::long_array_var anIDs = theIDSource->GetIDs();
+  if ( anIDs->length() == 0 )
+  {
+    if ( error ) *error = IDSource_EMPTY;
+    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, getMeshDS(), theElemSet, SMDSAbs_Node );
+    }
+    else
+    {
+      if ( error ) *error = IDSource_INVALID;
+      return false;
+    }
+  }
+  else
+  {
+    arrayToSet( anIDs, getMeshDS(), theElemSet, theType);
+    if ( bool(anIDs->length()) != bool(theElemSet.size()))
+    {
+      if ( error ) *error = IDSource_INVALID;
+      return false;
+    }
+  }
+  return true;
+}
 
 //================================================================================
 /*!
- * \brief Duplicates given elements, i.e. creates new elements based on the 
+ * \brief Duplicates given elements, i.e. creates new elements based on the
  *        same nodes as the given ones.
  * \param theElements - container of elements to duplicate.
  * \param theGroupName - a name of group to contain the generated elements.
@@ -5973,7 +5376,6 @@ SMESH_MeshEditor_i::DoubleElements(SMESH::SMESH_IDSource_ptr theElements,
   TPythonDump pyDump;
 
   TIDSortedElemSet elems;
-  prepareIdSource( theElements );
   if ( idSourceToSet( theElements, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true))
   {
     getEditor().DoubleElements( elems );
@@ -7170,7 +6572,6 @@ SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
 
   TIDSortedElemSet elements;
   SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume;
-  prepareIdSource( idSource );
   if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true ))
   {
     // mesh to fill in
@@ -7260,9 +6661,9 @@ CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
     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 groupsOfThisMesh  = new SMESH::ListOfIDSources;
   SMESH::ListOfIDSources_var groupsOfOtherMesh = new SMESH::ListOfIDSources;
-  groupsOfThisMesh->length( groups.length() );
+  groupsOfThisMesh ->length( groups.length() );
   groupsOfOtherMesh->length( groups.length() );
   int nbGroups = 0, nbGroupsOfOtherMesh = 0;
   for ( int i = 0; i < groups.length(); ++i )
index bce7c4c4c4c291ca722a823ed11ea2b0033537f2..3c36508b84597492b031d77762214bdbf76464a6 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -42,9 +42,10 @@ class SMESH_Mesh_i;
 
 namespace MeshEditor_I {
   struct TPreviewMesh;
+  struct ExtrusionParams;
 }
 
-class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor
+class SMESH_I_EXPORT SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor
 {
 public:
   SMESH_MeshEditor_i(SMESH_Mesh_i * theMesh, bool isPreview);
@@ -56,6 +57,8 @@ public:
    */
   int GetMeshId() const { return myMesh->GetId(); }
 
+  SMESH::SMESH_Mesh_ptr GetMesh();
+
   // --- CORBA
 
   /*!
@@ -114,6 +117,8 @@ public:
     throw (SALOME::SALOME_Exception);
   CORBA::Long AddPolygonalFace(const SMESH::long_array & IDsOfNodes)
     throw (SALOME::SALOME_Exception);
+  CORBA::Long AddQuadPolygonalFace(const SMESH::long_array & IDsOfNodes)
+    throw (SALOME::SALOME_Exception);
   CORBA::Long AddVolume(const SMESH::long_array & IDsOfNodes)
     throw (SALOME::SALOME_Exception);
   CORBA::Long AddPolyhedralVolume(const SMESH::long_array & IDsOfNodes,
@@ -216,7 +221,7 @@ public:
                              CORBA::Boolean                 outsideNormal)
     throw (SALOME::SALOME_Exception);
 
-  // Split/Join faces
+  // Split/Join
   CORBA::Boolean TriToQuad       (const SMESH::long_array &   IDsOfElements,
                                   SMESH::NumericalFunctor_ptr Criterion,
                                   CORBA::Double               MaxAngle)
@@ -251,6 +256,8 @@ public:
                                           CORBA::Short               methodFlags,
                                           CORBA::Boolean             allDomains)
     throw (SALOME::SALOME_Exception);
+  void           SplitBiQuadraticIntoLinear(const SMESH::ListOfIDSources& elems)
+    throw (SALOME::SALOME_Exception);
 
   CORBA::Boolean Smooth(const SMESH::long_array &              IDsOfElements,
                         const SMESH::long_array &              IDsOfFixedNodes,
@@ -307,109 +314,59 @@ public:
   void RenumberNodes() throw (SALOME::SALOME_Exception);
   void RenumberElements() throw (SALOME::SALOME_Exception);
 
-  void RotationSweep(const SMESH::long_array & IDsOfElements,
-                     const SMESH::AxisStruct & Axis,
-                     CORBA::Double             AngleInRadians,
-                     CORBA::Long               NbOfSteps,
-                     CORBA::Double             Tolerance)
-    throw (SALOME::SALOME_Exception);
-  void RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject,
-                           const SMESH::AxisStruct & Axis,
-                           CORBA::Double             AngleInRadians,
-                           CORBA::Long               NbOfSteps,
-                           CORBA::Double             Tolerance)
-    throw (SALOME::SALOME_Exception);
-  void RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
-                             const SMESH::AxisStruct & Axis,
-                             CORBA::Double             AngleInRadians,
-                             CORBA::Long               NbOfSteps,
-                             CORBA::Double             Tolerance)
-    throw (SALOME::SALOME_Exception);
-  void RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
-                             const SMESH::AxisStruct & Axis,
-                             CORBA::Double             AngleInRadians,
-                             CORBA::Long               NbOfSteps,
-                             CORBA::Double             Tolerance)
-    throw (SALOME::SALOME_Exception);
-
-  void ExtrusionSweep(const SMESH::long_array & IDsOfElements,
-                      const SMESH::DirStruct &  StepVector,
-                      CORBA::Long               NbOfSteps)
-    throw (SALOME::SALOME_Exception);
-  void ExtrusionSweep0D(const SMESH::long_array & IDsOfElements,
-                      const SMESH::DirStruct &  StepVector,
-                      CORBA::Long               NbOfSteps)
-    throw (SALOME::SALOME_Exception);
-
-  void ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
-                            const SMESH::DirStruct &  StepVector,
-                            CORBA::Long               NbOfSteps)
-    throw (SALOME::SALOME_Exception);
-
-  void ExtrusionSweepObject0D(SMESH::SMESH_IDSource_ptr theObject,
-                              const SMESH::DirStruct &  StepVector,
-                              CORBA::Long               NbOfSteps)
-    throw (SALOME::SALOME_Exception);
-  void ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
-                              const SMESH::DirStruct &  StepVector,
-                              CORBA::Long               NbOfSteps)
-    throw (SALOME::SALOME_Exception);
-  void ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
-                              const SMESH::DirStruct &  StepVector,
-                              CORBA::Long               NbOfSteps)
-    throw (SALOME::SALOME_Exception);
-  void AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
-                         const SMESH::DirStruct &  theStepVector,
-                         CORBA::Long               theNbOfSteps,
-                         CORBA::Long               theExtrFlags,
-                         CORBA::Double             theSewTolerance)
-    throw (SALOME::SALOME_Exception);
-
-  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)
-    throw (SALOME::SALOME_Exception);
-
-  SMESH::SMESH_MeshEditor::Extrusion_Error
-  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)
-    throw (SALOME::SALOME_Exception);
-  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)
-    throw (SALOME::SALOME_Exception);
-  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)
+  SMESH::ListOfGroups* RotationSweepObjects(const SMESH::ListOfIDSources & nodes,
+                                            const SMESH::ListOfIDSources & edges,
+                                            const SMESH::ListOfIDSources & faces,
+                                            const SMESH::AxisStruct &      Axis,
+                                            CORBA::Double                  AngleInRadians,
+                                            CORBA::Long                    NbOfSteps,
+                                            CORBA::Double                  Tolerance,
+                                            CORBA::Boolean                 toMakeGroups)
+    throw (SALOME::SALOME_Exception);
+
+  SMESH::ListOfGroups* ExtrusionSweepObjects(const SMESH::ListOfIDSources & nodes,
+                                             const SMESH::ListOfIDSources & edges,
+                                             const SMESH::ListOfIDSources & faces,
+                                             const SMESH::DirStruct &       stepVector,
+                                             CORBA::Long                    nbOfSteps,
+                                             CORBA::Boolean                 toMakeGroups)
+    throw (SALOME::SALOME_Exception);
+
+  SMESH::ListOfGroups* ExtrusionByNormal(const SMESH::ListOfIDSources& objects,
+                                         CORBA::Double                 stepSize,
+                                         CORBA::Long                   nbOfSteps,
+                                         CORBA::Boolean                byAverageNormal,
+                                         CORBA::Boolean                useInputElemsOnly,
+                                         CORBA::Boolean                makeGroups,
+                                         CORBA::Short                  dim)
+    throw (SALOME::SALOME_Exception);
+  SMESH::ListOfGroups*  AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
+                                          const SMESH::DirStruct &  theStepVector,
+                                          CORBA::Long               theNbOfSteps,
+                                          CORBA::Long               theExtrFlags,
+                                          CORBA::Double             theSewTolerance,
+                                          CORBA::Boolean            theMakeGroups)
+    throw (SALOME::SALOME_Exception);
+
+  SMESH::ListOfGroups*
+    ExtrusionAlongPathObjects(const SMESH::ListOfIDSources & nodes,
+                              const SMESH::ListOfIDSources & edges,
+                              const SMESH::ListOfIDSources & faces,
+                              SMESH::SMESH_IDSource_ptr      PathMesh,
+                              GEOM::GEOM_Object_ptr          PathShape,
+                              CORBA::Long                    NodeStart,
+                              CORBA::Boolean                 HasAngles,
+                              const SMESH::double_array &    Angles,
+                              CORBA::Boolean                 LinearVariation,
+                              CORBA::Boolean                 HasRefPoint,
+                              const SMESH::PointStruct &     RefPoint,
+                              bool                           MakeGroups,
+                              SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
     throw (SALOME::SALOME_Exception);
 
   SMESH::double_array* LinearAnglesVariation(SMESH::SMESH_Mesh_ptr       PathMesh,
-                                             GEOM::GEOM_Object_ptr       PathShape,
-                                             const SMESH::double_array & Angles);
+                                               GEOM::GEOM_Object_ptr       PathShape,
+                                               const SMESH::double_array & Angles);
 
   void Mirror(const SMESH::long_array &           IDsOfElements,
               const SMESH::AxisStruct &           Axis,
@@ -440,128 +397,6 @@ public:
                     CORBA::Boolean             Copy)
     throw (SALOME::SALOME_Exception);
 
-  SMESH::ListOfGroups* RotationSweepMakeGroups(const SMESH::long_array& IDsOfElements,
-                                               const SMESH::AxisStruct& Axix,
-                                               CORBA::Double            AngleInRadians,
-                                               CORBA::Long              NbOfSteps,
-                                               CORBA::Double            Tolerance)
-    throw (SALOME::SALOME_Exception);
-  SMESH::ListOfGroups* RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr Object,
-                                                     const SMESH::AxisStruct&  Axix,
-                                                     CORBA::Double             AngleInRadians,
-                                                     CORBA::Long               NbOfSteps,
-                                                     CORBA::Double             Tolerance)
-    throw (SALOME::SALOME_Exception);
-  SMESH::ListOfGroups* RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr Object,
-                                                       const SMESH::AxisStruct&  Axix,
-                                                       CORBA::Double             AngleInRadians,
-                                                       CORBA::Long               NbOfSteps,
-                                                       CORBA::Double             Tolerance)
-    throw (SALOME::SALOME_Exception);
-  SMESH::ListOfGroups* RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr Object,
-                                                       const SMESH::AxisStruct&  Axix,
-                                                       CORBA::Double             AngleInRadians,
-                                                       CORBA::Long               NbOfSteps,
-                                                       CORBA::Double             Tolerance)
-    throw (SALOME::SALOME_Exception);
-  SMESH::ListOfGroups* ExtrusionSweepMakeGroups(const SMESH::long_array& IDsOfElements,
-                                                const SMESH::DirStruct&  StepVector,
-                                                CORBA::Long              NbOfSteps)
-    throw (SALOME::SALOME_Exception);
-  SMESH::ListOfGroups* ExtrusionSweepMakeGroups0D(const SMESH::long_array& IDsOfElements,
-                                                const SMESH::DirStruct&  StepVector,
-                                                CORBA::Long              NbOfSteps)
-    throw (SALOME::SALOME_Exception);
-
-  SMESH::ListOfGroups* AdvancedExtrusionMakeGroups(const SMESH::long_array& IDsOfElements,
-                                                   const SMESH::DirStruct&  StepVector,
-                                                   CORBA::Long              NbOfSteps,
-                                                   CORBA::Long              ExtrFlags,
-                                                   CORBA::Double            SewTolerance)
-    throw (SALOME::SALOME_Exception);
-  SMESH::ListOfGroups* ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr Object,
-                                                      const SMESH::DirStruct&   StepVector,
-                                                      CORBA::Long               NbOfSteps)
-    throw (SALOME::SALOME_Exception);
-  SMESH::ListOfGroups* ExtrusionSweepObject0DMakeGroups(SMESH::SMESH_IDSource_ptr Object,
-                                                        const SMESH::DirStruct&   StepVector,
-                                                        CORBA::Long               NbOfSteps)
-    throw (SALOME::SALOME_Exception);
-  SMESH::ListOfGroups* ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr Object,
-                                                        const SMESH::DirStruct&   StepVector,
-                                                        CORBA::Long               NbOfSteps)
-    throw (SALOME::SALOME_Exception);
-  SMESH::ListOfGroups* ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr Object,
-                                                        const SMESH::DirStruct&   StepVector,
-                                                        CORBA::Long               NbOfSteps)
-    throw (SALOME::SALOME_Exception);
-  SMESH::ListOfGroups* ExtrusionAlongPathMakeGroups(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& Error)
-    throw (SALOME::SALOME_Exception);
-  SMESH::ListOfGroups* ExtrusionAlongPathObjectMakeGroups(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)
-    throw (SALOME::SALOME_Exception);
-  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)
-    throw (SALOME::SALOME_Exception);
-  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)
-    throw (SALOME::SALOME_Exception);
-
-  // 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)
-    throw (SALOME::SALOME_Exception);
-  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)
-    throw (SALOME::SALOME_Exception);
-
   SMESH::ListOfGroups* MirrorMakeGroups(const SMESH::long_array&            IDsOfElements,
                                         const SMESH::AxisStruct&            Mirror,
                                         SMESH::SMESH_MeshEditor::MirrorType MirrorType)
@@ -639,18 +474,22 @@ public:
     throw (SALOME::SALOME_Exception);
 
   void FindCoincidentNodes (CORBA::Double                  Tolerance,
-                            SMESH::array_of_long_array_out GroupsOfNodes)
+                            SMESH::array_of_long_array_out GroupsOfNodes,
+                            CORBA::Boolean                 SeparateCornersAndMedium)
     throw (SALOME::SALOME_Exception);
   void FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr      Object,
                                  CORBA::Double                  Tolerance,
-                                 SMESH::array_of_long_array_out GroupsOfNodes)
+                                 SMESH::array_of_long_array_out GroupsOfNodes,
+                                 CORBA::Boolean                 SeparateCornersAndMedium)
     throw (SALOME::SALOME_Exception);
   void FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr      Object,
                                     CORBA::Double                  Tolerance,
                                     SMESH::array_of_long_array_out GroupsOfNodes,
-                                    const SMESH::ListOfIDSources&  ExceptSubMeshOrGroups)
+                                    const SMESH::ListOfIDSources&  ExceptSubMeshOrGroups,
+                                    CORBA::Boolean                 SeparateCornersAndMedium)
     throw (SALOME::SALOME_Exception);
-  void MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
+  void MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes,
+                   const SMESH::ListOfIDSources&     NodesToKeep )
     throw (SALOME::SALOME_Exception);
   void FindEqualElements(SMESH::SMESH_IDSource_ptr      Object,
                          SMESH::array_of_long_array_out GroupsOfElementsID)
@@ -699,6 +538,12 @@ public:
   CORBA::Short GetPointState(CORBA::Double x, CORBA::Double y, CORBA::Double z)
     throw (SALOME::SALOME_Exception);
 
+  SMESH::CoincidentFreeBorders* FindCoincidentFreeBorders(CORBA::Double tolerance);
+  CORBA::Short SewCoincidentFreeBorders(const SMESH::CoincidentFreeBorders& freeBorders,
+                                        CORBA::Boolean                      createPolygons,
+                                        CORBA::Boolean                      createPolyedrs)
+    throw (SALOME::SALOME_Exception);
+
   SMESH::SMESH_MeshEditor::Sew_Error
   SewFreeBorders(CORBA::Long FirstNodeID1,
                  CORBA::Long SecondNodeID1,
@@ -707,15 +552,13 @@ public:
                  CORBA::Long SecondNodeID2,
                  CORBA::Long LastNodeID2,
                  CORBA::Boolean CreatePolygons,
-                 CORBA::Boolean CreatePolyedrs)
-    throw (SALOME::SALOME_Exception);
+                 CORBA::Boolean CreatePolyedrs) throw (SALOME::SALOME_Exception);
   SMESH::SMESH_MeshEditor::Sew_Error
   SewConformFreeBorders(CORBA::Long FirstNodeID1,
                         CORBA::Long SecondNodeID1,
                         CORBA::Long LastNodeID1,
                         CORBA::Long FirstNodeID2,
-                        CORBA::Long SecondNodeID2)
-    throw (SALOME::SALOME_Exception);
+                        CORBA::Long SecondNodeID2) throw (SALOME::SALOME_Exception);
   SMESH::SMESH_MeshEditor::Sew_Error
   SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
                   CORBA::Long SecondNodeIDOnFreeBorder,
@@ -723,16 +566,14 @@ public:
                   CORBA::Long FirstNodeIDOnSide,
                   CORBA::Long LastNodeIDOnSide,
                   CORBA::Boolean CreatePolygons,
-                  CORBA::Boolean CreatePolyedrs)
-    throw (SALOME::SALOME_Exception);
+                  CORBA::Boolean CreatePolyedrs) throw (SALOME::SALOME_Exception);
   SMESH::SMESH_MeshEditor::Sew_Error
   SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
                   const SMESH::long_array& IDsOfSide2Elements,
                   CORBA::Long NodeID1OfSide1ToMerge,
                   CORBA::Long NodeID1OfSide2ToMerge,
                   CORBA::Long NodeID2OfSide1ToMerge,
-                  CORBA::Long NodeID2OfSide2ToMerge)
-    throw (SALOME::SALOME_Exception);
+                  CORBA::Long NodeID2OfSide2ToMerge) throw (SALOME::SALOME_Exception);
 
   /*!
    * Set new nodes for given element.
@@ -1017,51 +858,6 @@ private: //!< private methods
   SMESH::ListOfGroups* getGroups(const std::list<int>* groupIDs)
     throw (SALOME::SALOME_Exception);
 
-  SMESH::ListOfGroups* rotationSweep(const SMESH::long_array & IDsOfElements,
-                                     const SMESH::AxisStruct & Axis,
-                                     CORBA::Double             AngleInRadians,
-                                     CORBA::Long               NbOfSteps,
-                                     CORBA::Double             Tolerance,
-                                     const bool                MakeGroups,
-                                     const SMDSAbs_ElementType ElementType=SMDSAbs_All)
-    throw (SALOME::SALOME_Exception);
-  SMESH::ListOfGroups* extrusionSweep(const SMESH::long_array & IDsOfElements,
-                                      const SMESH::DirStruct &  StepVector,
-                                      CORBA::Long               NbOfSteps,
-                                      bool                      MakeGroups,
-                                      const SMDSAbs_ElementType ElementType=SMDSAbs_All)
-    throw (SALOME::SALOME_Exception);
-  SMESH::ListOfGroups* advancedExtrusion(const SMESH::long_array & theIDsOfElements,
-                                         const SMESH::DirStruct &  theStepVector,
-                                         CORBA::Long               theNbOfSteps,
-                                         CORBA::Long               theExtrFlags,
-                                         CORBA::Double             theSewTolerance,
-                                         const bool                MakeGroups)
-    throw (SALOME::SALOME_Exception);
-  SMESH::ListOfGroups* 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,
-                                          const bool                  MakeGroups,
-                                          SMESH::SMESH_MeshEditor::Extrusion_Error & Error,
-                                          const SMDSAbs_ElementType   ElementType=SMDSAbs_All)
-    throw (SALOME::SALOME_Exception);
-  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)
-    throw (SALOME::SALOME_Exception);
   SMESH::ListOfGroups* mirror(TIDSortedElemSet &                  IDsOfElements,
                               const SMESH::AxisStruct &           Axis,
                               SMESH::SMESH_MeshEditor::MirrorType MirrorType,
@@ -1098,14 +894,31 @@ private: //!< private methods
 
   SMESH::SMESH_Mesh_ptr makeMesh(const char* theMeshName);
 
-  void dumpGroupsList(SMESH::TPythonDump & theDumpPython, 
+  void dumpGroupsList(SMESH::TPythonDump &        theDumpPython,
                       const SMESH::ListOfGroups * theGroupList);
 
   string generateGroupName(const string& thePrefix);
 
   void prepareIdSource(SMESH::SMESH_IDSource_ptr theObject);
 
-private: //!< fields
+
+  enum IDSource_Error { IDSource_OK, IDSource_INVALID, IDSource_EMPTY };
+
+  bool idSourceToSet(SMESH::SMESH_IDSource_ptr  theIDSource,
+                     const SMESHDS_Mesh*        theMeshDS,
+                     TIDSortedElemSet&          theElemSet,
+                     const SMDSAbs_ElementType  theType,
+                     const bool                 emptyIfIsMesh = false,
+                     IDSource_Error*            error = 0);
+
+  void findCoincidentNodes( TIDSortedNodeSet &             Nodes,
+                            CORBA::Double                  Tolerance,
+                            SMESH::array_of_long_array_out GroupsOfNodes,
+                            CORBA::Boolean                 SeparateCornersAndMedium);
+
+
+
+ private: //!< fields
 
   SMESH_Mesh_i*                myMesh_i;
   SMESH_Mesh *                 myMesh;
index f58249f2ef8ef9f954c7d7972ea5ef19fdf8936d..52a6ff400858da5903f9d98df7e720a04457d613 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index a5ed1ac3cc05f09eda82048861185dcef174f648..728a75ddb8ee179295e70d97e17a5fff2a4e54ff 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -79,6 +79,8 @@
 #include <iostream>
 #include <sstream>
 
+#include <vtkUnstructuredGridWriter.h>
+
 // to pass CORBA exception through SMESH_TRY
 #define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; }
 
@@ -103,7 +105,7 @@ int SMESH_Mesh_i::_idGenerator = 0;
 
 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
                             SMESH_Gen_i*            gen_i,
-                            CORBA::Long studyId )
+                            CORBA::Long             studyId )
 : SALOME::GenericObj_i( thePOA )
 {
   MESSAGE("SMESH_Mesh_i");
@@ -159,6 +161,11 @@ SMESH_Mesh_i::~SMESH_Mesh_i()
   }
   _mapHypo.clear();
 
+  // clear cashed shapes if no more meshes remain; (the cash is blame,
+  // together with publishing, of spent time increasing in issue 22874)
+  if ( _impl->NbMeshes() == 1 )
+    _gen_i->GetShapeReader()->ClearClientBuffer();
+
   delete _editor; _editor = NULL;
   delete _previewEditor; _previewEditor = NULL;
   delete _impl; _impl = NULL;
@@ -225,7 +232,25 @@ GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
   try {
     TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
     if ( !S.IsNull() )
+    {
       aShapeObj = _gen_i->ShapeToGeomObject( S );
+      if ( aShapeObj->_is_nil() )
+      {
+        // S was removed from GEOM_Client by newGroupShape() called by other mesh;
+        // find GEOM_Object by entry (IPAL52735)
+        list<TGeomGroupData>::iterator data = _geomGroupData.begin();
+        for ( ; data != _geomGroupData.end(); ++data )
+          if ( data->_smeshObject->_is_equivalent( _this() ))
+          {
+            SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
+            if ( study->_is_nil() ) break;
+            SALOMEDS::SObject_wrap so = study->FindObjectID( data->_groupEntry.c_str() );
+            CORBA::Object_var     obj = _gen_i->SObjectToObject( so );
+            aShapeObj = GEOM::GEOM_Object::_narrow( obj );
+            break;
+          }
+      }
+    }
   }
   catch(SALOME_Exception & S_ex) {
     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
@@ -1050,6 +1075,7 @@ void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
       builder->RemoveObjectWithChildren( aGroupSO );
     }
   }
+  aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
 
   // Remove the group from SMESH data structures
   removeGroup( aGroup->GetLocalID() );
@@ -1073,11 +1099,35 @@ void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup
   if ( theGroup->_is_nil() )
     return;
 
+  vector<int> nodeIds; // to remove nodes becoming free
+  if ( !theGroup->IsEmpty() )
+  {
+    CORBA::Long elemID = theGroup->GetID( 1 );
+    int nbElemNodes = GetElemNbNodes( elemID );
+    if ( nbElemNodes > 0 )
+      nodeIds.reserve( theGroup->Size() * nbElemNodes );
+  }
+
   // Remove contents
   SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
   SMDS_ElemIteratorPtr     elemIt = GetElements( idSrc, theGroup->GetType() );
   while ( elemIt->more() )
-    _impl->GetMeshDS()->RemoveElement( elemIt->next() );
+  {
+    const SMDS_MeshElement* e = elemIt->next();
+
+    SMDS_ElemIteratorPtr nIt = e->nodesIterator();
+    while ( nIt->more() )
+      nodeIds.push_back( nIt->next()->GetID() );
+
+    _impl->GetMeshDS()->RemoveElement( e );
+  }
+
+  // Remove free nodes
+  if ( theGroup->GetType() != SMESH::NODE )
+    for ( size_t i = 0 ; i < nodeIds.size(); ++i )
+      if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
+        if ( n->NbInverseElements() == 0 )
+          _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
 
   TPythonDump pyDump; // Supress dump from RemoveGroup()
 
@@ -1561,25 +1611,52 @@ SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
   return aResGrp._retn();
 }
 
+namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
+{
+  bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
+                        bool & toStopChecking )
+  {
+    toStopChecking = ( nbCommon < nbChecked );
+    return nbCommon == nbNodes;
+  }
+  bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
+                         bool & toStopChecking )
+  {
+    toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
+    return nbCommon == nbCorners;
+  }
+  bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
+                              bool & toStopChecking )
+  {
+    return nbCommon > 0;
+  }
+  bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
+                               bool & toStopChecking )
+  {
+    return nbCommon >= (nbNodes+1) / 2;
+  }
+}
+
 //=============================================================================
 /*!
-  \brief Create groups of entities from existing groups of superior dimensions 
-  System
-  1) extract all nodes from each group,
-  2) combine all elements of specified dimension laying on these nodes.
-  \param theGroups list of source groups 
-  \param theElemType dimension of elements 
-  \param theName name of new group
-  \return pointer on new group
-  *
-  IMP 19939
+ * Create a group of entities basing on nodes of other groups.
+ *  \param [in] theGroups - list of either groups, sub-meshes or filters.
+ *  \param [in] anElemType - a type of elements to include to the new group.
+ *  \param [in] theName - a name of the new group.
+ *  \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
+ *  \param [in] theUnderlyingOnly - if \c True, an element is included to the
+ *         new group provided that it is based on nodes of an element of \a aListOfGroups
+ *  \return SMESH_Group - the created group
 */
+// IMP 19939, bug 22010, IMP 22635
 //=============================================================================
 
 SMESH::SMESH_Group_ptr
-SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups, 
-                             SMESH::ElementType         theElemType, 
-                             const char*                theName )
+SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
+                             SMESH::ElementType            theElemType,
+                             const char*                   theName,
+                             SMESH::NB_COMMON_NODES_ENUM   theNbCommonNodes,
+                             CORBA::Boolean                theUnderlyingOnly)
   throw (SALOME::SALOME_Exception)
 {
   SMESH::SMESH_Group_var aResGrp;
@@ -1595,6 +1672,17 @@ SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups,
 
   SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
 
+  bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
+  SMESH_Comment nbCoNoStr( "SMESH.");
+  switch ( theNbCommonNodes ) {
+  case SMESH::ALL_NODES   : isToInclude = isAllNodesCommon;        nbCoNoStr<<"ALL_NODES"   ;break;
+  case SMESH::MAIN        : isToInclude = isMainNodesCommon;       nbCoNoStr<<"MAIN"        ;break;
+  case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon;  nbCoNoStr<<"AT_LEAST_ONE";break;
+  case SMESH::MAJORITY    : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY"    ;break;
+  default: return aResGrp._retn();
+  }
+  int nbChecked, nbCommon, nbNodes, nbCorners;
+
   // Create a group
 
   TPythonDump pyDump;
@@ -1607,14 +1695,19 @@ SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups,
     SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
   SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
 
+  vector<bool> isNodeInGroups;
+
   for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
   {
-    SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
+    SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
     if ( CORBA::is_nil( aGrp ) )
       continue;
+    SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
+    if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
+      continue;
 
-    groupBaseDS = SMESH::DownCast<SMESH_GroupBase_i*>( aGrp )->GetGroupDS();
-    SMDS_ElemIteratorPtr elIt = groupBaseDS->GetElements();
+    SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
+    if ( !elIt ) continue;
 
     if ( theElemType == SMESH::NODE ) // get all nodes of elements
     {
@@ -1625,30 +1718,93 @@ SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups,
           resGroupCore.Add( nIt->next() );
       }
     }
-    else // get elements of theElemType based on nodes of every element of group
+    // get elements of theElemType based on nodes of every element of group
+    else if ( theUnderlyingOnly )
     {
       while ( elIt->more() )
       {
-        const SMDS_MeshElement* el = elIt->next(); // an element of group
+        const SMDS_MeshElement* el = elIt->next(); // an element of ref group
         TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
         TIDSortedElemSet checkedElems;
-        SMDS_ElemIteratorPtr nIt = el->nodesIterator();
+        SMDS_NodeIteratorPtr nIt = el->nodeIterator();
         while ( nIt->more() )
         {
-          const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nIt->next() );
+          const SMDS_MeshNode* n = nIt->next();
           SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
           // check nodes of elements of theElemType around el
           while ( elOfTypeIt->more() )
           {
             const SMDS_MeshElement* elOfType = elOfTypeIt->next();
             if ( !checkedElems.insert( elOfType ).second ) continue;
-
+            nbNodes   = elOfType->NbNodes();
+            nbCorners = elOfType->NbCornerNodes();
+            nbCommon  = 0;
+            bool toStopChecking = false;
             SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
-            bool allNodesOK = true;
-            while ( nIt2->more() && allNodesOK )
-              allNodesOK = elNodes.count( nIt2->next() );
-            if ( allNodesOK )
-              resGroupCore.Add( elOfType );
+            for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
+              if ( elNodes.count( nIt2->next() ) &&
+                   isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
+              {
+                resGroupCore.Add( elOfType );
+                break;
+              }
+          }
+        }
+      }
+    }
+    // get all nodes of elements of groups
+    else
+    {
+      while ( elIt->more() )
+      {
+        const SMDS_MeshElement* el = elIt->next(); // an element of group
+        SMDS_NodeIteratorPtr nIt = el->nodeIterator();
+        while ( nIt->more() )
+        {
+          const SMDS_MeshNode* n = nIt->next();
+          if ( n->GetID() >= (int) isNodeInGroups.size() )
+            isNodeInGroups.resize( n->GetID() + 1, false );
+          isNodeInGroups[ n->GetID() ] = true;
+        }
+      }
+    }
+  }
+
+  // Get elements of theElemType based on a certain number of nodes of elements of groups
+  if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
+  {
+    const SMDS_MeshNode* n;
+    vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
+    const int isNodeInGroupsSize = isNodeInGroups.size();
+    for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
+    {
+      if ( !isNodeInGroups[ iN ] ||
+           !( n = aMeshDS->FindNode( iN )))
+        continue;
+
+      // check nodes of elements of theElemType around n
+      SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
+      while ( elOfTypeIt->more() )
+      {
+        const SMDS_MeshElement*  elOfType = elOfTypeIt->next();
+        vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
+        if ( isChecked )
+          continue;
+        isChecked = true;
+
+        nbNodes   = elOfType->NbNodes();
+        nbCorners = elOfType->NbCornerNodes();
+        nbCommon  = 0;
+        bool toStopChecking = false;
+        SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
+        for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
+        {
+          const int nID = nIt->next()->GetID();
+          if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
+               isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
+          {
+            resGroupCore.Add( elOfType );
+            break;
           }
         }
       }
@@ -1658,7 +1814,8 @@ SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups,
   // Update Python script
   pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
          << ".CreateDimGroup( "
-         << theGroups << ", " << theElemType << ", '" << theName << "' )";
+         << theGroups << ", " << theElemType << ", '" << theName << "', "
+         << nbCoNoStr << ", " << theUnderlyingOnly << ")";
 
   SMESH_CATCH( SMESH::throwCorbaException );
 
@@ -1694,7 +1851,7 @@ void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
   CORBA::String_var entry = groupSO->GetID();
   groupData._groupEntry = entry.in();
   // indices
-  for ( int i = 0; i < ids->length(); ++i )
+  for ( CORBA::ULong i = 0; i < ids->length(); ++i )
     groupData._indices.insert( ids[i] );
   // SMESH object
   groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
@@ -1747,7 +1904,7 @@ TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
     GEOM::GEOM_IGroupOperations_wrap groupOp =
       geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
     GEOM::ListOfLong_var   ids = groupOp->GetObjects( geomGroup );
-    for ( int i = 0; i < ids->length(); ++i )
+    for ( CORBA::ULong i = 0; i < ids->length(); ++i )
       curIndices.insert( ids[i] );
 
     if ( groupData._indices == curIndices )
@@ -1814,15 +1971,21 @@ void SMESH_Mesh_i::CheckGeomModif()
   if ( study->_is_nil() ) return;
 
   GEOM::GEOM_Object_var mainGO = _gen_i->ShapeToGeomObject( _impl->GetShapeToMesh() );
-  if ( mainGO->_is_nil() ) return;
+  //if ( mainGO->_is_nil() ) return;
+
+  // Update after group modification
 
-  if ( mainGO->GetType() == GEOM_GROUP ||
+  if ( mainGO->_is_nil() || /* shape was removed from GEOM_Client by newGroupShape()
+                               called by other mesh (IPAL52735) */
+       mainGO->GetType() == GEOM_GROUP ||
        mainGO->GetTick() == _mainShapeTick )
   {
     CheckGeomGroupModif();
     return;
   }
 
+  // Update after shape transformation like Translate
+
   GEOM_Client* geomClient = _gen_i->GetShapeReader();
   if ( !geomClient ) return;
   GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
@@ -2100,9 +2263,11 @@ void SMESH_Mesh_i::CheckGeomGroupModif()
           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
+      // set new shape to mesh -> DS of sub-meshes and geom groups are deleted
+      _impl->Clear();
+      _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
       _impl->ShapeToMesh( newShape );
-      
+
       // reassign hypotheses
       TShapeHypList::iterator indS_hyps = assignedHyps.begin();
       for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
@@ -2119,7 +2284,7 @@ void SMESH_Mesh_i::CheckGeomGroupModif()
           continue;
         for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
           _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
-        // care of submeshes
+        // care of sub-meshes
         SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
         if ( newID != oldID ) {
           _mapSubMesh   [ newID ] = newSubmesh;
@@ -3233,7 +3398,7 @@ void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field&        fieldWriter,
         {
           const SMDS_MeshElement* e = elemIt->next();
           const int shapeID = e->getshapeId();
-          if ( shapeID < 1 || shapeID >= dblVals.size() )
+          if ( shapeID < 1 || shapeID >= (int) dblVals.size() )
             fieldWriter.AddValue( noneDblValue );
           else
             fieldWriter.AddValue( dblVals[ shapeID ]);
@@ -3243,7 +3408,7 @@ void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field&        fieldWriter,
         {
           const SMDS_MeshElement* e = elemIt->next();
           const int shapeID = e->getshapeId();
-          if ( shapeID < 1 || shapeID >= intVals.size() )
+          if ( shapeID < 1 || shapeID >= (int) intVals.size() )
             fieldWriter.AddValue( (double) noneIntValue );
           else
             fieldWriter.AddValue( (double) intVals[ shapeID ]);
@@ -3438,8 +3603,16 @@ void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
 
   PrepareForWriting(file,overwrite);
 
+  std::string meshName("");
+  SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
+  SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( study, meshPart );
+  if ( !so->_is_nil() )
+  {
+    CORBA::String_var name = so->GetName();
+    meshName = name.in();
+  }
   SMESH_MeshPartDS partDS( meshPart );
-  _impl->ExportCGNS(file, &partDS);
+  _impl->ExportCGNS(file, &partDS, meshName.c_str() );
 
   TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
                 << meshPart<< ", r'" << file << "', " << overwrite << ")";
@@ -3592,7 +3765,7 @@ CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
   return _impl->NbBiQuadQuadrangles();
 }
 
-CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
+CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
   if ( _preMeshInfo )
@@ -3601,6 +3774,15 @@ CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
   return _impl->NbPolygons();
 }
 
+CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
+
+  return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
+}
+
 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
   throw(SALOME::SALOME_Exception)
 {
@@ -4491,7 +4673,7 @@ SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long  elemId,
       {
         aResult->length( vtool.NbFaceNodes( faceIndex ));
         const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
-        for ( int i = 0; i < aResult->length(); ++i )
+        for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
           aResult[ i ] = nn[ i ]->GetID();
       }
     }
@@ -4540,7 +4722,7 @@ CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
   if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
   {
     vector< const SMDS_MeshNode * > nn( nodes.length() );
-    for ( int i = 0; i < nodes.length(); ++i )
+    for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
       if ( !( nn[i] = mesh->FindNode( nodes[i] )))
         return elemID;
 
@@ -4678,6 +4860,7 @@ SMESH_Mesh_i::MakeGroupsOfBadInputElements( int         theSubShapeID,
     THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
 
   SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
+  ::SMESH_MeshEditor::ElemFeatures elemType;
 
   // submesh by subshape id
   if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
@@ -4710,7 +4893,7 @@ SMESH_Mesh_i::MakeGroupsOfBadInputElements( int         theSubShapeID,
           if ( elem )
           {
             ::SMESH_MeshEditor editor( _impl );
-            elem = editor.AddElement( nodes, elem->GetType(), elem->IsPoly() );
+            elem = editor.AddElement( nodes, elemType.Init( elem ));
           }
         }
         if ( elem )
@@ -4737,7 +4920,6 @@ SMESH_Mesh_i::MakeGroupsOfBadInputElements( int         theSubShapeID,
           SALOMEDS::SObject_wrap aSO =
             _gen_i->PublishGroup( study, mesh, groups[ iG ],
                                  GEOM::GEOM_Object::_nil(), theGroupName);
-          aSO->_is_nil(); // avoid "unused variable" warning
         }
         SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
         if ( !grp_i ) continue;
@@ -4929,11 +5111,11 @@ SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
     SALOMEDS::Study_var    aStudy = gen->GetCurrentStudy();
     if ( !aStudy->_is_nil()) {
       SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters); 
-      if(aSections->length() > 0) {
-        SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
-        aResult->length(aVars.length());
-        for(int i = 0;i < aVars.length();i++)
-          aResult[i] = CORBA::string_dup( aVars[i]);
+      if ( aSections->length() > 0 ) {
+        SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
+        aResult->length( aVars.length() );
+        for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
+          aResult[i] = CORBA::string_dup( aVars[i] );
       }
     }
   }
@@ -4959,6 +5141,8 @@ SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
   if (_impl->NbVolumes())    types[nbTypes++] = SMESH::VOLUME;
   if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
   if (_impl->NbBalls())      types[nbTypes++] = SMESH::BALL;
+  if (_impl->NbNodes() &&
+      nbTypes == 0 )         types[nbTypes++] = SMESH::NODE;
   types->length( nbTypes );
 
   return types._retn();
@@ -5048,6 +5232,37 @@ void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
   while (theItr->more())
     theInfo[ theItr->next()->GetEntityType() ]++;
 }
+//=============================================================================
+/*
+ * Returns mesh unstructed grid information.
+ */
+//=============================================================================
+
+SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
+{
+  SALOMEDS::TMPFile_var SeqFile;
+  if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
+    SMDS_UnstructuredGrid* aGrid = aMeshDS->getGrid();
+    if(aGrid) {
+      vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
+      aWriter->WriteToOutputStringOn();
+      aWriter->SetInputData(aGrid);
+      aWriter->SetFileTypeToBinary();
+      aWriter->Write();
+      char* str = aWriter->GetOutputString();
+      int size = aWriter->GetOutputStringLength();
+      
+      //Allocate octect buffer of required size
+      CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
+      //Copy ostrstream content to the octect buffer
+      memcpy(OctetBuf, str, size);
+      //Create and return TMPFile
+      SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
+      aWriter->Delete();
+    }
+  }
+  return SeqFile._retn();
+}
 
 //=============================================================================
 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
@@ -5131,7 +5346,7 @@ namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_v
           _elem = _mesh->FindNode( *_idPtr++ );
         }
         else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
-                 _elem->GetType() != _type )
+                 (_elem->GetType() != _type && _type != SMDSAbs_All ))
         {
           _elem = 0;
         }
@@ -5192,7 +5407,7 @@ SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObje
                                                SMESH::ElementType        theType)
 {
   SMDS_ElemIteratorPtr  elemIt;
-  bool                  typeOK = false;
+  bool                  typeOK = ( theType == SMESH::ALL );
   SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
 
   SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
@@ -5211,7 +5426,7 @@ SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObje
     if ( sm )
     {
       elemIt = sm->GetElements();
-      if ( elemType != SMDSAbs_Node )
+      if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
       {
         typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
         elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
@@ -5221,15 +5436,19 @@ SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObje
   else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
   {
     SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
-    if ( groupDS && ( groupDS->GetType() == elemType || elemType == SMDSAbs_Node ))
+    if ( groupDS && ( elemType == groupDS->GetType()  ||
+                      elemType == SMDSAbs_Node ||
+                      elemType == SMDSAbs_All ))
     {
       elemIt = groupDS->GetElements();
-      typeOK = ( groupDS->GetType() == elemType );
+      typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
     }
   }
   else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
   {
-    if ( filter_i->GetElementType() == theType || elemType == SMDSAbs_Node )
+    if ( filter_i->GetElementType() == theType ||
+         elemType == SMDSAbs_Node ||
+         elemType == SMDSAbs_All)
     {
       SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
       if ( pred_i && pred_i->GetPredicate() )
@@ -5237,7 +5456,7 @@ SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObje
         SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
         SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
         elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
-        typeOK = ( filterType == elemType );
+        typeOK = ( filterType == elemType || elemType == SMDSAbs_All );
       }
     }
   }
@@ -5245,7 +5464,7 @@ SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObje
   {
     SMESH::array_of_ElementType_var types = theObject->GetTypes();
     const bool                    isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
-    if ( isNodes && elemType != SMDSAbs_Node )
+    if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
       return elemIt;
     if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
     {
@@ -5258,7 +5477,7 @@ SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObje
       SMESH::long_array_var ids = theObject->GetIDs();
       elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
     }
-    typeOK = ( isNodes == ( elemType == SMDSAbs_Node ));
+    typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
   }
 
   if ( elemIt && elemIt->more() && !typeOK )
@@ -5418,7 +5637,7 @@ class SMESH_DimHyp
       if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
         nbSame++;
     // the submeshes are concurrent if their algorithms has different parameters
-    return nbSame != theOther->_hypotheses.size() - 1;
+    return nbSame != (int)theOther->_hypotheses.size() - 1;
   }
 
   // Return true if algorithm of this SMESH_DimHyp is used if no
@@ -5851,14 +6070,14 @@ SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
     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]))
+      for ( CORBA::ULong 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++)
+      for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
         if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
           if ( _elements[ e->GetType() ].insert( e ).second )
           {
@@ -5874,6 +6093,8 @@ SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
     }
     myInfo = tmpInfo;
 
+    ShapeToMesh( _meshDS->ShapeToMesh() );
+
     _meshDS = 0; // to enforce iteration on _elements and _nodes
   }
 }
index e4c1b634a93defe52ba8eaf37db6d731178ff546..2a67fd8a78815d20cf2a99bc68f6e15fb824267e 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -160,9 +160,11 @@ public:
                                           const char* theName )
     throw (SALOME::SALOME_Exception);
 
-  SMESH::SMESH_Group_ptr CreateDimGroup( const SMESH::ListOfGroups& theGroups,
-                                         SMESH::ElementType theElemType,
-                                         const char* theName )
+  SMESH::SMESH_Group_ptr CreateDimGroup( const SMESH::ListOfIDSources& theGroups,
+                                         SMESH::ElementType            theElemType,
+                                         const char*                   theName,
+                                         SMESH::NB_COMMON_NODES_ENUM   theNbCommonNodes,
+                                         CORBA::Boolean                theUnderlyingOnly )
     throw (SALOME::SALOME_Exception);
 
 
@@ -316,6 +318,9 @@ public:
   CORBA::Long NbPolygons()
     throw (SALOME::SALOME_Exception);
 
+  CORBA::Long NbPolygonsOfOrder(SMESH::ElementOrder order=SMESH::ORDER_ANY)
+    throw (SALOME::SALOME_Exception);
+
   CORBA::Long NbVolumes()
     throw (SALOME::SALOME_Exception);
 
@@ -650,6 +655,10 @@ public:
    * happen if mesh data is not yet fully loaded from the file of study.
    */
   bool IsMeshInfoCorrect();
+   /*!
+    * Returns mesh unstructed grid information.
+    */
+   virtual SALOMEDS::TMPFile* GetVtkUgStream();
 
   std::map<int, SMESH_subMesh_i*> _mapSubMesh_i; //NRI
   std::map<int, ::SMESH_subMesh*> _mapSubMesh;   //NRI
index 800df2eceb47810bd5f85e8cbd933b8e4c663094..943a1b76738ae4c9d42e335936b3a649a0f27322 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index 12491c5bebc1213a0c22d808126ae43d1899ece9..1d93cf8e0b2d9e6b7942a007d4a455c82d7a7914 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index 8a90fb7655de3e76a1fbba55d1536581a56729ec..511433f6fb833a7f1932a44e61672652220b9104 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -83,28 +83,31 @@ SMESH::SMESH_Pattern_ptr SMESH_Gen_i::GetPattern()
 //=======================================================================
 
 SMESH_Pattern_i::SMESH_Pattern_i( SMESH_Gen_i* theGen_i ):
-       myGen( theGen_i )
+  myGen( theGen_i )
 {
 }
 
 //=======================================================================
 //function : getMesh
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 ::SMESH_Mesh* SMESH_Pattern_i::getMesh( SMESH::SMESH_Mesh_ptr & theMesh )
 {
-  SMESH_Mesh_i* anImplPtr = 
+  SMESH_Mesh_i* anImplPtr =
     dynamic_cast<SMESH_Mesh_i*>( SMESH_Gen_i::GetServant( theMesh ).in() );
   if ( anImplPtr )
+  {
+    anImplPtr->Load();
     return & anImplPtr->GetImpl();
+  }
 
   return 0;
 }
 
 //=======================================================================
 //function : LoadFromFile
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 CORBA::Boolean SMESH_Pattern_i::LoadFromFile(const char* theFileContents)
@@ -281,7 +284,7 @@ SMESH::point_array*
 
   list<const gp_XYZ *> xyzList;
   set<const SMDS_MeshFace*> fset;
-  for (int i = 0; i < theFacesIDs.length(); i++)
+  for ( CORBA::ULong i = 0; i < theFacesIDs.length(); i++)
   {
     CORBA::Long index = theFacesIDs[i];
     const SMDS_MeshElement * elem = aMesh->GetMeshDS()->FindElement(index);
@@ -342,7 +345,7 @@ SMESH::point_array*
 
   list<const gp_XYZ *> xyzList;
   set<const SMDS_MeshVolume*> vset;
-  for (int i = 0; i < theVolumesIDs.length(); i++)
+  for ( CORBA::ULong i = 0; i < theVolumesIDs.length(); i++)
   {
     CORBA::Long index = theVolumesIDs[i];
     const SMDS_MeshElement * elem = aMesh->GetMeshDS()->FindElement(index);
index ef39ace50e0e0e90ba49c841b874a49d156f7466..adf93ccb19ad6ea604612610d7d8e1fcdb9d8b0b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 59a7e65c8318f73712850918bad3f1181882b1cc..21fe1513eef3b5612d5a5e9faadf626840060d57 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -899,7 +899,7 @@ void SMESH_PreMeshInfo::readSubMeshes(DriverMED_R_SMESHDS_Mesh* reader) const
           HDFdataset* aDataset = new HDFdataset( (char*) aDSName.c_str(), aGroup );
           aDataset->OpenOnDisk();
           // read submesh IDs for all elements sorted by ID
-          int nbElems = aDataset->GetSize();
+          size_t nbElems = aDataset->GetSize();
           int* smIDs = new int [ nbElems ];
           aDataset->ReadFromDisk( smIDs );
           aDataset->CloseOnDisk();
@@ -921,7 +921,7 @@ void SMESH_PreMeshInfo::readSubMeshes(DriverMED_R_SMESHDS_Mesh* reader) const
           }
           // add elements to submeshes
           TIDSortedElemSet::iterator iE = elemSet.begin();
-          for ( int i = 0; i < nbElems; ++i, ++iE )
+          for ( size_t i = 0; i < nbElems; ++i, ++iE )
           {
             int smID = smIDs[ i ];
             if ( smID == 0 ) continue;
index ef2351cf1c16ef7b6067d3a147bb017fb8af1d32..7a38acb9c04aa269db775a8892866624c98d8783 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 13d66a497d5bcd605251e744ef0d0379f94c90ec..696376297855ea7de8a9601a6446609a66f40c13 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -27,6 +27,7 @@
 
 #include <SALOMEconfig.h>
 #include CORBA_SERVER_HEADER(SMESH_Mesh)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
 #include CORBA_SERVER_HEADER(GEOM_Gen)
 #include CORBA_SERVER_HEADER(SALOMEDS)
 
@@ -229,6 +230,9 @@ namespace SMESH
     TPythonDump&
     operator<<(const SMESH::ListOfIDSources& theList);
 
+    TPythonDump&
+    operator<<(const SMESH::CoincidentFreeBorders& theCFB);
+
     static const char* SMESHGenName() { return "smeshgen"; }
     static const char* MeshEditorName() { return "mesh_editor"; }
     static const char* NotPublishedObjectName();
index ac64d86ad9ef83f867a07c05297571559956d147..ee9117e2cae0528bd925a1dbe019ea5f7e8151b5 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -35,8 +35,9 @@
 #include "OpUtil.hxx"
 #include "Utils_ExceptHandlers.hxx"
 
-#include <TopoDS_Iterator.hxx>
 #include <TopExp_Explorer.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopoDS_Iterator.hxx>
 
 using namespace std;
 
@@ -94,55 +95,92 @@ typedef list<SMESHDS_SubMesh*> TListOfSubMeshes;
 bool getSubMeshes(::SMESH_subMesh*  theSubMesh,
                   TListOfSubMeshes& theSubMeshList)
 {
-  int size = theSubMeshList.size();
+  size_t size = theSubMeshList.size();
 
   SMESH_Mesh*      aMesh      = theSubMesh->GetFather();
   SMESHDS_Mesh*    aMeshDS    = aMesh->GetMeshDS();
   SMESHDS_SubMesh* aSubMeshDS = theSubMesh->GetSubMeshDS();
+  ::SMESH_subMesh* sm;
 
   // nodes can be bound to either vertex, edge, face or solid_or_shell
-  TopoDS_Shape aShape = theSubMesh->GetSubShape();
-  switch ( aShape.ShapeType() )
+  TopoDS_Shape         aShape = theSubMesh->GetSubShape();
+  TopAbs_ShapeEnum aShapeType = aShape.ShapeType();
+
+  // IPAL18558: Wrong information of the created sub-mesh is shown. (Sub-mesh on a FACE
+  // with only 1D algo assigned
+  // Find dimension of sub-meshes to return as highest dimension of the assigned algorithm
+  if ( theSubMesh->IsEmpty() && !theSubMesh->GetAlgo() )
   {
-  case TopAbs_SOLID: {
-    // add submesh of solid itself
-    aSubMeshDS = aMeshDS->MeshElements( aShape );
-    if ( aSubMeshDS )
+    // on father sub-meshes, check presence of an algo which will mesh this sub-mesh
+    // even if no algo is assigned to this sub-mesh
+    bool topAlgoPresent = false;
+    TopTools_ListIteratorOfListOfShape ancestors( aMesh->GetAncestors( aShape ));
+    for ( ; ancestors.More() && !topAlgoPresent; ancestors.Next() )
+      if (( sm = aMesh->GetSubMeshContaining( ancestors.Value() )))
+        topAlgoPresent = ( sm->GetAlgo() && !sm->GetAlgo()->NeedDiscreteBoundary() );
+
+    if ( !topAlgoPresent )
+    {
+      // look for a sub-mesh with an algo
+      SMESH_subMeshIteratorPtr smIt =
+        theSubMesh->getDependsOnIterator(/*includeSelf=*/false, /*complexShapeFirst=*/true);
+      TopAbs_ShapeEnum algoShape = TopAbs_SHAPE;
+      while ( smIt->more() && algoShape == TopAbs_SHAPE )
+      {
+        sm = smIt->next();
+        if ( sm->GetAlgo() )
+          algoShape = sm->GetSubShape().ShapeType();
+      }
+      if ( algoShape != TopAbs_SHAPE )
+      {
+        // return all sub-meshes on this shape type
+        smIt = theSubMesh->getDependsOnIterator(/*includeSelf=*/false, /*complexShapeFirst=*/true);
+        while ( smIt->more() )
+        {
+          sm = smIt->next();
+          if ( sm->GetSubShape().ShapeType() == algoShape && sm->GetSubMeshDS() )
+            theSubMeshList.push_back( sm->GetSubMeshDS() );
+        }
+        return size < theSubMeshList.size();
+      }
+    }
+  }
+
+  switch ( aShapeType )
+  {
+  case TopAbs_SOLID:
+  {
+    // add sub-mesh of solid itself
+    if (( aSubMeshDS = aMeshDS->MeshElements( aShape )))
       theSubMeshList.push_back( aSubMeshDS );
+
     // and of the first shell
     TopExp_Explorer exp( aShape, TopAbs_SHELL );
-    if ( exp.More() ) {
-      aSubMeshDS = aMeshDS->MeshElements( exp.Current() );
-      if ( aSubMeshDS )
+    if ( exp.More() )
+      if (( aSubMeshDS = aMeshDS->MeshElements( exp.Current() )))
         theSubMeshList.push_back( aSubMeshDS );
-    }
     break;
   }
   case TopAbs_WIRE:
   case TopAbs_COMPOUND:
-  case TopAbs_COMPSOLID: {
+  case TopAbs_COMPSOLID:
+  {
     // call getSubMeshes() for sub-shapes
     list<TopoDS_Shape> shapeList;
     shapeList.push_back( aShape );
     list<TopoDS_Shape>::iterator sh = shapeList.begin();
     for ( ; sh != shapeList.end(); ++sh ) {
       for ( TopoDS_Iterator it( *sh ); it.More(); it.Next() ) {
-        if ( ::SMESH_subMesh* aSubMesh = aMesh->GetSubMeshContaining( it.Value() ))
-          getSubMeshes( aSubMesh, theSubMeshList ); // add found submesh or explore deeper
+        if (( sm = aMesh->GetSubMeshContaining( it.Value() )))
+          getSubMeshes( sm, theSubMeshList ); // add found sub-mesh or explore deeper
         else
           // no submesh for a compound inside compound
           shapeList.push_back( it.Value() );
       }
     }
-    // return only unique submeshes
-    set<SMESHDS_SubMesh*> smSet;
-    TListOfSubMeshes::iterator sm = theSubMeshList.begin();
-    while ( sm != theSubMeshList.end() ) {
-      if ( !smSet.insert( *sm ).second )
-        sm = theSubMeshList.erase( sm );
-      else
-        ++sm;
-    }
+    // return only unique sub-meshes
+    set<SMESHDS_SubMesh*> smSet( theSubMeshList.begin(), theSubMeshList.end() );
+    theSubMeshList.assign( smSet.begin(), smSet.end() );
     break;
   }
   default:
@@ -607,3 +645,14 @@ bool SMESH_subMesh_i::IsMeshInfoCorrect()
 {
   return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
 }
+
+//=======================================================================
+//function : GetVtkUgStream
+//purpose  : Return data vtk unstructured grid (not implemented)
+//=======================================================================
+
+SALOMEDS::TMPFile* SMESH_subMesh_i::GetVtkUgStream()
+{
+  SALOMEDS::TMPFile_var SeqFile;
+  return SeqFile._retn();
+}
index 69fdcd72ec323a6ad002ac4fa2c39036fd2ee45f..689dd8e281621363adf092053d53841773f78532 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -110,7 +110,10 @@ public:
    * happen if mesh data is not yet fully loaded from the file of study.
    */
   virtual bool IsMeshInfoCorrect();
-
+  /*!
+   * Returns mesh unstructed grid information.
+   */
+  virtual SALOMEDS::TMPFile* GetVtkUgStream();
 
 protected:
 
index a8ae78e0857049ad804d956bce2b68ee7a58c419..e0ace848efc73a05ccc073a080289bf4f18779c9 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2012-2015  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
index 3b1f2f4b2a9cbbe858ea7c0eb6db870d6b87b433..118dc04e36747166aa98a2fd89ccc8cf53e6f917 100644 (file)
@@ -1,5 +1,5 @@
 # -*- coding: iso-8859-1 -*-
-# Copyright (C) 2010-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2010-2015  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
@@ -17,3 +17,4 @@
 #
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
index a043765799c6872dff1abbb53f15badbb03d5c47..51bcc356773f266caad8bc13754f4729aac1ccbd 100644 (file)
@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 #
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  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
index f11ded9118dfa37df9496e72e77c7053ac6f810e..d93e6ef98b6b368310aa65a4afd2aeefe96ea591 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2012-2015  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
@@ -89,6 +89,7 @@ SET(_bin_SCRIPTS
   PAL_MESH_043_2D.py
   PAL_MESH_043_3D.py
   SMESH_reg.py
+  smesh_selection.py
 )
 
 SET(smesh_SCRIPTS
index 672183e8cb4d8f03a7c172d5e78dd5a783740895..4cf0f4b584e8db09b032e512988800587abb64d5 100755 (executable)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index b36472401a2a48a43942a37df9914f50dd7100e3..a2f469e29129ef801bbc5d4da9e65678f3dcafc5 100755 (executable)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 8ed443096410bc7ffb5dffd615d9efd2f037043b..baa2649dcd9cc455f21714a1b60a8a70fafc3180 100755 (executable)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -89,5 +89,5 @@ smesh.SetName(hypNbSeg2, "NumberOfSegments_" + str(numberOfSegments2))
 mesh1.Compute()
 mesh2.Compute()
 
-# ---- udate object browser
-salome.sg.updateObjBrowser(1);
+# ---- update object browser
+salome.sg.updateObjBrowser(1)
index 1d8468aada42e9aa39b88412b98294b8668caafe..2785aa41e085ce51864112f17fcee8c1021451e4 100644 (file)
@@ -1,5 +1,5 @@
 # -*- coding: utf-8 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index cfbfdbd42c714816bf1180a884e4693b8098a256..b12261f71434610a23b2b4ccf7988ff386304564 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 30d418663a08e36d45f8e8c184612cbd9ba384e8..7a8d552eaa938e5ac00c5a920b8e94807c82d2fc 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  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
@@ -103,3 +103,5 @@ smesh.SetName(Compound1, 'Compound_with_RenamedGrps_and_MergeElems')
 Compound2 = smesh.Concatenate([Mesh_inf.GetMesh(), Mesh_sup.GetMesh()], 1, 0, 1e-05, True)
 smesh.SetName(Compound2, 'Compound_with_UniteGrps_and_GrpsOfAllElems')
 #end
+
+salome.sg.updateObjBrowser(1)
index 4140aaeb46bee14568989b62914a0dee00acb07d..d0e0697783037cf3a40c5d2bdf1f3702a35625c0 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 4e1aeb1f2b6e4e08eda3e49a2716fde4193a3fbc..b4904841bc915bd778d10721e79b0512e11d21c5 100755 (executable)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 54e6b5360d127abd23d077290ef1fc1199a0982e..f9477781c3ad2094bc948e308360b6e465adb901 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 09637e6c344c1485ec00528064108dd34d026da0..fb692941c6cf0e67ed1897d8ff07dc3b299023d8 100755 (executable)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -86,10 +86,17 @@ geompy.addToStudy(Fillet_1, "Fillet_1")
 
 #Chamfer applying
 print "Chamfer creation..."
-Chamfer_1 = geompy.MakeChamferEdge(Fillet_1, 10, 10, 16, 50 )
-geompy.addToStudy(Chamfer_1, "Chamfer_1")
-Chamfer_2 = geompy.MakeChamferEdge(Chamfer_1, 10, 10, 21, 31 )
-geompy.addToStudy(Chamfer_2, "Chamfer_2")
+cyl_face = geompy.GetFaceNearPoint( Fillet_1, geompy.MakeVertex( 50, 0, 45 ), theName='cyl_face')
+cyl_face_id = geompy.GetSubShapeID( Fillet_1, cyl_face )
+top_face = geompy.GetFaceNearPoint( Fillet_1, geompy.MakeVertex( 60, 0, 90 ), theName='top_face')
+top_face_id = geompy.GetSubShapeID( Fillet_1, top_face )
+Chamfer_1 = geompy.MakeChamferEdge(Fillet_1, 10, 10, cyl_face_id, top_face_id, theName='Chamfer_1' )
+
+cyl_face = geompy.GetFaceNearPoint( Chamfer_1, geompy.MakeVertex( 80, 0, 85 ), theName='cyl_face')
+cyl_face_id = geompy.GetSubShapeID( Chamfer_1, cyl_face )
+top_face = geompy.GetFaceNearPoint( Chamfer_1, geompy.MakeVertex( 65, 0, 90 ), theName='top_face')
+top_face_id = geompy.GetSubShapeID( Chamfer_1, top_face )
+Chamfer_2 = geompy.MakeChamferEdge(Chamfer_1, 10, 10, cyl_face_id, top_face_id, theName='Chamfer_2' )
 
 #Import of the shape from "slots.brep"
 print "Import multi-rotation from the DATA_DIR/Shapes/Brep/slots.brep"
index 16c301efbdc95f4e81aa2b21a757b26821b185c4..f6d4d1b7ea4aba747606b1a6e9fb86a35cb8422a 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 0b745d4c84aeafde795bca5f42df1dd4b209b310..9e3d724639a939aa0b8eeb2e28550ef648fdcaee 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -117,3 +117,5 @@ algo.NumberOfSegments(NbSeg)
 my_hexa.Quadrangle()
 my_hexa.Hexahedron()
 my_hexa.Compute()
+
+salome.sg.updateObjBrowser(1)
index 84fbef2f64f74ec55a5d58b00ffdeb5c2eaf35cf..d30b11edf1cda8796396e47f9f144a86ac8754d8 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index d287da529749d15203f95789e624a0f14ec0ab50..66eb6ba6b273efeda95e4e9817f261e7f7f8d6d1 100755 (executable)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 4677ff7605982d2305eb25996bf52d4f47c1f5cd..a4b9ce58ebf9f4f7a8dea82785f6576bec6dc997 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -121,9 +121,6 @@ print hypVolume.GetId()
 print hypVolume.GetMaxElementVolume()
 smesh.SetName(hypVolume, "MaxElementVolume_" + str(maxElementVolume))
 
-
-salome.sg.updateObjBrowser(1)
-
 print "-------------------------- compute shell"
 ret = mesh.Compute()
 print ret
@@ -140,3 +137,5 @@ if ret != 0:
     print "Number of tetrahedrons: ", mesh.NbTetras()
 else:
     print "probleme when computing the mesh"
+
+salome.sg.updateObjBrowser(1)
index c914e253658045fecec5356f7fc897828e1754e7..f2cfeb4dd8c777a322fac0d0901781158c2a65cd 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -131,9 +131,6 @@ print hypVolume.GetId()
 print hypVolume.GetMaxElementVolume()
 smesh.SetName(hypVolume, "MaxElementVolume_" + str(maxElementVolume))
 
-
-salome.sg.updateObjBrowser(1)
-
 print "-------------------------- compute shell"
 ret = mesh.Compute()
 print ret
@@ -150,3 +147,5 @@ if ret != 0:
     print "Number of tetrahedrons: ", mesh.NbTetras()
 else:
     print "probleme when computing the mesh"
+
+salome.sg.updateObjBrowser(1)
index 42797d079c7d747d770510f7361624d1b6234b00..2f96f70a3dbc6ff1722c6e653d02e5051d473ec8 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -90,8 +90,6 @@ print hypVolume.GetId()
 print hypVolume.GetMaxElementVolume()
 smesh.SetName(hypVolume, "MaxElementVolume_" + str(maxElementVolume))
 
-salome.sg.updateObjBrowser(1)
-
 print "-------------------------- compute the mesh of the boxe"
 ret = mesh.Compute()
 print ret
@@ -108,3 +106,5 @@ if ret != 0:
     print "Number of tetrahedrons: ", mesh.NbTetras()
 else:
     print "probleme when computing the mesh"
+
+salome.sg.updateObjBrowser(1)
index 6604c5ba6af7e0b6b424cef28989f247ea4ae2cc..7cc0f0eccd59475fc974529ab33ad406b4cec2dd 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 2423b8898a552becfd8c7a1f7fa5c2fc98471fcd..8414aa21a68ce596061ddcb8da97850a266197a1 100755 (executable)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 58baf90b6a97418a7a4185f60e820cf84690eef1..0da9420c2028c5c53fa44be41921749d8ab62cb7 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 7c30de974af903b72b731e3c32d634c3b85ce79f..e0b0c0bad838c75154d0ef34cf85deb4e6b462f7 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -82,9 +82,6 @@ print "-------------------------- Hexa_3D"
 hexa3D = mesh.Hexahedron()
 hexa3D.SetName("Hexa_3D")
 
-
-salome.sg.updateObjBrowser(1)
-
 print "-------------------------- compute compshell"
 ret = mesh.Compute()
 print ret
@@ -101,3 +98,5 @@ if ret != 0:
     print "Number of hexahedrons : ", mesh.NbHexas()
 else:
     print "problem when Computing the mesh"
+
+salome.sg.updateObjBrowser(1)
index 5fa307f9cbbf97479257744cedbda8a7577631a0..c8ad219be09e58efb4dcb36eba375c431aabcc44 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -61,8 +61,6 @@ netgen.SetMaxSize( 50 )
 netgen.SetFineness( smeshBuilder.Fine )
 #netgen.SetOptimize( 1 )
 
-salome.sg.updateObjBrowser(1)
-
 print "-------------------------- compute mesh"
 ret = mesh.Compute()
 print ret
@@ -77,3 +75,5 @@ if ret != 0:
     
 else:
     print "problem when computing the mesh"
+
+salome.sg.updateObjBrowser(1)
index 0964cff0ddd267a6f48d46885e664c6d3d957e66..daf2b8793c53ca1236a084932e0f4f33556d46ed 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -105,9 +105,6 @@ print hypVolume.GetId()
 print hypVolume.GetMaxElementVolume()
 smesh.SetName(hypVolume, "MaxElementVolume_" + str(maxElementVolume))
 
-
-salome.sg.updateObjBrowser(1)
-
 print "-------------------------- compute compshell"
 ret = mesh.Compute(mesh)
 print ret
@@ -125,3 +122,5 @@ if ret != 0:
     
 else:
     print "problem when computing the mesh"
+
+salome.sg.updateObjBrowser(1)
index 699bca4937369d1e7e62631b025abddb51806086..225fb0941f414b311e505fafafbf5b496e99f2f6 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -91,10 +91,6 @@ print hypLengthFromEdge.GetName()
 print hypLengthFromEdge.GetId()
 smesh.SetName(hypLengthFromEdge,"LengthFromEdge")
 
-
-salome.sg.updateObjBrowser(1)
-
-
 print "-------------------------- compute the skin flight"
 ret = mesh.Compute()
 print ret
@@ -110,3 +106,5 @@ if ret != 0:
     print "Number of volumes    : ", mesh.NbVolumes()
 else:
     print "probleme when computing the mesh"
+
+salome.sg.updateObjBrowser(1)
index b5be912c4e2341b4bd6ad76b52f959ec694dcc05..aa0b091bc58debe2828c5fc86d6c8b77756e8d9a 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 1284b20e5151e75f390325ab6bac2b4eaa2e5f4d..acfa4f3a40a69bf1cb50de08a3e1147b08ac2a06 100755 (executable)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index bd1b239dcc2593078aea75c85a75bf0dbd94bfb7..70d4edcc5999fb1a2e1e08f31d18ad2ac5b47b47 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 2db6baf0f456c338fc18808c097b9924ec9b4fd4..af6c00d1dfe9c961e1e29a7c734e65c5a8c220c9 100644 (file)
@@ -1,5 +1,5 @@
 # -*- coding: utf-8 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index a6a757a0a9b9d084748fcc6c9961145b4cbad4c7..46670e57b0f2c77e012e4c4cb846ec0078fa15d9 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -119,8 +119,6 @@ netgen.SetFineness( smeshBuilder.Fine )
 netgen.SetQuadAllowed( 1 )
 #netgen.SetOptimize( 1 )
 
-salome.sg.updateObjBrowser(1)
-
 print "-------------------------- compute mesh"
 ret = mesh.Compute()
 print ret
@@ -136,3 +134,5 @@ if ret != 0:
     
 else:
     print "problem when computing the mesh"
+
+salome.sg.updateObjBrowser(1)
index 7a72d6f5c0d8a315f950a993a916e7997f980456..aa5257ae730da127b80d4c10c79159f75c9c8fa5 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 8883aba833deb73e0ecc3ddc818b4cc5b66250cb..72b89134c5371cd6d3bb7af6b3ea5bfa09e19d10 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index f8bdb0f58616dcbf508bb8e2c108fbafa294dbcb..95862f0bd0c743dbb16f5c7b77d815ccc0a448cf 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 5a2c43eac96748aa52f67043a0a75e2fd9b91a63..e153cd6588c34c309d24976a9bd5bbc73b138456 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -146,3 +146,5 @@ for a in log:
             #ii = ii+1
             ii = ii+1
             print "AddTriangle %i - %i %i %i" % (ind, i1, i2, i3)
+
+salome.sg.updateObjBrowser(1)
index ce8ffb33cdab8eb9ac738f88d02d986afa1ced13..71207a2991c75f416b706e297134d4e63a0e0369 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 5a4237e0abf7a173f129d23bff2af91aa7dfc007..2341ab69a056b0d6dcf96dbc602a5825b0a9dbc3 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 30eb5e17b6b405f54837d800ae3edb5793a7f454..ae87f3faa57ff1880c21d35e96ca316f5dc4027c 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 9c11bb8b9b54312c4eb3cd97ebae1335b1c92b66..4f45d16aa493f844d232a729868162f09bdea8e1 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 65bb26292b825e991399b2f3c0f3af1befa60a06..c7638497955b23c7cfcde1b7031a73b5d30d6e71 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index bd63444ed227941fcd38047d431ade911466a10d..93a8a3b71c68417cd579a13cfbf7b2586116839e 100755 (executable)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index df88ecc30a8b16231de84f27140f8d3e22c54522..02d39a482899f163012eb6ef52de0f69fe84ed00 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 1496202ffeaaf9884fddc74c4e92c65807e2caac..6dd91e28875d897a6c5f0a6025d70ff08f96a216 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  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
@@ -42,9 +42,14 @@ Hexa        = "Hexa_3D"
 QUADRANGLE  = "Quadrangle_2D"
 ## Algorithm type: Radial Quadrangle 1D-2D algorithm, see StdMeshersBuilder_RadialQuadrangle1D2D
 RADIAL_QUAD = "RadialQuadrangle_1D2D"
+## Algorithm type: Quadrangle (Medial Axis Projection) 1D-2D algorithm, see StdMeshersBuilder_QuadMA_1D2D
+QUAD_MA_PROJ = "QuadFromMedialAxis_1D2D"
+## Algorithm type: Polygon Per Face 2D algorithm, see StdMeshersBuilder_PolygonPerFace
+POLYGON     = "PolygonPerFace_2D"
 
-# import items of enum QuadType
+# import items of enums
 for e in StdMeshers.QuadType._items: exec('%s = StdMeshers.%s'%(e,e))
+for e in StdMeshers.VLExtrusionMethod._items: exec('%s = StdMeshers.%s'%(e,e))
 
 #----------------------
 # Algorithms
@@ -63,7 +68,7 @@ class StdMeshersBuilder_Segment(Mesh_Algorithm):
     ## type of algorithm used with helper function in smeshBuilder.Mesh class
     #  @internal
     algoType   = REGULAR
-    ## flag pointing either this algorithm should be used by default in dynamic method
+    ## flag pointing whether this algorithm should be used by default in dynamic method
     #  of smeshBuilder.Mesh class
     #  @internal
     isDefault  = True
@@ -143,7 +148,7 @@ class StdMeshersBuilder_Segment(Mesh_Algorithm):
             reversedEdges, UseExisting = [], reversedEdges
         entry = self.MainShapeEntry()
         reversedEdgeInd = self.ReversedEdgeIndices(reversedEdges)
-        if s == []:
+        if not s:
             hyp = self.Hypothesis("NumberOfSegments", [n, reversedEdgeInd, entry],
                                   UseExisting=UseExisting,
                                   CompareMethod=self._compareNumberOfSegments)
@@ -151,7 +156,6 @@ class StdMeshersBuilder_Segment(Mesh_Algorithm):
             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 )
@@ -422,7 +426,7 @@ class StdMeshersBuilder_CompositeSegment(StdMeshersBuilder_Segment):
     ## type of algorithm used with helper function in smeshBuilder.Mesh class
     #  @internal
     algoType   = COMPOSITE
-    ## flag pointing either this algorithm should be used by default in dynamic method
+    ## flag pointing whether this algorithm should be used by default in dynamic method
     #  of smeshBuilder.Mesh class
     #  @internal
     isDefault  = False
@@ -455,9 +459,6 @@ class StdMeshersBuilder_Segment_Python(Mesh_Algorithm):
     algoType   = PYTHON
     ## doc string of the method
     #  @internal
-    docHelper  = "Creates tetrahedron 3D algorithm for solids"
-    ## doc string of the method
-    #  @internal
     docHelper  = "Creates segment 1D algorithm for edges"
 
     ## Private constructor.
@@ -498,7 +499,7 @@ class StdMeshersBuilder_Triangle_MEFISTO(Mesh_Algorithm):
     ## type of algorithm used with helper function in smeshBuilder.Mesh class
     #  @internal
     algoType   = MEFISTO
-    ## flag pointing either this algorithm should be used by default in dynamic method
+    ## flag pointing whether this algorithm should be used by default in dynamic method
     #  of smeshBuilder.Mesh class
     #  @internal
     isDefault  = True
@@ -552,7 +553,7 @@ class StdMeshersBuilder_Quadrangle(Mesh_Algorithm):
     ## type of algorithm used with helper function in smeshBuilder.Mesh class
     #  @internal
     algoType   = QUADRANGLE
-    ## flag pointing either this algorithm should be used by default in dynamic method
+    ## flag pointing whether this algorithm should be used by default in dynamic method
     #  of smeshBuilder.Mesh class
     #  @internal
     isDefault  = True
@@ -699,7 +700,7 @@ class StdMeshersBuilder_Hexahedron(Mesh_Algorithm):
     ## type of algorithm used with helper function in smeshBuilder.Mesh class
     #  @internal
     algoType   = Hexa
-    ## flag pointing either this algorithm should be used by default in dynamic method
+    ## flag pointing whether this algorithm should be used by default in dynamic method
     #  of smeshBuilder.Mesh class
     #  @internal
     isDefault  = True
@@ -731,7 +732,7 @@ class StdMeshersBuilder_Projection1D(Mesh_Algorithm):
     ## type of algorithm used with helper function in smeshBuilder.Mesh class
     #  @internal
     algoType   = "Projection_1D"
-    ## flag pointing either this algorithm should be used by default in dynamic method
+    ## flag pointing whether this algorithm should be used by default in dynamic method
     #  of smeshBuilder.Mesh class
     #  @internal
     isDefault  = True
@@ -789,7 +790,7 @@ class StdMeshersBuilder_Projection2D(Mesh_Algorithm):
     ## type of algorithm used with helper function in smeshBuilder.Mesh class
     #  @internal
     algoType   = "Projection_2D"
-    ## flag pointing either this algorithm should be used by default in dynamic method
+    ## flag pointing whether this algorithm should be used by default in dynamic method
     #  of smeshBuilder.Mesh class
     #  @internal
     isDefault  = True
@@ -856,7 +857,7 @@ class StdMeshersBuilder_Projection1D2D(StdMeshersBuilder_Projection2D):
     algoType   = "Projection_1D2D"
     ## doc string of the method
     #  @internal
-    docHelper  = "Creates projection 1D-2D algorithm for edges and faces"
+    docHelper  = "Creates projection 1D-2D algorithm for faces"
 
     ## Private constructor.
     #  @param mesh parent mesh object algorithm is assigned to
@@ -1037,11 +1038,10 @@ class StdMeshersBuilder_Prism3D(Mesh_Algorithm):
         if self.algoType != "RadialPrism_3D":
             print "Prism_3D algorith doesn't support any hyposesis"
             return None
-        if s == []:
+        if not s:
             hyp = self.OwnHypothesis("NumberOfSegments", [n])
         else:
             hyp = self.OwnHypothesis("NumberOfSegments", [n,s])
-            hyp.SetDistrType( 1 )
             hyp.SetScaleFactor(s)
         hyp.SetNumberOfSegments(n)
         return hyp
@@ -1100,8 +1100,7 @@ class StdMeshersBuilder_Prism3D(Mesh_Algorithm):
 
     pass # end of StdMeshersBuilder_Prism3D class
 
-## Defines a Prism 3D algorithm, which is either "Extrusion 3D" or "Radial Prism"
-#  depending on geometry
+## Defines a Prism 3D algorithm
 # 
 #  It is created by calling smeshBuilder.Mesh.Prism(geom=0)
 #
@@ -1116,7 +1115,7 @@ class StdMeshersBuilder_RadialPrism3D(StdMeshersBuilder_Prism3D):
     algoType   = "RadialPrism_3D"
     ## doc string of the method
     #  @internal
-    docHelper  = "Creates prism 3D algorithm for volumes"
+    docHelper  = "Creates Raial Prism 3D algorithm for volumes"
 
     ## Private constructor.
     #  @param mesh parent mesh object algorithm is assigned to
@@ -1133,30 +1132,12 @@ class StdMeshersBuilder_RadialPrism3D(StdMeshersBuilder_Prism3D):
         self.nbLayers = None
         return
 
-## Defines a Radial Quadrangle 1D-2D algorithm
+## Base class for algorithms supporting radial distribution hypotheses
 # 
-#  It is created by calling smeshBuilder.Mesh.Quadrangle(smeshBuilder.RADIAL_QUAD,geom=0)
-#
-#  @ingroup l2_algos_radialq
-class StdMeshersBuilder_RadialQuadrangle1D2D(Mesh_Algorithm):
+class StdMeshersBuilder_RadialAlgorithm(Mesh_Algorithm):
 
-    ## name of the dynamic method in smeshBuilder.Mesh class
-    #  @internal
-    meshMethod = "Quadrangle"
-    ## type of algorithm used with helper function in smeshBuilder.Mesh class
-    #  @internal
-    algoType   = RADIAL_QUAD
-    ## doc string of the method
-    #  @internal
-    docHelper  = "Creates quadrangle 1D-2D algorithm for triangular faces"
-
-    ## Private constructor.
-    #  @param mesh parent mesh object algorithm is assigned to
-    #  @param geom geometry (shape/sub-shape) algorithm is assigned to;
-    #              if it is @c 0 (default), the algorithm is assigned to the main shape
-    def __init__(self, mesh, geom=0):
+    def __init__(self):
         Mesh_Algorithm.__init__(self)
-        self.Create(mesh, geom, self.algoType)
 
         self.distribHyp = None #self.Hypothesis("LayerDistribution2D", UseExisting=0)
         self.nbLayers = None
@@ -1259,6 +1240,96 @@ class StdMeshersBuilder_RadialQuadrangle1D2D(Mesh_Algorithm):
 
     pass # end of StdMeshersBuilder_RadialQuadrangle1D2D class
 
+## Defines a Radial Quadrangle 1D-2D algorithm
+# 
+#  It is created by calling smeshBuilder.Mesh.Quadrangle(smeshBuilder.RADIAL_QUAD,geom=0)
+#
+#  @ingroup l2_algos_radialq
+class StdMeshersBuilder_RadialQuadrangle1D2D(StdMeshersBuilder_RadialAlgorithm):
+
+    ## name of the dynamic method in smeshBuilder.Mesh class
+    #  @internal
+    meshMethod = "Quadrangle"
+    ## type of algorithm used with helper function in smeshBuilder.Mesh class
+    #  @internal
+    algoType   = RADIAL_QUAD
+    ## doc string of the method
+    #  @internal
+    docHelper  = "Creates quadrangle 1D-2D algorithm for faces having a shape of disk or a disk segment"
+
+    ## Private constructor.
+    #  @param mesh parent mesh object algorithm is assigned to
+    #  @param geom geometry (shape/sub-shape) algorithm is assigned to;
+    #              if it is @c 0 (default), the algorithm is assigned to the main shape
+    def __init__(self, mesh, geom=0):
+        StdMeshersBuilder_RadialAlgorithm.__init__(self)
+        self.Create(mesh, geom, self.algoType)
+
+        self.distribHyp = None #self.Hypothesis("LayerDistribution2D", UseExisting=0)
+        self.nbLayers = None
+        pass
+
+
+## Defines a Quadrangle (Medial Axis Projection) 1D-2D algorithm
+# 
+#  It is created by calling smeshBuilder.Mesh.Quadrangle(smeshBuilder.QUAD_MA_PROJ,geom=0)
+#
+#  @ingroup l2_algos_quad_ma
+class StdMeshersBuilder_QuadMA_1D2D(StdMeshersBuilder_RadialAlgorithm):
+
+    ## name of the dynamic method in smeshBuilder.Mesh class
+    #  @internal
+    meshMethod = "Quadrangle"
+    ## type of algorithm used with helper function in smeshBuilder.Mesh class
+    #  @internal
+    algoType   = QUAD_MA_PROJ
+    ## doc string of the method
+    #  @internal
+    docHelper  = "Creates quadrangle 1D-2D algorithm for faces"
+
+    ## Private constructor.
+    #  @param mesh parent mesh object algorithm is assigned to
+    #  @param geom geometry (shape/sub-shape) algorithm is assigned to;
+    #              if it is @c 0 (default), the algorithm is assigned to the main shape
+    def __init__(self, mesh, geom=0):
+        StdMeshersBuilder_RadialAlgorithm.__init__(self)
+        self.Create(mesh, geom, self.algoType)
+        pass
+
+    pass
+
+## Defines a Polygon Per Face 2D algorithm
+# 
+#  It is created by calling smeshBuilder.Mesh.Polygon(geom=0)
+#
+#  @ingroup l2_algos_quad_ma
+class StdMeshersBuilder_PolygonPerFace(Mesh_Algorithm):
+
+    ## name of the dynamic method in smeshBuilder.Mesh class
+    #  @internal
+    meshMethod = "Polygon"
+    ## type of algorithm used with helper function in smeshBuilder.Mesh class
+    #  @internal
+    algoType   = POLYGON
+    ## flag pointing whether this algorithm should be used by default in dynamic method
+    #  of smeshBuilder.Mesh class
+    #  @internal
+    isDefault  = True
+    ## doc string of the method
+    #  @internal
+    docHelper  = "Creates polygon 2D algorithm for faces"
+
+    ## Private constructor.
+    #  @param mesh parent mesh object algorithm is assigned to
+    #  @param geom geometry (shape/sub-shape) algorithm is assigned to;
+    #              if it is @c 0 (default), the algorithm is assigned to the main shape
+    def __init__(self, mesh, geom=0):
+        Mesh_Algorithm.__init__(self)
+        self.Create(mesh, geom, self.algoType)
+        pass
+
+    pass
+
 ## Defines a Use Existing Elements 1D algorithm
 #
 #  It is created by calling smeshBuilder.Mesh.UseExisting1DElements(geom=0)
@@ -1272,7 +1343,7 @@ class StdMeshersBuilder_UseExistingElements_1D(Mesh_Algorithm):
     ## type of algorithm used with helper function in smeshBuilder.Mesh class
     #  @internal
     algoType   = "Import_1D"
-    ## flag pointing either this algorithm should be used by default in dynamic method
+    ## flag pointing whether this algorithm should be used by default in dynamic method
     #  of smeshBuilder.Mesh class
     #  @internal
     isDefault  = True
@@ -1322,13 +1393,13 @@ class StdMeshersBuilder_UseExistingElements_1D2D(Mesh_Algorithm):
     ## type of algorithm used with helper function in smeshBuilder.Mesh class
     #  @internal
     algoType   = "Import_1D2D"
-    ## flag pointing either this algorithm should be used by default in dynamic method
+    ## flag pointing whether this algorithm should be used by default in dynamic method
     #  of smeshBuilder.Mesh class
     #  @internal
     isDefault  = True
     ## doc string of the method
     #  @internal
-    docHelper  = "Creates 1D-2D algorithm for edges/faces with reusing of existing mesh elements"
+    docHelper  = "Creates 1D-2D algorithm for faces with reusing of existing mesh elements"
 
     ## Private constructor.
     #  @param mesh parent mesh object algorithm is assigned to
@@ -1346,15 +1417,16 @@ class StdMeshersBuilder_UseExistingElements_1D2D(Mesh_Algorithm):
     #  @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:
-            from salome.smesh.smeshBuilder import AssureGeomPublished
-            AssureGeomPublished( self.mesh, group )
+        import SMESH
         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)
+                              UseExisting=UseExisting, CompareMethod=compFun, toAdd=False)
+        if groups and isinstance( groups, SMESH._objref_SMESH_GroupBase ):
+            groups = [groups]
         hyp.SetSourceFaces(groups)
         hyp.SetCopySourceMesh(toCopyMesh, toCopyGroups)
+        self.mesh.AddHypothesis(hyp, self.geom)
         return hyp
 
     pass # end of StdMeshersBuilder_UseExistingElements_1D2D class
@@ -1372,13 +1444,13 @@ class StdMeshersBuilder_Cartesian_3D(Mesh_Algorithm):
     ## type of algorithm used with helper function in smeshBuilder.Mesh class
     #  @internal
     algoType   = "Cartesian_3D"
-    ## flag pointing either this algorithm should be used by default in dynamic method
+    ## flag pointing whether this algorithm should be used by default in dynamic method
     #  of smeshBuilder.Mesh class
     #  @internal
     isDefault  = True
     ## doc string of the method
     #  @internal
-    docHelper  = "Creates body fitting 3D algorithm for volumes"
+    docHelper  = "Creates Body Fitting 3D algorithm for volumes"
 
     ## Private constructor.
     #  @param mesh parent mesh object algorithm is assigned to
@@ -1508,7 +1580,7 @@ class StdMeshersBuilder_UseExisting_1D(Mesh_Algorithm):
     algoType   = "UseExisting_1D"
     ## doc string of the method
     #  @internal
-    docHelper  = "Creates 1D algorithm for edges with reusing of existing mesh elements"
+    docHelper  = "Creates 1D algorithm allowing batch meshing of edges"
 
     ## Private constructor.
     #  @param mesh parent mesh object algorithm is assigned to
@@ -1536,7 +1608,7 @@ class StdMeshersBuilder_UseExisting_2D(Mesh_Algorithm):
     algoType   = "UseExisting_2D"
     ## doc string of the method
     #  @internal
-    docHelper  = "Creates 2D algorithm for faces with reusing of existing mesh elements"
+    docHelper  = "Creates 2D algorithm allowing batch meshing of faces"
 
     ## Private constructor.
     #  @param mesh parent mesh object algorithm is assigned to
index af0e5b2080c95da71cc6eddce5bad559a3d19075..1ceca641f73a8834ec18dcbee42ed6777d01bb50 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index d3e5ced2da7534d4b0f160eb41edbb0b110f20fd..88ca7ae8b2dbea9b0d980c916f7b4a44ff9470e2 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 0d92fa69ebc7e6db742061e5b9fa26aee6e9b1ce..e8c4c38e22604f64ddd79fe6ad34f1b99ec4b965 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 3c75a1a8c552f269641db999fb26f4cddff79d14..7782a9c4baea4918f4e1df72408ce01441aaab2d 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index aac3b4fc864d8f5cde7647764866c1e4f4226c23..f5bc3b385b1531f637a3c236e4dd0f016e6e176b 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -319,3 +319,8 @@ algo.Propagation()
 # ----------------
 
 hexa.Compute()
+
+# Update object browser
+# ---------------------
+
+salome.sg.updateObjBrowser(1)
index 1080b3957917a1f3858650879e131352423c7611..e80bb8e50629ba60aa63ac4d8530495c3013052a 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -121,3 +121,8 @@ hexa.Hexahedron()
 # ----------------
 
 hexa.Compute()
+
+# Update object browser
+# ---------------------
+
+salome.sg.updateObjBrowser(1)
index a339e350e065d3483068983f45da2c862cbe7018..18a725b9257a8302478dc11763394f1d565bdd30 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -108,3 +108,8 @@ hexa.Hexahedron()
 # ----------------
 
 hexa.Compute()
+
+# Update object browser
+# ---------------------
+
+salome.sg.updateObjBrowser(1)
index fae3a095fb48abb64c3efee861a0fbe7a7f97e28..9039986c701e6551f4a8e46888a43e0a534e02e1 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -113,3 +113,8 @@ localMesh(box_tetra2, 0)
 # -------------
 
 mixed.Compute()
+
+# Update object browser
+# ---------------------
+
+salome.sg.updateObjBrowser(1)
index b7a55672e44f0e8c758c7fb41489f4a50c12f79c..5fa0caffcaa1a7901d66e52d4a560fb2f476bd77 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -148,3 +148,8 @@ hexa.Hexahedron()
 # -------------
 
 hexa.Compute()
+
+# Update object browser
+# ---------------------
+
+salome.sg.updateObjBrowser(1)
index 45a831cfdfa610366bc39b5947fd98ab42ed29cd..00cad90e690682ee61fae6cd5a2ab20b40ee7d18 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -165,3 +165,8 @@ algo4.Propagation()
 # -------------
 
 hexa.Compute()
+
+# Update object browser
+# ---------------------
+
+salome.sg.updateObjBrowser(1)
index 1b5cd2c996242913204a086bba74743c16fc5472..c6f1a607fbea320b4f72c0b784f23570d52e4c39 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -105,3 +105,8 @@ hexa.Hexahedron()
 # -------------
 
 hexa.Compute()
+
+# Update object browser
+# ---------------------
+
+salome.sg.updateObjBrowser(1)
index 1b00e2dd7d0303ab132d4e4fae1b84677ad0849e..3ce8e825a4b659290549872e561369ecc8a9db4c 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -138,3 +138,8 @@ hexa.Hexahedron()
 # -------------
 
 hexa.Compute()
+
+# Update object browser
+# ---------------------
+
+salome.sg.updateObjBrowser(1)
index 367fbdd25b421a6536f6fb941357239e67f02b34..c9509b5e431ffb39984ea1051cbc83a761f17cc0 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -141,3 +141,8 @@ hexa.Hexahedron()
 # -------------
 
 hexa.Compute()
+
+# Update object browser
+# ---------------------
+
+salome.sg.updateObjBrowser(1)
index d129ffea4d50f73c48f190d302f8e90282324b91..f7066d8c18bcc5cece9e3dbbfcef92b4bcdacd11 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -103,3 +103,8 @@ hexa.Hexahedron()
 # -------------
 
 hexa.Compute()
+
+# Update object browser
+# ---------------------
+
+salome.sg.updateObjBrowser(1)
index 197132f4131cc31abe799e4312fa4bf4bdd8f5b9..939559ef7e5bb6d8d1d62ec6bc37ab74d4d741be 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -124,3 +124,8 @@ hexa.Hexahedron()
 # -------------
 
 hexa.Compute()
+
+# Update object browser
+# ---------------------
+
+salome.sg.updateObjBrowser(1)
index a548126d40b1c154a28a3b39fa5bbc328e59b140..81e1b800fc69751b85f97955f02b2edfea75df0a 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -139,3 +139,8 @@ hexa.Hexahedron()
 # -------------
 
 hexa.Compute()
+
+# Update object browser
+# ---------------------
+
+salome.sg.updateObjBrowser(1)
index e34f06c2b7d76d6af6cc2f16ee0d68c798e67df0..da9807f3e7b2ade215c2bc1f1ad930df61d3ec71 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -257,3 +257,8 @@ local(cyl_x+d, cyl_y+d, box_dz, 10)
 # ----------------
 
 hexa.Compute()
+
+# Update object browser
+# ---------------------
+
+salome.sg.updateObjBrowser(1)
index 6f007504e7b17323b92c20996df7de7794aded5b..e9593802515b6d710b6278536aa89660cfce7704 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -142,3 +142,8 @@ while m_i<m_n:
 # --------------------
 
 hexa.Compute()
+
+# Update object browser
+# ---------------------
+
+salome.sg.updateObjBrowser(1)
index 27f4c6115f41423683cf8bbb654928adccd55a44..e985ac62eb5e711aedaf2ca786bc28802b3b9cd1 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -201,3 +201,8 @@ hexa.Hexahedron()
 # -------------
 
 hexa.Compute()
+
+# Update object browser
+# ---------------------
+
+salome.sg.updateObjBrowser(1)
index 1f98e3f1dbc1bd587e6a8db492cbb28c4ef86134..3493bd640aa43562813cfe21aae96bebe807fcbd 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -145,3 +145,8 @@ local(gx+g_dx, gy-g_dy, gz     , 21)
 # -------------
 
 hexa.Compute()
+
+# Update object browser
+# ---------------------
+
+salome.sg.updateObjBrowser(1)
index a204dcafca90619697aa308333ec18c91b501242..3f9b29359ae420ba5beceedcbbe6ad9dd972143c 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -104,3 +104,7 @@ hexa.Hexahedron()
 # ------------------
 
 hexa.Compute()
+# Update object browser
+# ---------------------
+
+salome.sg.updateObjBrowser(1)
index be243ac99eec87b831f206b7b4babb02bc55372d..c71329fd9817a5e9c98ba6df5e186d851401dc78 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -141,3 +141,8 @@ hexa.Hexahedron()
 # ------------------
 
 hexa.Compute()
+
+# Update object browser
+# ---------------------
+
+salome.sg.updateObjBrowser(1)
index d59b048a56b6e148114efdf180765d0c762db363..60aa987e8b4e4195c5f28984534e31c8aefd6604 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -186,3 +186,8 @@ hexa.Compute()
 # --------------------
 
 hexa_groupe = hexa.Group(groupe)
+
+# Update object browser
+# ---------------------
+
+salome.sg.updateObjBrowser(1)
index ebd582a8d89a71a601ad0ff4e862a511dd2a9cab..7f620af0883232e9ccf8dbea70e2ded92cda28ab 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -132,3 +132,8 @@ tetra.Compute()
 # ------------------------
 
 tetra.Group(group)
+
+# Update object browser
+# ---------------------
+
+salome.sg.updateObjBrowser(1)
\ No newline at end of file
index f510c05fa95c7783ce8efa3d67daaacf5818ef35..17109658641e23db3d26a4cfa68a7df0ae18fc2b 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  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
@@ -130,3 +130,8 @@ hexa.Compute()
 hexa.Group(group_a)
 hexa.Group(group_b)
 hexa.Group(group_1)
+
+# Update object browser
+# ---------------------
+
+salome.sg.updateObjBrowser(1)
index a709614fae8e1b2189c18b6130dcf123e376017d..edfeac2d30b896444af4a144346b31785cfa452b 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  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
index 53dcd14a7031bbb26491c0052987237d0084d135..d86cf997ef2e8477e1493f3a554043d6d0543195 100755 (executable)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  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
index f40a8284a5e3863b3c7ace63a8afa2da490db405..a3b299d4d2e9a3d7d64ec6786971303b2e6110d0 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  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
@@ -90,3 +90,8 @@ if os.access(results+".xml", os.F_OK):
     print "Ok: tepal"
 else:
     print "KO: tepal"
+
+# Update object browser
+# ---------------------
+
+salome.sg.updateObjBrowser(1)
index 037dfcec7c39ad83d4049c8715173e0bbbe14b56..1be697535e5f037813dbf41340ae33ec855a8e3f 100755 (executable)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  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
index 42f763228e11c69c2f5246ea859d04c322a8119c..87f931f84fa9cb6a294231df88721197c9ea218a 100644 (file)
@@ -1,5 +1,5 @@
 #  -*- coding: iso-8859-1 -*-
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index fe63e726b055c95b706df6619fa9836ee80927ae..0dc3b25f05890e36ef4893fdce7f48ef9e29ceac 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  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
@@ -161,6 +161,9 @@ 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):
+    if len( args ) != 6:
+        raise RuntimeError,\
+              "Bad nb args (%s) passed in SMESH.AxisStruct(x,y,z,dx,dy,dz)"%(len( args ))
     ax.x, ax.y, ax.z, ax.vx, ax.vy, ax.vz, ax.parameters,hasVars = ParseParameters(*args)
     pass
 SMESH.AxisStruct.__init__ = __initAxisStruct
@@ -232,7 +235,7 @@ def TreatHypoStatus(status, hypName, geomName, isAlgo, mesh):
     elif status == HYP_BAD_SUBSHAPE :
         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"
+        reason = "the algorithm is not applicable to this geometry"
     elif status == HYP_HIDDEN_ALGO:
         reason = "it is hidden by an algorithm of an upper dimension, which generates elements of all dimensions"
     elif status == HYP_HIDING_ALGO:
@@ -520,7 +523,8 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen):
         #return self.IsEmbeddedMode()
         return SMESH._objref_SMESH_Gen.IsEmbeddedMode(self)
 
-    ## Sets the current study
+    ## Sets the current study. Calling SetCurrentStudy( None ) allows to
+    #  switch OFF automatic pubilishing in the Study of mesh objects.
     #  @ingroup l1_auxiliary
     def SetCurrentStudy( self, theStudy, geompyD = None ):
         #self.SetCurrentStudy(theStudy)
@@ -536,6 +540,12 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen):
             notebook = salome_notebook.NoteBook( theStudy )
         else:
             notebook = salome_notebook.NoteBook( salome_notebook.PseudoStudyForNoteBook() )
+        if theStudy:
+            sb = theStudy.NewBuilder()
+            sc = theStudy.FindComponent("SMESH")
+            if sc: sb.LoadWith(sc, self)
+            pass
+        pass
 
     ## Gets the current study
     #  @ingroup l1_auxiliary
@@ -595,14 +605,15 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen):
         if error.comment: print "*** CreateMeshesFromGMF() errors:\n", error.comment
         return Mesh(self, self.geompyD, aSmeshMesh), error
 
-    ## Concatenate the given meshes into one mesh.
-    #  @return an instance of Mesh class
-    #  @param meshes the meshes to combine into one mesh
+    ## Concatenate the given meshes into one mesh. All groups of input meshes will be
+    #  present in the new mesh.
+    #  @param meshes the meshes, sub-meshes and groups 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 mergeNodesAndElements if true, equal nodes and elements are merged
     #  @param mergeTolerance tolerance for merging nodes
-    #  @param allGroups forces creation of groups of all elements
+    #  @param allGroups forces creation of groups corresponding to every input mesh
     #  @param name name of a new mesh
+    #  @return an instance of Mesh class
     def Concatenate( self, meshes, uniteIdenticalGroups,
                      mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False,
                      name = ""):
@@ -678,15 +689,17 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen):
 
     ## 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 elementType the type of elements(SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
+    #  @param CritType the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.)
+    #          Type SMESH.FunctorType._items in the Python Console to see all values.
+    #          Note that the items starting from FT_LessThan are not suitable for CritType.
+    #  @param Compare  belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
     #  @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
+    #  @param UnaryOp  SMESH.FT_LogicalNOT or SMESH.FT_Undefined
+    #  @param BinaryOp a binary logical operation SMESH.FT_LogicalAND, SMESH.FT_LogicalOR or
+    #                  SMESH.FT_Undefined
+    #  @param Tolerance the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
+    #         SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
     #  @return SMESH.Filter.Criterion
     #
     #  <a href="../tui_filters_page.html#combining_filters">Example of Criteria usage</a>
@@ -721,7 +734,7 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen):
 
         if CritType in [FT_BelongToGeom,     FT_BelongToPlane, FT_BelongToGenSurface,
                         FT_BelongToCylinder, FT_LyingOnGeom]:
-            # Checks that Threshold is GEOM object
+            # Check that Threshold is GEOM object
             if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object):
                 aCriterion.ThresholdStr = GetName(aThreshold)
                 aCriterion.ThresholdID  = aThreshold.GetStudyEntry()
@@ -730,23 +743,39 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen):
                     if not name:
                         name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
                     aCriterion.ThresholdID = self.geompyD.addToStudy( aThreshold, name )
-                    #raise RuntimeError, "Threshold shape must be published"
+            # or a name of GEOM object
+            elif isinstance( aThreshold, str ):
+                aCriterion.ThresholdStr = aThreshold
             else:
-                print "Error: The Threshold should be a shape."
-                return None
+                raise TypeError, "The Threshold should be a shape."
             if isinstance(UnaryOp,float):
                 aCriterion.Tolerance = UnaryOp
                 UnaryOp = FT_Undefined
                 pass
+        elif CritType == FT_BelongToMeshGroup:
+            # Check that Threshold is a group
+            if isinstance(aThreshold, SMESH._objref_SMESH_GroupBase):
+                if aThreshold.GetType() != elementType:
+                    raise ValueError, "Group type mismatches Element type"
+                aCriterion.ThresholdStr = aThreshold.GetName()
+                aCriterion.ThresholdID  = salome.orb.object_to_string( aThreshold )
+                study = self.GetCurrentStudy()
+                if study:
+                    so = study.FindObjectIOR( aCriterion.ThresholdID )
+                    if so:
+                        entry = so.GetID()
+                        if entry:
+                            aCriterion.ThresholdID = entry
+            else:
+                raise TypeError, "The Threshold should be a Mesh Group"
         elif CritType == FT_RangeOfIds:
-            # Checks that Threshold is string
+            # Check that Threshold is string
             if isinstance(aThreshold, str):
                 aCriterion.ThresholdStr = aThreshold
             else:
-                print "Error: The Threshold should be a string."
-                return None
+                raise TypeError, "The Threshold should be a string."
         elif CritType == FT_CoplanarFaces:
-            # Checks the Threshold
+            # Check the Threshold
             if isinstance(aThreshold, int):
                 aCriterion.ThresholdID = str(aThreshold)
             elif isinstance(aThreshold, str):
@@ -755,10 +784,10 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen):
                     raise ValueError, "Invalid ID of mesh face: '%s'"%aThreshold
                 aCriterion.ThresholdID = aThreshold
             else:
-                raise ValueError,\
+                raise TypeError,\
                       "The Threshold should be an ID of mesh face and not '%s'"%aThreshold
         elif CritType == FT_ConnectedElements:
-            # Checks the Threshold
+            # Check the Threshold
             if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object): # shape
                 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
                 if not aCriterion.ThresholdID:
@@ -778,11 +807,11 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen):
                 else:
                     aCriterion.ThresholdStr = aThreshold # hope that it's point coordinates
             else:
-                raise ValueError,\
+                raise TypeError,\
                       "The Threshold should either a VERTEX, or a node ID, "\
                       "or a list of point coordinates and not '%s'"%aThreshold
         elif CritType == FT_ElemGeomType:
-            # Checks the Threshold
+            # Check the Threshold
             try:
                 aCriterion.Threshold = self.EnumToLong(aThreshold)
                 assert( aThreshold in SMESH.GeometryType._items )
@@ -790,12 +819,11 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen):
                 if isinstance(aThreshold, int):
                     aCriterion.Threshold = aThreshold
                 else:
-                    print "Error: The Threshold should be an integer or SMESH.GeometryType."
-                    return None
+                    raise TypeError, "The Threshold should be an integer or SMESH.GeometryType."
                 pass
             pass
         elif CritType == FT_EntityType:
-            # Checks the Threshold
+            # Check the Threshold
             try:
                 aCriterion.Threshold = self.EnumToLong(aThreshold)
                 assert( aThreshold in SMESH.EntityType._items )
@@ -803,18 +831,16 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen):
                 if isinstance(aThreshold, int):
                     aCriterion.Threshold = aThreshold
                 else:
-                    print "Error: The Threshold should be an integer or SMESH.EntityType."
-                    return None
+                    raise TypeError, "The Threshold should be an integer or SMESH.EntityType."
                 pass
             pass
         
         elif CritType == FT_GroupColor:
-            # Checks the Threshold
+            # Check the Threshold
             try:
                 aCriterion.ThresholdStr = self.ColorToString(aThreshold)
             except:
-                print "Error: The threshold value should be of SALOMEDS.Color type"
-                return None
+                raise TypeError, "The threshold value should be of SALOMEDS.Color type"
             pass
         elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_FreeNodes, FT_FreeFaces,
                           FT_LinearOrQuadratic, FT_BadOrientedVolume,
@@ -832,7 +858,7 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen):
                 aThreshold = float(aThreshold)
                 aCriterion.Threshold = aThreshold
             except:
-                print "Error: The Threshold should be a number."
+                raise TypeError, "The Threshold should be a number."
                 return None
 
         if Threshold ==  FT_LogicalNOT or UnaryOp ==  FT_LogicalNOT:
@@ -850,13 +876,15 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen):
         return aCriterion
 
     ## Creates a filter with the given parameters
-    #  @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 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
+    #  @param elementType the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
+    #  @param CritType the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.)
+    #          Type SMESH.FunctorType._items in the Python Console to see all values.
+    #          Note that the items starting from FT_LessThan are not suitable for CritType.
+    #  @param Compare  belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
+    #  @param Threshold the threshold value (range of ids as string, shape, numeric)
+    #  @param UnaryOp  SMESH.FT_LogicalNOT or SMESH.FT_Undefined
+    #  @param Tolerance the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
+    #         SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces and SMESH.FT_EqualNodes criteria
     #  @param mesh the mesh to initialize the filter with
     #  @return SMESH_Filter
     #
@@ -899,7 +927,9 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen):
         return aFilter
 
     ## Creates a numerical functor by its type
-    #  @param theCriterion FT_...; functor type
+    #  @param theCriterion functor type - an item of SMESH.FunctorType enumeration.
+    #          Type SMESH.FunctorType._items in the Python Console to see all items.
+    #          Note that not all items correspond to numerical functors.
     #  @return SMESH_NumericalFunctor
     #  @ingroup l1_controls
     def GetFunctor(self,theCriterion):
@@ -1234,7 +1264,6 @@ class Mesh:
         for attrName in dir(self):
             attr = getattr( self, attrName )
             if isinstance( attr, algoCreator ):
-                #print "algoCreator ", attrName
                 setattr( self, attrName, attr.copy( self ))
                 pass
             pass
@@ -1369,9 +1398,10 @@ class Mesh:
     #  @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()
+    #  @param refresh if @c True, Object browser is automatically updated (when running in GUI)
     #  @return True or False
     #  @ingroup l2_construct
-    def Compute(self, geom=0, discardModifs=False):
+    def Compute(self, geom=0, discardModifs=False, refresh=False):
         if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
             if self.geom == 0:
                 geom = self.mesh.GetShapeToMesh()
@@ -1395,37 +1425,7 @@ class Mesh:
             # 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( geomBuilder.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)
+                shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
                 errText = ""
                 stdErrors = ["OK",                   #COMPERR_OK
                              "Invalid input mesh",   #COMPERR_BAD_INPUT_MESH
@@ -1499,42 +1499,132 @@ class Mesh:
             smeshgui = salome.ImportComponentGUI("SMESH")
             smeshgui.Init(self.mesh.GetStudyId())
             smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), ok, (self.NbNodes()==0) )
-            salome.sg.updateObjBrowser(1)
+            if refresh: salome.sg.updateObjBrowser(1)
             pass
         return ok
 
-    ## Return submesh objects list in meshing order
-    #  @return list of list of submesh objects
+    ## Return a name of a sub-shape by its ID
+    #  @param subShapeID a unique ID of a sub-shape
+    #  @return a string describing the sub-shape; possible variants:
+    #  - "Face_12"    (published sub-shape)
+    #  - FACE #3      (not published sub-shape)
+    #  - sub-shape #3 (invalid sub-shape ID)
+    #  - #3           (error in this function)
+    def GetSubShapeName(self, subShapeID ):
+        if not self.mesh.HasShapeToMesh():
+            return ""
+        try:
+            shapeText = ""
+            mainIOR  = salome.orb.object_to_string( self.GetShape() )
+            for sname in salome.myStudyManager.GetOpenStudies():
+                s = salome.myStudyManager.GetStudyByName(sname)
+                if not s: continue
+                mainSO = s.FindObjectIOR(mainIOR)
+                if not mainSO: continue
+                if subShapeID == 1:
+                    shapeText = '"%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( geomBuilder.GEOM._objref_GEOM_Object )
+                    if not go: continue
+                    try:
+                        ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
+                    except:
+                        continue
+                    if ids == subShapeID:
+                        shapeText = '"%s"' % subSO.GetName()
+                        break
+            if not shapeText:
+                shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
+                if shape:
+                    shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
+                else:
+                    shapeText = 'sub-shape #%s' % (subShapeID)
+        except:
+            shapeText = "#%s" % (subShapeID)
+        return shapeText
+
+    ## Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
+    #  error of an algorithm
+    #  @param publish if @c True, the returned groups will be published in the study
+    #  @return a list of GEOM groups each named after a failed algorithm
+    def GetFailedShapes(self, publish=False):
+
+        algo2shapes = {}
+        computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
+        for err in computeErrors:
+            shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
+            if not shape: continue
+            if err.algoName in algo2shapes:
+                algo2shapes[ err.algoName ].append( shape )
+            else:
+                algo2shapes[ err.algoName ] = [ shape ]
+            pass
+
+        groups = []
+        for algoName, shapes in algo2shapes.items():
+            while shapes:
+                groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
+                otherTypeShapes = []
+                sameTypeShapes  = []
+                group = self.geompyD.CreateGroup( self.geom, groupType )
+                for shape in shapes:
+                    if shape.GetShapeType() == shapes[0].GetShapeType():
+                        sameTypeShapes.append( shape )
+                    else:
+                        otherTypeShapes.append( shape )
+                self.geompyD.UnionList( group, sameTypeShapes )
+                if otherTypeShapes:
+                    group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
+                else:
+                    group.SetName( algoName )
+                groups.append( group )
+                shapes = otherTypeShapes
+            pass
+        if publish:
+            for group in groups:
+                self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
+        return groups
+
+    ## Return sub-mesh objects list in meshing order
+    #  @return list of list of sub-meshes
     #  @ingroup l2_construct
     def GetMeshOrder(self):
         return self.mesh.GetMeshOrder()
 
-    ## Return submesh objects list in meshing order
-    #  @return list of list of submesh objects
+    ## Set order in which concurrent sub-meshes sould be meshed
+    #  @param submeshes list of sub-meshes
     #  @ingroup l2_construct
     def SetMeshOrder(self, submeshes):
         return self.mesh.SetMeshOrder(submeshes)
 
     ## Removes all nodes and elements
+    #  @param refresh if @c True, Object browser is automatically updated (when running in GUI)
     #  @ingroup l2_construct
-    def Clear(self):
+    def Clear(self, refresh=False):
         self.mesh.Clear()
         if ( salome.sg.hasDesktop() and 
-             salome.myStudyManager.GetStudyByID( self.mesh.GetStudyId() )):
+             salome.myStudyManager.GetStudyByID( self.mesh.GetStudyId() ) ):
             smeshgui = salome.ImportComponentGUI("SMESH")
             smeshgui.Init(self.mesh.GetStudyId())
             smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), False, True )
-            salome.sg.updateObjBrowser(1)
+            if refresh: salome.sg.updateObjBrowser(1)
 
     ## Removes all nodes and elements of indicated shape
+    #  @param refresh if @c True, Object browser is automatically updated (when running in GUI)
+    #  @param geomId the ID of a sub-shape to remove elements on
     #  @ingroup l2_construct
-    def ClearSubMesh(self, geomId):
+    def ClearSubMesh(self, geomId, refresh=False):
         self.mesh.ClearSubMesh(geomId)
         if salome.sg.hasDesktop():
             smeshgui = salome.ImportComponentGUI("SMESH")
             smeshgui.Init(self.mesh.GetStudyId())
             smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), False, True )
-            salome.sg.updateObjBrowser(1)
+            if refresh: salome.sg.updateObjBrowser(1)
 
     ## Computes a tetrahedral mesh using AutomaticLength + MEFISTO + Tetrahedron
     #  @param fineness [0.0,1.0] defines mesh fineness
@@ -1576,6 +1666,8 @@ class Mesh:
     #  @return SMESH.Hypothesis_Status
     #  @ingroup l2_hypotheses
     def AddHypothesis(self, hyp, geom=0):
+        if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
+            hyp, geom = geom, hyp
         if isinstance( hyp, Mesh_Algorithm ):
             hyp = hyp.GetAlgorithm()
             pass
@@ -1588,9 +1680,10 @@ class Mesh:
         if self.mesh.HasShapeToMesh():
             hyp_type     = hyp.GetName()
             lib_name     = hyp.GetLibName()
-            checkAll    = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
-            if checkAll and geom:
-                checkAll = geom.GetType() == 37
+            # checkAll    = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
+            # if checkAll and geom:
+            #     checkAll = geom.GetType() == 37
+            checkAll     = False
             isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
         if isApplicable:
             AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
@@ -1801,7 +1894,8 @@ class Mesh:
     # ----------------------
 
     ## Creates an empty mesh group
-    #  @param elementType the type of elements in the group
+    #  @param elementType the type of elements in the group; either of 
+    #         (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
     #  @param name the name of the mesh group
     #  @return SMESH_Group
     #  @ingroup l2_grps_create
@@ -1824,8 +1918,9 @@ class Mesh:
     #  the name is the same as the geometrical group name
     #  @param grp  a geometrical group, a vertex, an edge, a face or a solid
     #  @param name the name of the mesh group
-    #  @param typ  the type of elements in the group. If not set, it is
-    #              automatically detected by the type of the geometry
+    #  @param typ  the type of elements in the group; either of 
+    #         (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
+    #         automatically detected by the type of the geometry
     #  @return SMESH_GroupOnGeom
     #  @ingroup l2_grps_create
     def GroupOnGeom(self, grp, name="", typ=None):
@@ -1860,7 +1955,8 @@ class Mesh:
     ## 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 typ  the type of elements in the group; either of 
+    #         (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
     #  @param name the name of the mesh group
     #  @param filter the filter defining group contents
     #  @return SMESH_GroupOnFilter
@@ -1870,7 +1966,8 @@ class Mesh:
 
     ## Creates a mesh group by the given ids of elements
     #  @param groupName the name of the mesh group
-    #  @param elementType the type of elements in the group
+    #  @param elementType the type of elements in the group; either of 
+    #         (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
     #  @param elemIDs the list of ids
     #  @return SMESH_Group
     #  @ingroup l2_grps_create
@@ -1886,13 +1983,15 @@ class Mesh:
 
     ## Creates a mesh group by the given conditions
     #  @param groupName the name of the mesh group
-    #  @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 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
+    #  @param elementType the type of elements(SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
+    #  @param CritType the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.)
+    #          Type SMESH.FunctorType._items in the Python Console to see all values.
+    #          Note that the items starting from FT_LessThan are not suitable for CritType.
+    #  @param Compare  belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
+    #  @param Threshold the threshold value (range of ids as string, shape, numeric)
+    #  @param UnaryOp  SMESH.FT_LogicalNOT or SMESH.FT_Undefined
+    #  @param Tolerance the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
+    #         SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
     #  @return SMESH_GroupOnFilter
     #  @ingroup l2_grps_create
     def MakeGroup(self,
@@ -1948,11 +2047,24 @@ class Mesh:
     def RemoveGroupWithContents(self, group):
         self.mesh.RemoveGroupWithContents(group)
 
-    ## Gets the list of groups existing in the mesh in the order of creation (starting from the oldest one)
+    ## Gets the list of groups existing in the mesh in the order
+    #  of creation (starting from the oldest one)
+    #  @param elemType type of elements the groups contain; either of 
+    #         (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME);
+    #         by default groups of elements of all types are returned
     #  @return a sequence of SMESH_GroupBase
     #  @ingroup l2_grps_create
-    def GetGroups(self):
-        return self.mesh.GetGroups()
+    def GetGroups(self, elemType = SMESH.ALL):
+        groups = self.mesh.GetGroups()
+        if elemType == SMESH.ALL:
+            return groups
+        typedGroups = []
+        for g in groups:
+            if g.GetType() == elemType:
+                typedGroups.append( g )
+                pass
+            pass
+        return typedGroups
 
     ## Gets the number of groups existing in the mesh
     #  @return the quantity of groups as an integer value
@@ -1970,7 +2082,26 @@ class Mesh:
             names.append(group.GetName())
         return names
 
-    ## Produces a union of two groups
+    ## Finds groups by name and type
+    #  @param name name of the group of interest
+    #  @param elemType type of elements the groups contain; either of 
+    #         (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME);
+    #         by default one group of any type of elements is returned
+    #         if elemType == SMESH.ALL then all groups of any type are returned
+    #  @return a list of SMESH_GroupBase's
+    #  @ingroup l2_grps_create
+    def GetGroupByName(self, name, elemType = None):
+        groups = []
+        for group in self.GetGroups():
+            if group.GetName() == name:
+                if elemType is None:
+                    return [group]
+                if ( elemType == SMESH.ALL or 
+                     group.GetType() == elemType ):
+                    groups.append( group )
+        return groups
+
+    ## Produces a union of two groups.
     #  A new group is created. All mesh elements that are
     #  present in the initial groups are added to the new one
     #  @return an instance of SMESH_Group
@@ -1978,7 +2109,7 @@ class Mesh:
     def UnionGroups(self, group1, group2, name):
         return self.mesh.UnionGroups(group1, group2, name)
 
-    ## Produces a union list of groups
+    ## Produces a union list of groups.
     #  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
@@ -1986,7 +2117,7 @@ class Mesh:
     def UnionListOfGroups(self, groups, name):
       return self.mesh.UnionListOfGroups(groups, name)
 
-    ## Prodices an intersection of two groups
+    ## 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.
     #  @return an instance of SMESH_Group
@@ -1994,7 +2125,7 @@ class Mesh:
     def IntersectGroups(self, group1, group2, name):
         return self.mesh.IntersectGroups(group1, group2, name)
 
-    ## Produces an intersection of groups
+    ## Produces an intersection of groups.
     #  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
@@ -2002,7 +2133,7 @@ class Mesh:
     def IntersectListOfGroups(self, groups, name):
       return self.mesh.IntersectListOfGroups(groups, name)
 
-    ## Produces a cut of two groups
+    ## Produces a cut of two groups.
     #  A new group is created. All mesh elements that are present in
     #  the main group but are not present in the tool group are added to the new one
     #  @return an instance of SMESH_Group
@@ -2010,22 +2141,36 @@ class Mesh:
     def CutGroups(self, main_group, tool_group, name):
         return self.mesh.CutGroups(main_group, tool_group, name)
 
-    ## Produces a cut of groups
+    ## Produces a cut of 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)
+        return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
 
-    ## 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
+    ##
+    #  Create a standalone group of entities basing on nodes of other groups.
+    #  \param groups - list of groups, sub-meshes or filters, of any type.
+    #  \param elemType - a type of elements to include to the new group; either of 
+    #         (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
+    #  \param name - a name of the new group.
+    #  \param nbCommonNodes - a criterion of inclusion of an element to the new group
+    #         basing on number of element nodes common with reference \a groups.
+    #         Meaning of possible values are:
+    #         - SMESH.ALL_NODES - include if all nodes are common,
+    #         - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
+    #         - SMESH.AT_LEAST_ONE - include if one or more node is common,
+    #         - SMEHS.MAJORITY - include if half of nodes or more are common.
+    #  \param underlyingOnly - if \c True (default), an element is included to the
+    #         new group provided that it is based on nodes of one element of \a groups.
     #  @return an instance of SMESH_Group
     #  @ingroup l2_grps_operon
-    def CreateDimGroup(self, groups, elem_type, name):
-      return self.mesh.CreateDimGroup(groups, elem_type, name)
+    def CreateDimGroup(self, groups, elemType, name,
+                       nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
+        if isinstance( groups, SMESH._objref_SMESH_IDSource ):
+            groups = [groups]
+        return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
 
 
     ## Convert group on geom into standalone group
@@ -2093,9 +2238,17 @@ class Mesh:
 
     ## 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
+    #  @param ids list of IDs
+    #  @param elemType type of elements; this parameter is used to distinguish
+    #         IDs of nodes from IDs of elements; by default ids are treated as
+    #         IDs of elements; use SMESH.NODE if ids are IDs of nodes.
     #  @return an instance of SMESH_IDSource
+    #  @warning call UnRegister() for the returned object as soon as it is no more useful:
+    #          idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
+    #          mesh.DoSomething( idSrc )
+    #          idSrc.UnRegister()
     #  @ingroup l1_auxiliary
-    def GetIDSource(self, ids, elemType):
+    def GetIDSource(self, ids, elemType = SMESH.ALL):
         return self.editor.MakeIDSource(ids, elemType)
 
 
@@ -2141,7 +2294,7 @@ class Mesh:
 
     ## Returns the number of edges with the given order in the mesh
     #  @param elementOrder the order of elements:
-    #         ORDER_ANY, ORDER_LINEAR or ORDER_QUADRATIC
+    #         SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC
     #  @return an integer value
     #  @ingroup l1_meshinfo
     def NbEdgesOfOrder(self, elementOrder):
@@ -2155,7 +2308,7 @@ class Mesh:
 
     ## Returns the number of faces with the given order in the mesh
     #  @param elementOrder the order of elements:
-    #         ORDER_ANY, ORDER_LINEAR or ORDER_QUADRATIC
+    #         SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC
     #  @return an integer value
     #  @ingroup l1_meshinfo
     def NbFacesOfOrder(self, elementOrder):
@@ -2169,7 +2322,7 @@ class Mesh:
 
     ## Returns the number of triangles with the given order in the mesh
     #  @param elementOrder is the order of elements:
-    #         ORDER_ANY, ORDER_LINEAR or ORDER_QUADRATIC
+    #         SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC
     #  @return an integer value
     #  @ingroup l1_meshinfo
     def NbTrianglesOfOrder(self, elementOrder):
@@ -2189,7 +2342,7 @@ class Mesh:
 
     ## Returns the number of quadrangles with the given order in the mesh
     #  @param elementOrder the order of elements:
-    #         ORDER_ANY, ORDER_LINEAR or ORDER_QUADRATIC
+    #         SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC
     #  @return an integer value
     #  @ingroup l1_meshinfo
     def NbQuadranglesOfOrder(self, elementOrder):
@@ -2201,11 +2354,13 @@ class Mesh:
     def NbBiQuadQuadrangles(self):
         return self.mesh.NbBiQuadQuadrangles()
 
-    ## Returns the number of polygons in the mesh
+    ## Returns the number of polygons of given order in the mesh
+    #  @param elementOrder the order of elements:
+    #         SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC
     #  @return an integer value
     #  @ingroup l1_meshinfo
-    def NbPolygons(self):
-        return self.mesh.NbPolygons()
+    def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
+        return self.mesh.NbPolygonsOfOrder(elementOrder)
 
     ## Returns the number of volumes in the mesh
     #  @return an integer value
@@ -2215,7 +2370,7 @@ class Mesh:
 
     ## Returns the number of volumes with the given order in the mesh
     #  @param elementOrder  the order of elements:
-    #         ORDER_ANY, ORDER_LINEAR or ORDER_QUADRATIC
+    #         SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC
     #  @return an integer value
     #  @ingroup l1_meshinfo
     def NbVolumesOfOrder(self, elementOrder):
@@ -2229,7 +2384,7 @@ class Mesh:
 
     ## Returns the number of tetrahedrons with the given order in the mesh
     #  @param elementOrder  the order of elements:
-    #         ORDER_ANY, ORDER_LINEAR or ORDER_QUADRATIC
+    #         SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC
     #  @return an integer value
     #  @ingroup l1_meshinfo
     def NbTetrasOfOrder(self, elementOrder):
@@ -2243,7 +2398,7 @@ class Mesh:
 
     ## Returns the number of hexahedrons with the given order in the mesh
     #  @param elementOrder  the order of elements:
-    #         ORDER_ANY, ORDER_LINEAR or ORDER_QUADRATIC
+    #         SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC
     #  @return an integer value
     #  @ingroup l1_meshinfo
     def NbHexasOfOrder(self, elementOrder):
@@ -2263,7 +2418,7 @@ class Mesh:
 
     ## Returns the number of pyramids with the given order in the mesh
     #  @param elementOrder  the order of elements:
-    #         ORDER_ANY, ORDER_LINEAR or ORDER_QUADRATIC
+    #         SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC
     #  @return an integer value
     #  @ingroup l1_meshinfo
     def NbPyramidsOfOrder(self, elementOrder):
@@ -2277,7 +2432,7 @@ class Mesh:
 
     ## Returns the number of prisms with the given order in the mesh
     #  @param elementOrder  the order of elements:
-    #         ORDER_ANY, ORDER_LINEAR or ORDER_QUADRATIC
+    #         SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC
     #  @return an integer value
     #  @ingroup l1_meshinfo
     def NbPrismsOfOrder(self, elementOrder):
@@ -2308,7 +2463,8 @@ 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 (SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
+    #  @param elementType  the required type of elements, either of
+    #         (SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
     #  @return list of integer values
     #  @ingroup l1_meshinfo
     def GetElementsByType(self, elementType):
@@ -2325,18 +2481,21 @@ class Mesh:
 
     ## Returns the type of mesh element
     #  @return the value from SMESH::ElementType enumeration
+    #          Type SMESH.ElementType._items in the Python Console to see all possible values.
     #  @ingroup l1_meshinfo
-    def GetElementType(self, id, iselem):
+    def GetElementType(self, id, iselem=True):
         return self.mesh.GetElementType(id, iselem)
 
     ## Returns the geometric type of mesh element
     #  @return the value from SMESH::EntityType enumeration
+    #          Type SMESH.EntityType._items in the Python Console to see all possible values.
     #  @ingroup l1_meshinfo
     def GetElementGeomType(self, id):
         return self.mesh.GetElementGeomType(id)
 
     ## Returns the shape type of mesh element
-    #  @return the value from SMESH::GeometryType enumeration
+    #  @return the value from SMESH::GeometryType enumeration.
+    #          Type SMESH.GeometryType._items in the Python Console to see all possible values.
     #  @ingroup l1_meshinfo
     def GetElementShape(self, id):
         return self.mesh.GetElementShape(id)
@@ -2347,8 +2506,8 @@ class Mesh:
     #  @return the list of integer values
     #  @ingroup l1_meshinfo
     def GetSubMeshElementsId(self, Shape):
-        if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
-            ShapeID = Shape.GetSubShapeIndices()[0]
+        if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
+            ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
         else:
             ShapeID = Shape
         return self.mesh.GetSubMeshElementsId(ShapeID)
@@ -2360,7 +2519,7 @@ class Mesh:
     #  @return the list of integer values
     #  @ingroup l1_meshinfo
     def GetSubMeshNodesId(self, Shape, all):
-        if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
+        if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
             ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
         else:
             ShapeID = Shape
@@ -2372,8 +2531,8 @@ class Mesh:
     #  @return element type
     #  @ingroup l1_meshinfo
     def GetSubMeshElementType(self, Shape):
-        if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
-            ShapeID = Shape.GetSubShapeIndices()[0]
+        if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
+            ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
         else:
             ShapeID = Shape
         return self.mesh.GetSubMeshElementType(ShapeID)
@@ -2414,24 +2573,22 @@ class Mesh:
     def GetElementPosition(self,ElemID):
         return self.mesh.GetElementPosition(ElemID)
 
-    ## If the given element is a node, returns the ID of shape
-    #  \n If there is no node for the given ID - returns -1
-    #  @return an integer value
+    ## Returns the ID of the shape, on which the given node was generated.
+    #  @return an integer value > 0 or -1 if there is no node for the given
+    #          ID or the node is not assigned to any geometry
     #  @ingroup l1_meshinfo
     def GetShapeID(self, id):
         return self.mesh.GetShapeID(id)
 
-    ## Returns the ID of the result shape after
-    #  FindShape() from SMESH_MeshEditor for the given element
-    #  \n If there is no element for the given ID - returns -1
-    #  @return an integer value
+    ## Returns the ID of the shape, on which the given element was generated.
+    #  @return an integer value > 0 or -1 if there is no element for the given
+    #          ID or the element is not assigned to any geometry
     #  @ingroup l1_meshinfo
     def GetShapeIDForElem(self,id):
         return self.mesh.GetShapeIDForElem(id)
 
-    ## Returns the number of nodes for the given element
-    #  \n If there is no element for the given ID - returns -1
-    #  @return an integer value
+    ## Returns the number of nodes of the given element
+    #  @return an integer value > 0 or -1 if there is no element for the given ID
     #  @ingroup l1_meshinfo
     def GetElemNbNodes(self, id):
         return self.mesh.GetElemNbNodes(id)
@@ -2456,8 +2613,11 @@ class Mesh:
         return self.mesh.IsMediumNode(elementID, nodeID)
 
     ## Returns true if the given node is the medium node in one of quadratic elements
+    #  @param nodeID ID of the node
+    #  @param elementType  the type of elements to check a state of the node, either of
+    #         (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
     #  @ingroup l1_meshinfo
-    def IsMediumNodeOfAnyElem(self, nodeID, elementType):
+    def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
         return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
 
     ## Returns the number of edges for the given element
@@ -2715,6 +2875,14 @@ class Mesh:
     def AddPolygonalFace(self, IdsOfNodes):
         return self.editor.AddPolygonalFace(IdsOfNodes)
 
+    ## Adds a quadratic polygonal face to the mesh by the list of node IDs
+    #  @param IdsOfNodes the list of node IDs for creation of the element;
+    #         corner nodes follow first.
+    #  @return the Id of the new face
+    #  @ingroup l2_modif_add
+    def AddQuadPolygonalFace(self, IdsOfNodes):
+        return self.editor.AddQuadPolygonalFace(IdsOfNodes)
+
     ## Creates both simple and quadratic volume (this is determined
     #  by the number of given nodes).
     #  @param IDsOfNodes the list of node IDs for creation of the element.
@@ -2753,7 +2921,7 @@ class Mesh:
     #  @ingroup l2_modif_add
     def SetNodeOnVertex(self, NodeID, Vertex):
         if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
-            VertexID = Vertex.GetSubShapeIndices()[0]
+            VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
         else:
             VertexID = Vertex
         try:
@@ -2771,7 +2939,7 @@ class Mesh:
     #  @ingroup l2_modif_add
     def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
         if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
-            EdgeID = Edge.GetSubShapeIndices()[0]
+            EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
         else:
             EdgeID = Edge
         try:
@@ -2789,7 +2957,7 @@ class Mesh:
     #  @ingroup l2_modif_add
     def SetNodeOnFace(self, NodeID, Face, u, v):
         if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
-            FaceID = Face.GetSubShapeIndices()[0]
+            FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
         else:
             FaceID = Face
         try:
@@ -2805,7 +2973,7 @@ class Mesh:
     #  @ingroup l2_modif_add
     def SetNodeInVolume(self, NodeID, Solid):
         if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
-            SolidID = Solid.GetSubShapeIndices()[0]
+            SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
         else:
             SolidID = Solid
         try:
@@ -2821,7 +2989,7 @@ class Mesh:
     #  @ingroup l2_modif_add
     def SetMeshElementOnShape(self, ElementID, Shape):
         if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
-            ShapeID = Shape.GetSubShapeIndices()[0]
+            ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
         else:
             ShapeID = Shape
         try:
@@ -2871,8 +3039,9 @@ class Mesh:
     #  @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 elementType type of elements to find; either of 
+    #         (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME); 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
@@ -2882,10 +3051,9 @@ class Mesh:
         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.
-
+    ## Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
+    #  0-IN, 1-OUT, 2-ON, 3-UNKNOWN
+    #  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)
 
@@ -3003,12 +3171,14 @@ class Mesh:
         return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
 
     ## Fuses the neighbouring triangles into quadrangles.
-    #  @param IDsOfElements The triangles to be fused,
-    #  @param theCriterion  is a numerical functor, in terms of enum SMESH.FunctorType, used to
-    #                       choose a neighbour to fuse with.
+    #  @param IDsOfElements The triangles to be fused.
+    #  @param theCriterion  a numerical functor, in terms of enum SMESH.FunctorType, used to
+    #          applied to possible quadrangles to choose a neighbour to fuse with.
+    #          Type SMESH.FunctorType._items in the Python Console to see all items.
+    #          Note that not all items correspond to numerical functors.
     #  @param MaxAngle      is the maximum angle between element normals at which the fusion
-    #                       is still performed; theMaxAngle is mesured in radians.
-    #                       Also it could be a name of variable which defines angle in degrees.
+    #          is still performed; theMaxAngle is mesured in radians.
+    #          Also it could be a name of variable which defines angle in degrees.
     #  @return TRUE in case of success, FALSE otherwise.
     #  @ingroup l2_modif_unitetri
     def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
@@ -3021,10 +3191,12 @@ class Mesh:
 
     ## Fuses the neighbouring triangles of the object into quadrangles
     #  @param theObject is mesh, submesh or group
-    #  @param theCriterion is a numerical functor, in terms of enum SMESH.FunctorType, used to
-    #         choose a neighbour to fuse with.
+    #  @param theCriterion is a numerical functor, in terms of enum SMESH.FunctorType,
+    #          applied to possible quadrangles to choose a neighbour to fuse with.
+    #          Type SMESH.FunctorType._items in the Python Console to see all items.
+    #          Note that not all items correspond to numerical functors.
     #  @param MaxAngle   a max angle between element normals at which the fusion
-    #                   is still performed; theMaxAngle is mesured in radians.
+    #          is still performed; theMaxAngle is mesured in radians.
     #  @return TRUE in case of success, FALSE otherwise.
     #  @ingroup l2_modif_unitetri
     def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
@@ -3037,9 +3209,11 @@ class Mesh:
 
     ## Splits quadrangles into triangles.
     #  @param IDsOfElements the faces to be splitted.
-    #  @param theCriterion   is a numerical functor, in terms of enum SMESH.FunctorType, used to
+    #  @param theCriterion is a numerical functor, in terms of enum SMESH.FunctorType, used to
     #         choose a diagonal for splitting. If @a theCriterion is None, which is a default
     #         value, then quadrangles will be split by the smallest diagonal.
+    #         Type SMESH.FunctorType._items in the Python Console to see all items.
+    #         Note that not all items correspond to numerical functors.
     #  @return TRUE in case of success, FALSE otherwise.
     #  @ingroup l2_modif_cutquadr
     def QuadToTri (self, IDsOfElements, theCriterion = None):
@@ -3056,6 +3230,8 @@ class Mesh:
     #  @param theCriterion is a numerical functor, in terms of enum SMESH.FunctorType, used to
     #         choose a diagonal for splitting. If @a theCriterion is None, which is a default
     #         value, then quadrangles will be split by the smallest diagonal.
+    #         Type SMESH.FunctorType._items in the Python Console to see all items.
+    #         Note that not all items correspond to numerical functors.
     #  @return TRUE in case of success, FALSE otherwise.
     #  @ingroup l2_modif_cutquadr
     def QuadToTriObject (self, theObject, theCriterion = None):
@@ -3107,6 +3283,8 @@ class Mesh:
     #  @param IDOfQuad   the ID of the quadrangle to be splitted.
     #  @param theCriterion  is a numerical functor, in terms of enum SMESH.FunctorType, used to
     #         choose a diagonal for splitting.
+    #         Type SMESH.FunctorType._items in the Python Console to see all items.
+    #         Note that not all items correspond to numerical functors.
     #  @return 1 if 1-3 diagonal is better, 2 if 2-4
     #          diagonal is better, 0 if error occurs.
     #  @ingroup l2_modif_cutquadr
@@ -3127,6 +3305,29 @@ class Mesh:
             elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
             unRegister.set( elems )
         self.editor.SplitVolumesIntoTetra(elems, method)
+        return
+
+    ## Split bi-quadratic elements into linear ones without creation of additional nodes:
+    #   - bi-quadratic triangle will be split into 3 linear quadrangles;
+    #   - bi-quadratic quadrangle will be split into 4 linear quadrangles;
+    #   - tri-quadratic hexahedron will be split into 8 linear hexahedra.
+    #   Quadratic elements of lower dimension  adjacent to the split bi-quadratic element
+    #   will be split in order to keep the mesh conformal.
+    #  @param elems - elements to split: sub-meshes, groups, filters or element IDs;
+    #         if None (default), all bi-quadratic elements will be split
+    #  @ingroup l2_modif_cutquadr
+    def SplitBiQuadraticIntoLinear(self, elems=None):
+        unRegister = genObjUnRegister()
+        if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
+            elems = self.editor.MakeIDSource(elems, SMESH.ALL)
+            unRegister.set( elems )
+        if elems is None:
+            elems = [ self.GetMesh() ]
+        if isinstance( elems, Mesh ):
+            elems = [ elems.GetMesh() ]
+        if not isinstance( elems, list ):
+            elems = [elems]
+        self.editor.SplitBiQuadraticIntoLinear( elems )
 
     ## Splits hexahedra into prisms
     #  @param elems either a list of elements or a mesh or a group or a submesh or a filter
@@ -3387,11 +3588,11 @@ class Mesh:
     #  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
+    #         1 - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
     #  @param theSubMesh a group or a sub-mesh to convert; WARNING: in this case the mesh can become not conformal
     #  @param theToBiQuad If True, converts the mesh to bi-quadratic
     #  @ingroup l2_modif_tofromqu
-    def ConvertToQuadratic(self, theForce3d, theSubMesh=None, theToBiQuad=False):
+    def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
         if isinstance( theSubMesh, Mesh ):
             theSubMesh = theSubMesh.mesh
         if theToBiQuad:
@@ -3419,15 +3620,15 @@ class Mesh:
     ## 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()
+    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
+    #  @param dimension - defines type of boundary elements to create, either of
+    #                     { 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
@@ -3457,7 +3658,8 @@ class Mesh:
     ##
     # @brief Creates missing boundary elements around either the whole mesh or 
     #    groups of elements
-    #  @param dimension - defines type of boundary elements to create
+    #  @param dimension - defines type of boundary elements to create, either of
+    #                     { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
     #  @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 
@@ -3487,10 +3689,27 @@ class Mesh:
     def RenumberElements(self):
         self.editor.RenumberElements()
 
-    ## Generates new elements by rotation of the elements around the axis
-    #  @param IDsOfElements the list of ids of elements to sweep
-    #  @param Axis the axis of rotation, AxisStruct or line(geom object)
-    #  @param AngleInRadians the angle of Rotation (in radians) or a name of variable which defines angle in degrees
+    ## Private method converting \a arg into a list of SMESH_IdSource's
+    def _getIdSourceList(self, arg, idType, unRegister):
+        if arg and isinstance( arg, list ):
+            if isinstance( arg[0], int ):
+                arg = self.GetIDSource( arg, idType )
+                unRegister.set( arg )
+            elif isinstance( arg[0], Mesh ):
+                arg[0] = arg[0].GetMesh()
+        elif isinstance( arg, Mesh ):
+            arg = arg.GetMesh()
+        if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
+            arg = [arg]
+        return arg
+
+    ## Generates new elements by rotation of the given elements and nodes around the axis
+    #  @param nodes - nodes to revolve: a list including ids, groups, sub-meshes or a mesh
+    #  @param edges - edges to revolve: a list including ids, groups, sub-meshes or a mesh
+    #  @param faces - faces to revolve: a list including ids, groups, sub-meshes or a mesh
+    #  @param Axis the axis of rotation: AxisStruct, line (geom object) or [x,y,z,dx,dy,dz]
+    #  @param AngleInRadians the angle of Rotation (in radians) or a name of variable
+    #         which defines angle in degrees
     #  @param NbOfSteps the number of steps
     #  @param Tolerance tolerance
     #  @param MakeGroups forces the generation of new groups from existing ones
@@ -3498,23 +3717,44 @@ class Mesh:
     #                    of all steps, else - size of each step
     #  @return the list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
     #  @ingroup l2_modif_extrurev
-    def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
-                      MakeGroups=False, TotalAngle=False):
-        if IDsOfElements == []:
-            IDsOfElements = self.GetElementsId()
-        if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
-            Axis = self.smeshpyD.GetAxisStruct(Axis)
+    def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
+                             MakeGroups=False, TotalAngle=False):
+        unRegister = genObjUnRegister()
+        nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
+        edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
+        faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
+
+        if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
+            Axis = self.smeshpyD.GetAxisStruct( Axis )
+        if isinstance( Axis, list ):
+            Axis = SMESH.AxisStruct( *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
-        if MakeGroups:
-            return self.editor.RotationSweepMakeGroups(IDsOfElements, Axis,
-                                                       AngleInRadians, NbOfSteps, Tolerance)
-        self.editor.RotationSweep(IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance)
-        return []
+        return self.editor.RotationSweepObjects( nodes, edges, faces,
+                                                 Axis, AngleInRadians,
+                                                 NbOfSteps, Tolerance, MakeGroups)
+
+    ## Generates new elements by rotation of the elements around the axis
+    #  @param IDsOfElements the list of ids of elements to sweep
+    #  @param Axis the axis of rotation, AxisStruct or line(geom object)
+    #  @param AngleInRadians the angle of Rotation (in radians) or a name of variable which defines angle in degrees
+    #  @param NbOfSteps the number of steps
+    #  @param Tolerance tolerance
+    #  @param MakeGroups forces the generation of new groups from existing ones
+    #  @param TotalAngle gives meaning of AngleInRadians: if True then it is an angular size
+    #                    of all steps, else - size of each step
+    #  @return the list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
+    #  @ingroup l2_modif_extrurev
+    def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
+                      MakeGroups=False, TotalAngle=False):
+        return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
+                                         AngleInRadians, NbOfSteps, Tolerance,
+                                         MakeGroups, TotalAngle)
 
     ## Generates new elements by rotation of the elements of object around the axis
     #  @param theObject object which elements should be sweeped.
@@ -3530,21 +3770,9 @@ class Mesh:
     #  @ingroup l2_modif_extrurev
     def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
                             MakeGroups=False, TotalAngle=False):
-        if ( isinstance( theObject, Mesh )):
-            theObject = theObject.GetMesh()
-        if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
-            Axis = self.smeshpyD.GetAxisStruct(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
-        if MakeGroups:
-            return self.editor.RotationSweepObjectMakeGroups(theObject, Axis, AngleInRadians,
-                                                             NbOfSteps, Tolerance)
-        self.editor.RotationSweepObject(theObject, Axis, AngleInRadians, NbOfSteps, Tolerance)
-        return []
+        return self.RotationSweepObjects( [], theObject, theObject, Axis,
+                                          AngleInRadians, NbOfSteps, Tolerance,
+                                          MakeGroups, TotalAngle )
 
     ## Generates new elements by rotation of the elements of object around the axis
     #  @param theObject object which elements should be sweeped.
@@ -3560,21 +3788,9 @@ class Mesh:
     #  @ingroup l2_modif_extrurev
     def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
                               MakeGroups=False, TotalAngle=False):
-        if ( isinstance( theObject, Mesh )):
-            theObject = theObject.GetMesh()
-        if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
-            Axis = self.smeshpyD.GetAxisStruct(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
-        if MakeGroups:
-            return self.editor.RotationSweepObject1DMakeGroups(theObject, Axis, AngleInRadians,
-                                                               NbOfSteps, Tolerance)
-        self.editor.RotationSweepObject1D(theObject, Axis, AngleInRadians, NbOfSteps, Tolerance)
-        return []
+        return self.RotationSweepObjects([],theObject,[], Axis,
+                                         AngleInRadians, NbOfSteps, Tolerance,
+                                         MakeGroups, TotalAngle)
 
     ## Generates new elements by rotation of the elements of object around the axis
     #  @param theObject object which elements should be sweeped.
@@ -3590,113 +3806,113 @@ class Mesh:
     #  @ingroup l2_modif_extrurev
     def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
                               MakeGroups=False, TotalAngle=False):
-        if ( isinstance( theObject, Mesh )):
-            theObject = theObject.GetMesh()
-        if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
-            Axis = self.smeshpyD.GetAxisStruct(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
-        if MakeGroups:
-            return self.editor.RotationSweepObject2DMakeGroups(theObject, Axis, AngleInRadians,
-                                                             NbOfSteps, Tolerance)
-        self.editor.RotationSweepObject2D(theObject, Axis, AngleInRadians, NbOfSteps, Tolerance)
-        return []
+        return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
+                                         NbOfSteps, Tolerance, MakeGroups, TotalAngle)
 
-    ## Generates new elements by extrusion of the elements with given ids
-    #  @param IDsOfElements the list of elements ids for extrusion
+    ## Generates new elements by extrusion of the given elements and nodes
+    #  @param nodes - nodes to extrude: a list including ids, groups, sub-meshes or a mesh
+    #  @param edges - edges to extrude: a list including ids, groups, sub-meshes or a mesh
+    #  @param faces - faces to extrude: a list including ids, groups, sub-meshes or a mesh
     #  @param StepVector vector or DirStruct or 3 vector components, 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, IsNodes = False):
-        if IDsOfElements == []:
-            IDsOfElements = self.GetElementsId()
+    def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False):
+        unRegister = genObjUnRegister()
+        nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
+        edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
+        faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
+
         if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
             StepVector = self.smeshpyD.GetDirStruct(StepVector)
         if isinstance( StepVector, list ):
             StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
+
         NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
         Parameters = StepVector.PS.parameters + var_separator + Parameters
         self.mesh.SetParameters(Parameters)
-        if MakeGroups:
-            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 []
+
+        return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
+                                                  StepVector, NbOfSteps, MakeGroups)
+
 
     ## Generates new elements by extrusion of the elements with given ids
-    #  @param IDsOfElements is ids of elements
+    #  @param IDsOfElements the list of ids of elements or nodes for extrusion
     #  @param StepVector vector or DirStruct or 3 vector components, 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 ExtrFlags sets flags for extrusion
-    #  @param SewTolerance uses for comparing locations of nodes if flag
-    #         EXTRUSION_FLAG_SEW is set
     #  @param MakeGroups forces the generation of new groups from existing ones
-    #  @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
+    #  @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 AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
-                          ExtrFlags, SewTolerance, MakeGroups=False):
-        if ( isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object)):
-            StepVector = self.smeshpyD.GetDirStruct(StepVector)
-        if isinstance( StepVector, list ):
-            StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
-        if MakeGroups:
-            return self.editor.AdvancedExtrusionMakeGroups(IDsOfElements, StepVector, NbOfSteps,
-                                                           ExtrFlags, SewTolerance)
-        self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
-                                      ExtrFlags, SewTolerance)
-        return []
+    def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
+        n,e,f = [],[],[]
+        if IsNodes: n = IDsOfElements
+        else      : e,f, = IDsOfElements,IDsOfElements
+        return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
+
+    ## Generates new elements by extrusion along the normal to a discretized surface or wire
+    #  @param Elements elements to extrude - a list including ids, groups, sub-meshes or a mesh.
+    #         Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
+    #  @param StepSize length of one extrusion step (the total extrusion
+    #         length will be \a NbOfSteps * \a StepSize ).
+    #  @param NbOfSteps number of extrusion steps.
+    #  @param ByAverageNormal if True each node is translated by \a StepSize
+    #         along the average of the normal vectors to the faces sharing the node;
+    #         else each node is translated along the same average normal till
+    #         intersection with the plane got by translation of the face sharing
+    #         the node along its own normal by \a StepSize.
+    #  @param UseInputElemsOnly to use only \a Elements when computing extrusion direction
+    #         for every node of \a Elements.
+    #  @param MakeGroups forces generation of new groups from existing ones.
+    #  @param Dim dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
+    #         is not yet implemented. This parameter is used if \a Elements contains
+    #         both faces and edges, i.e. \a Elements is a Mesh.
+    #  @return the list of created groups (SMESH_GroupBase) if \a MakeGroups=True,
+    #          empty list otherwise.
+    #  @ingroup l2_modif_extrurev
+    def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
+                          ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
+        unRegister = genObjUnRegister()
+        if isinstance( Elements, Mesh ):
+            Elements = [ Elements.GetMesh() ]
+        if isinstance( Elements, list ):
+            if not Elements:
+                raise RuntimeError, "Elements empty!"
+            if isinstance( Elements[0], int ):
+                Elements = self.GetIDSource( Elements, SMESH.ALL )
+                unRegister.set( Elements )
+        if not isinstance( Elements, list ):
+            Elements = [ Elements ]
+        StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
+        self.mesh.SetParameters(Parameters)
+        return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
+                                             ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
 
-    ## Generates new elements by extrusion of the elements which belong to the object
-    #  @param theObject the object which elements should be processed.
-    #                   It can be a mesh, a sub mesh or a group.
+    ## Generates new elements by extrusion of the elements or nodes which belong to the object
+    #  @param theObject the object whose elements or nodes should be processed.
+    #                   It can be a mesh, a sub-mesh or a group.
     #  @param StepVector vector or DirStruct or 3 vector components, 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
+    #  @param IsNodes is True if elements to extrude 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, IsNodes=False):
-        if ( isinstance( theObject, Mesh )):
-            theObject = theObject.GetMesh()
-        if ( isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object)):
-            StepVector = self.smeshpyD.GetDirStruct(StepVector)
-        if isinstance( StepVector, list ):
-            StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
-        NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
-        Parameters = StepVector.PS.parameters + var_separator + Parameters
-        self.mesh.SetParameters(Parameters)
-        if MakeGroups:
-            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.
-    #                   It can be a mesh, a sub mesh or a group.
+        n,e,f = [],[],[]
+        if IsNodes: n    = theObject
+        else      : e,f, = theObject,theObject
+        return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
+
+    ## Generates new elements by extrusion of edges which belong to the object
+    #  @param theObject object whose 1D elements should be processed.
+    #                   It can be a mesh, a sub-mesh or a group.
     #  @param StepVector vector or DirStruct or 3 vector components, defining
     #         the direction and value of extrusion for one step (the total extrusion
     #         length will be NbOfSteps * ||StepVector||)
@@ -3705,23 +3921,11 @@ class Mesh:
     #  @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
     #  @ingroup l2_modif_extrurev
     def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
-        if ( isinstance( theObject, Mesh )):
-            theObject = theObject.GetMesh()
-        if ( isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object)):
-            StepVector = self.smeshpyD.GetDirStruct(StepVector)
-        if isinstance( StepVector, list ):
-            StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
-        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)
-        self.editor.ExtrusionSweepObject1D(theObject, StepVector, NbOfSteps)
-        return []
+        return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
 
-    ## Generates new elements by extrusion of the elements which belong to the object
-    #  @param theObject object which elements should be processed.
-    #                   It can be a mesh, a sub mesh or a group.
+    ## Generates new elements by extrusion of faces which belong to the object
+    #  @param theObject object whose 2D elements should be processed.
+    #                   It can be a mesh, a sub-mesh or a group.
     #  @param StepVector vector or DirStruct or 3 vector components, defining
     #         the direction and value of extrusion for one step (the total extrusion
     #         length will be NbOfSteps * ||StepVector||)
@@ -3730,25 +3934,75 @@ class Mesh:
     #  @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
     #  @ingroup l2_modif_extrurev
     def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
-        if ( isinstance( theObject, Mesh )):
-            theObject = theObject.GetMesh()
-        if ( isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object)):
+        return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
+
+    ## Generates new elements by extrusion of the elements with given ids
+    #  @param IDsOfElements is ids of elements
+    #  @param StepVector vector or DirStruct or 3 vector components, 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 ExtrFlags sets flags for extrusion
+    #  @param SewTolerance uses for comparing locations of nodes if flag
+    #         EXTRUSION_FLAG_SEW is set
+    #  @param MakeGroups forces the generation of new groups from existing ones
+    #  @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
+    #  @ingroup l2_modif_extrurev
+    def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
+                          ExtrFlags, SewTolerance, MakeGroups=False):
+        if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
             StepVector = self.smeshpyD.GetDirStruct(StepVector)
         if isinstance( StepVector, list ):
             StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
-        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 []
+        return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
+                                             ExtrFlags, SewTolerance, MakeGroups)
 
+    ## Generates new elements by extrusion of the given elements and nodes along the path.
+    #  The path of extrusion must be a meshed edge.
+    #  @param Nodes nodes to extrude: a list including ids, groups, sub-meshes or a mesh
+    #  @param Edges edges to extrude: a list including ids, groups, sub-meshes or a mesh
+    #  @param Faces faces to extrude: a list including ids, groups, sub-meshes or a mesh
+    #  @param PathMesh 1D mesh or 1D sub-mesh, along which proceeds the extrusion
+    #  @param PathShape shape (edge) defines the sub-mesh of PathMesh if PathMesh
+    #         contains not only path segments, else it can be None
+    #  @param NodeStart the first or the last node on the 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
+    #  @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
+    #  @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error
+    #  @ingroup l2_modif_extrurev
+    def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathMesh, PathShape=None,
+                                  NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
+                                  HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False):
+        unRegister = genObjUnRegister()
+        Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
+        Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
+        Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
 
+        if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
+            RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
+        if isinstance( RefPoint, list ):
+            if not RefPoint: RefPoint = [0,0,0]
+            RefPoint = SMESH.PointStruct( *RefPoint )
+        if isinstance( PathMesh, Mesh ):
+            PathMesh = PathMesh.GetMesh()
+        Angles,AnglesParameters,hasVars = ParseAngles(Angles)
+        Parameters = AnglesParameters + var_separator + RefPoint.parameters
+        self.mesh.SetParameters(Parameters)
+        return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
+                                                     PathMesh, PathShape, NodeStart,
+                                                     HasAngles, Angles, LinearVariation,
+                                                     HasRefPoint, RefPoint, MakeGroups)
 
     ## 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 Base mesh or group, or sub-mesh, 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
@@ -3767,36 +4021,18 @@ class Mesh:
     #          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, geomBuilder.GEOM._objref_GEOM_Object):
-            RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
-            pass
-        elif isinstance( RefPoint, list ):
-            RefPoint = PointStruct(*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"
-
+                            HasAngles=False, Angles=[], LinearVariation=False,
+                            HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
+                            ElemType=SMESH.FACE):
+        n,e,f = [],[],[]
+        if ElemType == SMESH.NODE: n = Base
+        if ElemType == SMESH.EDGE: e = Base
+        if ElemType == SMESH.FACE: f = Base
+        gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
+                                               HasAngles, Angles, LinearVariation,
+                                               HasRefPoint, RefPoint, MakeGroups)
+        if MakeGroups: return gr,er
+        return er
 
     ## Generates new elements by extrusion of the given elements
     #  The path of extrusion must be a meshed edge.
@@ -3817,32 +4053,20 @@ class Mesh:
     #          only SMESH::Extrusion_Error otherwise
     #  @ingroup l2_modif_extrurev
     def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
-                           HasAngles, Angles, HasRefPoint, RefPoint,
+                           HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
                            MakeGroups=False, LinearVariation=False):
-        if IDsOfElements == []:
-            IDsOfElements = self.GetElementsId()
-        if ( isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object)):
-            RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
-            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
-        if MakeGroups:
-            return self.editor.ExtrusionAlongPathMakeGroups(IDsOfElements, PathMesh,
-                                                            PathShape, NodeStart, HasAngles,
-                                                            Angles, HasRefPoint, RefPoint)
-        return self.editor.ExtrusionAlongPath(IDsOfElements, PathMesh, PathShape,
-                                              NodeStart, HasAngles, Angles, HasRefPoint, RefPoint)
+        n,e,f = [],IDsOfElements,IDsOfElements
+        gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
+                                               NodeStart, HasAngles, Angles,
+                                               LinearVariation,
+                                               HasRefPoint, RefPoint, MakeGroups)
+        if MakeGroups: return gr,er
+        return er
 
     ## 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.
-    #                   It can be a mesh, a sub mesh or a group.
+    #  @param theObject the object whose 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
@@ -3859,32 +4083,19 @@ class Mesh:
     #          only SMESH::Extrusion_Error otherwise
     #  @ingroup l2_modif_extrurev
     def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
-                                 HasAngles, Angles, HasRefPoint, RefPoint,
+                                 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
                                  MakeGroups=False, LinearVariation=False):
-        if ( isinstance( theObject, Mesh )):
-            theObject = theObject.GetMesh()
-        if ( isinstance( RefPoint, geomBuilder.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
-        if MakeGroups:
-            return self.editor.ExtrusionAlongPathObjectMakeGroups(theObject, PathMesh,
-                                                                  PathShape, NodeStart, HasAngles,
-                                                                  Angles, HasRefPoint, RefPoint)
-        return self.editor.ExtrusionAlongPathObject(theObject, PathMesh, PathShape,
-                                                    NodeStart, HasAngles, Angles, HasRefPoint,
-                                                    RefPoint)
-
-    ## Generates new elements by extrusion of the elements which belong to the object
+        n,e,f = [],theObject,theObject
+        gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
+                                               HasAngles, Angles, LinearVariation,
+                                               HasRefPoint, RefPoint, MakeGroups)
+        if MakeGroups: return gr,er
+        return er
+
+    ## Generates new elements by extrusion of mesh segments which belong to the object
     #  The path of extrusion must be a meshed edge.
-    #  @param theObject the object which elements should be processed.
-    #                   It can be a mesh, a sub mesh or a group.
+    #  @param theObject the object whose 1D 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
@@ -3901,32 +4112,19 @@ class Mesh:
     #          only SMESH::Extrusion_Error otherwise
     #  @ingroup l2_modif_extrurev
     def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
-                                   HasAngles, Angles, HasRefPoint, RefPoint,
+                                   HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
                                    MakeGroups=False, LinearVariation=False):
-        if ( isinstance( theObject, Mesh )):
-            theObject = theObject.GetMesh()
-        if ( isinstance( RefPoint, geomBuilder.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
-        if MakeGroups:
-            return self.editor.ExtrusionAlongPathObject1DMakeGroups(theObject, PathMesh,
-                                                                    PathShape, NodeStart, HasAngles,
-                                                                    Angles, HasRefPoint, RefPoint)
-        return self.editor.ExtrusionAlongPathObject1D(theObject, PathMesh, PathShape,
-                                                      NodeStart, HasAngles, Angles, HasRefPoint,
-                                                      RefPoint)
-
-    ## Generates new elements by extrusion of the elements which belong to the object
+        n,e,f = [],theObject,[]
+        gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
+                                               HasAngles, Angles, LinearVariation,
+                                               HasRefPoint, RefPoint, MakeGroups)
+        if MakeGroups: return gr,er
+        return er
+
+    ## Generates new elements by extrusion of faces which belong to the object
     #  The path of extrusion must be a meshed edge.
-    #  @param theObject the object which elements should be processed.
-    #                   It can be a mesh, a sub mesh or a group.
+    #  @param theObject the object whose 2D 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
@@ -3943,33 +4141,20 @@ class Mesh:
     #          only SMESH::Extrusion_Error otherwise
     #  @ingroup l2_modif_extrurev
     def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
-                                   HasAngles, Angles, HasRefPoint, RefPoint,
+                                   HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
                                    MakeGroups=False, LinearVariation=False):
-        if ( isinstance( theObject, Mesh )):
-            theObject = theObject.GetMesh()
-        if ( isinstance( RefPoint, geomBuilder.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
-        if MakeGroups:
-            return self.editor.ExtrusionAlongPathObject2DMakeGroups(theObject, PathMesh,
-                                                                    PathShape, NodeStart, HasAngles,
-                                                                    Angles, HasRefPoint, RefPoint)
-        return self.editor.ExtrusionAlongPathObject2D(theObject, PathMesh, PathShape,
-                                                      NodeStart, HasAngles, Angles, HasRefPoint,
-                                                      RefPoint)
+        n,e,f = [],[],theObject
+        gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
+                                               HasAngles, Angles, LinearVariation,
+                                               HasRefPoint, RefPoint, MakeGroups)
+        if MakeGroups: return gr,er
+        return er
 
     ## Creates a symmetrical copy of mesh elements
     #  @param IDsOfElements list of elements ids
     #  @param Mirror is AxisStruct or geom object(point, line, plane)
-    #  @param theMirrorType is  POINT, AXIS or PLANE
-    #  If the Mirror is a geom object this parameter is unnecessary
+    #  @param theMirrorType smeshBuilder.POINT, smeshBuilder.AXIS or smeshBuilder.PLANE
+    #         If the Mirror is a geom object this parameter is unnecessary
     #  @param Copy allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
     #  @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
@@ -3990,8 +4175,8 @@ class Mesh:
     ## Creates a new mesh by a symmetrical copy of mesh elements
     #  @param IDsOfElements the list of elements ids
     #  @param Mirror is AxisStruct or geom object (point, line, plane)
-    #  @param theMirrorType is  POINT, AXIS or PLANE
-    #  If the Mirror is a geom object this parameter is unnecessary
+    #  @param theMirrorType smeshBuilder.POINT, smeshBuilder.AXIS or smeshBuilder.PLANE
+    #         If the Mirror is a geom object this parameter is unnecessary
     #  @param MakeGroups to generate new groups from existing ones
     #  @param NewMeshName a name of the new mesh to create
     #  @return instance of Mesh class
@@ -4011,8 +4196,8 @@ class Mesh:
     ## Creates a symmetrical copy of the object
     #  @param theObject mesh, submesh or group
     #  @param Mirror AxisStruct or geom object (point, line, plane)
-    #  @param theMirrorType is  POINT, AXIS or PLANE
-    #  If the Mirror is a geom object this parameter is unnecessary
+    #  @param theMirrorType smeshBuilder.POINT, smeshBuilder.AXIS or smeshBuilder.PLANE
+    #         If the Mirror is a geom object this parameter is unnecessary
     #  @param Copy allows copying the element (Copy is 1) or replacing it with its mirror (Copy is 0)
     #  @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
@@ -4033,8 +4218,8 @@ class Mesh:
     ## Creates a new mesh by a symmetrical copy of the object
     #  @param theObject mesh, submesh or group
     #  @param Mirror AxisStruct or geom object (point, line, plane)
-    #  @param theMirrorType POINT, AXIS or PLANE
-    #  If the Mirror is a geom object this parameter is unnecessary
+    #  @param theMirrorType smeshBuilder.POINT, smeshBuilder.AXIS or smeshBuilder.PLANE
+    #         If the Mirror is a geom object this parameter is unnecessary
     #  @param MakeGroups forces the generation of new groups from existing ones
     #  @param NewMeshName the name of the new mesh to create
     #  @return instance of Mesh class
@@ -4131,7 +4316,7 @@ class Mesh:
 
     ## Scales the object
     #  @param theObject - the object to translate (mesh, submesh, or group)
-    #  @param thePoint - base point for scale
+    #  @param thePoint - base point for scale (SMESH.PointStruct or list of 3 coordinates)
     #  @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
@@ -4145,6 +4330,8 @@ class Mesh:
         if ( isinstance( theObject, list )):
             theObject = self.GetIDSource(theObject, SMESH.ALL)
             unRegister.set( theObject )
+        if ( isinstance( thePoint, list )):
+            thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
         if ( isinstance( theScaleFact, float )):
              theScaleFact = [theScaleFact]
         if ( isinstance( theScaleFact, int )):
@@ -4159,7 +4346,7 @@ class Mesh:
 
     ## 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 thePoint - base point for scale (SMESH.PointStruct or list of 3 coordinates)
     #  @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
@@ -4171,6 +4358,8 @@ class Mesh:
         if ( isinstance( theObject, list )):
             theObject = self.GetIDSource(theObject,SMESH.ALL)
             unRegister.set( theObject )
+        if ( isinstance( thePoint, list )):
+            thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
         if ( isinstance( theScaleFact, float )):
              theScaleFact = [theScaleFact]
         if ( isinstance( theScaleFact, int )):
@@ -4267,45 +4456,63 @@ class Mesh:
 
     ## Finds groups of adjacent nodes within Tolerance.
     #  @param Tolerance the value of tolerance
-    #  @return the list of pairs of nodes IDs (e.g. [[1,12],[25,4]])
+    #  @param SeparateCornerAndMediumNodes if @c True, in quadratic mesh puts
+    #         corner and medium nodes in separate groups thus preventing
+    #         their further merge.
+    #  @return the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
     #  @ingroup l2_modif_trsf
-    def FindCoincidentNodes (self, Tolerance):
-        return self.editor.FindCoincidentNodes(Tolerance)
+    def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
+        return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
 
     ## 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 pairs of nodes IDs (e.g. [[1,12],[25,4]])
+    #  @param SeparateCornerAndMediumNodes if @c True, in quadratic mesh puts
+    #         corner and medium nodes in separate groups thus preventing
+    #         their further merge.
+    #  @return the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
     #  @ingroup l2_modif_trsf
-    def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance, exceptNodes=[]):
+    def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
+                                   exceptNodes=[], SeparateCornerAndMediumNodes=False):
         unRegister = genObjUnRegister()
         if (isinstance( SubMeshOrGroup, Mesh )):
             SubMeshOrGroup = SubMeshOrGroup.GetMesh()
-        if not isinstance( exceptNodes, list):
+        if not isinstance( exceptNodes, list ):
             exceptNodes = [ exceptNodes ]
-        if exceptNodes and isinstance( exceptNodes[0], int):
-            exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE)]
+        if exceptNodes and isinstance( exceptNodes[0], int ):
+            exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
             unRegister.set( exceptNodes )
-        return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,exceptNodes)
+        return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
+                                                        exceptNodes, SeparateCornerAndMediumNodes)
 
     ## Merges nodes
-    #  @param GroupsOfNodes a list of pairs of nodes IDs for merging (e.g. [[1,12],[25,4]])
+    #  @param GroupsOfNodes a list of groups of nodes IDs for merging
+    #         (e.g. [[1,12,13],[25,4]], then nodes 12, 13 and 4 will be removed and replaced
+    #         by nodes 1 and 25 correspondingly in all elements and groups
+    #  @param NodesToKeep nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
+    #         If @a NodesToKeep does not include a node to keep for some group to merge,
+    #         then the first node in the group is kept.
     #  @ingroup l2_modif_trsf
-    def MergeNodes (self, GroupsOfNodes):
-        self.editor.MergeNodes(GroupsOfNodes)
+    def MergeNodes (self, GroupsOfNodes, NodesToKeep=[]):
+        # NodesToKeep are converted to SMESH_IDSource in meshEditor.MergeNodes()
+        self.editor.MergeNodes(GroupsOfNodes,NodesToKeep)
 
     ## Finds the elements built on the same nodes.
     #  @param MeshOrSubMeshOrGroup Mesh or SubMesh, or Group of elements for searching
-    #  @return the list of pairs of equal elements IDs (e.g. [[1,12],[25,4]])
+    #  @return the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
     #  @ingroup l2_modif_trsf
-    def FindEqualElements (self, MeshOrSubMeshOrGroup):
-        if ( isinstance( MeshOrSubMeshOrGroup, Mesh )):
+    def FindEqualElements (self, MeshOrSubMeshOrGroup=None):
+        if not MeshOrSubMeshOrGroup:
+            MeshOrSubMeshOrGroup=self.mesh
+        elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
             MeshOrSubMeshOrGroup = MeshOrSubMeshOrGroup.GetMesh()
-        return self.editor.FindEqualElements(MeshOrSubMeshOrGroup)
+        return self.editor.FindEqualElements( MeshOrSubMeshOrGroup )
 
     ## Merges elements in each given group.
-    #  @param GroupsOfElementsID a list of pairs of elements IDs for merging (e.g. [[1,12],[25,4]])
+    #  @param GroupsOfElementsID a list of groups of elements IDs for merging
+    #        (e.g. [[1,12,13],[25,4]], then elements 12, 13 and 4 will be removed and
+    #        replaced by elements 1 and 25 in all groups)
     #  @ingroup l2_modif_trsf
     def MergeElements(self, GroupsOfElementsID):
         self.editor.MergeElements(GroupsOfElementsID)
@@ -4315,6 +4522,52 @@ class Mesh:
     def MergeEqualElements(self):
         self.editor.MergeEqualElements()
 
+    ## Returns groups of FreeBorder's coincident within the given tolerance.
+    #  @param tolerance the tolerance. If the tolerance <= 0.0 then one tenth of an average
+    #         size of elements adjacent to free borders being compared is used.
+    #  @return SMESH.CoincidentFreeBorders structure
+    #  @ingroup l2_modif_trsf
+    def FindCoincidentFreeBorders (self, tolerance=0.):
+        return self.editor.FindCoincidentFreeBorders( tolerance )
+        
+    ## Sew FreeBorder's of each group
+    #  @param freeBorders either a SMESH.CoincidentFreeBorders structure or a list of lists
+    #         where each enclosed list contains node IDs of a group of coincident free
+    #         borders such that each consequent triple of IDs within a group describes
+    #         a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
+    #         last node of a border.
+    #         For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
+    #         groups of coincident free borders, each group including two borders.
+    #  @param createPolygons if @c True faces adjacent to free borders are converted to
+    #         polygons if a node of opposite border falls on a face edge, else such
+    #         faces are split into several ones.
+    #  @param createPolyhedra if @c True volumes adjacent to free borders are converted to
+    #         polyhedra if a node of opposite border falls on a volume edge, else such
+    #         volumes, if any, remain intact and the mesh becomes non-conformal.
+    #  @return a number of successfully sewed groups
+    #  @ingroup l2_modif_trsf
+    def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
+        if freeBorders and isinstance( freeBorders, list ):
+            # construct SMESH.CoincidentFreeBorders
+            if isinstance( freeBorders[0], int ):
+                freeBorders = [freeBorders]
+            borders = []
+            coincidentGroups = []
+            for nodeList in freeBorders:
+                if not nodeList or len( nodeList ) % 3:
+                    raise ValueError, "Wrong number of nodes in this group: %s" % nodeList
+                group = []
+                while nodeList:
+                    group.append  ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
+                    borders.append( SMESH.FreeBorder( nodeList[:3] ))
+                    nodeList = nodeList[3:]
+                    pass
+                coincidentGroups.append( group )
+                pass
+            freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
+
+        return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
+
     ## Sews free borders
     #  @return SMESH::Sew_Error
     #  @ingroup l2_modif_trsf
@@ -4385,11 +4638,12 @@ class Mesh:
     def ClearLastCreated(self):
         self.editor.ClearLastCreated()
 
-    ## Creates Duplicates given elements, i.e. creates new elements based on the 
+    ## Creates duplicates of given elements, i.e. creates new elements based on the 
     #  same nodes as the given ones.
     #  @param theElements - container of elements to duplicate. It can be a Mesh,
-    #         sub-mesh, group, filter or a list of element IDs.
-    # @param theGroupName - a name of group to contain the generated elements.
+    #         sub-mesh, group, filter or a list of element IDs. If \a theElements is
+    #         a Mesh, elements of highest dimension are duplicated
+    #  @param theGroupName - a name of group to contain the generated elements.
     #                    If a group with such a name already exists, the new elements
     #                    are added to the existng group, else a new group is created.
     #                    If \a theGroupName is empty, new elements are not added 
@@ -4589,9 +4843,15 @@ class Mesh:
             self.functors[ funcType._v ] = fn
         return fn
 
-    def _valueFromFunctor(self, funcType, elemId):
+    ## Returns value of a functor for a given element
+    #  @param funcType an item of SMESH.FunctorType enum
+    #         Type "SMESH.FunctorType._items" in the Python Console to see all items.
+    #  @param elemId element or node ID
+    #  @param isElem @a elemId is ID of element or node
+    #  @return the functor value or zero in case of invalid arguments
+    def FunctorValue(self, funcType, elemId, isElem=True):
         fn = self._getFunctor( funcType )
-        if fn.GetElementType() == self.GetElementType(elemId, True):
+        if fn.GetElementType() == self.GetElementType(elemId, isElem):
             val = fn.GetValue(elemId)
         else:
             val = 0
@@ -4606,7 +4866,7 @@ class Mesh:
         if elemId == None:
             length = self.smeshpyD.GetLength(self)
         else:
-            length = self._valueFromFunctor(SMESH.FT_Length, elemId)
+            length = self.FunctorValue(SMESH.FT_Length, elemId)
         return length
 
     ## Get area of 2D element or sum of areas of all 2D mesh elements
@@ -4618,7 +4878,7 @@ class Mesh:
         if elemId == None:
             area = self.smeshpyD.GetArea(self)
         else:
-            area = self._valueFromFunctor(SMESH.FT_Area, elemId)
+            area = self.FunctorValue(SMESH.FT_Area, elemId)
         return area
 
     ## Get volume of 3D element or sum of volumes of all 3D mesh elements
@@ -4630,7 +4890,7 @@ class Mesh:
         if elemId == None:
             volume = self.smeshpyD.GetVolume(self)
         else:
-            volume = self._valueFromFunctor(SMESH.FT_Volume3D, elemId)
+            volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
         return volume
 
     ## Get maximum element length.
@@ -4642,7 +4902,7 @@ class Mesh:
             ftype = SMESH.FT_MaxElementLength3D
         else:
             ftype = SMESH.FT_MaxElementLength2D
-        return self._valueFromFunctor(ftype, elemId)
+        return self.FunctorValue(ftype, elemId)
 
     ## Get aspect ratio of 2D or 3D element.
     #  @param elemId mesh element ID
@@ -4653,35 +4913,35 @@ class Mesh:
             ftype = SMESH.FT_AspectRatio3D
         else:
             ftype = SMESH.FT_AspectRatio
-        return self._valueFromFunctor(ftype, elemId)
+        return self.FunctorValue(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)
+        return self.FunctorValue(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)
+        return self.FunctorValue(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)
+        return self.FunctorValue(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)
+        return self.FunctorValue(SMESH.FT_Skew, elemId)
 
     ## Return minimal and maximal value of a given functor.
     #  @param funType a functor type, an item of SMESH.FunctorType enum
@@ -4699,6 +4959,8 @@ class Mesh:
         fun = self._getFunctor( funType )
         if fun:
             if meshPart:
+                if hasattr( meshPart, "SetMesh" ):
+                    meshPart.SetMesh( self.mesh ) # set mesh to filter
                 hist = fun.GetLocalHistogram( 1, False, meshPart )
             else:
                 hist = fun.GetHistogram( 1, False )
@@ -4708,10 +4970,73 @@ class Mesh:
 
     pass # end of Mesh class
 
+
+## class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
+#  with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
+#
+class meshProxy(SMESH._objref_SMESH_Mesh):
+    def __init__(self):
+        SMESH._objref_SMESH_Mesh.__init__(self)
+    def __deepcopy__(self, memo=None):
+        new = self.__class__()
+        return new
+    def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
+        if len( args ) == 3:
+            args += SMESH.ALL_NODES, True
+        return SMESH._objref_SMESH_Mesh.CreateDimGroup( self, *args )
+    pass
+omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
+
+## class used to compensate change of CORBA API of SMESH_MeshEditor for backward compatibility
+#  with old dump scripts which call SMESH_MeshEditor directly and not via smeshBuilder.Mesh
+#
+class meshEditor(SMESH._objref_SMESH_MeshEditor):
+    def __init__(self):
+        SMESH._objref_SMESH_MeshEditor.__init__(self)
+        self.mesh = None
+    def __getattr__(self, name ): # method called if an attribute not found
+        if not self.mesh:         # look for name() method in Mesh class
+            self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
+        if hasattr( self.mesh, name ):
+            return getattr( self.mesh, name )
+        if name == "ExtrusionAlongPathObjX":
+            return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
+        print "meshEditor: attribute '%s' NOT FOUND" % name
+        return None
+    def __deepcopy__(self, memo=None):
+        new = self.__class__()
+        return new
+    def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
+        if len( args ) == 1: args += False,
+        return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
+    def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
+        if len( args ) == 2: args += False,
+        return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
+    def MergeNodes(self,*args): # a 2nd arg added (NodesToKeep)
+        if len( args ) == 1:
+            return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [] )
+        NodesToKeep = args[1]
+        unRegister  = genObjUnRegister()
+        if NodesToKeep:
+            if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
+                NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
+            if not isinstance( NodesToKeep, list ):
+                NodesToKeep = [ NodesToKeep ]
+        return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep )
+    pass
+omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
+
 ## Helper class for wrapping of SMESH.SMESH_Pattern CORBA class
 #
 class Pattern(SMESH._objref_SMESH_Pattern):
 
+    def LoadFromFile(self, patternTextOrFile ):
+        text = patternTextOrFile
+        if os.path.exists( text ):
+            text = open( patternTextOrFile ).read()
+            pass
+        return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
+
     def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
         decrFun = lambda i: i-1
         theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
@@ -4724,6 +5049,11 @@ class Pattern(SMESH._objref_SMESH_Pattern):
         theMesh.SetParameters(Parameters)
         return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
 
+    def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
+        if isinstance( mesh, Mesh ):
+            mesh = mesh.GetMesh()
+        return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
+
 # Registering the new proxy for Pattern
 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
 
index 8ce382e179b8b5c93545682b58c1274fc6678b75..a57b034633f9e65d9c1a8e809aece3bd0405a79f 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2015  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
@@ -23,7 +23,7 @@
 
 import salome
 from salome.geom import geomBuilder
-import SMESH
+import SMESH, StdMeshers
 
 ## The base class to define meshing algorithms
 #
@@ -85,6 +85,7 @@ class Mesh_Algorithm:
                     attr = hypo_so_i.FindAttribute("AttributeIOR")[1]
                     if attr is not None:
                         anIOR = attr.Value()
+                        if not anIOR: continue # prevent exception in orb.string_to_object()
                         hypo_o_i = salome.orb.string_to_object(anIOR)
                         if hypo_o_i is not None:
                             # Check if this is a hypothesis
@@ -128,6 +129,7 @@ class Mesh_Algorithm:
                     attr = algo_so_i.FindAttribute("AttributeIOR")[1]
                     if attr is not None:
                         anIOR = attr.Value()
+                        if not anIOR: continue # prevent exception in orb.string_to_object()
                         algo_o_i = salome.orb.string_to_object(anIOR)
                         if algo_o_i is not None:
                             # Check if this is an algorithm
@@ -266,29 +268,41 @@ class Mesh_Algorithm:
     #         the value of \a isFacesToIgnore parameter.
     #  @param isFacesToIgnore if \c True, the Viscous layers are not generated on the
     #         faces specified by the previous parameter (\a faces).
+    #  @param extrMethod extrusion method defines how position of new nodes are found during
+    #         prism construction and how creation of distorted and intersecting prisms is
+    #         prevented. Possible values are:
+    #       - StdMeshers.SURF_OFFSET_SMOOTH (default) method extrudes nodes along normal
+    #         to underlying geometrical surface. Smoothing of internal surface of
+    #         element layers can be used to avoid creation of invalid prisms.
+    #       - StdMeshers.FACE_OFFSET method extrudes nodes along average normal of
+    #         surrounding mesh faces till intersection with a neighbor mesh face
+    #         translated along its own normal by the layers thickness. Thickness
+    #         of layers can be limited to avoid creation of invalid prisms.
+    #       - StdMeshers.NODE_OFFSET method extrudes nodes along average normal of
+    #         surrounding mesh faces by the layers thickness. Thickness of
+    #         layers can be limited to avoid creation of invalid prisms.
     #  @ingroup l3_hypos_additi
     def ViscousLayers(self, thickness, numberOfLayers, stretchFactor,
-                      faces=[], isFacesToIgnore=True ):
+                      faces=[], isFacesToIgnore=True, extrMethod=StdMeshers.SURF_OFFSET_SMOOTH ):
         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 faces and isinstance( faces[0], geomBuilder.GEOM._objref_GEOM_Object ):
-            import GEOM
             faceIDs = []
-            for f in faces:
-                if self.mesh.geompyD.ShapeIdToType( f.GetType() ) == "GROUP":
-                    faceIDs += f.GetSubShapeIndices()
-                else:
-                    faceIDs += [self.mesh.geompyD.GetSubShapeID(self.mesh.geom, f)]
+            for shape in faces:
+                ff = self.mesh.geompyD.SubShapeAll( shape, self.mesh.geompyD.ShapeType["FACE"] )
+                for f in ff:
+                    faceIDs.append( self.mesh.geompyD.GetSubShapeID(self.mesh.geom, f))
             faces = faceIDs
         hyp = self.Hypothesis("ViscousLayers",
                               [thickness, numberOfLayers, stretchFactor, faces, isFacesToIgnore],
                               toAdd=False)
-        hyp.SetTotalThickness(thickness)
-        hyp.SetNumberLayers(numberOfLayers)
-        hyp.SetStretchFactor(stretchFactor)
-        hyp.SetFaces(faces, isFacesToIgnore)
+        hyp.SetTotalThickness( thickness )
+        hyp.SetNumberLayers( numberOfLayers )
+        hyp.SetStretchFactor( stretchFactor )
+        hyp.SetFaces( faces, isFacesToIgnore )
+        hyp.SetMethod( extrMethod )
         self.mesh.AddHypothesis( hyp, self.geom )
         return hyp
 
@@ -311,7 +325,12 @@ class Mesh_Algorithm:
         if not "ViscousLayers2D" in self.GetCompatibleHypothesis():
             raise TypeError, "ViscousLayers2D are not supported by %s"%self.algo.GetName()
         if edges and isinstance( edges[0], geomBuilder.GEOM._objref_GEOM_Object ):
-            edges = [ self.mesh.geompyD.GetSubShapeID(self.mesh.geom, f) for f in edges ]
+            edgeIDs = []
+            for shape in edges:
+                ee = self.mesh.geompyD.SubShapeAll( shape, self.mesh.geompyD.ShapeType["EDGE"])
+                for e in ee:
+                    edgeIDs.append( self.mesh.geompyD.GetSubShapeID( self.mesh.geom, e ))
+            edges = edgeIDs
         hyp = self.Hypothesis("ViscousLayers2D",
                               [thickness, numberOfLayers, stretchFactor, edges, isEdgesToIgnore],
                               toAdd=False)
diff --git a/src/SMESH_SWIG/smesh_selection.py b/src/SMESH_SWIG/smesh_selection.py
new file mode 100644 (file)
index 0000000..a2c5257
--- /dev/null
@@ -0,0 +1,156 @@
+# Copyright (C) 2015  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, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# 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_selection.py
+#  Author : Roman NIKOLAEV, OPEN CASCADE ( roman.nikolaev@opencascade.com )
+#  Module : SMESH
+
+import salome
+salome.salome_init()
+
+import libSMESH_Swig
+sm_gui = libSMESH_Swig.SMESH_Swig()
+
+import SMESH, SALOMEDS
+from salome.smesh import smeshBuilder
+smesh =  smeshBuilder.New(salome.myStudy)
+
+import GEOM
+
+# swig -> idl
+_converter = { 
+    libSMESH_Swig.EdgeOfCell    :  None, # TODO: check how to process it
+    libSMESH_Swig.Node          :  SMESH.NODE,
+    libSMESH_Swig.Edge          :  SMESH.EDGE,
+    libSMESH_Swig.Face          :  SMESH.FACE,
+    libSMESH_Swig.Volume        :  SMESH.VOLUME,
+    libSMESH_Swig.Elem0D        :  SMESH.ELEM0D,
+    libSMESH_Swig.Ball          :  SMESH.BALL,
+    libSMESH_Swig.Cell          :  SMESH.ALL
+}
+
+# Converts swig to idl enumeration
+def _swig2idl( type ):
+    if _converter.has_key( type ) :
+        return _converter[type]
+    return None
+
+def _getEntry(mesh):
+    if isinstance( mesh, smeshBuilder.Mesh ) :
+        return salome.ObjectToID( mesh.GetMesh() )
+    else :
+        if isinstance( mesh, str ) :
+            return mesh
+    return None
+
+def _getMesh(mesh):
+    if isinstance( mesh, smeshBuilder.Mesh ) :
+        return mesh.GetMesh()
+    else :
+        if isinstance( mesh, str ) :
+            return salome.IDToObject( mesh )
+    return None
+
+def _getGeom(geom):
+    if isinstance( geom, GEOM._objref_GEOM_Object ) :
+        return geom
+    else :
+        if isinstance( geom, str ) :
+            return salome.IDToObject( geom )
+    return None
+
+
+# Selects an elements lst on the mesh
+def select( mesh, lst, append = False ) :
+    # Check mesh parameter
+    entry = _getEntry(mesh)   
+    if entry is None:
+        print "Wrong 'mesh' parameter"
+        return
+    
+    # Check lst parameter
+    tmp = []
+    if isinstance( lst, int ) :
+        tmp.append( lst )
+    else :
+        if isinstance( lst,list ) :
+            tmp = lst
+        else :
+            print "Wrong 'lst' parameter"
+            return
+    sm_gui.select( entry, tmp, append )
+
+
+def _preProcess(mesh) :
+    m = _getMesh(mesh);
+    if m is None:
+        print "Wrong 'mesh' parameter"
+        return [None, None]
+    
+    elemType = _swig2idl(sm_gui.getSelectionMode())
+    if elemType is None:
+        return [None, None]
+    return [m, elemType]
+
+
+
+# Selects an elements on the mesh inside the sphere with radius r and center (x, y, z)
+def selectInsideSphere( mesh, x, y, z, r, append = False ) :
+
+    [m, elemType] = _preProcess(mesh)
+    if m is None or elemType is None :
+        return
+    
+    l = smesh.GetInsideSphere( m, elemType, x, y, z, r )
+    if len(l) > 0:
+        select(mesh, l, append)
+
+# Selects an elements on the mesh inside the box
+def selectInsideBox( mesh, x1, y1, z1, x2, y2, z2 , append = False ) :    
+
+    [m, elemType] = _preProcess(mesh)
+    if m is None or elemType is None :
+        return
+
+    l = smesh.GetInsideBox( m, elemType, x1, y1, z1, x2, y2, z2 )
+    if len(l) > 0:
+        select(mesh, l, append)
+
+# Selects an elements on the mesh inside the cylinder
+def selectInsideCylinder( mesh, x, y, z, dx, dy, dz, h, r, append = False ) :
+
+    [m, elemType] = _preProcess(mesh)
+    if m is None or elemType is None :
+        return
+
+    l = smesh.GetInsideCylinder( m, elemType, x, y, z, dx, dy, dz, h, r )
+    if len(l) > 0:
+        select(mesh, l, append)
+
+# Selects an elements on the mesh inside the geometrical object
+def selectInside( mesh, geom, tolerance , append = False ):
+
+    [m, elemType] = _preProcess(mesh)
+    if m is None or elemType is None :
+        return    
+
+    g = _getGeom(geom)
+
+    l = smesh.GetInside( m, elemType, g ,tolerance )
+    if len(l) > 0:
+        select(mesh, l, append)
index acc21d3c8d9dc78b30b6e41952d1a918bf033917..68aadb290e9778eef33c7ecc90faeb98ee6276e6 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2012-2015  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
@@ -35,6 +35,9 @@ INCLUDE_DIRECTORIES(
   ${Boost_INCLUDE_DIRS}
   ${CMAKE_CURRENT_SOURCE_DIR}
   ${PROJECT_SOURCE_DIR}/src/SMESHGUI
+  ${PROJECT_SOURCE_DIR}/src/OBJECT
+  ${PROJECT_SOURCE_DIR}/src/SMESHDS
+  ${PROJECT_SOURCE_DIR}/src/SMDS
   ${PROJECT_BINARY_DIR}/idl
 )
 
index 633f986f91a02ef684c00afceacc6bf82a93dce7..cb37aff4e65a958c841645a39c7490c9380ce8c8 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
 //
 #include "libSMESH_Swig.h"
 
+
 #include <SMESHGUI.h>
 #include <SMESHGUI_Utils.h>
 #include <SMESHGUI_Displayer.h>
+#include <SMESHGUI_VTKUtils.h>
+#include <SMESH_Actor.h>
 
 // SALOME KERNEL includes
 #include <Utils_ORB_INIT.hxx>
 #include <SUIT_ViewManager.h>
 #include <SALOME_Prs.h>
 #include <SUIT_ViewWindow.h>
+#include <SVTK_ViewWindow.h>
 #include <VTKViewer_ViewModel.h>
 #include <SALOME_Event.h>
 #include <SalomeApp_Application.h>
+#include <LightApp_SelectionMgr.h>
+#include <SVTK_RenderWindowInteractor.h>
 
 // OCCT includes
 #include <TopAbs.hxx>
+#include <TColStd_MapOfInteger.hxx>
 
 // Qt includes
 #include <QApplication>
@@ -730,3 +737,112 @@ void SMESH_Swig::SetMeshIcon(const char* theMeshEntry,
                               theIsComputed,
                               isEmpty));
 }
+
+/*!
+  \brief Helper class for selection event.
+*/
+class TSelectListEvent: public SALOME_Event
+{
+  const char*       myId;
+  std::vector<int>  myIdsList;
+  bool              myIsAppend;
+
+public:
+  TSelectListEvent(const char* id, std::vector<int> ids, bool append) :
+    myId(id),
+    myIdsList(ids),
+    myIsAppend(append)
+  {}
+  virtual void Execute()
+  {
+    SMESHGUI* aSMESHGUI = SMESHGUI::GetSMESHGUI();
+    if( !aSMESHGUI ) 
+      return;
+    
+    LightApp_SelectionMgr* selMgr = SMESH::GetSelectionMgr( aSMESHGUI );
+    if( !selMgr )
+      return;
+    
+    selMgr->clearFilters();
+
+    SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( aSMESHGUI );
+    if(!aViewWindow)
+      return;
+
+    SMESH_Actor* anActor = SMESH::FindActorByEntry( myId );
+    
+    if (!anActor || !anActor->hasIO())
+      return;
+    
+    Handle(SALOME_InteractiveObject) anIO = anActor->getIO();
+    SALOME_ListIO aList;
+    aList.Append(anIO);
+    selMgr->setSelectedObjects(aList, false);
+
+    if ( aViewWindow->SelectionMode() ==  ActorSelection ) {
+      return;
+    }
+        
+    TColStd_MapOfInteger aMap;
+    std::vector<int>::const_iterator anIter;
+    for (anIter = myIdsList.begin(); anIter != myIdsList.end(); ++anIter) {
+      aMap.Add(*anIter);
+    }
+
+    // Set new selection
+    SVTK_Selector* aSelector  = aViewWindow->GetSelector();
+    aSelector->AddOrRemoveIndex(anIO, aMap, myIsAppend);
+    aViewWindow->highlight( anIO, true, true );
+    aViewWindow->GetInteractor()->onEmitSelectionChanged();
+  }
+};
+
+/*!
+  \brief Select the elements on the mesh, sub-mesh or group.
+  \param id object entry
+  \param ids list of the element ids
+  \param mode selection mode
+*/
+void SMESH_Swig::select( const char* id, std::vector<int> ids, bool append ) {
+  ProcessVoidEvent( new TSelectListEvent( id, ids, append ) );
+}
+  
+/*!
+  \brief Select the elements on the mesh, sub-mesh or group.
+  \param id object entry
+  \param id id of the element
+  \param mode selection mode
+*/
+void SMESH_Swig::select( const char* id, int id1, bool append ) {
+  std::vector<int> ids;
+  ids.push_back( id1 );
+  ProcessVoidEvent( new TSelectListEvent( id, ids, append ) );
+}
+
+
+class TGetSelectionModeEvent : public SALOME_Event
+{
+public:
+  typedef int TResult;
+  TResult myResult;
+  TGetSelectionModeEvent() : myResult( -1 ) {}
+  virtual void Execute()
+  {
+    SMESHGUI* aSMESHGUI = SMESHGUI::GetSMESHGUI();
+    if( !aSMESHGUI ) 
+      return;
+
+    SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( aSMESHGUI );
+    if(!aViewWindow)
+      return;
+    
+    myResult = aViewWindow->SelectionMode();
+  }
+};
+
+/*!
+  \brief Get selection mode of the active VTK View window.
+*/
+int SMESH_Swig::getSelectionMode() {
+  return ProcessEvent( new TGetSelectionModeEvent() );
+}
index e20cdbc11613529f14a00f61276d98b339ba5e9d..8c30149e9def6b85b28d3f3d99989e2053e63a18 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
 #include <SALOMEconfig.h>
 #include CORBA_SERVER_HEADER(SALOMEDS)
 
+//std includes
+#include <vector>
+
+#include <SVTK_Selection.h>
+
+#include <SVTK_Selection.h>
+
+enum
+  {
+    Node       = NodeSelection,
+    Cell       = CellSelection,
+    EdgeOfCell = EdgeOfCellSelection,
+    Edge       = EdgeSelection,
+    Face       = FaceSelection,
+    Volume     = VolumeSelection,
+    Actor      = ActorSelection,
+    Elem0D     = Elem0DSelection,
+    Ball       = BallSelection
+  };
+
 class SMESH_SWIG_EXPORT SMESH_Swig
 {
 public:
@@ -74,6 +94,11 @@ public:
    */
   void                       SetMeshIcon( const char*, const bool, const bool );
 
+  // --------------------- for the test purposes -----------------------
+  int  getSelectionMode();
+  void select( const char *id, std::vector<int> ids, bool append = false );
+  void select( const char *id, int id1, bool append = false );
+
 private:
   SALOMEDS::Study_var        myStudy;
   SALOMEDS::StudyBuilder_var myStudyBuilder;
index f255dd54990f0a43be04fca17e730afce3e25a7e..227008b3b7cc577265519a1f756ce2bb9cdfab4d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
 }
 
 %include "typemaps.i"
+%include "std_vector.i"
+
+namespace std {
+    %template(VectorInt) vector<int>;
+};
+
+
+/* Selection mode enumeration (corresponds to constants from the SALOME_Selection.h) */
+enum
+  {
+    Node,
+    Cell,
+    EdgeOfCell,
+    Edge,
+    Face,
+    Volume,
+    Actor,
+    Elem0D,
+    Ball
+  };
 
 class SMESH_Swig
 {
@@ -76,4 +96,10 @@ class SMESH_Swig
 
   void CreateAndDisplayActor( const char* Mesh_Entry );
   void EraseActor( const char* Mesh_Entry, const bool allViewers = false );
+
+  // --------------------- for the test purposes -----------------------
+  int  getSelectionMode();
+  void select( const char *id, std::vector<int> ids, bool append = false );
+  void select( const char *id, int id1, bool append = false );
+
 };
index b30a69e09697af69ec80cd09673524ff0116c9a9..6327d5d21a12e7280b4b3115f2a7a859d14eb930 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2012-2015  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
@@ -62,6 +62,7 @@ SET(_link_LIBRARIES
   ${CAS_TKAdvTools}
   ${CAS_TKTopAlgo}
   ${CAS_TKG3d}
+  ${CAS_TKOffset}
   ${GEOM_GEOMUtils}
   SMESHimpl
   SMESHDS
@@ -130,6 +131,8 @@ SET(StdMeshers_HEADERS
   StdMeshers_Projection_1D2D.hxx
   StdMeshers_CartesianParameters3D.hxx
   StdMeshers_Cartesian_3D.hxx
+  StdMeshers_QuadFromMedialAxis_1D2D.hxx
+  StdMeshers_PolygonPerFace_2D.hxx
 )
 
 IF(SALOME_SMESH_ENABLE_MEFISTO)
@@ -193,6 +196,8 @@ SET(StdMeshers_SOURCES
   StdMeshers_CartesianParameters3D.cxx
   StdMeshers_Cartesian_3D.cxx
   StdMeshers_Adaptive1D.cxx
+  StdMeshers_QuadFromMedialAxis_1D2D.cxx
+  StdMeshers_PolygonPerFace_2D.cxx
 )
 
 IF(SALOME_SMESH_ENABLE_MEFISTO)
index 3d62963feded83156119bf7c2cc68525e19786d7..88c712d448f4b3b08e6ac38e265c69a93925bb26 100755 (executable)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 7bcfca77d6a8f71eadc62ab64c2a55a45c5955ff..2fc76a7b3d555c566c08102b30fce5ffa19a4580 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -535,7 +535,7 @@ namespace // internal utils
         for ( int i = 0; i < 3; ++i )
         {
           const gp_Pnt& pn = myNodes->Value(n[i]);
-          if ( avoidTria = ( pn.SquareDistance( *avoidPnt ) <= tol2 ))
+          if (( avoidTria = ( pn.SquareDistance( *avoidPnt ) <= tol2 )))
             break;
           if ( !projectedOnly )
             minD2 = Min( minD2, pn.SquareDistance( p ));
@@ -703,7 +703,7 @@ namespace // internal utils
   void ElementBndBoxTree::buildChildrenData()
   {
     ElemTreeData* data = GetElemData();
-    for ( int i = 0; i < _elementIDs.size(); ++i )
+    for ( size_t i = 0; i < _elementIDs.size(); ++i )
     {
       const Bnd_B3d* elemBox = data->GetBox( _elementIDs[i] );
       for (int j = 0; j < 8; j++)
@@ -718,7 +718,7 @@ namespace // internal utils
     {
       ElementBndBoxTree* child = static_cast<ElementBndBoxTree*>( myChildren[j] );
       child->_elementIDs = data->myWorkIDs[ j ];
-      if ( child->_elementIDs.size() <= theMaxNbElemsInLeaf )
+      if ((int) child->_elementIDs.size() <= theMaxNbElemsInLeaf )
         child->myIsLeaf = true;
       data->myWorkIDs[ j ].clear();
     }
@@ -741,7 +741,7 @@ namespace // internal utils
       if ( isLeaf() )
       {
         ElemTreeData* data = GetElemData();
-        for ( int i = 0; i < _elementIDs.size(); ++i )
+        for ( size_t i = 0; i < _elementIDs.size(); ++i )
           if ( !data->GetBox( _elementIDs[i] )->IsOut( center, radius ))
             foundElemIDs.push_back( _elementIDs[i] );
       }
@@ -1197,7 +1197,7 @@ bool AdaptiveAlgo::Compute(SMESH_Mesh &         theMesh,
   StdMeshers_Regular_1D::_value[ DEFLECTION_IND ] = myHyp->GetDeflection();
 
   list< double > params;
-  for ( int iE = 0; iE < myEdges.size(); ++iE )
+  for ( size_t iE = 0; iE < myEdges.size(); ++iE )
   {
     EdgeData& eData = myEdges[ iE ];
     //cout << "E " << theMesh.GetMeshDS()->ShapeToIndex( eData.Edge() ) << endl;
@@ -1243,7 +1243,7 @@ bool AdaptiveAlgo::Compute(SMESH_Mesh &         theMesh,
 
     triaSearcher->SetSizeByTrias( sizeTree, myHyp->GetDeflection() );
 
-    for ( int iE = 0; iE < myEdges.size(); ++iE )
+    for ( size_t iE = 0; iE < myEdges.size(); ++iE )
     {
       EdgeData& eData = myEdges[ iE ];
 
@@ -1290,6 +1290,7 @@ bool AdaptiveAlgo::Compute(SMESH_Mesh &         theMesh,
         //cout << "E " << theMesh.GetMeshDS()->ShapeToIndex( eData.Edge() ) << endl;
         sizeDecreased = false;
         const gp_Pnt* avoidPnt = & eData.First().myP;
+        EdgeData::TPntIter pItLast = --eData.myPoints.end(), pItFirst = eData.myPoints.begin();
         for ( pIt1 = eData.myPoints.begin(); pIt1 != eData.myPoints.end();  )
         {
           double distToFace =
@@ -1307,19 +1308,16 @@ bool AdaptiveAlgo::Compute(SMESH_Mesh &         theMesh,
               //      << "\t SetSize " << allowedSize << " at "
               //      << pIt1->myP.X() <<", "<< pIt1->myP.Y()<<", "<<pIt1->myP.Z() << endl;
               pIt2 = pIt1;
-              if ( --pIt2 != eData.myPoints.end() && pIt2->mySegSize > allowedSize )
+              if ( pIt1 != pItFirst && ( --pIt2 )->mySegSize > allowedSize )
                 sizeTree.SetSize( eData.myC3d.Value( 0.6*pIt2->myU + 0.4*pIt1->myU ), allowedSize );
               pIt2 = pIt1;
-              if ( ++pIt2 != eData.myPoints.end() && pIt2->mySegSize > allowedSize )
+              if ( pIt1 != pItLast  && ( ++pIt2 )->mySegSize > allowedSize )
                 sizeTree.SetSize( eData.myC3d.Value( 0.6*pIt2->myU + 0.4*pIt1->myU ), allowedSize );
             }
             pIt1->mySegSize = allowedSize;
           }
           ++pIt1;
-          if ( & (*pIt1) == & eData.Last() )
-            avoidPnt = & eData.Last().myP;
-          else
-            avoidPnt = NULL;
+          avoidPnt = ( pIt1 == pItLast ) ? & eData.Last().myP : NULL;
 
           if ( iLoop > 20 )
           {
@@ -1356,7 +1354,7 @@ bool AdaptiveAlgo::makeSegments()
 
   vector< double > nbSegs, params;
 
-  for ( int iE = 0; iE < myEdges.size(); ++iE )
+  for ( size_t iE = 0; iE < myEdges.size(); ++iE )
   {
     EdgeData& eData = myEdges[ iE ];
 
@@ -1367,13 +1365,13 @@ bool AdaptiveAlgo::makeSegments()
       edgeMinSize = Min( edgeMinSize,
                          Min( pIt1->mySegSize, mySizeTree->GetSize( pIt1->myP )));
 
-    const double f = eData.myC3d.FirstParameter(), l = eData.myC3d.LastParameter();
+    const double      f = eData.myC3d.FirstParameter(), l = eData.myC3d.LastParameter();
     const double parLen = l - f;
     const int  nbDivSeg = 5;
-    int           nbDiv = Max( 1, int ( eData.myLength / edgeMinSize * nbDivSeg ));
+    size_t        nbDiv = Max( 1, int ( eData.myLength / edgeMinSize * nbDivSeg ));
 
     // compute nb of segments
-    bool toRecompute = true;
+    bool  toRecompute = true;
     double maxSegSize = 0;
     size_t i = 1, segCount;
     //cout << "E " << theMesh.GetMeshDS()->ShapeToIndex( eData.Edge() ) << endl;
@@ -1431,7 +1429,7 @@ bool AdaptiveAlgo::makeSegments()
     }
 
     // compute parameters of nodes
-    int nbSegFinal = Max( 1, int(floor( nbSegs.back() + 0.5 )));
+    size_t nbSegFinal = Max( 1, int(floor( nbSegs.back() + 0.5 )));
     double fact = nbSegFinal / nbSegs.back();
     if ( maxSegSize / fact > myHyp->GetMaxSize() )
       fact = ++nbSegFinal / nbSegs.back();
@@ -1504,7 +1502,7 @@ bool AdaptiveAlgo::Evaluate(SMESH_Mesh &         theMesh,
 
   for ( ; edExp.More(); edExp.Next() )
   {
-    const TopoDS_Edge & edge = TopoDS::Edge( edExp.Current() );
+    //const TopoDS_Edge & edge = TopoDS::Edge( edExp.Current() );
     StdMeshers_Regular_1D::Evaluate( theMesh, theShape, theResMap );
   }
   return true;
index a6211808737ba44051c5eef788470c62e75cfe0e..291a22f879e8ddc3390d6ee0741fec5beae24db5 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 481b5b17305e80ed7bc1910ea792e267e6f0d3c1..2642dd1af0db6b91a7af20c067dfc6bb5a3c51e9 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -155,7 +155,7 @@ istream & StdMeshers_Arithmetic1D::LoadFrom(istream & load)
   isOK = (load >> intVal);
   if (isOK && intVal > 0) {
     _edgeIDs.reserve( intVal );
-    for (int i = 0; i < _edgeIDs.capacity() && isOK; i++) {
+    for ( size_t i = 0; i < _edgeIDs.capacity() && isOK; i++) {
       isOK = (load >> intVal);
       if ( isOK ) _edgeIDs.push_back( intVal );
     }
@@ -167,7 +167,7 @@ istream & StdMeshers_Arithmetic1D::LoadFrom(istream & load)
 
 //=============================================================================
 /*!
- *  
+ *
  */
 //=============================================================================
 
index 8a402383a6d27c57f640f77a6e14209978404cc6..9d00419fbc687d03ac1d1831fa06ac8e53b5a041 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 5c04dd7fc1bccd86eb7b2c1c193c57dc6635b431..1bfa33215eca3a7a584e2acfeedb61098b7d3ca8 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 3d74c78cf126b75b2bc87166bc8cf99aaeae74e8..79a9d7a2a92e311abdb5c6c42243f3edc02b8f32 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index b2e15df8c1a8ec1f5d5b9b782f800150c3047a97..6d8135590881ee261260d7d6b46cbcf9074255db 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -240,6 +240,7 @@ bool StdMeshers_CartesianParameters3D::GetFixedPoint(double p[3]) const
   if ( Precision::IsInfinite( _fixedPoint[0] ))
     return false;
   std::copy( &_fixedPoint[0], &_fixedPoint[0]+3, &p[0] );
+  return true;
 }
 
 
@@ -371,7 +372,7 @@ void StdMeshers_CartesianParameters3D::ComputeCoordinates(const double    x0,
   // correct coords if a forced point is too close to a neighbor node
   if ( forced )
   {
-    int iF = 0;
+    size_t iF = 0;
     double minLen = ( x1 - x0 );
     for ( size_t i = 1; i < coords.size(); ++i )
     {
@@ -522,9 +523,8 @@ ComputeOptimalAxesDirs(const TopoDS_Shape& shape,
   const TCooTriple*           norm1 = 0;
   double                      sumArea = 0;
   vector< const TCooTriple* > norms;
-  for ( int iF = 1; norm2a != areasByNormal.end(); ++norm2a, ++iF )
+  for ( size_t iF = 1; norm2a != areasByNormal.end(); ++norm2a, ++iF )
   {
-
     if ( !norm1 || !sameDir( *norm1, norm2a->first ))
     {
       if ( !norms.empty() )
index 5edbc53a2be71a3b02787c709cc6cbcacfe74cd9..befb9afd8e8f17f01f4717c4cae2c832490ac5e5 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index bec175bb39dde87462443df5733713eea0cb90cc..c2aa6f3e490b24dce2f91bbfdaf03c27bc2a363c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -2731,7 +2731,7 @@ namespace
              chn.back()->IsLinked( quad._eIntNodes[ iP ]->_intPoint ))
         {
           chn.push_back( quad._eIntNodes[ iP ]);
-          found = quad._eIntNodes[ iP ]->_usedInFace = &quad;
+          found = ( quad._eIntNodes[ iP ]->_usedInFace = &quad );
           break;
         }
     } while ( found && ! chn.back()->IsLinked( n2->_intPoint ) );
@@ -2823,7 +2823,7 @@ namespace
               ( !avoidFace || quad._eIntNodes[ iP ]->IsOnFace( avoidFace )))
           {
             chn.push_back( quad._eIntNodes[ iP ]);
-            found = quad._eIntNodes[ iP ]->_usedInFace = &quad;
+            found = ( quad._eIntNodes[ iP ]->_usedInFace = &quad );
             break;
           }
       } while ( found );
@@ -3135,7 +3135,7 @@ namespace
     if ( !_vIntNodes.empty() )
       return false;
 
-    const int ijk[3] = { _i, _j, _k };
+    const size_t ijk[3] = { _i, _j, _k };
     F_IntersectPoint curIntPnt;
 
     // consider a cell to be in a hole if all links in any direction
index 0caab9f1ed811537db76bc9da8beda86f8af7bfb..552d7fc168b31bad758b96784593cfc4422d298a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 1311ca42c0a8ef762c5534be5aea76b20f1429a3..20e7048b9ab5a4f5953c7c9ece6ebabe149d171e 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
@@ -41,6 +41,7 @@
 #include <Standard_ErrorHandler.hxx>
 #include <Standard_Failure.hxx>
 #include <TopExp_Explorer.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
 #include <TopTools_MapIteratorOfMapOfShape.hxx>
 #include <TopTools_MapOfShape.hxx>
 #include <TopTools_SequenceOfShape.hxx>
@@ -61,9 +62,7 @@
 #ifdef _DEBUG_
 // #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;}
+// #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; }
 #endif
 
 #ifndef DUMP_VERT
@@ -79,6 +78,8 @@ enum EQuadSides{ Q_BOTTOM=0, Q_RIGHT, Q_TOP, Q_LEFT,   Q_CHILD, Q_PARENT };
 
 enum EBoxSides{ B_BOTTOM=0, B_RIGHT, B_TOP, B_LEFT, B_FRONT, B_BACK, B_UNDEFINED };
 
+enum EAxes{ COO_X=1, COO_Y, COO_Z };
+
 //================================================================================
 /*!
  * \brief Convertor of a pair of integers to a sole index
@@ -105,6 +106,7 @@ public:
   const _FaceSide* GetSide(const int i) const;
   int size() const { return myChildren.size(); }
   int NbVertices() const;
+  int NbCommonVertices( const TopTools_MapOfShape& VV ) const;
   TopoDS_Vertex FirstVertex() const;
   TopoDS_Vertex LastVertex() const;
   TopoDS_Vertex Vertex(int i) const;
@@ -145,10 +147,10 @@ public:
 public: //** Methods to find and orient faces of 6 sides of the box **//
   
   //!< initialization
-  bool Init(const TopoDS_Face& f);
+  bool Init(const TopoDS_Face& f, SMESH_Mesh& mesh );
 
   //!< try to unite self with other face
-  bool AddContinuousFace( const _QuadFaceGrid& f );
+  bool AddContinuousFace( const _QuadFaceGrid& f, const TopTools_MapOfShape& internalEdges );
 
   //!< Try to set the side as bottom hirizontal side
   bool SetBottomSide(const _FaceSide& side, int* sideIndex=0);
@@ -157,7 +159,7 @@ public: //** Methods to find and orient faces of 6 sides of the box **//
   _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*/);
+  void ReverseEdges();
 
   bool IsComplex() const { return !myChildren.empty(); }
 
@@ -177,6 +179,9 @@ public: //** Loading and access to mesh **//
   //!< Load nodes of a mesh
   bool LoadGrid( SMESH_Mesh& mesh );
 
+  //!< Computes normalized parameters of nodes of myGrid
+  void ComputeIJK( int i1, int i2, double v3 );
+
   //!< Return number of segments on the hirizontal sides
   int GetNbHoriSegments(SMESH_Mesh& mesh, bool withBrothers=false) const;
 
@@ -192,6 +197,9 @@ public: //** Loading and access to mesh **//
   //!< Return node coordinates by its position
   gp_XYZ GetXYZ(int iHori, int iVert) const;
 
+  //!< Return normalized parameters of nodes within the unitary cube
+  gp_XYZ& GetIJK(int iCol, int iRow) { return myIJK[ myIndexer( iCol, iRow )]; }
+
 public: //** Access to member fields **//
 
   //!< Return i-th face side (0<i<4)
@@ -241,8 +249,9 @@ private:
   _QuadFaceGrid* myRightBrother;
   _QuadFaceGrid* myUpBrother;
 
-  _Indexer    myIndexer;
+  _Indexer                      myIndexer;
   vector<const SMDS_MeshNode*>  myGrid;
+  vector<gp_XYZ>                myIJK; // normalized parameters of nodes
 
   SMESH_ComputeErrorPtr         myError;
 
@@ -276,6 +285,175 @@ bool StdMeshers_CompositeHexa_3D::CheckHypothesis(SMESH_Mesh&         aMesh,
   return true;
 }
 
+namespace
+{
+
+  //================================================================================
+  /*!
+   * \brief Checks structure of a quadrangular mesh at the common VERTEX of two EDGEs.
+   *        Returns true if there are two quadrangles near the VERTEX.
+   */
+  //================================================================================
+
+  bool isContinuousMesh(TopoDS_Edge        E1,
+                        TopoDS_Edge        E2,
+                        const TopoDS_Face& F,
+                        const SMESH_Mesh&  mesh)
+  {
+    if (E1.Orientation() > TopAbs_REVERSED) // INTERNAL
+      E1.Orientation( TopAbs_FORWARD );
+    if (E2.Orientation() > TopAbs_REVERSED) // INTERNAL
+      E2.Orientation( TopAbs_FORWARD );
+
+    TopoDS_Vertex V;
+    if ( !TopExp::CommonVertex( E1, E2, V )) return false;
+
+    const SMDS_MeshNode* n = SMESH_Algo::VertexNode( V, mesh.GetMeshDS() );
+    if ( !n ) return false;
+
+    SMESHDS_SubMesh* sm = mesh.GetSubMeshContaining( F )->GetSubMeshDS();
+    if ( !sm ) return false;
+
+    int nbQuads = 0;
+    SMDS_ElemIteratorPtr fIt = n->GetInverseElementIterator(SMDSAbs_Face);
+    while ( fIt->more() )
+    {
+      const SMDS_MeshElement* f = fIt->next();
+      if ( !sm->Contains( f )) continue;
+
+      if ( f->NbCornerNodes() == 4 )
+        ++nbQuads;
+      else
+        return false;
+    }
+    return nbQuads == 2;
+  }
+
+  //================================================================================
+  /*!
+   * \brief Finds VERTEXes located at block corners
+   */
+  //================================================================================
+
+  void getBlockCorners( SMESH_Mesh&          mesh,
+                        const TopoDS_Shape&  shape,
+                        TopTools_MapOfShape& cornerVV)
+  {
+    set<int> faceIDs; // ids of FACEs in the shape
+    TopExp_Explorer exp;
+    for ( exp.Init( shape, TopAbs_FACE ); exp.More(); exp.Next() )
+      faceIDs.insert( mesh.GetMeshDS()->ShapeToIndex( exp.Current() ));
+
+    TopTools_MapOfShape checkedVV;
+    for ( exp.Init( shape, TopAbs_VERTEX ); exp.More(); exp.Next() )
+    {
+      TopoDS_Vertex V = TopoDS::Vertex( exp.Current() );
+      if ( !checkedVV.Add( V )) continue;
+
+      const SMDS_MeshNode* n = SMESH_Algo::VertexNode( V, mesh.GetMeshDS() );
+      if ( !n ) continue;
+
+      int nbQuads = 0;
+      SMDS_ElemIteratorPtr fIt = n->GetInverseElementIterator(SMDSAbs_Face);
+      while ( fIt->more() )
+      {
+        const SMDS_MeshElement* f = fIt->next();
+        if ( !faceIDs.count( f->getshapeId() )) continue;
+
+        if ( f->NbCornerNodes() == 4 )
+          ++nbQuads;
+        else
+          nbQuads = 100;
+      }
+      if ( nbQuads == 3 )
+        cornerVV.Add( V );
+    }
+  }
+
+  //================================================================================
+  /*!
+   * \brief Return EDGEs dividing one box side
+   */
+  //================================================================================
+
+  bool getInternalEdges( SMESH_Mesh&                mesh,
+                         const TopoDS_Shape&        shape,
+                         const TopTools_MapOfShape& cornerVV,
+                         TopTools_MapOfShape&       internEE)
+  {
+    TopTools_IndexedMapOfShape subEE, subFF;
+    TopExp::MapShapes( shape, TopAbs_EDGE, subEE );
+    TopExp::MapShapes( shape, TopAbs_FACE, subFF );
+
+    TopoDS_Vertex VV[2];
+    TopTools_MapOfShape subChecked/*, ridgeEE*/;
+    TopTools_MapIteratorOfMapOfShape vIt( cornerVV );
+    for ( ; vIt.More(); vIt.Next() )
+    {
+      TopoDS_Shape V0 = vIt.Key();
+      // walk from one corner VERTEX to another along ridge EDGEs
+      PShapeIteratorPtr riIt = SMESH_MesherHelper::GetAncestors( V0, mesh, TopAbs_EDGE );
+      while ( const TopoDS_Shape* riE = riIt->next() )
+      {
+        if ( !subEE.Contains( *riE ) || !subChecked.Add( *riE ))
+          continue;
+        TopoDS_Edge ridgeE = TopoDS::Edge( *riE );
+        while ( !ridgeE.IsNull() )
+        {
+          TopExp::Vertices( ridgeE, VV[0], VV[1] );
+          TopoDS_Shape V1 = VV[ V0.IsSame( VV[0] )];
+          if ( cornerVV.Contains( V1 ) )
+            break; // ridgeE reached a corner VERTEX
+
+          // detect internal EDGEs among those sharing V1. There can be 2, 3 or 4 EDGEs and
+          // number of internal EDGEs is N-2
+          TopoDS_Shape nextRidgeE;
+          PShapeIteratorPtr eIt = SMESH_MesherHelper::GetAncestors( V1, mesh, TopAbs_EDGE );
+          while ( const TopoDS_Shape* E = eIt->next() )
+          {
+            if ( E->IsSame( ridgeE ) || !subEE.Contains( *E ) || !subChecked.Add( *E ))
+              continue;
+            // look for FACEs sharing both E and ridgeE
+            PShapeIteratorPtr fIt = SMESH_MesherHelper::GetAncestors( *E, mesh, TopAbs_FACE );
+            while ( const TopoDS_Shape* F = fIt->next() )
+            {
+              if ( !SMESH_MesherHelper::IsSubShape( ridgeE, *F ))
+                continue;
+              if ( isContinuousMesh( ridgeE, TopoDS::Edge( *E ), TopoDS::Face( *F ), mesh ))
+              {
+                nextRidgeE = *E;
+              }
+              else
+              {
+                internEE.Add( *E );
+              }
+              break;
+            }
+          }
+          // look for the next ridge EDGE ending at V1
+          if ( nextRidgeE.IsNull() )
+          {
+            eIt = SMESH_MesherHelper::GetAncestors( V1, mesh, TopAbs_EDGE );
+            while ( const TopoDS_Shape* E = eIt->next() )
+              if ( !ridgeE.IsSame( *E ) && !internEE.Contains( *E ) && subEE.Contains( *E ))
+              {
+                nextRidgeE = *E;
+                break;
+              }
+          }
+          ridgeE = TopoDS::Edge( nextRidgeE );
+          V0 = V1;
+
+          if ( ridgeE.IsNull() )
+            return false;
+        } // check EDGEs around the last VERTEX of ridgeE 
+      } // loop on ridge EDGEs around a corner VERTEX
+    } // loop on on corner VERTEXes
+
+    return true;
+  } // getInternalEdges()
+} // namespace
+
 //================================================================================
 /*!
  * \brief Tries to find 6 sides of a box
@@ -284,6 +462,7 @@ bool StdMeshers_CompositeHexa_3D::CheckHypothesis(SMESH_Mesh&         aMesh,
 
 bool StdMeshers_CompositeHexa_3D::findBoxFaces( const TopoDS_Shape&    shape,
                                                 list< _QuadFaceGrid >& boxFaces,
+                                                SMESH_Mesh&            mesh,
                                                 _QuadFaceGrid * &      fBottom,
                                                 _QuadFaceGrid * &      fTop,
                                                 _QuadFaceGrid * &      fFront,
@@ -291,27 +470,35 @@ bool StdMeshers_CompositeHexa_3D::findBoxFaces( const TopoDS_Shape&    shape,
                                                 _QuadFaceGrid * &      fLeft,
                                                 _QuadFaceGrid * &      fRight)
 {
+  TopTools_MapOfShape cornerVertices;
+  getBlockCorners( mesh, shape, cornerVertices );
+  if ( cornerVertices.Extent() != 8 )
+    return error( COMPERR_BAD_INPUT_MESH, "Can't find 8 corners of a block by 2D mesh" );
+  TopTools_MapOfShape internalEdges;
+  if ( !getInternalEdges( mesh, shape, cornerVertices, internalEdges ))
+    return error( COMPERR_BAD_INPUT_MESH, "2D mesh is not suitable for i,j,k hexa meshing" );
+
   list< _QuadFaceGrid >::iterator boxFace;
   TopExp_Explorer exp;
   int nbFaces = 0;
-  for ( exp.Init( shape, TopAbs_FACE); exp.More(); exp.Next(), ++nbFaces )
+  for ( exp.Init( shape, TopAbs_FACE ); exp.More(); exp.Next(), ++nbFaces )
   {
     _QuadFaceGrid f;
-    if ( !f.Init( TopoDS::Face( exp.Current() )))
+    if ( !f.Init( TopoDS::Face( exp.Current() ), mesh ))
       return error (COMPERR_BAD_SHAPE);
 
-    _QuadFaceGrid* prevContinuous = 0; 
+    _QuadFaceGrid* prevContinuous = 0;
     for ( boxFace = boxFaces.begin(); boxFace != boxFaces.end(); ++boxFace )
     {
       if ( prevContinuous )
       {
-        if ( prevContinuous->AddContinuousFace( *boxFace ))
+        if ( prevContinuous->AddContinuousFace( *boxFace, internalEdges ))
           boxFace = --boxFaces.erase( boxFace );
       }
-      else if ( boxFace->AddContinuousFace( f ))
+      else if ( boxFace->AddContinuousFace( f, internalEdges ))
       {
         prevContinuous = & (*boxFace);
-      }   
+      }
     }
     if ( !prevContinuous )
       boxFaces.push_back( f );
@@ -326,7 +513,7 @@ bool StdMeshers_CompositeHexa_3D::findBoxFaces( const TopoDS_Shape&    shape,
     boxFaces.resize( 6 );
     boxFace = boxFaces.begin();
     for ( exp.Init( shape, TopAbs_FACE); exp.More(); exp.Next(), ++boxFace )
-      boxFace->Init( TopoDS::Face( exp.Current() ) );
+      boxFace->Init( TopoDS::Face( exp.Current() ), mesh );
   }
   // ----------------------------------------
   // Find out position of faces within a box
@@ -396,7 +583,7 @@ bool StdMeshers_CompositeHexa_3D::Compute(SMESH_Mesh&         theMesh,
   // -------------------------
   list< _QuadFaceGrid > boxFaceContainer;
   _QuadFaceGrid *fBottom, *fTop, *fFront, *fBack, *fLeft, *fRight;
-  if ( ! findBoxFaces( theShape, boxFaceContainer,
+  if ( ! findBoxFaces( theShape, boxFaceContainer, theMesh,
                        fBottom, fTop, fFront, fBack, fLeft, fRight))
     return false;
 
@@ -412,6 +599,14 @@ bool StdMeshers_CompositeHexa_3D::Compute(SMESH_Mesh&         theMesh,
   if ( !fRight ->LoadGrid( theMesh )) return error( fRight ->GetError() );
   if ( !fTop   ->LoadGrid( theMesh )) return error( fTop   ->GetError() );
 
+  // compute normalized parameters of nodes on sides (PAL23189)
+  fBottom->ComputeIJK( COO_X, COO_Y, /*z=*/0. );
+  fBack  ->ComputeIJK( COO_X, COO_Z, /*y=*/1. );
+  fLeft  ->ComputeIJK( COO_Y, COO_Z, /*x=*/0. );
+  fFront ->ComputeIJK( COO_X, COO_Z, /*y=*/0. );
+  fRight ->ComputeIJK( COO_Y, COO_Z, /*x=*/1. );
+  fTop   ->ComputeIJK( COO_X, COO_Y, /*z=*/1. );
+
   int x, xSize = fBottom->GetNbHoriSegments(theMesh) + 1, X = xSize - 1;
   int y, ySize = fBottom->GetNbVertSegments(theMesh) + 1, Y = ySize - 1;
   int z, zSize = fFront ->GetNbVertSegments(theMesh) + 1, Z = zSize - 1;
@@ -467,13 +662,14 @@ bool StdMeshers_CompositeHexa_3D::Compute(SMESH_Mesh&         theMesh,
   pointsOnShapes[ SMESH_Block::ID_V011 ] = fTop->GetXYZ( 0, Y );
   pointsOnShapes[ SMESH_Block::ID_V111 ] = fTop->GetXYZ( X, Y );
 
+  gp_XYZ params; // normalized parameters of an internal node within the unit box
+
   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) );
+    const double rX = x / double(X);
     for ( y = 1; y < ySize-1; ++y )
     {
-      params.SetCoord( 2, y / double(Y) );
+      const double rY = y / double(Y);
       // column to fill during z loop
       vector< const SMDS_MeshNode* >& column = columns[ colIndex( x, y )];
       // points projections on horizontal edges
@@ -490,14 +686,28 @@ bool StdMeshers_CompositeHexa_3D::Compute(SMESH_Mesh&         theMesh,
       pointsOnShapes[ SMESH_Block::ID_Fxy1 ] = fTop   ->GetXYZ( x, y );
       for ( z = 1; z < zSize-1; ++z ) // z loop
       {
-        params.SetCoord( 3, z / double(Z) );
+        // compute normalized parameters of an internal node within the unit box
+        const double   rZ = z / double(Z);
+        const gp_XYZ& pBo = fBottom->GetIJK( x, y );
+        const gp_XYZ& pTo = fTop   ->GetIJK( x, y );
+        const gp_XYZ& pFr = fFront ->GetIJK( x, z );
+        const gp_XYZ& pBa = fBack  ->GetIJK( x, z );
+        const gp_XYZ& pLe = fLeft  ->GetIJK( y, z );
+        const gp_XYZ& pRi = fRight ->GetIJK( y, z );
+        params.SetCoord( 1, 0.5 * ( pBo.X() * ( 1. - rZ ) + pTo.X() * rZ  +
+                                    pFr.X() * ( 1. - rY ) + pBa.X() * rY ));
+        params.SetCoord( 2, 0.5 * ( pBo.Y() * ( 1. - rZ ) + pTo.Y() * rZ  +
+                                    pLe.Y() * ( 1. - rX ) + pRi.Y() * rX ));
+        params.SetCoord( 3, 0.5 * ( pFr.Z() * ( 1. - rY ) + pBa.Z() * rY  +
+                                    pLe.Z() * ( 1. - rX ) + pRi.Z() * rX ));
+
         // point projections 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_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 );
         // point projections on vertical faces
-        pointsOnShapes[ SMESH_Block::ID_Fx0z ] = fFront->GetXYZ( x, z );    
+        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 );
@@ -559,7 +769,7 @@ bool StdMeshers_CompositeHexa_3D::Evaluate(SMESH_Mesh&         theMesh,
   // -------------------------
   list< _QuadFaceGrid > boxFaceContainer;
   _QuadFaceGrid *fBottom, *fTop, *fFront, *fBack, *fLeft, *fRight;
-  if ( ! findBoxFaces( theShape, boxFaceContainer,
+  if ( ! findBoxFaces( theShape, boxFaceContainer, theMesh,
                        fBottom, fTop, fFront, fBack, fLeft, fRight))
     return false;
 
@@ -645,7 +855,7 @@ _QuadFaceGrid::_QuadFaceGrid():
  */
 //================================================================================
 
-bool _QuadFaceGrid::Init(const TopoDS_Face& f)
+bool _QuadFaceGrid::Init(const TopoDS_Face& f, SMESH_Mesh& mesh)
 {
   myFace         = f;
   mySides        = _FaceSide();
@@ -680,6 +890,12 @@ bool _QuadFaceGrid::Init(const TopoDS_Face& f)
         else if ( SMESH_Algo::IsContinuous( sideEdges.front(), edges.back() )) {
           sideEdges.splice( sideEdges.begin(), edges, --edges.end());
         }
+        else if ( isContinuousMesh( sideEdges.back(), edges.front(), f, mesh )) {
+          sideEdges.splice( sideEdges.end(), edges, edges.begin());
+        }
+        else if ( isContinuousMesh( sideEdges.front(), edges.back(), f, mesh )) {
+          sideEdges.splice( sideEdges.begin(), edges, --edges.end());
+        }
         else {
           break;
         }
@@ -706,41 +922,38 @@ bool _QuadFaceGrid::Init(const TopoDS_Face& f)
  */
 //================================================================================
 
-bool _QuadFaceGrid::AddContinuousFace( const _QuadFaceGrid& other )
+bool _QuadFaceGrid::AddContinuousFace( const _QuadFaceGrid&       other,
+                                       const TopTools_MapOfShape& internalEdges)
 {
   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 an otherSide
-      const double angleTol = M_PI / 180. / 2.;
-      int iV, nbV = otherSide.NbVertices(), nbCollinear = 0;
-      for ( iV = 0; iV < nbV; ++iV )
+    if ( mySides.Contain( otherSide, &iMyCommon ))
+    {
+      if ( internalEdges.Contains( otherSide.Edge( 0 )))
       {
-        TopoDS_Vertex v = otherSide.Vertex( iV );
-        gp_Vec n1, n2;
-        if ( !GetNormal( v, n1 ) || !other.GetNormal( v, n2 ))
-          continue;
-        if ( n1 * n2 < 0 )
-          n1.Reverse();
-        if ( n1.Angle(n2) < angleTol )
-          nbCollinear++;
-        else
-          break;
-      }
-      if ( nbCollinear > 1 ) { // this face becomes composite if not yet is
         DUMP_VERT("Cont 1", mySides.GetSide(iMyCommon)->FirstVertex());
         DUMP_VERT("Cont 2", mySides.GetSide(iMyCommon)->LastVertex());
         DUMP_VERT("Cont 3", otherSide.FirstVertex());
         DUMP_VERT("Cont 4", otherSide.LastVertex());
-        if ( myChildren.empty() ) {
+
+        if ( myChildren.empty() )
+        {
           myChildren.push_back( *this );
           myFace.Nullify();
         }
+        else // find iMyCommon in myChildren
+        {
+          for ( TChildIterator children = GetChildren(); children.more(); ) {
+            const _QuadFaceGrid& child = children.next();
+            if ( child.mySides.Contain( otherSide, &iMyCommon ))
+              break;
+          }
+        }
 
         // orient new children equally
-        int otherBottomIndex = ( 4 + i - iMyCommon + 2 ) % 4;
+        int otherBottomIndex = SMESH_MesherHelper::WrapIndex( i - iMyCommon + 2, 4 );
         if ( other.IsComplex() )
           for ( TChildIterator children = other.GetChildren(); children.more(); ) {
             myChildren.push_back( children.next() );
@@ -757,7 +970,7 @@ bool _QuadFaceGrid::AddContinuousFace( const _QuadFaceGrid& other )
         if ( other.IsComplex() )
           for ( TChildIterator children = other.GetChildren(); children.more(); )
           {
-            const _QuadFaceGrid& child =  children.next();
+            const _QuadFaceGrid& child = children.next();
             for ( int i = 0; i < 4; ++i )
               mySides.AppendSide( child.GetSide(i) );
           }
@@ -799,9 +1012,9 @@ bool _QuadFaceGrid::SetBottomSide(const _FaceSide& bottom, int* sideIndex)
     {
       if ( childFace->SetBottomSide( bottom, &myBottomIndex ))
       {
-        TChildren::iterator orientedCild = childFace;
+        TChildren::iterator orientedChild = childFace;
         for ( childFace = myChildren.begin(); childFace != childEnd; ++childFace ) {
-          if ( childFace != orientedCild )
+          if ( childFace != orientedChild )
             childFace->SetBottomSide( childFace->GetSide( myBottomIndex ));
         }
         if ( sideIndex )
@@ -873,7 +1086,7 @@ const _FaceSide& _QuadFaceGrid::GetSide(int i) const
  */
 //================================================================================
 
-void _QuadFaceGrid::ReverseEdges(/*int e1, int e2*/)
+void _QuadFaceGrid::ReverseEdges()
 {
   myReverse = !myReverse;
 
@@ -884,8 +1097,6 @@ void _QuadFaceGrid::ReverseEdges(/*int e1, int e2*/)
 
   if ( myChildren.empty() )
   {
-//     mySides.GetSide( e1 )->Reverse();
-//     mySides.GetSide( e2 )->Reverse();
     DumpVertices();
   }
   else
@@ -893,7 +1104,7 @@ void _QuadFaceGrid::ReverseEdges(/*int e1, int e2*/)
     DumpVertices();
     TChildren::iterator child = myChildren.begin(), childEnd = myChildren.end();
     for ( ; child != childEnd; ++child )
-      child->ReverseEdges( /*e1, e2*/ );
+      child->ReverseEdges();
   }
 }
 
@@ -942,10 +1153,10 @@ bool _QuadFaceGrid::LoadGrid( SMESH_Mesh& mesh )
 
   // store the rest nodes row by row
 
-  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;
+  TIDSortedElemSet emptySet, avoidSet;
+  const SMDS_MeshElement* firstQuad = 0; // most left face above the last row of found nodes
+
+  size_t nbFoundNodes = myIndexer._xSize;
   while ( nbFoundNodes != myGrid.size() )
   {
     // first and last nodes of the last filled row of nodes
@@ -961,8 +1172,6 @@ bool _QuadFaceGrid::LoadGrid( SMESH_Mesh& mesh )
     //     o---o  o  o  o  o
     //n1down    n2down
     //
-    TIDSortedElemSet emptySet, avoidSet;
-    avoidSet.insert( firstQuad );
     firstQuad = SMESH_MeshAlgos::FindFaceInSet( n1down, n2down, emptySet, avoidSet);
     while ( firstQuad && !faceSubMesh->Contains( firstQuad )) {
       avoidSet.insert( firstQuad );
@@ -1009,13 +1218,60 @@ bool _QuadFaceGrid::LoadGrid( SMESH_Mesh& mesh )
       n1down = myGrid[ nbFoundNodes - myIndexer._xSize - 1 ];
       n1up   = n2up;
     }
+    avoidSet.clear(); avoidSet.insert( firstQuad );
   }
-  mesh.GetMeshDS()->RemoveNode(dummy);
   DumpGrid(); // debug
 
   return true;
 }
 
+//================================================================================
+/*!
+ * \brief Fill myIJK with normalized parameters of nodes in myGrid
+ *  \param [in] i1 - coordinate index along rows of myGrid
+ *  \param [in] i2 - coordinate index along columns of myGrid
+ *  \param [in] v3 - value of the constant parameter
+ */
+//================================================================================
+
+void _QuadFaceGrid::ComputeIJK( int i1, int i2, double v3 )
+{
+  gp_XYZ ijk( v3, v3, v3 );
+  myIJK.resize( myIndexer.size(), ijk );
+
+  const size_t nbCol = myIndexer._xSize;
+  const size_t nbRow = myIndexer._ySize;
+
+  vector< double > len( nbRow );
+  len[0] = 0;
+  for ( size_t i = 0; i < nbCol; ++i )
+  {
+    gp_Pnt pPrev = GetXYZ( i, 0 );
+    for ( size_t j = 1; j < nbRow; ++j )
+    {
+      gp_Pnt p = GetXYZ( i, j );
+      len[ j ] = len[ j-1 ] + p.Distance( pPrev );
+      pPrev = p;
+    }
+    for ( size_t j = 0; j < nbRow; ++j )
+      GetIJK( i, j ).SetCoord( i2, len[ j ]/len.back() );
+  }
+
+  len.resize( nbCol );
+  for ( size_t j = 0; j < nbRow; ++j )
+  {
+    gp_Pnt pPrev = GetXYZ( 0, j );
+    for ( size_t i = 1; i < nbCol; ++i )
+    {
+      gp_Pnt p = GetXYZ( i, j );
+      len[ i ] = len[ i-1 ] + p.Distance( pPrev );
+      pPrev = p;
+    }
+    for ( size_t i = 0; i < nbCol; ++i )
+      GetIJK( i, j ).SetCoord( i1, len[ i ]/len.back() );
+  }
+}
+
 //================================================================================
 /*!
  * \brief Find out mutual location of children: find their right and up brothers
@@ -1272,8 +1528,8 @@ const SMDS_MeshNode* _QuadFaceGrid::GetNode(int iHori, int iVert) const
 
 gp_XYZ _QuadFaceGrid::GetXYZ(int iHori, int iVert) const
 {
-  const SMDS_MeshNode* n = myGrid[ myIndexer( iHori, iVert )];
-  return gp_XYZ( n->X(), n->Y(), n->Z() );
+  SMESH_TNodeXYZ xyz = myGrid[ myIndexer( iHori, iVert )];
+  return xyz;
 }
 
 //================================================================================
@@ -1424,8 +1680,6 @@ _FaceSide::_FaceSide(const list<TopoDS_Edge>& edges):
   for ( ; edge != eEnd; ++edge ) {
     myChildren.push_back( _FaceSide( *edge ));
     myNbChildren++;
-//     myVertices.insert( myChildren.back().myVertices.begin(),
-//                        myChildren.back().myVertices.end() );
     myVertices.Add( myChildren.back().FirstVertex() );
     myVertices.Add( myChildren.back().LastVertex() );
     myChildren.back().SetID( Q_CHILD ); // not to splice them
@@ -1434,7 +1688,7 @@ _FaceSide::_FaceSide(const list<TopoDS_Edge>& edges):
 
 //=======================================================================
 //function : GetSide
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 _FaceSide* _FaceSide::GetSide(const int i)
@@ -1471,9 +1725,24 @@ int _FaceSide::NbVertices() const
   return myNbChildren + 1;
 }
 
+//=======================================================================
+//function : NbCommonVertices
+//purpose  : Returns number of my vertices common with the given ones
+//=======================================================================
+
+int _FaceSide::NbCommonVertices( const TopTools_MapOfShape& VV ) const
+{
+  int nbCommon = 0;
+  TopTools_MapIteratorOfMapOfShape vIt ( myVertices );
+  for ( ; vIt.More(); vIt.Next() )
+    nbCommon += ( VV.Contains( vIt.Key() ));
+
+  return nbCommon;
+}
+
 //=======================================================================
 //function : FirstVertex
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 TopoDS_Vertex _FaceSide::FirstVertex() const
index 0a27f88f988e24db24ef740ab84fad6338490c2e..5545f781a7ff9655a4e5f882176ca84cefde6780 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
@@ -59,6 +59,7 @@ private:
 
   bool findBoxFaces( const TopoDS_Shape&    shape,
                      list< _QuadFaceGrid >& boxFaceContainer,
+                     SMESH_Mesh&            mesh,
                      _QuadFaceGrid * &      fBottom,
                      _QuadFaceGrid * &      fTop,
                      _QuadFaceGrid * &      fFront,
index 5a830c208a46d75158c56663f1ec61f6cf9f3b6e..bc1516f5b8d36198b6138aad3adaa3f58f06c56a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 //  Module : SMESH
 //
 #include "StdMeshers_CompositeSegment_1D.hxx"
-#include "StdMeshers_FaceSide.hxx"
-#include "StdMeshers_AutomaticLength.hxx"
 
+#include "SMDS_MeshElement.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "SMESH_Comment.hxx"
 #include "SMESH_Gen.hxx"
-#include "SMESH_Mesh.hxx"
 #include "SMESH_HypoFilter.hxx"
+#include "SMESH_Mesh.hxx"
+#include "SMESH_TypeDefs.hxx"
 #include "SMESH_subMesh.hxx"
 #include "SMESH_subMeshEventListener.hxx"
-#include "SMESH_Comment.hxx"
-
-#include "SMDS_MeshElement.hxx"
-#include "SMDS_MeshNode.hxx"
+#include "StdMeshers_AutomaticLength.hxx"
+#include "StdMeshers_FaceSide.hxx"
 
 #include "utilities.h"
 
@@ -173,7 +173,7 @@ namespace {
               // 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
+              SMESHUtils::Deleter< StdMeshers_FaceSide > side
                 ( StdMeshers_CompositeSegment_1D::GetFaceSide(*subMesh->GetFather(),
                                                               edge, face, false ));
               if ( side->NbEdges() > 1 && side->NbSegments() )
@@ -287,21 +287,21 @@ void StdMeshers_CompositeSegment_1D::SetEventListener(SMESH_subMesh* subMesh)
     // 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 ));
+    SMESHUtils::Deleter< 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 );
+        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( new VertexNodesRestoringListener(), 0, subMesh);
+  subMesh->SetEventListener( new VertexNodesRestoringListener(), 0, subMesh );
   StdMeshers_Regular_1D::SetEventListener( subMesh );
 }
 
@@ -368,7 +368,7 @@ bool StdMeshers_CompositeSegment_1D::Compute(SMESH_Mesh &         aMesh,
 
   // Get edges to be discretized as a whole
   TopoDS_Face nullFace;
-  auto_ptr< StdMeshers_FaceSide > side( GetFaceSide(aMesh, edge, nullFace, true ));
+  SMESHUtils::Deleter< StdMeshers_FaceSide > side( GetFaceSide(aMesh, edge, nullFace, true ));
   //side->dump("IN COMPOSITE SEG");
 
   if ( side->NbEdges() < 2 )
@@ -384,7 +384,7 @@ bool StdMeshers_CompositeSegment_1D::Compute(SMESH_Mesh &         aMesh,
   }
 
   // Compute node parameters
-  auto_ptr< BRepAdaptor_CompCurve > C3d ( side->GetCurve3d() );
+  SMESHUtils::Deleter< BRepAdaptor_CompCurve > C3d ( side->GetCurve3d() );
   double f = C3d->FirstParameter(), l = C3d->LastParameter();
   list< double > params;
   if ( !computeInternalParameters ( aMesh, *C3d, side->Length(), f, l, params, false ))
index f7cd5d32480aa8a08e0ee635ece582e86eef1bac..12e08a5a1fb7cb2d074eb15f68183d90d8dd1b67 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index cf8223cd84e0cca35afc4ed0b3cfefca1c51a357..2fbaefb01b7386bbe912df73ea3a5f8d06b8d6e5 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -212,7 +212,7 @@ bool StdMeshers_Deflection1D::SetParametersByMesh(const SMESH_Mesh*   theMesh,
       if ( SMESH_Algo::GetNodeParamOnEdge( aMeshDS, edge, params ))
       {
         nbEdges++;
-        for ( int i = 1; i < params.size(); ++i )
+        for ( size_t i = 1; i < params.size(); ++i )
           _value = Max( _value, deflection( AdaptCurve, params[ i-1 ], params[ i ]));
       }
     }
index e52536b2fa1245cfb66d79d3df5d479d002ff99f..c1b8a7a1f83b60898f146b894eaa8a88a6554cbf 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 3a0a7334ba579666a3e6b17f4f1d31f02098cabb..455f82baeb9c78cade280b6f710ffbf322c36920 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index e974e95f7be5708fe4c81cf534d7ef1af1dff972..261d702645b1913813ddf1f284179501b5c6e657 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 84884800b0e0b2ee463b7e34e1e1324018cdbdbd..2625b9fb1322eab64c256b743d3c76a64c076069 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -79,8 +79,6 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face&   theFace,
 //================================================================================
 /*!
  * \brief Constructor of a side of several edges
-  * \param theFace - the face
-  * \param theEdge - the edge
  */
 //================================================================================
 
@@ -101,6 +99,7 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face&   theFace,
   myNormPar.resize   ( nbEdges );
   myEdgeLength.resize( nbEdges );
   myIsUniform.resize ( nbEdges, true );
+  myFace               = theFace;
   myLength             = 0;
   myNbPonits           = myNbSegments = 0;
   myProxyMesh          = theProxyMesh;
@@ -114,14 +113,13 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face&   theFace,
 
   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;
     myEdgeLength[i] = SMESH_Algo::EdgeLength( *edge );
     if ( myEdgeLength[i] < DBL_MIN ) nbDegen++;
     myLength += myEdgeLength[i];
-    myEdge[i] = *edge;
+    myEdge  [i] = *edge;
     myEdgeID[i] = meshDS->ShapeToIndex( *edge );
     if ( !theIsForward ) myEdge[i].Reverse();
 
@@ -132,34 +130,16 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face&   theFace,
     if ( myEdge[i].Orientation() == TopAbs_REVERSED )
       std::swap( myFirst[i], myLast[i] );
 
-    if ( const SMESHDS_SubMesh* sm = myProxyMesh->GetSubMesh( *edge )) {
-      int nbN = sm->NbNodes();
-      if ( theIgnoreMediumNodes ) {
-        SMDS_ElemIteratorPtr elemIt = sm->GetElements();
-        if ( elemIt->more() && elemIt->next()->IsQuadratic() )
-          nbN -= sm->NbElements();
-      }
-      myNbPonits += nbN;
-      myNbSegments += sm->NbElements();
-    }
-
-    // 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;
-
     // check if the edge has a non-uniform parametrization (issue 0020705)
     if ( !myC2d[i].IsNull() )
     {
-      if ( myEdgeLength[i] > DBL_MIN)
+      if ( 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 p2 = myFirst[i]+(myLast[i]-myFirst[i])/2.;
+        double 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;
@@ -169,26 +149,20 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face&   theFace,
       }
       else
       {
-        const TopoDS_Vertex& V = TopoDS::Vertex( vExp.Value() );
+        const TopoDS_Vertex& V = SMESH_MesherHelper::IthVertex( 0, *edge );
         Handle(Geom_Curve) C3d = new Geom_Line( BRep_Tool::Pnt( V ), gp::DX() );
         myC3dAdaptor[i].Load( C3d, 0, 0.5 * BRep_Tool::Tolerance( V ));
       }
     }
-    // reverse a proxy submesh
+    // reverse a proxy sub-mesh
     if ( !theIsForward )
       reverseProxySubmesh( myEdge[i] );
 
   } // loop on edges
 
-  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;
-  }
+  // count nodes and segments
+  NbPoints( /*update=*/true );
+
   if ( nbEdges > 1 && myLength > DBL_MIN ) {
     const double degenNormLen = 1.e-5;
     double totLength = myLength;
@@ -209,8 +183,6 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face&   theFace,
 //================================================================================
 /*!
  * \brief Constructor of a side for vertex using data from other FaceSide
- *  \param theVertex - the vertex
- *  \param theSide - the side
  */
 //================================================================================
 
@@ -271,6 +243,7 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(UVPtStructVec&     theSideNodes,
   myMissingVertexNodes = myIgnoreMediumNodes = false;
   myDefaultPnt2d.SetCoord( 1e100, 1e100 );
 
+  myFace       = theFace;
   myPoints     = theSideNodes;
   myNbPonits   = myPoints.size();
   myNbSegments = myNbPonits + 1;
@@ -332,21 +305,29 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(UVPtStructVec&     theSideNodes,
 const vector<UVPtStruct>& StdMeshers_FaceSide::GetUVPtStruct(bool   isXConst,
                                                              double constValue) const
 {
-  if ( myPoints.empty() ) {
-
+  if ( myPoints.empty() )
+  {
     if ( NbEdges() == 0 ) return myPoints;
 
-    SMESHDS_Mesh* meshDS = myProxyMesh->GetMeshDS();
-    SMESH_MesherHelper helper(*myProxyMesh->GetMesh());
+    StdMeshers_FaceSide* me = const_cast< StdMeshers_FaceSide* >( this );
+    SMESHDS_Mesh*    meshDS = myProxyMesh->GetMeshDS();
+    SMESH_MesherHelper eHelper( *myProxyMesh->GetMesh() );
+    SMESH_MesherHelper fHelper( *myProxyMesh->GetMesh() );
+    fHelper.SetSubShape( myFace );
     bool paramOK;
     double eps = 1e-100;
 
     // sort nodes of all edges putting them into a map
 
-    map< double, const SMDS_MeshNode*> u2node;
-    vector< const SMESH_ProxyMesh::SubMesh* > proxySubMesh( myEdge.size());
+    map< double, const SMDS_MeshNode*>            u2node;
+    vector< pair< double, const SMDS_MeshNode*> > u2nodeVec;
+    vector<const SMDS_MeshNode*>                  nodes;
+    set<const SMDS_MeshNode*>                     vertexNodes;
+    vector< const SMESH_ProxyMesh::SubMesh* >     proxySubMesh( myEdge.size() );
     int nbProxyNodes = 0;
-    for ( size_t iE = 0; iE < myEdge.size(); ++iE )
+    size_t iE;
+
+    for ( iE = 0; iE < myEdge.size(); ++iE )
     {
       proxySubMesh[iE] = myProxyMesh->GetProxySubMesh( myEdge[iE] );
       if ( proxySubMesh[iE] )
@@ -361,74 +342,91 @@ const vector<UVPtStruct>& StdMeshers_FaceSide::GetUVPtStruct(bool   isXConst,
           continue;
         }
       }
-      // 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[iE]);
-      VV[1] = SMESH_MesherHelper::IthVertex( 1, myEdge[iE]);
-      const SMDS_MeshNode* node = SMESH_Algo::VertexNode( VV[0], meshDS );
-      double prevNormPar = ( iE == 0 ? 0 : myNormPar[ iE-1 ]); // normalized param
-      if ( node ) { // nodes on internal vertices may be missing
-        u2node.insert( u2node.end(), make_pair( prevNormPar, node ));
+
+      // Add 1st vertex node of a current edge
+      const SMDS_MeshNode* node = VertexNode( iE );
+      const double  prevNormPar = ( iE == 0 ? 0 : myNormPar[ iE-1 ]); // normalized param
+      if ( node ) // nodes on internal vertices may be missing
+      {
+        if ( vertexNodes.insert( node ).second ||
+             fHelper.IsRealSeam  ( node->getshapeId() ) ||
+             fHelper.IsDegenShape( node->getshapeId() ))
+          u2node.insert( u2node.end(), make_pair( prevNormPar, node ));
       }
-      else if ( iE == 0 ) {
-        MESSAGE(" NO NODE on VERTEX" );
-        return myPoints;
+      else if ( iE == 0 )
+      {
+        for ( ++iE; iE < myEdge.size(); ++iE )
+          if (( node = VertexNode( iE ))) {
+            u2node.insert( make_pair( prevNormPar, node ));
+            break;
+          }
+        --iE;
+
+        if ( !node )
+          return myPoints;
+        vertexNodes.insert( node );
       }
 
-      // Put internal nodes
-      if ( const SMESHDS_SubMesh* sm = myProxyMesh->GetSubMesh( myEdge[iE] ))
+      // Add internal nodes
+      nodes.clear();
+      if ( !GetEdgeNodes( iE, nodes, /*v0=*/false, /*v1=*/false ))
+        return myPoints;
+      if ( !nodes.empty() )
       {
-        vector< pair< double, const SMDS_MeshNode*> > u2nodeVec;
-        u2nodeVec.reserve( sm->NbNodes() );
-        SMDS_NodeIteratorPtr nItr = sm->GetNodes();
+        u2nodeVec.clear();
         double paramSize = myLast[iE] - myFirst[iE];
         double r         = myNormPar[iE] - prevNormPar;
-        helper.SetSubShape( myEdge[iE] );
-        helper.ToFixNodeParameters( true );
+        eHelper.SetSubShape( myEdge[iE] );
+        eHelper.ToFixNodeParameters( true );
         if ( !myIsUniform[iE] )
-          while ( nItr->more() )
+          for ( size_t i = 0; i < nodes.size(); ++i )
           {
-            const SMDS_MeshNode* node = nItr->next();
-            if ( myIgnoreMediumNodes && SMESH_MeshEditor::IsMedium( node, SMDSAbs_Edge ))
-              continue;
-            double u = helper.GetNodeU( myEdge[iE], node, 0, &paramOK );
-            double aLenU = GCPnts_AbscissaPoint::Length
-              ( const_cast<GeomAdaptor_Curve&>( myC3dAdaptor[iE]), myFirst[iE], u );
+            double     u = eHelper.GetNodeU( myEdge[iE], nodes[i], 0, &paramOK );
+            double aLenU = GCPnts_AbscissaPoint::Length( me->myC3dAdaptor[iE], myFirst[iE], u );
             if ( myEdgeLength[iE] < aLenU ) // nonregression test "3D_mesh_NETGEN/G6"
             {
               u2nodeVec.clear();
               break;
             }
-            double normPar = prevNormPar + r*aLenU/myEdgeLength[iE];
-            u2nodeVec.push_back( make_pair( normPar, node ));
+            double normPar = prevNormPar + r * aLenU / myEdgeLength[iE];
+            u2nodeVec.push_back( make_pair( normPar, nodes[i] ));
           }
-        nItr = sm->GetNodes();
         if ( u2nodeVec.empty() )
-          while ( nItr->more() )
+          for ( size_t i = 0; i < nodes.size(); ++i )
           {
-            const SMDS_MeshNode* node = nItr->next();
-            if ( myIgnoreMediumNodes && SMESH_MeshEditor::IsMedium( node, SMDSAbs_Edge ))
-              continue;
-            double u = helper.GetNodeU( myEdge[iE], node, 0, &paramOK );
-
+            double u = eHelper.GetNodeU( myEdge[iE], nodes[i], 0, &paramOK );
             // paramSize is signed so orientation is taken into account
             double normPar = prevNormPar + r * ( u - myFirst[iE] ) / paramSize;
-            u2nodeVec.push_back( make_pair( normPar, node ));
+            u2nodeVec.push_back( make_pair( normPar, nodes[i] ));
           }
         for ( size_t j = 0; j < u2nodeVec.size(); ++j )
           u2node.insert( u2node.end(), u2nodeVec[j] );
       }
+    } // loop on myEdge's
+
+    // Add 2nd VERTEX node for a last EDGE
+    if ( !proxySubMesh.back() )
+    {
+      if ( u2node.empty() ) return myPoints;
 
-      // Put 2nd vertex node for a last edge
-      if ( iE+1 == myEdge.size() ) {
-        node = SMESH_Algo::VertexNode( VV[1], meshDS );
-        if ( !node ) {
-          MESSAGE(" NO NODE on VERTEX" );
+      const SMDS_MeshNode* node;
+      if ( IsClosed() && !proxySubMesh[0] )
+        node = u2node.begin()->second;
+      else
+      {
+        node = VertexNode( iE );
+        while ( !node && iE > 0 )
+          node = VertexNode( --iE );
+        if ( !node )
           return myPoints;
-        }
-        u2node.insert( u2node.end(), make_pair( 1., node ));
       }
-    } // loop on myEdge's
+      if ( u2node.rbegin()->second == node &&
+           !fHelper.IsRealSeam  ( node->getshapeId() ) &&
+           !fHelper.IsDegenShape( node->getshapeId() ))
+        u2node.erase( --u2node.end() );
+
+      u2node.insert( u2node.end(), make_pair( 1., node ));
+    }
 
     if ( u2node.size() + nbProxyNodes != myNbPonits &&
          u2node.size() + nbProxyNodes != NbPoints( /*update=*/true ))
@@ -440,7 +438,7 @@ const vector<UVPtStruct>& StdMeshers_FaceSide::GetUVPtStruct(bool   isXConst,
 
     // fill array of UVPtStruct
 
-    UVPtStructVec& points = const_cast< UVPtStructVec& >( myPoints );
+    UVPtStructVec& points = me->myPoints;
     points.resize( myNbPonits );
 
     int iPt = 0;
@@ -487,7 +485,7 @@ const vector<UVPtStruct>& StdMeshers_FaceSide::GetUVPtStruct(bool   isXConst,
           // -- U ----------------------------------------------
           const SMDS_EdgePosition* epos =
             dynamic_cast<const SMDS_EdgePosition*>(uvPt.node->GetPosition());
-          if ( epos ) {
+          if ( epos && uvPt.node->getshapeId() == myEdgeID[iE] ) {
             uvPt.param = epos->GetUParameter();
           }
           else {
@@ -577,76 +575,122 @@ const vector<UVPtStruct>& StdMeshers_FaceSide::SimulateUVPtStruct(int    nbSeg,
 //purpose  : Return nodes in the order they encounter while walking along the side
 //=======================================================================
 
-std::vector<const SMDS_MeshNode*> StdMeshers_FaceSide::GetOrderedNodes() const
+std::vector<const SMDS_MeshNode*> StdMeshers_FaceSide::GetOrderedNodes(int theEdgeInd) const
 {
   vector<const SMDS_MeshNode*> resultNodes;
-  if ( myPoints.empty() )
+  if ( myPoints.empty() || ( theEdgeInd >= 0 && NbEdges() > 0 ))
   {
     if ( NbEdges() == 0 ) return resultNodes;
 
     SMESHDS_Mesh* meshDS = myProxyMesh->GetMeshDS();
-    SMESH_MesherHelper helper(*myProxyMesh->GetMesh());
-    bool paramOK;
+    SMESH_MesherHelper eHelper( *myProxyMesh->GetMesh() );
+    SMESH_MesherHelper fHelper( *myProxyMesh->GetMesh() );
+    fHelper.SetSubShape( myFace );
+    bool paramOK = true;
 
     // Sort nodes of all edges putting them into a map
 
     map< double, const SMDS_MeshNode*> u2node;
-    for ( int i = 0; i < myEdge.size(); ++i )
+    vector<const SMDS_MeshNode*>       nodes;
+    set<const SMDS_MeshNode*>          vertexNodes;
+    int iE = 0, iEnd = myEdge.size();
+    if ( theEdgeInd >= 0 )
     {
-      // 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
+      iE   = theEdgeInd % NbEdges();
+      iEnd = iE + 1;
+    }
+    for ( iE = 0; iE < iEnd; ++iE )
+    {
+      double prevNormPar = ( iE == 0 ? 0 : myNormPar[ iE-1 ]); // normalized param
+
+      const SMESH_ProxyMesh::SubMesh* proxySM = myProxyMesh->GetProxySubMesh( myEdge[iE] );
+      if ( proxySM )
+      {
+        const UVPtStructVec& points = proxySM->GetUVPtStructVec();
+        for ( size_t i = 0; i < points.size(); ++i )
+          u2node.insert( make_pair( prevNormPar + points[i].normParam, points[i].node ));
+        continue;
+      }
+
+      // Add 1st vertex node of a current EDGE
+      const SMDS_MeshNode* node = VertexNode( iE );
       if ( node ) { // nodes on internal vertices may be missing
-        u2node.insert( make_pair( prevNormPar, node ));
+        if ( vertexNodes.insert( node ).second ||
+             fHelper.IsRealSeam  ( node->getshapeId() ) ||
+             fHelper.IsDegenShape( node->getshapeId() ))
+          u2node.insert( make_pair( prevNormPar, node ));
       }
-      else if ( i == 0 ) {
-        MESSAGE(" NO NODE on VERTEX" );
-        return resultNodes;
+      else if ( iE == 0 )
+      {
+        if ( nodes.empty() ) {
+          for ( ++iE; iE < iEnd; ++iE )
+            if (( node = VertexNode( iE ))) {
+              u2node.insert( make_pair( prevNormPar, node ));
+              break;
+            }
+          --iE;
+        }
+        if ( !node )
+          return resultNodes;
+        vertexNodes.insert( node );
       }
 
-      // Put internal nodes
-      if ( SMESHDS_SubMesh* sm = meshDS->MeshElements( myEdge[i] ))
+      // Add internal nodes
+      nodes.clear();
+      if ( !GetEdgeNodes( iE, nodes, /*v0=*/false, /*v1=*/false ))
+        return resultNodes;
+      if ( !nodes.empty() )
       {
-        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() )
+        double paramSize = myLast[iE] - myFirst[iE];
+        double r         = myNormPar[iE] - prevNormPar;
+        eHelper.SetSubShape( myEdge[iE] );
+        eHelper.ToFixNodeParameters( true );
+        for ( size_t i = 0; i < nodes.size(); ++i )
         {
-          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 u = eHelper.GetNodeU( myEdge[iE], nodes[i], 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 ));
+          double normPar = prevNormPar + r * ( u - myFirst[iE] ) / paramSize;
+          u2node.insert( u2node.end(), make_pair( normPar, nodes[i] ));
         }
       }
 
-      // Put 2nd vertex node for a last edge
-      if ( i+1 == myEdge.size() ) {
-        node = SMESH_Algo::VertexNode( VV[1], meshDS );
-        if ( !node ) {
+    } // loop on myEdges
+
+    if ( u2node.empty() ) return resultNodes;
+
+    // Add 2nd vertex node for a last EDGE
+    {
+      const SMDS_MeshNode* node;
+      if ( IsClosed() && theEdgeInd < 0 )
+        node = u2node.begin()->second;
+      else
+      {
+        node = VertexNode( iE );
+        while ( !node && iE > 0 )
+          node = VertexNode( --iE );
+        if ( !node )
           return resultNodes;
-        }
-        u2node.insert( u2node.end(), make_pair( 1., node ));
       }
+      if ( u2node.rbegin()->second == node &&
+           !fHelper.IsRealSeam  ( node->getshapeId() ) &&
+           !fHelper.IsDegenShape( node->getshapeId() ))
+        u2node.erase( --u2node.end() );
+
+      u2node.insert( u2node.end(), make_pair( 1., node ));
     }
 
     // Fill the result vector
 
-    if ( u2node.size() == myNbPonits )
+    if ( theEdgeInd < 0 &&
+         u2node.size() != myNbPonits &&
+         u2node.size() != NbPoints( /*update=*/true ))
     {
-      resultNodes.reserve( u2node.size() );
-      map< double, const SMDS_MeshNode*>::iterator u2n = u2node.begin();
-      for ( ; u2n != u2node.end(); ++u2n )
-        resultNodes.push_back( u2n->second );
+      u2node.clear();
     }
+    resultNodes.reserve( u2node.size() );
+    map< double, const SMDS_MeshNode*>::iterator u2n = u2node.begin();
+    for ( ; u2n != u2node.end(); ++u2n )
+      resultNodes.push_back( u2n->second );
   }
   else
   {
@@ -658,6 +702,133 @@ std::vector<const SMDS_MeshNode*> StdMeshers_FaceSide::GetOrderedNodes() const
   return resultNodes;
 }
 
+//================================================================================
+/*!
+ * \brief Return (unsorted) nodes of the i-th EDGE.
+ *        Nodes moved to other geometry by MergeNodes() are also returned.
+ *  \retval bool - is OK
+ */
+//================================================================================
+
+bool StdMeshers_FaceSide::GetEdgeNodes(size_t                        i,
+                                       vector<const SMDS_MeshNode*>& nodes,
+                                       bool                          inlude1stVertex,
+                                       bool                          inludeLastVertex) const
+{
+  if ( i >= myEdge.size() )
+    return false;
+
+  SMESH_Mesh*     mesh = myProxyMesh->GetMesh();
+  SMESHDS_Mesh* meshDS = mesh->GetMeshDS();
+  SMESHDS_SubMesh*  sm = meshDS->MeshElements( myEdge[i] );
+
+  if ( inlude1stVertex )
+  {
+    if ( const SMDS_MeshNode* n0 = VertexNode( i ))
+      nodes.push_back( n0 );
+  }
+
+  if ( sm && ( sm->NbElements() > 0 || sm->NbNodes() > 0 ))
+  {
+    if ( mesh->HasModificationsToDiscard() ) // check nb of nodes on the EDGE sub-mesh
+    {
+      int iQuad    = sm->NbElements() ? sm->GetElements()->next()->IsQuadratic() : 0;
+      int nbExpect = sm->NbElements() - 1 + iQuad * sm->NbElements();
+      if ( nbExpect != sm->NbNodes() ) // some nodes are moved from the EDGE by MergeNodes()
+      {
+        // add nodes of all segments
+        typedef set< const SMDS_MeshNode* > TNodeSet;
+        TNodeSet sharedNodes;
+        SMDS_ElemIteratorPtr segIt = sm->GetElements();
+        while ( segIt->more() )
+        {
+          const SMDS_MeshElement* seg = segIt->next();
+          if ( seg->GetType() != SMDSAbs_Edge )
+            continue;
+          for ( int i = 0; i < 3-myIgnoreMediumNodes; ++i )
+          {
+            const SMDS_MeshNode* n = seg->GetNode( i );
+            if ( i == 2 ) // medium node
+            {
+              nodes.push_back( n );
+            }
+            else
+            {
+              pair<TNodeSet::iterator, bool> it2new = sharedNodes.insert( n );
+              if ( !it2new.second ) // n encounters twice == it's on EDGE, not on VERTEX
+              {
+                nodes.push_back( n );
+                sharedNodes.erase( it2new.first );
+              }
+            }
+          }
+        }
+      }
+    }
+    if ( nodes.size() < 2 ) // add nodes assigned to the EDGE
+    {
+      SMDS_NodeIteratorPtr nItr = sm->GetNodes();
+      while ( nItr->more() )
+      {
+        const SMDS_MeshNode* n = nItr->next();
+        if ( myIgnoreMediumNodes && SMESH_MeshEditor::IsMedium( n, SMDSAbs_Edge ))
+          continue;
+        nodes.push_back( n );
+      }
+    }
+  } // if ( sm && sm->NbElements() > 0 )
+
+  if ( inludeLastVertex )
+  {
+    if ( const SMDS_MeshNode* n1 = VertexNode( i+1 ))
+      nodes.push_back( n1 );
+  }
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief Return a node from the i-th VERTEX (count starts from zero)
+ *        Nodes moved to other geometry by MergeNodes() are also returned.
+ *  \param [in] i - the VERTEX index
+ *  \param [out] isMoved - returns \c true if the found node is moved by MergeNodes()
+ *  \return const SMDS_MeshNode* - the found node
+ */
+//================================================================================
+
+const SMDS_MeshNode* StdMeshers_FaceSide::VertexNode(std::size_t i, bool* isMoved) const
+{
+  TopoDS_Vertex V = ( i >= myEdge.size() ) ? LastVertex() : FirstVertex(i);
+
+  const SMDS_MeshNode* n = SMESH_Algo::VertexNode( V, myProxyMesh->GetMeshDS() );
+
+  if ( !n && !myEdge.empty() && myProxyMesh->GetMesh()->HasModificationsToDiscard() )
+  {
+    size_t iE = ( i < myEdge.size() ) ? i : myEdge.size()-1;
+    SMESHDS_SubMesh* sm = myProxyMesh->GetMeshDS()->MeshElements( myEdgeID[ iE ]);
+
+    n = SMESH_Algo::VertexNode( V, sm, myProxyMesh->GetMesh(), /*checkV=*/false );
+
+    if (( !n ) &&
+        (( i > 0 && i < NbEdges() ) || IsClosed() ))
+    {
+      iE = SMESH_MesherHelper::WrapIndex( int(i)-1, NbEdges() );
+      sm = myProxyMesh->GetMeshDS()->MeshElements( myEdgeID[ iE ]);
+      n  = SMESH_Algo::VertexNode( V, sm, myProxyMesh->GetMesh(), /*checkV=*/false );
+    }
+
+    if ( n && n->GetPosition()->GetDim() == 1 ) // check that n does not lie on an EDGE of myFace
+    {
+      TopoDS_Shape S = SMESH_MesherHelper::GetSubShapeByNode( n, myProxyMesh->GetMeshDS() );
+      if ( SMESH_MesherHelper::IsSubShape( S, myFace ))
+        n = 0; // VERTEX ignored by e.g. Composite Wire Discretization algo
+    }
+    if ( isMoved )
+      *isMoved = n;
+  }
+  return n;
+}
+
 //================================================================================
 /*!
  * \brief reverse order of vector elements
@@ -667,8 +838,7 @@ std::vector<const SMDS_MeshNode*> StdMeshers_FaceSide::GetOrderedNodes() const
 
 template <typename T > void reverse(vector<T> & vec)
 {
-  for ( int f=0, r=vec.size()-1; f < r; ++f, --r )
-    std::swap( vec[f], vec[r] );
+  std::reverse( vec.begin(), vec.end() );
 }
 
 //================================================================================
@@ -788,30 +958,48 @@ int StdMeshers_FaceSide::NbPoints(const bool update) const
     me->myNbSegments = 0;
     me->myMissingVertexNodes = false;
 
+    vector<const SMDS_MeshNode*> nodes;
     for ( int i = 0; i < NbEdges(); ++i )
     {
-      TopoDS_Vertex v1 = SMESH_MesherHelper::IthVertex( 0, myEdge[i] );
-      if ( SMESH_Algo::VertexNode( v1, myProxyMesh->GetMeshDS() ))
-        me->myNbPonits += 1; // for the first end
-      else
-        me->myMissingVertexNodes = true;
-    
-      if ( const SMESHDS_SubMesh* sm = myProxyMesh->GetSubMesh( Edge(i) )) {
-        int nbN = sm->NbNodes();
-        if ( myIgnoreMediumNodes ) {
-          SMDS_ElemIteratorPtr elemIt = sm->GetElements();
-          if ( elemIt->more() && elemIt->next()->IsQuadratic() )
-            nbN -= sm->NbElements();
+      if ( const SMESHDS_SubMesh* sm = myProxyMesh->GetSubMesh( Edge(i) ))
+      {
+        if ( sm->NbNodes() == sm->NbElements()-1 || sm->NbElements() == 0 )
+        {
+          me->myNbPonits += sm->NbNodes();
+          if ( myIgnoreMediumNodes && sm->IsQuadratic() )
+            me->myNbPonits -= sm->NbElements();
+        }
+        else // nodes can be moved to other shapes by MergeNodes()
+        {
+          nodes.clear();
+          GetEdgeNodes( i, nodes, /*v1=*/false, /*v2=*/false );
+          me->myNbPonits += nodes.size();
         }
-        me->myNbPonits   += nbN;
         me->myNbSegments += sm->NbElements();
       }
     }
-    TopoDS_Vertex v1 = SMESH_MesherHelper::IthVertex( 1, Edge( NbEdges()-1 ));
-    if ( SMESH_Algo::VertexNode( v1, myProxyMesh->GetMeshDS() ))
-      me->myNbPonits++; // for the last end
-    else
-      me->myMissingVertexNodes = true;
+
+    SMESH_MesherHelper helper( *myProxyMesh->GetMesh() );
+    helper.SetSubShape( myFace );
+
+    std::set< const SMDS_MeshNode* > vNodes;
+    const int nbV = NbEdges() + !IsClosed();
+    for ( int i = 0; i < nbV; ++i )
+      if ( const SMDS_MeshNode* n = VertexNode( i ))
+      {
+        if ( !vNodes.insert( n ).second &&
+             ( helper.IsRealSeam  ( n->getshapeId() ) ||
+               helper.IsDegenShape( n->getshapeId() )))
+          me->myNbPonits++;
+      }
+      else
+      {
+        me->myMissingVertexNodes = true;
+      }
+    me->myNbPonits += vNodes.size();
+
+    if ( IsClosed() )
+      me->myNbPonits++; // closing node is repeated
   }
   return myNbPonits;
 }
@@ -928,7 +1116,7 @@ BRepAdaptor_CompCurve* StdMeshers_FaceSide::GetCurve3d() const
   for ( int i=0; i<myEdge.size(); ++i )
     aBuilder.Add( aWire, myEdge[i] );
 
-  if ( myEdge.size() == 2 && FirstVertex().IsSame( LastVertex() ))
+  if ( myEdge.size() == 2 && IsClosed() )
     aWire.Closed(true); // issue 0021141
 
   return new BRepAdaptor_CompCurve( aWire );
@@ -1118,3 +1306,13 @@ TopoDS_Vertex StdMeshers_FaceSide::LastVertex(int i) const
   return v;
 }
 
+//================================================================================
+/*!
+ * \brief Return \c true if the chain of EDGEs is closed
+ */
+//================================================================================
+
+bool StdMeshers_FaceSide::IsClosed() const
+{
+  return myEdge.empty() ? false : FirstVertex().IsSame( LastVertex() );
+}
index 30166d441e9bb11659a1373819779c8d712031f3..485081af0e6a2aacf7c0fd217c05b0dd57d996d1 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -191,10 +191,27 @@ public:
                                           bool   isXConst   = 0,
                                           double constValue = 0) const;
   /*!
-   * \brief Return nodes in the order they encounter while walking along the side.
+   * \brief Return nodes in the order they encounter while walking along
+   *  the while side or a specified EDGE.
     * For a closed side, the 1st point repeats at end
    */
-  std::vector<const SMDS_MeshNode*> GetOrderedNodes() const;
+  std::vector<const SMDS_MeshNode*> GetOrderedNodes(int iE=-1) const;
+
+  /*!
+   * \brief Return nodes of the i-th EDGE.
+   *        Nodes moved to other geometry by MergeNodes() are also returned.
+   * \retval bool - is OK
+   */
+  bool GetEdgeNodes(const size_t                       i,
+                    std::vector<const SMDS_MeshNode*>& nodes,
+                    bool                               inlude1stVertex=true,
+                    bool                               inludeLastVertex=true) const;
+
+  /*!
+   * \brief Return a node from the i-th VERTEX (count starts from zero)
+   *        Nodes moved to other geometry by MergeNodes() are also returned.
+   */
+  const SMDS_MeshNode* VertexNode(std::size_t i, bool* isMoved = 0) const;
 
   /*!
    * \brief Return edge and parameter on edge by normalized parameter
@@ -229,13 +246,17 @@ public:
    */
   const std::vector<TopoDS_Edge>& Edges() const { return myEdge; }
   /*!
-   * \brief Return 1st vertex of the i-the edge (count starts from zero)
+   * \brief Return 1st vertex of the i-th edge (count starts from zero)
    */
   TopoDS_Vertex FirstVertex(int i=0) const;
   /*!
-   * \brief Return last vertex of the i-the edge (count starts from zero)
+   * \brief Return last vertex of the i-th edge (count starts from zero)
    */
   TopoDS_Vertex LastVertex(int i=-1) const;
+  /*!
+   * \brief Return \c true if the chain of EDGEs is closed
+   */
+  bool IsClosed() const;
   /*!
    * \brief Return side length
    */
@@ -258,20 +279,20 @@ public:
    */
   inline Handle(Geom2d_Curve) Curve2d(int i) const;
   /*!
-   * \brief Return first normalized parameter of the i-the edge (count starts from zero)
+   * \brief Return first normalized parameter of the i-th edge (count starts from zero)
    */
   inline double FirstParameter(int i) const;
   /*!
-   * \brief Return last normalized parameter of the i-the edge (count starts from zero)
+   * \brief Return last normalized parameter of the i-th edge (count starts from zero)
    */
   inline double LastParameter(int i) const;
   /*!
-   * \brief Return first parameter of the i-the edge (count starts from zero).
+   * \brief Return first parameter of the i-th edge (count starts from zero).
    *        EDGE orientation is taken into account
    */
   inline double FirstU(int i) const;
   /*!
-   * \brief Return last parameter of the i-the edge (count starts from zero).
+   * \brief Return last parameter of the i-th edge (count starts from zero).
    *        EDGE orientation is taken into account
    */
   inline double LastU(int i) const;
@@ -289,6 +310,7 @@ protected:
   void reverseProxySubmesh( const TopoDS_Edge& E );
 
   // DON't FORGET to update Reverse() when adding one more vector!
+  TopoDS_Face                       myFace;
   std::vector<uvPtStruct>           myPoints, myFalsePoints;
   std::vector<TopoDS_Edge>          myEdge;
   std::vector<int>                  myEdgeID;
@@ -340,7 +362,7 @@ inline double StdMeshers_FaceSide::Parameter(double U, TopoDS_Edge & edge) const
 
 //================================================================================
 /*!
- * \brief Return first normalized parameter of the i-the edge
+ * \brief Return first normalized parameter of the i-th edge
  */
 //================================================================================
 
@@ -351,7 +373,7 @@ inline double StdMeshers_FaceSide::FirstParameter(int i) const
 
 //================================================================================
 /*!
- * \brief Return ast normalized parameter of the i-the edge
+ * \brief Return ast normalized parameter of the i-th edge
  */
 //================================================================================
 
@@ -362,7 +384,7 @@ inline double StdMeshers_FaceSide::LastParameter(int i) const
 
 //================================================================================
 /*!
- * \brief Return first parameter of the i-the edge
+ * \brief Return first parameter of the i-th edge
  */
 //================================================================================
 
@@ -373,7 +395,7 @@ inline double StdMeshers_FaceSide::FirstU(int i) const
 
 //================================================================================
 /*!
- * \brief Return last parameter of the i-the edge
+ * \brief Return last parameter of the i-th edge
  */
 //================================================================================
 
index a731f9b2a211a15205b7df465b8224dffa909cd3..cd9b520d3de3d237ecc321e17a512e39b0e9a32f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
@@ -154,7 +154,7 @@ istream & StdMeshers_FixedPoints1D::LoadFrom(istream & load)
   if (isOK && intVal > 0) {
     _params.clear();
     _params.reserve( intVal );
-    for (int i = 0; i < _params.capacity() && isOK; i++) {
+    for ( size_t i = 0; i < _params.capacity() && isOK; i++) {
       isOK = (load >> dblVal);
       if ( isOK ) _params.push_back( dblVal );
     }
@@ -164,7 +164,7 @@ istream & StdMeshers_FixedPoints1D::LoadFrom(istream & load)
   if (isOK && intVal > 0) {
     _nbsegs.clear();
     _nbsegs.reserve( intVal );
-    for (int i = 0; i < _nbsegs.capacity() && isOK; i++) {
+    for ( size_t i = 0; i < _nbsegs.capacity() && isOK; i++) {
       isOK = (load >> intVal);
       if ( isOK ) _nbsegs.push_back( intVal );
     }
@@ -174,7 +174,7 @@ istream & StdMeshers_FixedPoints1D::LoadFrom(istream & load)
   if (isOK && intVal > 0) {
     _edgeIDs.clear();
     _edgeIDs.reserve( intVal );
-    for (int i = 0; i < _edgeIDs.capacity() && isOK; i++) {
+    for ( size_t i = 0; i < _edgeIDs.capacity() && isOK; i++) {
       isOK = (load >> intVal);
       if ( isOK ) _edgeIDs.push_back( intVal );
     }
index 5cbcd4c10cb0b569ef54b9edff1da64514e547ce..23f5aa428bea162b1fd9a31dc3bcb6decfeb962c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index 35820dc4691d248cdc36e62fb62ecf5681cef6de..eb50e45a95c3e4cf6f0a97c84d3a4e5aacd049aa 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index a14edc2f53f8f249f1a273b7b53f3c17ab43a4d8..33f5057340472cd5632dcf1eff080096b2359818 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index b4a502da38930b5e93545cd00ce2d625436749c6..6f87ebf4a83cc20075cf4fa620adab9e14cf3dd7 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
@@ -107,14 +107,14 @@ namespace
       return true;
 
     set<const SMDS_MeshNode*> nodesInInverseFaces;
-    SMDS_ElemIteratorPtr fIt = n->GetInverseElementIterator(SMDSAbs_Face );
+    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 );
+    return (int)nodesInInverseFaces.size() != ( 6 + (nbF/2-1)*3 );
   }
 
   //================================================================================
@@ -212,7 +212,7 @@ namespace
     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)]
+#define _grid_access_(pobj, i) pobj->_grid[ ((i) < (int)pobj->_grid.size()) ? i : int(1e100)]
 #else
 #define _grid_access_(pobj, i) pobj->_grid[ i ]
 #endif
@@ -269,8 +269,8 @@ namespace
     //!< 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];
+      size_t i = _index( x, y );
+      return ( i >= _side->_grid.size() ) ? 0 : _side->_grid[i];
     }
     //!< Return an edge
     SMESH_OrientedLink edge(EQuadEdge edge) const
@@ -372,7 +372,7 @@ namespace
 
   //================================================================================
   /*!
-   * \brief Find and return number of submeshes corresponding to blocks
+   * \brief Find blocks and return their number
    */
   //================================================================================
 
@@ -421,7 +421,7 @@ namespace
           _allSides.push_back( _BlockSide() );
 
         _BlockSide& side = _allSides.back();
-        if ( !fillSide( side, face, *corner ) )
+        if ( !fillSide( side, face, *corner ))
         {
           if ( !_error.empty() )
             return false;
@@ -522,7 +522,7 @@ namespace
             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 ( 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 ));
@@ -533,7 +533,7 @@ namespace
       {
         // 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 )
+        for ( size_t i = 1; i < _blocks.size() && !isSame; ++i )
           isSame = ( block._corners == _blocks[i-1]._corners );
         ok = !isSame;
       }
@@ -606,12 +606,12 @@ namespace
       side._index._ySize = verRow1.size();
       side._grid.resize( side._index.size(), NULL );
 
-      for ( x = 0; x < horRow1.size(); ++x )
+      for ( x = 0; x < nbX; ++x )
       {
         side.setNode( x, 0, horRow1[x] );
         side.setNode( x, 1, horRow2[x] );
       }
-      for ( y = 0; y < verRow1.size(); ++y )
+      for ( y = 0; y < nbY; ++y )
       {
         side.setNode( 0, y, verRow1[y] );
         side.setNode( 1, y, verRow2[y] );
@@ -725,7 +725,9 @@ namespace
       if ( !n ) return false;
 
       prevSide = nextSide;
-      nbChainLinks++;
+
+      if ( ++nbChainLinks > NB_QUAD_SIDES )
+        return false;
     }
 
     return ( n == n2 && nbChainLinks == NB_QUAD_SIDES );
@@ -1003,6 +1005,9 @@ namespace
       SMESH_OrientedLink eAdja = _side[ adjacent[i] ].edge( edgeAdj[i] );
       ok = ( eBack == eAdja );
     }
+    ok = ok && ( _side[ B_BOTTOM ]._index.size() == _side[ B_TOP  ]._index.size() &&
+                 _side[ B_RIGHT  ]._index.size() == _side[ B_LEFT ]._index.size() &&
+                 _side[ B_FRONT  ]._index.size() == _side[ B_BACK ]._index.size() );
     return ok;
   }
 
@@ -1250,7 +1255,7 @@ bool StdMeshers_HexaFromSkin_3D::Evaluate(SMESH_Mesh &         aMesh,
 
   int entity = secondOrder ? SMDSEntity_Quad_Hexa : SMDSEntity_Hexa;
   vector<int>& nbByType = aResMap[ aMesh.GetSubMesh( aShape )];
-  if ( entity >= nbByType.size() )
+  if ( entity >= (int) nbByType.size() )
     nbByType.resize( SMDSEntity_Last, 0 );
 
   for ( int i = 0; i < nbBlocks; ++i )
index c6d5dbee20d19c117b43ef2ce58d38259811cbbf..82ff85872f02520e78d0656c7be2aae672ae0bfa 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index 8c54ad4e801a676338b67a2c7bbb0c2fa9290daa..34af3a6fd2375d1ac84df8f34e1a5589ba5e9ced 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -144,6 +144,7 @@ namespace
   //=============================================================================
 
   typedef boost::shared_ptr< FaceQuadStruct > FaceQuadStructPtr;
+  typedef std::vector<gp_XYZ>                 TXYZColumn;
 
   // symbolic names of box sides
   enum EBoxSides{ B_BOTTOM=0, B_RIGHT, B_TOP, B_LEFT, B_FRONT, B_BACK, B_NB_SIDES };
@@ -151,6 +152,8 @@ namespace
   // symbolic names of sides of quadrangle
   enum EQuadSides{ Q_BOTTOM=0, Q_RIGHT, Q_TOP, Q_LEFT, Q_NB_SIDES };
 
+  enum EAxes{ COO_X=1, COO_Y, COO_Z };
+
   //=============================================================================
   /*!
    * \brief Container of nodes of structured mesh on a qudrangular geom FACE
@@ -166,6 +169,9 @@ namespace
     // node column's taken form _u2nodesMap taking into account sub-shape orientation
     vector<TNodeColumn> _columns;
 
+    // columns of normalized parameters of nodes within the unitary cube
+    vector<TXYZColumn> _ijkColumns;
+
     // geometry of a cube side
     TopoDS_Face _sideF;
 
@@ -177,6 +183,10 @@ namespace
     {
       return SMESH_TNodeXYZ( GetNode( iCol, iRow ));
     }
+    gp_XYZ& GetIJK(int iCol, int iRow)
+    {
+      return _ijkColumns[iCol][iRow];
+    }
   };
 
   //================================================================================
@@ -276,6 +286,56 @@ namespace
     }
     return ( n == n00 || n == n01 || n == n10 || n == n11 );
   }
+
+  //================================================================================
+  /*!
+   * \brief Fill in _FaceGrid::_ijkColumns
+   *  \param [in,out] fg - a _FaceGrid
+   *  \param [in] i1 - coordinate index along _columns
+   *  \param [in] i2 - coordinate index along _columns[i]
+   *  \param [in] v3 - value of the constant parameter
+   */
+  //================================================================================
+
+  void computeIJK( _FaceGrid& fg, int i1, int i2, double v3 )
+  {
+    gp_XYZ ijk( v3, v3, v3 );
+    const size_t nbCol = fg._columns.size();
+    const size_t nbRow = fg._columns[0].size();
+
+    fg._ijkColumns.resize( nbCol );
+    for ( size_t i = 0; i < nbCol; ++i )
+      fg._ijkColumns[ i ].resize( nbRow, ijk );
+
+    vector< double > len( nbRow );
+    len[0] = 0;
+    for ( size_t i = 0; i < nbCol; ++i )
+    {
+      gp_Pnt pPrev = fg.GetXYZ( i, 0 );
+      for ( size_t j = 1; j < nbRow; ++j )
+      {
+        gp_Pnt p = fg.GetXYZ( i, j );
+        len[ j ] = len[ j-1 ] + p.Distance( pPrev );
+        pPrev = p;
+      }
+      for ( size_t j = 0; j < nbRow; ++j )
+        fg.GetIJK( i, j ).SetCoord( i2, len[ j ]/len.back() );
+    }
+
+    len.resize( nbCol );
+    for ( size_t j = 0; j < nbRow; ++j )
+    {
+      gp_Pnt pPrev = fg.GetXYZ( 0, j );
+      for ( size_t i = 1; i < nbCol; ++i )
+      {
+        gp_Pnt p = fg.GetXYZ( i, j );
+        len[ i ] = len[ i-1 ] + p.Distance( pPrev );
+        pPrev = p;
+      }
+      for ( size_t i = 0; i < nbCol; ++i )
+        fg.GetIJK( i, j ).SetCoord( i1, len[ i ]/len.back() );
+    }
+  }
 }
 
 //=============================================================================
@@ -444,15 +504,15 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh &         aMesh,
   {
     aCubeSide[i]._columns.resize( aCubeSide[i]._u2nodesMap.size() );
 
-    int iFwd = 0, iRev = aCubeSide[i]._columns.size()-1;
-    int* pi = isReverse[i] ? &iRev : &iFwd;
+    size_t iFwd = 0, iRev = aCubeSide[i]._columns.size()-1;
+    size_t*  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)
@@ -476,6 +536,14 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh &         aMesh,
   _FaceGrid* fFront  = & aCubeSide[ B_FRONT  ];
   _FaceGrid* fBack   = & aCubeSide[ B_BACK   ];
 
+  // compute normalized parameters of nodes on sides (PAL23189)
+  computeIJK( *fBottom, COO_X, COO_Y, /*z=*/0. );
+  computeIJK( *fRight,  COO_Y, COO_Z, /*x=*/1. );
+  computeIJK( *fTop,    COO_X, COO_Y, /*z=*/1. );
+  computeIJK( *fLeft,   COO_Y, COO_Z, /*x=*/0. );
+  computeIJK( *fFront,  COO_X, COO_Z, /*y=*/0. );
+  computeIJK( *fBack,   COO_X, COO_Z, /*y=*/1. );
+
   // 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;
@@ -531,13 +599,14 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh &         aMesh,
   pointsOnShapes[ SMESH_Block::ID_V011 ] = fTop->GetXYZ( 0, Y );
   pointsOnShapes[ SMESH_Block::ID_V111 ] = fTop->GetXYZ( X, Y );
 
+  gp_XYZ params; // normalized parameters of an internal node within the unit box
   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) );
+    const double rX = x / double(X);
     for ( y = 1; y < ySize-1; ++y )
     {
-      params.SetCoord( 2, y / double(Y) );
+      const double rY = 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
@@ -554,23 +623,36 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh &         aMesh,
       pointsOnShapes[ SMESH_Block::ID_Fxy1 ] = fTop   ->GetXYZ( x, y );
       for ( z = 1; z < zSize-1; ++z ) // z loop
       {
-        params.SetCoord( 3, z / double(Z) );
+        const double rZ = z / double(Z);
+
+        const gp_XYZ& pBo = fBottom->GetIJK( x, y );
+        const gp_XYZ& pTo = fTop   ->GetIJK( x, y );
+        const gp_XYZ& pFr = fFront ->GetIJK( x, z );
+        const gp_XYZ& pBa = fBack  ->GetIJK( x, z );
+        const gp_XYZ& pLe = fLeft  ->GetIJK( y, z );
+        const gp_XYZ& pRi = fRight ->GetIJK( y, z );
+        params.SetCoord( 1, 0.5 * ( pBo.X() * ( 1. - rZ ) + pTo.X() * rZ  +
+                                    pFr.X() * ( 1. - rY ) + pBa.X() * rY ));
+        params.SetCoord( 2, 0.5 * ( pBo.Y() * ( 1. - rZ ) + pTo.Y() * rZ  +
+                                    pLe.Y() * ( 1. - rX ) + pRi.Y() * rX ));
+        params.SetCoord( 3, 0.5 * ( pFr.Z() * ( 1. - rY ) + pBa.Z() * rY  +
+                                    pLe.Z() * ( 1. - rX ) + pRi.Z() * rX ));
+
         // 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_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_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() );
-
       }
     }
   }
index 7c64bd497ea41bfe2ab47e0271edd3edf880141f..e186863a57371d449b1bf9eace018673a031d904 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -55,7 +55,8 @@ public:
                         MapShapeNbElems& aResMap);
 
   static bool IsApplicable(const TopoDS_Shape & aShape, bool toCheckAll);
-protected:
+
+ protected:
 
   const StdMeshers_ViscousLayers* _viscousLayersHyp;
 };
index aea04659506f929498b36809838e4442662737fc..de6bfc0471f68744834cfde562434ab52d970448 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -125,14 +125,14 @@ namespace
                                       bool                        loaded=false)
   {
     vector<SMESH_Group*> okGroups;
-    for ( int i = 0; i < groups.size(); ++i )
+    for ( size_t 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();
+        map<int, SMESH_Mesh*>::iterator itm = studyContext->mapMesh.begin();
         for ( ; !okGroup && itm != studyContext->mapMesh.end(); itm++)
         {
           SMESH_Mesh::GroupIteratorPtr gIt = itm->second->GetGroups();
@@ -174,7 +174,7 @@ namespace
   {
     int tgtID = resMapKey.second;
     SMESH_Mesh* tgtMesh = 0;
-    map<int, SMESH_Mesh*>::iterator itm = itm = studyContext->mapMesh.begin();
+    map<int, SMESH_Mesh*>::iterator itm = studyContext->mapMesh.begin();
     for ( ; !tgtMesh && itm != studyContext->mapMesh.end(); itm++)
     {
       tgtMesh = (*itm).second;
@@ -250,7 +250,7 @@ std::vector<SMESH_Mesh*> StdMeshers_ImportSource1D::GetSourceMeshes() const
     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();
+      map<int, SMESH_Mesh*>::iterator itm = studyContext->mapMesh.begin();
       for ( ; itm != studyContext->mapMesh.end(); itm++)
       {
         SMESH_Mesh* mesh = (*itm).second;
@@ -394,7 +394,7 @@ void StdMeshers_ImportSource1D::RestoreGroups(const std::vector<SMESH_Group*>& g
   _groups = groups;
 
   _resultGroups.clear();
-  int i = 0;
+  size_t i = 0;
   while ( i < _resultGroupsStorage.size() )
   {
     int key1 = _resultGroupsStorage[i++];
index 78facb160ad419719cdaed8d826e0af72b0bb0f0..cb1db4440b8d1d01584d9aacc7953c0d42eb5134 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -61,6 +61,7 @@ class STDMESHERS_EXPORT StdMeshers_ImportSource1D : public SMESH_Hypothesis
   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);
+  virtual bool DataDependOnParams() const { return true; }
   void RestoreGroups(const std::vector<SMESH_Group*>& groups);
 
   void StoreResultGroups(const std::vector<SMESH_Group*>& groups,
index a69977dbe40c57c2054df1f7ca400c7fb13559f9..f53b60edeae7d2d4211390a16325eeb8b2341faf 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -685,7 +685,7 @@ bool StdMeshers_Import_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & th
   // import edges from groups
   TNodeNodeMap* n2n;
   TElemElemMap* e2e;
-  for ( int iG = 0; iG < srcGroups.size(); ++iG )
+  for ( size_t iG = 0; iG < srcGroups.size(); ++iG )
   {
     const SMESHDS_GroupBase* srcGroup = srcGroups[iG]->GetGroupDS();
 
@@ -711,7 +711,7 @@ bool StdMeshers_Import_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & th
       double mytol = a.Distance(edge->GetNode(edge->NbNodes()-1))/25;
       //mytol = max(1.E-5, 10*edgeTol); // too strict and not necessary
       //MESSAGE("mytol = " << mytol);
-      for ( unsigned i = 0; i < newNodes.size(); ++i, ++node )
+      for ( size_t i = 0; i < newNodes.size(); ++i, ++node )
       {
         TNodeNodeMap::iterator n2nIt = n2n->insert( make_pair( *node, (SMDS_MeshNode*)0 )).first;
         if ( n2nIt->second )
@@ -810,7 +810,7 @@ bool StdMeshers_Import_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & th
 
   // copy meshes
   vector<SMESH_Mesh*> srcMeshes = _sourceHyp->GetSourceMeshes();
-  for ( unsigned i = 0; i < srcMeshes.size(); ++i )
+  for ( size_t i = 0; i < srcMeshes.size(); ++i )
     importMesh( srcMeshes[i], theMesh, _sourceHyp, theShape );
 
   return true;
@@ -841,6 +841,7 @@ void StdMeshers_Import_1D::importMesh(const SMESH_Mesh*          srcMesh,
 
   // 1. Copy mesh
 
+  SMESH_MeshEditor::ElemFeatures elemType;
   vector<const SMDS_MeshNode*> newNodes;
   const SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
   SMDS_ElemIteratorPtr eIt = srcMeshDS->elementsIterator();
@@ -865,14 +866,14 @@ void StdMeshers_Import_1D::importMesh(const SMESH_Mesh*          srcMesh,
       tgtMeshDS->FindElement( newNodes, elem->GetType(), /*noMedium=*/false );
     if ( !newElem )
     {
-      newElem = additor.AddElement( newNodes, elem->GetType(), elem->IsPoly());
+      newElem = additor.AddElement( newNodes, elemType.Init( elem, /*basicOnly=*/false ));
       tgtSubMesh->AddElement( newElem );
     }
     if ( toCopyGroups )
       (*e2eIt).second = newElem;
   }
   // copy free nodes
-  if ( srcMeshDS->NbNodes() > n2n->size() )
+  if ( srcMeshDS->NbNodes() > (int) n2n->size() )
   {
     SMDS_NodeIteratorPtr nIt = srcMeshDS->nodesIterator();
     while( nIt->more() )
@@ -1027,7 +1028,7 @@ bool StdMeshers_Import_1D::Evaluate(SMESH_Mesh &         theMesh,
 
     // count edges imported from groups
     int nbEdges = 0, nbQuadEdges = 0;
-    for ( int iG = 0; iG < srcGroups.size(); ++iG )
+    for ( size_t iG = 0; iG < srcGroups.size(); ++iG )
     {
       const SMESHDS_GroupBase* srcGroup = srcGroups[iG]->GetGroupDS();
       SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements();
@@ -1056,7 +1057,7 @@ bool StdMeshers_Import_1D::Evaluate(SMESH_Mesh &         theMesh,
   }
 
   SMESH_subMesh * sm = theMesh.GetSubMesh(theShape);
-  aResMap.insert(make_pair(sm,aVec));
+  aResMap.insert( make_pair( sm, aVec ));
 
   return true;
 }
index b45fe5f501280744ba5ae4267949fc1565a075c1..487499cbd033507c125736bb553715821b248a65 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 636cd73ec006e4eec21bdfd1a88121e092febb41..df7f8c0655a6348b1dd87382e2b0fa2c1485b27a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 #include "Utils_SALOME_Exception.hxx"
 #include "utilities.h"
 
+#include <BRepBndLib.hxx>
+#include <BRepClass_FaceClassifier.hxx>
+#include <BRepTools.hxx>
 #include <BRep_Builder.hxx>
 #include <BRep_Tool.hxx>
+#include <Bnd_B2d.hxx>
+#include <Bnd_Box.hxx>
+#include <GeomAPI_ProjectPointOnSurf.hxx>
+#include <GeomAdaptor_Surface.hxx>
+#include <Precision.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>
 
@@ -185,11 +192,36 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
   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 );
+  const bool reverse =
+    ( helper.GetSubShapeOri( tgtMesh->ShapeToMesh(), geomFace ) == TopAbs_REVERSED );
   gp_Pnt p; gp_Vec du, dv;
 
+  // BRepClass_FaceClassifier is most time consuming, so minimize its usage
+  BRepClass_FaceClassifier classifier;
+  Bnd_B2d bndBox2d;
+  Bnd_Box bndBox3d;
+  {
+    Standard_Real umin,umax,vmin,vmax;
+    BRepTools::UVBounds(geomFace,umin,umax,vmin,vmax);
+    gp_XY pmin( umin,vmin ), pmax( umax,vmax );
+    bndBox2d.Add( pmin );
+    bndBox2d.Add( pmax );
+    if ( helper.HasSeam() )
+    {
+      const int i = helper.GetPeriodicIndex();
+      pmin.SetCoord( i, helper.GetOtherParam( pmin.Coord( i )));
+      pmax.SetCoord( i, helper.GetOtherParam( pmax.Coord( i )));
+      bndBox2d.Add( pmin );
+      bndBox2d.Add( pmax );
+    }
+    bndBox2d.Enlarge( 1e-2 * Sqrt( bndBox2d.SquareExtent() ));
+
+    BRepBndLib::Add( geomFace, bndBox3d );
+    bndBox3d.Enlarge( 1e-5 * sqrt( bndBox3d.SquareExtent() ));
+  }
+
   set<int> subShapeIDs;
   subShapeIDs.insert( shapeID );
 
@@ -213,7 +245,7 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
     existingNodes.insert( n );
   }
 
-  // get EDGESs and their ids and get existing nodes on EDGEs
+  // get EDGEs and their ids and get existing nodes on EDGEs
   vector< TopoDS_Edge > edges;
   for ( exp.Init( theShape, TopAbs_EDGE ); exp.More(); exp.Next() )
   {
@@ -244,7 +276,11 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
 
   StdMeshers_Import_1D::TNodeNodeMap* n2n;
   StdMeshers_Import_1D::TElemElemMap* e2e;
-  vector<const SMDS_MeshNode*> newNodes;
+  vector<TopAbs_State>         nodeState;
+  vector<const SMDS_MeshNode*> newNodes; // of a face
+  set   <const SMDS_MeshNode*> bndNodes; // nodes classified ON
+  vector<bool>                 isNodeIn; // nodes classified IN, by node ID
+
   for ( size_t iG = 0; iG < srcGroups.size(); ++iG )
   {
     const SMESHDS_GroupBase* srcGroup = srcGroups[iG]->GetGroupDS();
@@ -257,58 +293,139 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
     const double groupTol = 0.5 * sqrt( getMinElemSize2( srcGroup ));
     minGroupTol = std::min( groupTol, minGroupTol );
 
+    //GeomAdaptor_Surface S( surface );
+    // const double clsfTol = Min( S.UResolution( 0.1 * groupTol ), -- issue 0023092
+    //                             S.VResolution( 0.1 * groupTol ));
+    const double clsfTol = BRep_Tool::Tolerance( geomFace );
+
+    StdMeshers_Import_1D::TNodeNodeMap::iterator n2nIt;
+    pair< StdMeshers_Import_1D::TNodeNodeMap::iterator, bool > it_isnew;
+
     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();
+
+      SMDS_MeshElement::iterator node = face->begin_nodes();
+      if ( bndBox3d.IsOut( SMESH_TNodeXYZ( *node )))
+        continue;
+
       // find or create nodes of a new face
-      newNodes.resize( face->NbNodes() );
+      nodeState.resize( face->NbNodes() );
+      newNodes.resize( nodeState.size() );
       newNodes.back() = 0;
       int nbCreatedNodes = 0;
-      SMDS_MeshElement::iterator node = face->begin_nodes();
+      bool isOut = false, isIn = false; // if at least one node isIn - do not classify other 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 )
+        SMESH_TNodeXYZ nXYZ = *node;
+        nodeState[ i ] = TopAbs_UNKNOWN;
+        newNodes [ i ] = 0;
+
+        it_isnew = n2n->insert( make_pair( *node, (SMDS_MeshNode*)0 ));
+        n2nIt    = it_isnew.first;
+
+        const SMDS_MeshNode* & newNode = n2nIt->second;
+        if ( !it_isnew.second && !newNode )
+          break; // a node is mapped to NULL - it is OUT of the FACE
+
+        if ( newNode )
         {
-          if ( !subShapeIDs.count( n2nIt->second->getshapeId() )) // node already on an EDGE
-            break;
+          if ( !subShapeIDs.count( newNode->getshapeId() ))
+            break; // node is Imported onto other FACE
+          if ( newNode->GetID() < (int) isNodeIn.size() &&
+               isNodeIn[ newNode->GetID() ])
+            isIn = true;
+          if ( !isIn && bndNodes.count( *node ))
+            nodeState[ i ] = TopAbs_ON;
         }
         else
         {
-          // find a pre-existing node
+          // find a node pre-existing on EDGE or VERTEX
           dist2foundNodes.clear();
-          existingNodeOcTr.NodesAround( SMESH_TNodeXYZ( *node ), dist2foundNodes, groupTol );
+          existingNodeOcTr.NodesAround( nXYZ, dist2foundNodes, groupTol );
           if ( !dist2foundNodes.empty() )
-            (*n2nIt).second = dist2foundNodes.begin()->second;
+          {
+            newNode = dist2foundNodes.begin()->second;
+            nodeState[ i ] = TopAbs_ON;
+          }
         }
-        if ( !n2nIt->second )
+
+        if ( !newNode )
         {
-          // 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 ))
+          // find out if node lies on the surface of theShape
+          gp_XY uv( Precision::Infinite(), 0 );
+          isOut = ( !helper.CheckNodeUV( geomFace, *node, uv, groupTol, /*force=*/true ) ||
+                    bndBox2d.IsOut( uv ));
+          if ( !isOut && !isIn ) // classify
+          {
+            classifier.Perform( geomFace, uv, clsfTol );
+            nodeState[i] = classifier.State();
+            isOut = ( nodeState[i] == TopAbs_OUT );
+          }
+          if ( !isOut ) // create a new node
           {
-            SMDS_MeshNode* newNode = tgtMesh->AddNode( (*node)->X(), (*node)->Y(), (*node)->Z());
-            n2nIt->second = newNode;
+            newNode = tgtMesh->AddNode( nXYZ.X(), nXYZ.Y(), nXYZ.Z());
             tgtMesh->SetNodeOnFace( newNode, shapeID, uv.X(), uv.Y() );
             nbCreatedNodes++;
+            if ( newNode->GetID() >= (int) isNodeIn.size() )
+            {
+              isNodeIn.push_back( false ); // allow allocate more than newNode->GetID()
+              isNodeIn.resize( newNode->GetID() + 1, false );
+            }
+            if ( nodeState[i] == TopAbs_ON )
+              bndNodes.insert( *node );
+            else
+              isNodeIn[ newNode->GetID() ] = isIn = true;
           }
         }
-        if ( !(newNodes[i] = n2nIt->second ))
+        if ( !(newNodes[i] = newNode ) || isOut )
           break;
       }
+
       if ( !newNodes.back() )
         continue; // not all nodes of the face lie on theShape
 
+      if ( !isIn ) // if all nodes are on FACE boundary, a mesh face can be OUT
+      {
+        // check state of nodes created for other faces
+        for ( size_t i = 0; i < nodeState.size() && !isIn; ++i )
+        {
+          if ( nodeState[i] != TopAbs_UNKNOWN ) continue;
+          gp_XY uv = helper.GetNodeUV( geomFace, newNodes[i] );
+          classifier.Perform( geomFace, uv, clsfTol );
+          nodeState[i] = classifier.State();
+          isIn = ( nodeState[i] == TopAbs_IN );
+        }
+        if ( !isIn ) // classify face center
+        {
+          gp_XYZ gc( 0., 0., 0 );
+          for ( size_t i = 0; i < newNodes.size(); ++i )
+            gc += SMESH_TNodeXYZ( newNodes[i] );
+          gc /= newNodes.size();
+
+          TopLoc_Location loc;
+          GeomAPI_ProjectPointOnSurf& proj = helper.GetProjector( geomFace,
+                                                                  loc,
+                                                                  helper.MaxTolerance( geomFace ));
+          if ( !loc.IsIdentity() ) loc.Transformation().Inverted().Transforms( gc );
+          proj.Perform( gc );
+          if ( !proj.IsDone() || proj.NbPoints() < 1 )
+            continue;
+          Quantity_Parameter U,V;
+          proj.LowerDistanceParameters(U,V);
+          gp_XY uv( U,V );
+          classifier.Perform( geomFace, uv, clsfTol );
+          if ( classifier.State() != TopAbs_IN )
+            continue;
+        }
+      }
+
       // 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 
+        continue; // repeated face in source groups already created
 
       // check future face orientation
       const int nbCorners = face->NbCornerNodes();
@@ -319,7 +436,7 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
         gp_Vec geomNorm;
         do
         {
-          uv = helper.GetNodeUV( geomFace, newNodes[++iNode] );
+          gp_XY uv = helper.GetNodeUV( geomFace, newNodes[++iNode] );
           surface->D1( uv.X(),uv.Y(), p, du,dv );
           geomNorm = reverse ? dv^du : du^dv;
         }
@@ -337,7 +454,7 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
 
         if ( geomNorm * meshNorm < 0 )
           SMDS_MeshCell::applyInterlace
-            ( SMDS_MeshCell::reverseSmdsOrder( face->GetEntityType() ), newNodes );
+            ( SMDS_MeshCell::reverseSmdsOrder( face->GetEntityType(), newNodes.size() ), newNodes );
       }
 
       // make a new face
@@ -384,9 +501,15 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
         // }
       }
     }
-    helper.GetMeshDS()->RemoveNode(tmpNode);
+    // Remove OUT nodes from n2n map
+    for ( n2nIt = n2n->begin(); n2nIt != n2n->end(); )
+      if ( !n2nIt->second )
+        n2n->erase( n2nIt++ );
+      else
+        ++n2nIt;
   }
 
+
   // ==========================================================
   // Put nodes on geom edges and create edges on them;
   // check if the whole geom face is covered by imported faces
@@ -578,7 +701,7 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
         seamHelper.SetSubShape( edges[ iE ]);
         seamHelper.SetElementsOnShape( true );
 
-        if ( (*checkedFaces.begin())->IsQuadratic() )
+        if ( !checkedFaces.empty() && (*checkedFaces.begin())->IsQuadratic() )
           for ( set< const SMDS_MeshElement* >::iterator fIt = checkedFaces.begin();
                 fIt != checkedFaces.end(); ++fIt )
             seamHelper.AddTLinks( static_cast<const SMDS_MeshFace*>( *fIt ));
@@ -607,8 +730,7 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
     //   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 ]));
+      return error(SMESH_Comment("Failed to create segments on the edge #") << sm->GetId());
   }
 
   // ============
@@ -702,7 +824,7 @@ bool StdMeshers_Import_1D2D::Evaluate(SMESH_Mesh &         theMesh,
     set<const SMDS_MeshNode* > allNodes;
     gp_XY uv;
     double minGroupTol = 1e100;
-    for ( int iG = 0; iG < srcGroups.size(); ++iG )
+    for ( size_t iG = 0; iG < srcGroups.size(); ++iG )
     {
       const SMESHDS_GroupBase* srcGroup = srcGroups[iG]->GetGroupDS();
       const double groupTol = 0.5 * sqrt( getMinElemSize2( srcGroup ));
index e008b99d46dd8f398ab7431449b2f6a965f54e90..fb8b244ab741fef88eb1c492d1acdfab3b121082 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 6b7b972da1100d124501a5b23fc4d07433ab2bbd..03bb2c7f51a5e1a9e10e05dc3ba8b0832dcfa0c5 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 25823ecbbc67b317ce1f0e1abc38fc57a00cf70b..c2a77c08d342c8e4039dd216b88c1f4ead59617b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 815768e4fa88832cb51d40344893ce8b1cc9b5a5..6204a765bc41a9393ea3773a8bee58d4b6644ac9 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index a17fe0627141aa995e56ec55a17551ba1c329364..1049c68dd6ef3b2ca4c0952bbe1d9b14e00c15b9 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index 48bc31a8e6c5c14713ee8374fc27546886dcde5a..a31944c644543e7e20ec47dc8a38752613efebb1 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index fb9bf49de4bc79e96a20d1c1d3d8d404d5205ce8..714042cf9769ed32daa5f66c88ed653e7e55dade 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index a5712bdb07e3a67563999ed0b7c3d470effdadb3..ea14e8126153fc6026a06aef892f5ce9c8729712 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -224,7 +224,7 @@ bool StdMeshers_LocalLength::SetParametersByMesh(const SMESH_Mesh*   theMesh,
     SMESHDS_Mesh* aMeshDS = const_cast< SMESH_Mesh* >( theMesh )->GetMeshDS();
     if ( SMESH_Algo::GetNodeParamOnEdge( aMeshDS, edge, params ))
     {
-      for ( int i = 1; i < params.size(); ++i )
+      for ( size_t i = 1; i < params.size(); ++i )
         _length += GCPnts_AbscissaPoint::Length( AdaptCurve, params[ i-1 ], params[ i ]);
       nbEdges += params.size() - 1;
     }
index 5d3895d9e9733562c529d096cbe3227d900551c4..41b019109d45f8e6f1f69c8007ede8af06da3c63 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 34003c6c9df03a5557a69e43f5c0acf4499b868b..e7daf5ace19e9eee80a158662c1f1274be05cd0a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -587,7 +587,7 @@ bool StdMeshers_MEFISTO_2D::LoadPoints(TWireVector &                 wires,
     F = TopoDS::Face( _helper->GetSubShape() );
     TopExp::MapShapesAndAncestors( F, TopAbs_VERTEX, TopAbs_WIRE, VWMap );
     int nbVertices = 0;
-    for ( int iW = 0; iW < wires.size(); ++iW )
+    for ( size_t iW = 0; iW < wires.size(); ++iW )
       nbVertices += wires[ iW ]->NbEdges();
     if ( nbVertices == VWMap.Extent() )
       VWMap.Clear(); // wires have no common vertices
@@ -595,10 +595,10 @@ bool StdMeshers_MEFISTO_2D::LoadPoints(TWireVector &                 wires,
 
   int m = 0;
 
-  for ( int iW = 0; iW < wires.size(); ++iW )
+  for ( size_t iW = 0; iW < wires.size(); ++iW )
   {
     const vector<UVPtStruct>& uvPtVec = wires[ iW ]->GetUVPtStruct();
-    if ( uvPtVec.size() != wires[ iW ]->NbPoints() ) {
+    if ((int) uvPtVec.size() != wires[ iW ]->NbPoints() ) {
       return error(COMPERR_BAD_INPUT_MESH,SMESH_Comment("Unexpected nb of points on wire ")
                    << iW << ": " << uvPtVec.size()<<" != "<<wires[ iW ]->NbPoints()
                    << ", probably because of invalid node parameters on geom edges");
@@ -696,7 +696,7 @@ void StdMeshers_MEFISTO_2D::ComputeScaleOnFace(SMESH_Mesh &        aMesh,
   double xmax = -1.e300;
   double ymin = 1.e300;
   double ymax = -1.e300;
-  int nbp = 23;
+  const int nbp = 23;
   scalex = 1;
   scaley = 1;
 
@@ -720,13 +720,8 @@ void StdMeshers_MEFISTO_2D::ComputeScaleOnFace(SMESH_Mesh &        aMesh,
         ymin = p.Y();
       if (p.Y() > ymax)
         ymax = p.Y();
-      //    MESSAGE(" "<< f<<" "<<l<<" "<<param<<" "<<xmin<<" "<<xmax<<" "<<ymin<<" "<<ymax);
     }
   }
-  //   SCRUTE(xmin);
-  //   SCRUTE(xmax);
-  //   SCRUTE(ymin);
-  //   SCRUTE(ymax);
   double xmoy = (xmax + xmin) / 2.;
   double ymoy = (ymax + ymin) / 2.;
   double xsize = xmax - xmin;
@@ -754,23 +749,14 @@ void StdMeshers_MEFISTO_2D::ComputeScaleOnFace(SMESH_Mesh &        aMesh,
   }
   scalex = length_x / xsize;
   scaley = length_y / ysize;
-//   SCRUTE(xsize);
-//   SCRUTE(ysize);
   double xyratio = xsize*scalex/(ysize*scaley);
   const double maxratio = 1.e2;
-  //SCRUTE(xyratio);
   if (xyratio > maxratio) {
-    SCRUTE( scaley );
     scaley *= xyratio / maxratio;
-    SCRUTE( scaley );
   }
   else if (xyratio < 1./maxratio) {
-    SCRUTE( scalex );
     scalex *= 1 / xyratio / maxratio;
-    SCRUTE( scalex );
   }
-  ASSERT(scalex);
-  ASSERT(scaley);
 }
 
 // namespace
index c7b51380501940da15bd89ec5566ea7b5c4409a7..a1ece4b72f1739eb9f1565f4112226f0b737dcdb 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 0b027ad45db75d03f7233b868b6dfca659e2a482..726909c3dcc7af0329d65f4cb68d67e9aa2217af 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 4864643e9554a978b0e8849f4256d9205a47ce85..cdf19e997ba36b863d8a290ae96ca449767896f1 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 2b3fd114cfbf1370790320c46dc28e61a4a59ea9..4ece1400800dae7c94d2ef7fe96fd9cbc2fa70e4 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 9b1ef03b904f3d6f52b634922b5488ee91baac13..cff8162822f8102b2db5c3ef9a9207062ed527ff 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 661b3e6038cd7bd414c304b4d39748a14deeb3ab..3d552994013e4496dc2930e2e4e50755237dbded 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
@@ -213,7 +213,7 @@ bool StdMeshers_MaxLength::SetParametersByMesh(const SMESH_Mesh*   theMesh,
     SMESHDS_Mesh* aMeshDS = const_cast< SMESH_Mesh* >( theMesh )->GetMeshDS();
     if ( SMESH_Algo::GetNodeParamOnEdge( aMeshDS, edge, params ))
     {
-      for ( int i = 1; i < params.size(); ++i )
+      for ( size_t i = 1; i < params.size(); ++i )
         _length += GCPnts_AbscissaPoint::Length( AdaptCurve, params[ i-1 ], params[ i ]);
       nbEdges += params.size() - 1;
     }
index 48b2fe5a005d36a740458e0b7a9eebb07a67eaeb..6edd2e19eee0913f5981b52b42cbbf6ebf4ce4ab 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index e88b93fc9551568d537f0e99c79d734a6073063a..ab3a3e6bc49b300ebfa11e33338fbe6eac8cbd10 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 7d79bedf8194fd17a124bb577a788e3b6dd97776..4a57c4eb0424bad43f63e2ac772933e97cc768c0 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index ad7cfbfe2decbbc2b341e10e9324818f27bfbc0f..d3e0b5277df28cda7d9bb1db6e5793a767477b23 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 2e6365b5b43559f6b42ba27fd25424e16dcc0450..0a8bb43356d1d2f284e9e423427fca817ee26a8d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 66f5690f797e6688c7cc6c5122fd30dc591ecadd..ba5ce63173d775ac46fe3a361f7530e67174486f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index daad9b2fd620618822e9a8287162b59071f144cd..d0257cecbc25533256ff92913a5b7453a4a8a534 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index c9e48b7e2d341a5ab0ed9c54ad7a2f96005d83ba..8d262e36f17595715ef7aeaff76556baf7022dda 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -180,15 +180,17 @@ StdMeshers_NumberOfSegments::DistrType StdMeshers_NumberOfSegments::GetDistrType
 void StdMeshers_NumberOfSegments::SetScaleFactor(double scaleFactor)
   throw(SALOME_Exception)
 {
-  if (_distrType != DT_Scale)
-    _distrType = DT_Scale;
-    //throw SALOME_Exception(LOCALIZED("not a scale distribution"));
   if (scaleFactor < PRECISION)
     throw SALOME_Exception(LOCALIZED("scale factor must be positive"));
-  //if (fabs(scaleFactor - 1.0) < PRECISION)
-  //  throw SALOME_Exception(LOCALIZED("scale factor must not be equal to 1"));
 
-  if (fabs(_scaleFactor - scaleFactor) > PRECISION)
+  if (_distrType != DT_Scale)
+    _distrType = DT_Scale;
+
+//  commented by mpa for IPAL 52986
+//  if ( fabs(scaleFactor - 1.0) < PRECISION )
+//    _distrType = DT_Regular;
+
+  if ( fabs(_scaleFactor - scaleFactor) > PRECISION )
   {
     _scaleFactor = scaleFactor;
     NotifySubMeshesHypothesisModification();
@@ -197,7 +199,7 @@ void StdMeshers_NumberOfSegments::SetScaleFactor(double scaleFactor)
 
 //================================================================================
 /*!
- * 
+ *
  */
 //================================================================================
 
@@ -211,7 +213,7 @@ double StdMeshers_NumberOfSegments::GetScaleFactor() const
 
 //================================================================================
 /*!
- * 
+ *
  */
 //================================================================================
 
@@ -224,12 +226,12 @@ void StdMeshers_NumberOfSegments::SetTableFunction(const vector<double>& table)
   if ( (table.size() % 2) != 0 )
     throw SALOME_Exception(LOCALIZED("odd size of vector of table function"));
 
-  int i;
   double prev = -PRECISION;
   bool isSame = table.size() == _table.size();
 
   bool pos = false;
-  for (i=0; i < table.size()/2; i++) {
+  for ( size_t i = 0; i < table.size() / 2; i++ )
+  {
     double par = table[i*2];
     double val = table[i*2+1];
     if( _convMode==0 )
@@ -239,7 +241,8 @@ void StdMeshers_NumberOfSegments::SetTableFunction(const vector<double>& table)
         OCC_CATCH_SIGNALS;
 #endif
         val = pow( 10.0, val );
-      } catch(Standard_Failure) {
+      }
+      catch(Standard_Failure) {
         Handle(Standard_Failure) aFail = Standard_Failure::Caught();
         throw SALOME_Exception( LOCALIZED( "invalid value"));
         return;
@@ -248,19 +251,19 @@ void StdMeshers_NumberOfSegments::SetTableFunction(const vector<double>& table)
     else if( _convMode==1 && val<0.0 )
       val = 0.0;
 
-    if ( par<0 || par > 1)
+    if ( par < 0 || par > 1)
       throw SALOME_Exception(LOCALIZED("parameter of table function is out of range [0,1]"));
-    if ( fabs(par-prev)<PRECISION )
+    if ( fabs(par-prev) < PRECISION )
       throw SALOME_Exception(LOCALIZED("two parameters are the same"));
     if ( val < 0 )
       throw SALOME_Exception(LOCALIZED("value of table function is not positive"));
-    if( val>PRECISION )
+    if( val > PRECISION )
       pos = true;
     if (isSame)
     {
       double oldpar = _table[i*2];
       double oldval = _table[i*2+1];
-      if (fabs(par - oldpar) > PRECISION || fabs(val - oldval) > PRECISION)
+      if ( fabs(par - oldpar) > PRECISION || fabs(val - oldval) > PRECISION )
         isSame = false;
     }
     prev = par;
@@ -269,7 +272,7 @@ void StdMeshers_NumberOfSegments::SetTableFunction(const vector<double>& table)
   if( !pos )
     throw SALOME_Exception(LOCALIZED("value of table function is not positive"));
 
-  if( pos && !isSame )
+  if ( pos && !isSame )
   {
     _table = table;
     NotifySubMeshesHypothesisModification();
@@ -278,7 +281,7 @@ void StdMeshers_NumberOfSegments::SetTableFunction(const vector<double>& table)
 
 //================================================================================
 /*!
- * 
+ *
  */
 //================================================================================
 
@@ -394,7 +397,6 @@ void StdMeshers_NumberOfSegments::SetExpressionFunction(const char* expr)
 {
   if (_distrType != DT_ExprFunc)
     _distrType = DT_ExprFunc;
-    //throw SALOME_Exception(LOCALIZED("not an expression function distribution"));
 
   string func = CheckExpressionFunction( expr, _convMode );
   if( _func != func )
@@ -509,9 +511,8 @@ ostream & StdMeshers_NumberOfSegments::SaveTo(ostream & save)
     save << " " << _scaleFactor;
     break;
   case DT_TabFunc:
-    int i;
     save << " " << _table.size();
-    for (i=0; i < _table.size(); i++)
+    for ( size_t i = 0; i < _table.size(); i++ )
       save << " " << _table[i];
     break;
   case DT_ExprFunc:
@@ -599,8 +600,7 @@ istream & StdMeshers_NumberOfSegments::LoadFrom(istream & load)
       if (isOK)
       {
         _table.resize(a, 0.);
-        int i;
-        for (i=0; i < _table.size(); i++)
+        for ( size_t i=0; i < _table.size(); i++ )
         {
           isOK = (load >> b);
           if (isOK)
@@ -652,7 +652,7 @@ istream & StdMeshers_NumberOfSegments::LoadFrom(istream & load)
   isOK = (load >> intVal);
   if ( isOK && _distrType != DT_Regular && intVal > 0 ) {
     _edgeIDs.reserve( intVal );
-    for (int i = 0; i < _edgeIDs.capacity() && isOK; i++) {
+    for ( size_t i = 0; i < _edgeIDs.capacity() && isOK; i++) {
       isOK = (load >> intVal);
       if ( isOK ) _edgeIDs.push_back( intVal );
     }
@@ -664,7 +664,7 @@ istream & StdMeshers_NumberOfSegments::LoadFrom(istream & load)
 
 //=============================================================================
 /*!
- *  
+ *
  */
 //=============================================================================
 
index 6857cffb33cd1893445a659351993b13c03b3418..e09417eab007e0b7ab6d60cbb8234ab533e1bde0 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 2038c10f775e6eb8548065cc9910fb6d7b46b047..bb4f491b15a559477a6d55e08e92132d335d0d5e 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -657,7 +657,7 @@ void StdMeshers_Penta_3D::MakeVolumeMesh()
   }
   //
   // 2. Make pentahedrons
-  int aID0, k , aJ[3];
+  int aID0, k , aJ[4];
   vector<const SMDS_MeshNode*> aN;
   //
   SMDS_ElemIteratorPtr itf, aItNodes;
@@ -674,7 +674,7 @@ void StdMeshers_Penta_3D::MakeVolumeMesh()
     int nbFaceNodes = pE0->NbNodes();
     if(myCreateQuadratic)
       nbFaceNodes = nbFaceNodes/2;
-    if ( aN.size() < nbFaceNodes * 2 )
+    if ( (int) aN.size() < nbFaceNodes * 2 )
       aN.resize( nbFaceNodes * 2 );
     //
     for ( k=0; k<nbFaceNodes; ++k ) {
@@ -806,7 +806,7 @@ void StdMeshers_Penta_3D::MakeMeshOnFxy1()
     aNbNodes = pE0->NbNodes();
     if(myCreateQuadratic)
       aNbNodes = aNbNodes/2;
-    if ( aNodes1.size() < aNbNodes )
+    if ( (int) aNodes1.size() < aNbNodes )
       aNodes1.resize( aNbNodes );
     //
     k = aNbNodes-1; // reverse a face
@@ -1476,7 +1476,7 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes,
     nVec.resize( vsize, nullNode );
     loadedNodes.insert( nVec[ 0 ] = node );
   }
-  if ( theIJNodes.size() != hsize ) {
+  if ( (int) theIJNodes.size() != hsize ) {
     MESSAGE( "Wrong node positions on theBaseEdge" );
     return false;
   }
index ef09f3a35743f29d44024b801f6b3cca262915ee..32e1bcd5627bf5c974f558ce184fecab31ee90e9 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
diff --git a/src/StdMeshers/StdMeshers_PolygonPerFace_2D.cxx b/src/StdMeshers/StdMeshers_PolygonPerFace_2D.cxx
new file mode 100644 (file)
index 0000000..6b4960d
--- /dev/null
@@ -0,0 +1,158 @@
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&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, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// 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_PolygonPerFace_2D.cxx
+// Module    : SMESH
+// Created   : Fri Oct 20 11:37:07 2006
+// Author    : Edward AGAPOV (eap)
+//
+#include "StdMeshers_PolygonPerFace_2D.hxx"
+
+#include "SMESH_Comment.hxx"
+#include "SMESH_Mesh.hxx"
+#include "SMESH_MesherHelper.hxx"
+#include "SMESH_ProxyMesh.hxx"
+#include "SMESH_subMesh.hxx"
+#include "StdMeshers_FaceSide.hxx"
+#include "StdMeshers_ViscousLayers2D.hxx"
+
+#include <TopExp_Explorer.hxx>
+#include <TopoDS_Face.hxx>
+
+#include <vector>
+#include <TopoDS.hxx>
+
+using namespace std;
+
+//=======================================================================
+//function : StdMeshers_PolygonPerFace_2D
+//purpose  : 
+//=======================================================================
+
+StdMeshers_PolygonPerFace_2D::StdMeshers_PolygonPerFace_2D(int        hypId,
+                                                           int        studyId,
+                                                           SMESH_Gen* gen)
+  :SMESH_2D_Algo(hypId, studyId, gen)
+{
+  _name = "PolygonPerFace_2D";
+}
+
+//=======================================================================
+//function : CheckHypothesis
+//purpose  : 
+//=======================================================================
+
+bool StdMeshers_PolygonPerFace_2D::CheckHypothesis(SMESH_Mesh&                          theMesh,
+                                                   const TopoDS_Shape&                  theShape,
+                                                   SMESH_Hypothesis::Hypothesis_Status& theStatus)
+{
+  theStatus = HYP_OK;
+  return true;
+}
+
+//=======================================================================
+//function : Compute
+//purpose  :
+//=======================================================================
+
+bool StdMeshers_PolygonPerFace_2D::Compute(SMESH_Mesh&         theMesh,
+                                           const TopoDS_Shape& theShape)
+{
+  const TopoDS_Face& face = TopoDS::Face( theShape );
+
+  SMESH_MesherHelper helper( theMesh );
+  helper.SetElementsOnShape( true );
+  _quadraticMesh = helper.IsQuadraticSubMesh( face );
+
+  SMESH_ProxyMesh::Ptr proxyMesh = StdMeshers_ViscousLayers2D::Compute( theMesh, face );
+  if ( !proxyMesh )
+    return false;
+
+  TError erorr;
+  TSideVector wires = StdMeshers_FaceSide::GetFaceWires(face, theMesh,
+                                                        /*skipMediumNodes=*/_quadraticMesh,
+                                                        erorr, proxyMesh,
+                                                        /*checkVertexNodes=*/false);
+  if ( wires.size() != 1 )
+    return error( COMPERR_BAD_SHAPE, SMESH_Comment("One wire required, not ") << wires.size() );
+
+  vector<const SMDS_MeshNode*> nodes = wires[0]->GetOrderedNodes();
+  int nbNodes = int( nodes.size() ) - 1; // 1st node is repeated at end
+
+  switch ( nbNodes ) {
+  case 3:
+    helper.AddFace( nodes[0], nodes[1], nodes[2] );
+    break;
+  case 4:
+    helper.AddFace( nodes[0], nodes[1], nodes[2], nodes[3] );
+    break;
+  default:
+    if ( nbNodes < 3 )
+      return error( COMPERR_BAD_INPUT_MESH, "Less that 3 nodes on the wire" );
+    nodes.resize( nodes.size() - 1 );
+    helper.AddPolygonalFace ( nodes );
+  }
+
+  return true;
+}
+
+//=======================================================================
+//function : Evaluate
+//purpose  : 
+//=======================================================================
+
+bool StdMeshers_PolygonPerFace_2D::Evaluate(SMESH_Mesh&         theMesh,
+                                            const TopoDS_Shape& theShape,
+                                            MapShapeNbElems&    theResMap)
+{
+  // count nb segments
+  int nbLinSegs = 0, nbQuadSegs = 0;
+  TopExp_Explorer edge( theShape, TopAbs_EDGE );
+  for ( ; edge.More(); edge.Next() )
+  {
+    SMESH_subMesh* sm = theMesh.GetSubMesh( edge.Current() );
+    MapShapeNbElems::iterator sm2vec = theResMap.find( sm );
+    if ( sm2vec == theResMap.end() )
+      continue;
+    nbLinSegs  += sm2vec->second.at( SMDSEntity_Edge );
+    nbQuadSegs += sm2vec->second.at( SMDSEntity_Quad_Edge );
+  }
+
+  std::vector<int> aVec( SMDSEntity_Last, 0 );
+  switch ( nbLinSegs + nbQuadSegs ) {
+  case 3:
+    aVec[ nbQuadSegs ? SMDSEntity_Quad_Triangle : SMDSEntity_Triangle ] = 1;
+    break;
+  case 4:
+    aVec[ nbQuadSegs ? SMDSEntity_Quad_Quadrangle : SMDSEntity_Quadrangle ] = 1;
+    break;
+  default:
+    if ( nbLinSegs + nbQuadSegs < 3 )
+      return error( COMPERR_BAD_INPUT_MESH, "Less that 3 nodes on the wire" );
+    aVec[ nbQuadSegs ? SMDSEntity_Quad_Polygon : SMDSEntity_Polygon ] = 1;
+  }
+
+  SMESH_subMesh * sm = theMesh.GetSubMesh(theShape);
+  theResMap.insert(std::make_pair(sm,aVec));
+
+  return true;
+}
diff --git a/src/StdMeshers/StdMeshers_PolygonPerFace_2D.hxx b/src/StdMeshers/StdMeshers_PolygonPerFace_2D.hxx
new file mode 100644 (file)
index 0000000..5a6a604
--- /dev/null
@@ -0,0 +1,47 @@
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&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, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// 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_PolygonPerFace_2D.hxx
+//  Module : SMESH
+//
+#ifndef _SMESH_PolygonPerFace_2D_HXX_
+#define _SMESH_PolygonPerFace_2D_HXX_
+
+#include "SMESH_StdMeshers.hxx"
+#include "SMESH_Algo.hxx"
+
+class STDMESHERS_EXPORT StdMeshers_PolygonPerFace_2D: public SMESH_2D_Algo
+{
+ public:
+  StdMeshers_PolygonPerFace_2D(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);
+};
+
+#endif
index 04cc3aebe9e85e0b65293a7ad8669548b5853a7b..6227072d9ab3c5396b771dff47f6b624ffba0731 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -71,8 +71,7 @@ using namespace std;
 #ifdef _DEBUG_
 #define DBGOUT(msg) //cout << msg << endl;
 #define SHOWYXZ(msg, xyz)                                               \
-  // { gp_Pnt p (xyz);                                                     \
-  //   cout << msg << " ("<< p.X() << "; " <<p.Y() << "; " <<p.Z() << ") " <<endl; }
+  //{ gp_Pnt p (xyz); cout << msg << " ("<< p.X() << "; " <<p.Y() << "; " <<p.Z() << ") " <<endl; }
 #else
 #define DBGOUT(msg)
 #define SHOWYXZ(msg, xyz)
@@ -408,8 +407,8 @@ namespace {
       if ( nbQuads > 0 )
         toRemove = helper->IsStructured( faceSm );
       else
-        toRemove = quadAlgo->CheckNbEdges( *helper->GetMesh(),
-                                           faceSm->GetSubShape() );
+        toRemove = quadAlgo->CheckNbEdges( *helper->GetMesh(),
+                                             faceSm->GetSubShape() ) != NULL );
       nbRemoved += toRemove;
       if ( toRemove )
         smIt = notQuadSubMesh.erase( smIt );
@@ -905,7 +904,7 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
       return error( err );
     }
   }
-  return true;
+  return error( COMPERR_OK );
 }
 
 //================================================================================
@@ -2549,7 +2548,7 @@ namespace // utils used by StdMeshers_Prism_3D::IsApplicable()
       for ( iE = 0; iE < *nbE; ++e, ++iE )
         if ( SMESH_Algo::isDegenerated( *e ))
         {
-          ee.erase( e );
+          e = --ee.erase( e );
           --(*nbE);
           --iE;
         }
@@ -3476,10 +3475,8 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper*         helper,
     }
   }
 
-// #define SHOWYXZ(msg, xyz) {                     \
-//     gp_Pnt p (xyz);                                                     \
-//     cout << msg << " ("<< p.X() << "; " <<p.Y() << "; " <<p.Z() << ") " <<endl; \
-//   }
+// #define SHOWYXZ(msg, xyz) { gp_Pnt p(xyz); cout << msg << " ("<< p.X() << "; " <<p.Y() << "; " <<p.Z() << ") " <<endl; }
+
 //   double _u[]={ 0.1, 0.1, 0.9, 0.9 };
 //   double _v[]={ 0.1, 0.9, 0.1, 0.9 };
 //   for ( int z = 0; z < 2; ++z )
index 546bf4950b92281680bbc424827bcb9da51339ba..708a92ca9226a29e0cf948b76d84266fc737812c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 8dd29e4c8a261c48858acdb20c67c88fefa72feb..7fe47bd1476be70fc95f2a38e915375ad2d78270 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 3cbf55c8cc4a19840be24d36d004b57e8a28c559..9f40bd8762c23e264482383920cc0877f552a2ba 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 5034d7920398715666406c283a1145c55e57f9e6..05b80199de1603e6c0967a7f1297af9997b0dacb 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 892730e4402bb272fc9a95ef850cb79fb5fe8439..7f02586d2c352da941d03415d96e46ea3e897df2 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index efa55b390a1b629bf8ce818902844f134ed6772f..c6446dc972ee2780f80057c888e7e646cb51c5e4 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index abaa2df892e20f80bee6cb34be64a8873f17b4e3..53c7ac75934d167889b52fd055cda8f958fe30e6 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index e5ab88a1ecc8c024ef76ab3f972d64b8982d09cc..51a6398690b0a87fddc2df6443ec7cd0dc8019a6 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -52,6 +52,7 @@
 #include <BRep_Tool.hxx>
 #include <Bnd_Box.hxx>
 #include <Geom2d_Curve.hxx>
+#include <Geom_Curve.hxx>
 #include <TopAbs.hxx>
 #include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
@@ -78,23 +79,9 @@ using namespace std;
 #define RETURN_BAD_RESULT(msg) { MESSAGE(")-: Error: " << msg); return false; }
 #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) <<" "<<shapeIndex((v))<<endl;}\
-// }
+  // { show_shape((v),(msg)); }
 #define SHOW_LIST(msg,l) \
-// { \
-//     cout << msg << " ";\
-//     list< TopoDS_Edge >::const_iterator e = l.begin();\
-//     for ( int i = 0; e != l.end(); ++e, ++i ) {\
-//       cout << i << "V (" << TopExp::FirstVertex( *e, true ).TShape().operator->() << ") "\
-//            << i << "E (" << e->TShape().operator->() << "); "; }\
-//     cout << endl;\
-//   }
+  // { show_list((msg),(l)); }
 
 namespace HERE = StdMeshers_ProjectionUtils;
 
@@ -107,7 +94,24 @@ namespace {
       return max(theMeshDS[0]->ShapeToIndex(S), theMeshDS[1]->ShapeToIndex(S) );
     return long(S.TShape().operator->());
   }
-
+  void show_shape( TopoDS_Shape v, const char* msg ) // debug
+  {
+    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) <<" "<<shapeIndex((v))<<endl;}
+  }
+  void show_list( const char* msg, const list< TopoDS_Edge >& l ) // debug
+  {
+    cout << msg << " ";
+    list< TopoDS_Edge >::const_iterator e = l.begin();
+    for ( int i = 0; e != l.end(); ++e, ++i ) {
+      cout << i << "V (" << TopExp::FirstVertex( *e, true ).TShape().operator->() << ") "
+           << i << "E (" << e->TShape().operator->() << "); "; }
+    cout << endl;
+  }
   //================================================================================
   /*!
    * \brief Write shape for debug purposes
@@ -233,6 +237,7 @@ namespace {
         v2 = SMESH_MesherHelper::IthVertex( 0, *eIt2 );
         HERE::InsertAssociation( v1, v2, theMap );
       }
+      theMap.SetAssocType( HERE::TShapeShapeMap::FEW_EF );
       return true;
     }
     return false;
@@ -388,6 +393,7 @@ namespace {
         }
       }
     }
+    theMap.SetAssocType( HERE::TShapeShapeMap::PROPAGATION );
     return true;
   }
 
@@ -432,23 +438,36 @@ namespace {
           return true;
       }
     }
+    SMESH_MesherHelper helper( mesh );
+    helper.SetSubShape( shape );
+
     TopExp_Explorer expF( shape, TopAbs_FACE ), expE;
     if ( expF.More() ) {
       for ( ; expF.More(); expF.Next() ) {
         TopoDS_Shape wire =
           StdMeshers_ProjectionUtils::OuterShape( TopoDS::Face( expF.Current() ), TopAbs_WIRE );
         for ( expE.Init( wire, TopAbs_EDGE ); expE.More(); expE.Next() )
-          if ( !SMESH_MesherHelper::IsClosedEdge( TopoDS::Edge( expE.Current() )))
-            allBndEdges.push_back( TopoDS::Edge( expE.Current() ));
+          if ( ! helper.IsClosedEdge( TopoDS::Edge( expE.Current() )))
+          {
+            if ( helper.IsSeamShape( expE.Current() ))
+              allBndEdges.push_back( TopoDS::Edge( expE.Current() ));
+            else
+              allBndEdges.push_front( TopoDS::Edge( expE.Current() ));
+          }
       }
     }
     else if ( shape.ShapeType() != TopAbs_EDGE) { // no faces
       for ( expE.Init( shape, TopAbs_EDGE ); expE.More(); expE.Next() )
-        if ( !SMESH_MesherHelper::IsClosedEdge( TopoDS::Edge( expE.Current() )))
-          allBndEdges.push_back( TopoDS::Edge( expE.Current() ));
+        if ( ! helper.IsClosedEdge( TopoDS::Edge( expE.Current() )))
+        {
+          if ( helper.IsSeamShape( expE.Current() ))
+            allBndEdges.push_back( TopoDS::Edge( expE.Current() ));
+          else
+            allBndEdges.push_front( TopoDS::Edge( expE.Current() ));
+        }
     }
     else if ( shape.ShapeType() == TopAbs_EDGE ) {
-      if ( !SMESH_MesherHelper::IsClosedEdge( TopoDS::Edge( shape )))
+      if ( ! helper.IsClosedEdge( TopoDS::Edge( shape )))
         allBndEdges.push_back( TopoDS::Edge( shape ));
     }
     return !allBndEdges.empty();
@@ -477,9 +496,9 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
 {
   // Structure of this long function is following
   // 1) Group -> Group projection: theShape1 is a group member,
-  //    theShape2 is another group. We find a group theShape1 is in and recall self.
+  //    theShape2 is another group. We find the 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:
+  // 3) If vertex association is given, perform association according to shape type:
   //       switch ( ShapeType ) {
   //         case TopAbs_EDGE:
   //         case ...:
@@ -499,7 +518,8 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
   // =================================================================================
   // 1) Is it the case of associating a group member -> another group? (PAL16202, 16203)
   // =================================================================================
-  if ( theShape1.ShapeType() != theShape2.ShapeType() ) {
+  if ( theShape1.ShapeType() != theShape2.ShapeType() )
+  {
     TopoDS_Shape group1, group2;
     if ( theShape1.ShapeType() == TopAbs_COMPOUND ) {
       group1 = theShape1;
@@ -538,6 +558,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
       for ( ; s1It.More(); s1It.Next(), s2It.Next() )
         shapesQueue.push_back( make_pair( s1It.Value(), s2It.Value() ));
     }
+    theMap.SetAssocType( TShapeShapeMap::PARTNER );
     return true;
   }
 
@@ -546,6 +567,8 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
     //======================================================================
     // 3) HAS initial vertex association
     //======================================================================
+    bool isVCloseness = ( theMap._assocType == TShapeShapeMap::CLOSE_VERTEX );
+    theMap.SetAssocType( TShapeShapeMap::INIT_VERTEX );
     switch ( theShape1.ShapeType() ) {
       // ----------------------------------------------------------------------
     case TopAbs_EDGE: { // TopAbs_EDGE
@@ -594,7 +617,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
         }
       }
       list< TopoDS_Edge > edges1, edges2;
-      int nbE = FindFaceAssociation( face1, VV1, face2, VV2, edges1, edges2 );
+      int nbE = FindFaceAssociation( face1, VV1, face2, VV2, edges1, edges2, isVCloseness );
       if ( !nbE ) RETURN_BAD_RESULT("FindFaceAssociation() failed");
       fixAssocByPropagation( nbE, edges1, edges2, theMesh1, theMesh2 );
 
@@ -698,8 +721,6 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
           F2 = FF2[ 1 ];
       }
 
-      TopTools_MapOfShape boundEdges;
-
       // 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;
@@ -715,7 +736,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 );
         list< TopoDS_Edge > edges1, edges2;
-        int nbE = FindFaceAssociation( face1, VV1, face2, VV2, edges1, edges2 );
+        int nbE = FindFaceAssociation( face1, VV1, face2, VV2, edges1, edges2, isVCloseness );
         if ( !nbE ) RETURN_BAD_RESULT("FindFaceAssociation() failed");
         InsertAssociation( face1, face2, theMap ); // assoc faces
         MESSAGE("Assoc FACE " << theMesh1->GetMeshDS()->ShapeToIndex( face1 )<<
@@ -728,8 +749,8 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
         list< TopoDS_Edge >::iterator eIt2 = edges2.begin();
         for ( ; eIt1 != edges1.end(); ++eIt1, ++eIt2 )
         {
-          if ( !boundEdges.Add( *eIt1 )) continue; // already associated
-          InsertAssociation( *eIt1, *eIt2, theMap );  // assoc edges
+          if ( !InsertAssociation( *eIt1, *eIt2, theMap ))  // assoc edges
+            continue; // already associated
           VV1[0] = TopExp::FirstVertex( *eIt1, true );
           VV2[0] = TopExp::FirstVertex( *eIt2, true );
           InsertAssociation( VV1[0], VV2[0], theMap ); // assoc vertices
@@ -738,6 +759,10 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
           TopoDS_Face nextFace1 = GetNextFace( edgeToFace1, *eIt1, face1 );
           TopoDS_Face nextFace2 = GetNextFace( edgeToFace2, *eIt2, face2 );
           if ( !nextFace1.IsNull() && !nextFace2.IsNull() ) {
+            if ( SMESH_MesherHelper::GetSubShapeOri( nextFace1, *eIt1 ) == eIt1->Orientation() )
+              nextFace1.Reverse();
+            if ( SMESH_MesherHelper::GetSubShapeOri( nextFace2, *eIt2 ) == eIt2->Orientation() )
+              nextFace2.Reverse();
             FE1.push_back( make_pair( nextFace1, *eIt1 ));
             FE2.push_back( make_pair( nextFace2, *eIt2 ));
           }
@@ -1011,6 +1036,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
           InsertAssociation( edge1, prpEdge, theMap ); // insert with a proper orientation
         }
         InsertAssociation( theShape1, theShape2, theMap );
+        theMap.SetAssocType( TShapeShapeMap::PROPAGATION );
         return true; // done
       }
     }
@@ -1086,6 +1112,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
           InsertAssociation( VV1[0], VV2[0], theMap );
         }
         InsertAssociation( theShape1, theShape2, theMap );
+        theMap.SetAssocType( TShapeShapeMap::PROPAGATION );
         return true;
       }
     }
@@ -1150,7 +1177,11 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
       if ( !VV1[1].IsNull() ) {
         InsertAssociation( VV1[0], VV2[0], theMap );
         InsertAssociation( VV1[1], VV2[1], theMap );
-        return FindSubShapeAssociation( theShape1, theMesh1, theShape2, theMesh2, theMap);
+        TShapeShapeMap::EAssocType asType = theMap._assocType;
+        theMap.SetAssocType( TShapeShapeMap::PROPAGATION );
+        if ( FindSubShapeAssociation( theShape1, theMesh1, theShape2, theMesh2, theMap ))
+          return true;
+        theMap._assocType = asType;
       }
     }
     break; // try by vertex closeness
@@ -1206,8 +1237,11 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
       {
         InsertAssociation( VV1[0], VV1[0], theMap );
         InsertAssociation( VV1[1], VV1[1], theMap );
-        if (FindSubShapeAssociation( theShape1, theMesh1, theShape2, theMesh2, theMap ))
+        TShapeShapeMap::EAssocType asType = theMap._assocType;
+        theMap.SetAssocType( TShapeShapeMap::COMMON_VERTEX );
+        if ( FindSubShapeAssociation( theShape1, theMesh1, theShape2, theMesh2, theMap ))
           return true;
+        theMap._assocType = asType;
       }
     }
   }
@@ -1301,6 +1335,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
         break;
     }
   }
+  theMap.SetAssocType( TShapeShapeMap::CLOSE_VERTEX );
 
   InsertAssociation( VV1[ 0 ], VV2[ 0 ], theMap );
   InsertAssociation( VV1[ 1 ], VV2[ 1 ], theMap );
@@ -1325,6 +1360,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
  *  \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
+ *  \param isClosenessAssoc - is association starting by VERTEX closeness
  *  \retval int - nb of edges in an outer wire in a success case, else zero
  */
 //================================================================================
@@ -1334,7 +1370,8 @@ int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face&    face1,
                                                     const TopoDS_Face&    face2,
                                                     TopoDS_Vertex         VV2[2],
                                                     list< TopoDS_Edge > & edges1,
-                                                    list< TopoDS_Edge > & edges2)
+                                                    list< TopoDS_Edge > & edges2,
+                                                    const bool            isClosenessAssoc)
 {
   bool OK = false;
   list< int > nbEInW1, nbEInW2;
@@ -1363,46 +1400,56 @@ int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face&    face1,
     // Define if we need to reverse one of wires to make edges in lists match each other
 
     bool reverse = false;
+    const bool severalWires = ( nbEInW1.size() > 1 );
 
-    if ( !VV1[1].IsSame( TopExp::LastVertex( edges1.front(), true ))) {
+    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
+      edgeIt = --edges1.end(); // pointer to the last edge in the outer wire
+      if ( severalWires ) {
+        edgeIt = edges1.begin();
+        std::advance( edgeIt, nbEInW1.front()-1 );
+      }
+      if ( TopExp::FirstVertex( *edgeIt ).IsSame( TopExp::LastVertex( *edgeIt )) &&
+           SMESH_Algo::isDegenerated( *edgeIt )) {
+        --edgeIt; // skip a degenerated edge (test 3D_mesh_Projection_00/A3)
+      }
       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");
+        CONT_BAD_RESULT("GetOrderedEdges() failed");
       }
     }
-    if ( !VV2[1].IsSame( TopExp::LastVertex( edges2.front(), true ))) {
+    if ( !VV2[1].IsSame( TopExp::LastVertex( edges2.front(), true )))
+    {
       reverse = !reverse;
-      edgeIt = --edges2.end();
-      // move a degenerated edge from back to front
-      // http://www.salome-platform.org/forum/forum_11/173031193
-      if ( TopExp::FirstVertex( *edgeIt ).IsSame( TopExp::LastVertex( *edgeIt ))) {
-        edges2.splice( edges2.begin(), edges2, edgeIt );
-        edgeIt = --edges2.end();
-      }
       // check if the second vertex belongs to the first or last edge in the wire
+      edgeIt = --edges2.end(); // pointer to the last edge in the outer wire
+      if ( severalWires ) {
+        edgeIt = edges2.begin();
+        std::advance( edgeIt, nbEInW2.front()-1 );
+      }
+      if ( TopExp::FirstVertex( *edgeIt ).IsSame( TopExp::LastVertex( *edgeIt )) &&
+           SMESH_Algo::isDegenerated( *edgeIt )) {
+        --edgeIt;  // skip a degenerated edge
+      }
       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");
+        CONT_BAD_RESULT("GetOrderedEdges() failed");
       }
     }
     if ( reverse )
     {
       reverseEdges( edges2 , nbEInW2.front());
+
+      if ( SMESH_Algo::isDegenerated( edges2.front() ))
+      {
+        // move a degenerated edge to the back of the outer wire
+        edgeIt = edges2.end();
+        if ( severalWires ) {
+          edgeIt = edges2.begin();
+          std::advance( edgeIt, nbEInW2.front() );
+        }
+        edges2.splice( edgeIt, edges2, edges2.begin() );
+      }
       if (( VV1[1].IsSame( TopExp::LastVertex( edges1.front(), true ))) !=
           ( VV2[1].IsSame( TopExp::LastVertex( edges2.front(), true ))))
         CONT_BAD_RESULT("GetOrderedEdges() failed");
@@ -1410,6 +1457,65 @@ int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face&    face1,
     OK = true;
 
   } // loop algos getting an outer wire
+
+  if ( OK && nbEInW1.front() > 4 ) // care of a case where faces are closed (23032)
+  {
+    // check if the first edges are seam ones
+    list< TopoDS_Edge >::iterator revSeam1, revSeam2;
+    revSeam1 = std::find( ++edges1.begin(), edges1.end(), edges1.front().Reversed());
+    revSeam2 = edges2.end();
+    if ( revSeam1 != edges1.end() )
+      revSeam2 = std::find( ++edges2.begin(), edges2.end(), edges2.front().Reversed());
+    if ( revSeam2 != edges2.end() ) // two seams detected
+    {
+      bool reverse =
+        std::distance( edges1.begin(), revSeam1 ) != std::distance( edges2.begin(), revSeam2 );
+      if ( !reverse && isClosenessAssoc )
+      {
+        // compare orientations of a non-seam edges using 3D closeness;
+        // look for a non-seam edges
+        list< TopoDS_Edge >::iterator edge1 = ++edges1.begin();
+        list< TopoDS_Edge >::iterator edge2 = ++edges2.begin();
+        for ( ; edge1 != edges1.end(); ++edge1, ++edge2 )
+        {
+          if (( edge1 == revSeam1 ) ||
+              ( SMESH_Algo::isDegenerated( *edge1 )) ||
+              ( std::find( ++edges1.begin(), edges1.end(), edge1->Reversed()) != edges1.end() ))
+            continue;
+          gp_Pnt p1 = BRep_Tool::Pnt( VV1[0] );
+          gp_Pnt p2 = BRep_Tool::Pnt( VV2[0] );
+          gp_Vec vec2to1( p2, p1 );
+
+          gp_Pnt pp1[2], pp2[2];
+          const double r = 0.2345;
+          double f,l;
+          Handle(Geom_Curve) C = BRep_Tool::Curve( *edge1, f,l );
+          pp1[0] = C->Value( f * r + l * ( 1. - r ));
+          pp1[1] = C->Value( l * r + f * ( 1. - r ));
+          if ( edge1->Orientation() == TopAbs_REVERSED )
+            std::swap( pp1[0], pp1[1] );
+          C = BRep_Tool::Curve( *edge2, f,l );
+          if ( C.IsNull() ) return 0;
+          pp2[0] = C->Value( f * r + l * ( 1. - r )).Translated( vec2to1 );
+          pp2[1] = C->Value( l * r + f * ( 1. - r )).Translated( vec2to1 );
+          if ( edge2->Orientation() == TopAbs_REVERSED )
+            std::swap( pp2[0], pp2[1] );
+
+          double dist00 = pp1[0].SquareDistance( pp2[0] );
+          double dist01 = pp1[0].SquareDistance( pp2[1] );
+          reverse = ( dist00 > dist01 );
+          break;
+        }
+      }
+      if ( reverse ) // make a seam counterpart be the first
+      {
+        list< TopoDS_Edge >::iterator outWireEnd = edges2.begin();
+        std::advance( outWireEnd, nbEInW2.front() );
+        edges2.splice( outWireEnd, edges2, edges2.begin(), ++revSeam2 );
+        reverseEdges( edges2 , nbEInW2.front());
+      }
+    }
+  }
   
   // Try to orient all (if !OK) or only internal wires (issue 0020996) by UV similarity
 
@@ -1418,13 +1524,23 @@ int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face&    face1,
     // 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 );
+    BRepAdaptor_Surface surface1( face1, true );
+    BRepAdaptor_Surface surface2( face2, true );
+    // TODO: use TrsfFinder2D to superpose the faces
+    gp_Pnt2d v0f1UV( surface1.FirstUParameter(), surface1.FirstVParameter() );
+    gp_Pnt2d v0f2UV( surface2.FirstUParameter(), surface2.FirstVParameter() );
+    gp_Pnt2d v1f1UV( surface1.LastUParameter(),  surface1.LastVParameter() );
+    gp_Pnt2d v1f2UV( surface2.LastUParameter(),  surface2.LastVParameter() );
     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 );
+    // VV1[0] = TopExp::FirstVertex( edges1.front(), true ); // ori is important if face is closed
+    // VV1[1] = TopExp::LastVertex ( edges1.front(), true );
+    // VV2[0] = TopExp::FirstVertex( edges2.front(), true );
+    // VV2[1] = TopExp::LastVertex ( edges2.front(), true );
+    // 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 &&
@@ -1443,7 +1559,6 @@ int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face&    face1,
       list< int >::iterator nbE2, nbE1 = nbEInW1.begin();
       list< TopoDS_Edge >::iterator edge2Beg, edge1Beg = edges1.begin();
       if ( OK ) std::advance( edge1Beg, *nbE1++ );
-      // reach an end of edges of a current wire1
       list< TopoDS_Edge >::iterator edge2End, edge1End;
       //
       // find corresponding wires of face2
@@ -1473,31 +1588,33 @@ int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face&    face1,
           {
             // rotate edge2 untill coincidence with edge1 in 2D
             int i = *nbE2;
-            while ( i-- > 0 && !sameVertexUV( *edge2Beg, face2, 0, v0f1UV, vTolUV ))
+            bool sameUV = false;
+            while ( !( sameUV = sameVertexUV( *edge2Beg, face2, 0, v0f1UV, vTolUV )) && --i > 0 )
               // move edge2Beg to place before edge2End
               edges2.splice( edge2End, edges2, edge2Beg++ );
 
-            if ( edge2Beg != edges2.end() &&
-                 sameVertexUV( *edge2Beg, face2, 0, v0f1UV, vTolUV ))
+            if ( sameUV )
             {
               if ( iW1 == 0 ) OK = true; // OK is for the first wire
 
               // reverse edges2 if needed
               if ( SMESH_MesherHelper::IsClosedEdge( *edge1Beg ))
               {
-                double f,l;
-                Handle(Geom2d_Curve) c1 = BRep_Tool::CurveOnSurface( *edge1Beg, face1,f,l );
-                if (  edge1Beg->Orientation() == TopAbs_REVERSED )
-                  std::swap( f,l );
-                gp_Pnt2d uv1 = dUV + c1->Value( f * 0.8 + l * 0.2 ).XY();
-
-                Handle(Geom2d_Curve) c2 = BRep_Tool::CurveOnSurface( *edge2Beg, face2,f,l );
-                if (  edge2Beg->Orientation() == TopAbs_REVERSED )
-                  std::swap( f,l );
-                gp_Pnt2d uv2 = c2->Value( f * 0.8 + l * 0.2 );
-
-                if ( uv1.Distance( uv2 ) > vTolUV )
-                  edge2Beg->Reverse();
+                // Commented (so far?) as it's not checked if orientation must be same or reversed
+                // double f,l;
+                // Handle(Geom2d_Curve) c1 = BRep_Tool::CurveOnSurface( *edge1Beg, face1,f,l );
+                // if (  edge1Beg->Orientation() == TopAbs_REVERSED )
+                //   std::swap( f,l );
+                // gp_Pnt2d uv1 = dUV + c1->Value( f * 0.8 + l * 0.2 ).XY();
+
+                // Handle(Geom2d_Curve) c2 = BRep_Tool::CurveOnSurface( *edge2Beg, face2,f,l );
+                // if (  edge2Beg->Orientation() == TopAbs_REVERSED )
+                //   std::swap( f,l );
+                // gp_Pnt2d uv2 = c2->Value( f * 0.8 + l * 0.2 );
+                // gp_Pnt2d uv3 = c2->Value( l * 0.8 + f * 0.2 );
+
+                // if ( uv1.SquareDistance( uv2 ) > uv1.SquareDistance( uv3 ))
+                //   edge2Beg->Reverse();
               }
               else
               {
@@ -2066,7 +2183,7 @@ FindMatchingNodesOnFaces( const TopoDS_Face&     face1,
           static_cast<const SMDS_EdgePosition*>(node->GetPosition());
         pos2nodes.insert( make_pair( pos->GetUParameter(), node ));
       }
-      if ( pos2nodes.size() != edgeSM->NbNodes() )
+      if ((int) pos2nodes.size() != edgeSM->NbNodes() )
         RETURN_BAD_RESULT("Equal params of nodes on edge "
                           << smDS->ShapeToIndex( edge ) << " of face " << is2 );
     }
@@ -2504,13 +2621,13 @@ namespace StdMeshers_ProjectionUtils
     // cout << vec( 1 ) << "\t " << vec( 2 ) << endl
     //      << vec( 3 ) << "\t " << vec( 4 ) << endl;
 
-    _trsf.SetTranslation( tgtGC );
+    _trsf.SetTranslationPart( tgtGC );
     _srcOrig = srcGC;
 
-    gp_Mat2d& M = const_cast< gp_Mat2d& >( _trsf.HVectorialPart());
+    gp_Mat2d& M = const_cast< gp_Mat2d& >( _trsf.VectorialPart());
     M( 1,1 ) = vec( 1 );
-    M( 2,1 ) = vec( 2 );
-    M( 1,2 ) = vec( 3 );
+    M( 2,1 ) = vec( 2 ); // | 1 3 | -- is it correct ????????
+    M( 1,2 ) = vec( 3 ); // | 2 4 |
     M( 2,2 ) = vec( 4 );
 
     return true;
@@ -2601,9 +2718,9 @@ namespace StdMeshers_ProjectionUtils
     //      << vec( 7 ) << "\t " << vec( 8 ) << "\t " << vec( 9 ) << endl;
 
     _srcOrig = srcOrig;
-    _trsf.SetTranslation( tgtOrig );
+    _trsf.SetTranslationPart( tgtOrig );
 
-    gp_Mat& M = const_cast< gp_Mat& >( _trsf.HVectorialPart() );
+    gp_Mat& M = const_cast< gp_Mat& >( _trsf.VectorialPart() );
     M.SetRows( gp_XYZ( vec( 1 ), vec( 2 ), vec( 3 )),
                gp_XYZ( vec( 4 ), vec( 5 ), vec( 6 )),
                gp_XYZ( vec( 7 ), vec( 8 ), vec( 9 )));
@@ -2631,7 +2748,7 @@ namespace StdMeshers_ProjectionUtils
 
   gp_XYZ TrsfFinder3D::TransformVec( const gp_Vec& v ) const
   {
-    return v.XYZ().Multiplied( _trsf.HVectorialPart() );
+    return v.XYZ().Multiplied( _trsf.VectorialPart() );
   }
   //================================================================================
   /*!
@@ -2646,7 +2763,7 @@ namespace StdMeshers_ProjectionUtils
     {
       // seems to be defined via Solve()
       gp_XYZ newSrcOrig = _trsf.TranslationPart();
-      gp_Mat& M = const_cast< gp_Mat& >( _trsf.HVectorialPart() );
+      gp_Mat& M = const_cast< gp_Mat& >( _trsf.VectorialPart() );
       const double D = M.Determinant();
       if ( D < 1e-3 * ( newSrcOrig - _srcOrig ).Modulus() )
       {
@@ -2657,7 +2774,7 @@ namespace StdMeshers_ProjectionUtils
         return false;
       }
       gp_Mat Minv = M.Inverted();
-      _trsf.SetTranslation( _srcOrig );
+      _trsf.SetTranslationPart( _srcOrig );
       _srcOrig = newSrcOrig;
       M = Minv;
     }
index e7ea4423d7e50b07cf92f163d90e1324c3201790..266918aafe55658c1ffd41282833988771ab6977 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -36,8 +36,8 @@
 #include <TopoDS_Edge.hxx>
 #include <TopoDS_Face.hxx>
 #include <TopoDS_Vertex.hxx>
-#include <gp_Trsf.hxx>
-#include <gp_Trsf2d.hxx>
+#include <gp_GTrsf.hxx>
+#include <gp_GTrsf2d.hxx>
 
 #include <list>
 #include <map>
@@ -59,6 +59,10 @@ struct StdMeshers_ShapeShapeBiDirectionMap
 {
   TopTools_DataMapOfShapeShape _map1to2, _map2to1;
 
+  enum EAssocType {
+    UNDEF, INIT_VERTEX, PROPAGATION, PARTNER, CLOSE_VERTEX, COMMON_VERTEX, FEW_EF };
+  EAssocType _assocType;
+
   // convention: s1 - target, s2 - source
   bool Bind( const TopoDS_Shape& s1, const TopoDS_Shape& s2 )
   { _map1to2.Bind( s1, s2 ); return _map2to1.Bind( s2, s1 ); }
@@ -72,6 +76,8 @@ struct StdMeshers_ShapeShapeBiDirectionMap
     // passes incorrect isShape2
     return (isShape2 ? _map2to1 : _map1to2)( s );
   }
+  StdMeshers_ShapeShapeBiDirectionMap() : _assocType( UNDEF ) {}
+  void SetAssocType( EAssocType type ) { if ( _assocType == UNDEF ) _assocType = type; }
 };
 
 /*!
@@ -91,12 +97,12 @@ namespace StdMeshers_ProjectionUtils
    */
   class TrsfFinder2D
   {
-    gp_Trsf2d _trsf;
-    gp_XY     _srcOrig;
+    gp_GTrsf2d _trsf;
+    gp_XY      _srcOrig;
   public:
     TrsfFinder2D(): _srcOrig(0,0) {}
 
-    void Set( const gp_Trsf2d& t ) { _trsf = t; } // it's an alternative to Solve()
+    void Set( const gp_GTrsf2d& t ) { _trsf = t; } // it's an alternative to Solve()
 
     bool Solve( const std::vector< gp_XY >& srcPnts,
                 const std::vector< gp_XY >& tgtPnts );
@@ -111,12 +117,12 @@ namespace StdMeshers_ProjectionUtils
    */
   class TrsfFinder3D
   {
-    gp_Trsf _trsf;
-    gp_XYZ  _srcOrig;
+    gp_GTrsf _trsf;
+    gp_XYZ   _srcOrig;
   public:
     TrsfFinder3D(): _srcOrig(0,0,0) {}
 
-    void Set( const gp_Trsf& t ) { _trsf = t; } // it's an alternative to Solve()
+    void Set( const gp_GTrsf& t ) { _trsf = t; } // it's an alternative to Solve()
 
     bool Solve( const std::vector< gp_XYZ > & srcPnts,
                 const std::vector< gp_XYZ > & tgtPnts );
@@ -148,20 +154,22 @@ namespace StdMeshers_ProjectionUtils
 
   /*!
    * \brief Find association of edges of faces
-   * \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 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
+   *  \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 edges1 - out list of edges of face 1
+   *  \param edges2 - out list of edges of face 2
+   *  \param isClosenessAssoc - is association starting by VERTEX closeness
+   *  \retval int - nb of edges in an outer wire in a success case, else zero
    */
   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);
+                          std::list< TopoDS_Edge > & edges2,
+                          const bool                 isClosenessAssoc=false);
 
   /*!
    * \brief Insert vertex association defined by a hypothesis into a map
index 10da51638ee6219e584d9de170871a2418e6bdda..efeacb0e2c3d15e13f48f35c881bf1b394d633d1 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index b76450ef401ee06b95930611b1cf8987f1841274..55b2dbca74366b2a9cc3e3f434c5b6ae61378f77 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 63fc73dc9ae518f145fa3b2b6bd9d39e891a47c7..125412c9f9a67653510a28c7b40061f51e9b01e7 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index a8a20f405adbe1788bf86c485faff73f0b507eb4..6465a0acea36511b2533970ed948e070dc1cbfd3 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 7b3d1e1e1f157ff9157f722b9978e02af6f1dcdd..66c8936280fb7271407aa60b095616cb84c763ae 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 #include <TopExp_Explorer.hxx>
 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_MapOfShape.hxx>
 #include <TopoDS.hxx>
+#include <TopoDS_Solid.hxx>
 #include <gp_Ax2.hxx>
 #include <gp_Ax3.hxx>
+#include <gp_GTrsf.hxx>
 
 
 using namespace std;
@@ -391,15 +394,16 @@ namespace {
   {
     double f,l;
     Handle(Geom2d_Curve) c1 = BRep_Tool::CurveOnSurface( E1, F, f, l );
-    gp_Pnt2d uvLast1 = c1->Value( E1.Orientation() == TopAbs_REVERSED ? f : l );
+    gp_Pnt2d uvFirst1 = c1->Value( f );
+    gp_Pnt2d uvLast1  = c1->Value( l );
 
     Handle(Geom2d_Curve) c2 = BRep_Tool::CurveOnSurface( E2, F, f, l );
-    gp_Pnt2d uvFirst2 = c2->Value( f );
-    gp_Pnt2d uvLast2  = c2->Value( l );
-    double tol2 = 1e-5 * uvLast2.SquareDistance( uvFirst2 );
+    gp_Pnt2d uvFirst2 = c2->Value( E2.Orientation() == TopAbs_REVERSED ? l : f );
+    double tol2 = Max( Precision::PConfusion() * Precision::PConfusion(),
+                       1e-5 * uvLast1.SquareDistance( uvFirst1 ));
 
-    return (( uvLast1.SquareDistance( uvFirst2 ) < tol2 ) ||
-            ( uvLast1.SquareDistance( uvLast2 ) < tol2 ));
+    return (( uvFirst2.SquareDistance( uvFirst1 ) < tol2 ) ||
+            ( uvFirst2.SquareDistance( uvLast1  ) < tol2 ));
   }
 
   //================================================================================
@@ -419,23 +423,25 @@ namespace {
                   TAssocTool::TNodeNodeMap&          src2tgtNodes,
                   bool&                              is1DComputed)
   {
-    SMESHDS_Mesh* tgtMeshDS = tgtMesh->GetMeshDS();
-    SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
-
     src2tgtNodes.clear();
 
     // get ordered src EDGEs
     TError err;
     srcWires = StdMeshers_FaceSide::GetFaceWires( srcFace, *srcMesh,/*skipMediumNodes=*/0, err);
-    if ( err && !err->IsOK() )
+    if (( err && !err->IsOK() ) ||
+        ( srcWires.empty() ))
       return err;
 
+    SMESH_MesherHelper srcHelper( *srcMesh );
+    srcHelper.SetSubShape( srcFace );
+
     // make corresponding sequence of tgt EDGEs
     tgtWires.resize( srcWires.size() );
     for ( size_t iW = 0; iW < srcWires.size(); ++iW )
     {
-      list< TopoDS_Edge > tgtEdges;
       StdMeshers_FaceSidePtr srcWire = srcWires[iW];
+
+      list< TopoDS_Edge > tgtEdges;
       TopTools_IndexedMapOfShape edgeMap; // to detect seam edges
       for ( int iE = 0; iE < srcWire->NbEdges(); ++iE )
       {
@@ -453,7 +459,8 @@ namespace {
           {
             list< TopoDS_Edge >::iterator eIt = tgtEdges.begin();
             std::advance( eIt, index-1 );
-            eIt->Reverse();
+            if ( are2dConnected( tgtEdges.back(), *eIt, tgtFace ))
+              eIt->Reverse();
           }
           else
           {
@@ -469,56 +476,58 @@ namespace {
             tgtE = nE.second;
         }
         tgtEdges.push_back( tgtE );
+      }
 
+      tgtWires[ iW ].reset( new StdMeshers_FaceSide( tgtFace, tgtEdges, tgtMesh,
+                                                     /*theIsForward = */ true,
+                                                     /*theIgnoreMediumNodes = */false));
+      StdMeshers_FaceSidePtr tgtWire = tgtWires[ iW ];
 
-        // Fill map of src to tgt nodes with nodes on edges
+      // Fill map of src to tgt nodes with nodes on edges
 
-        if ( srcMesh->GetSubMesh( srcE )->IsEmpty() ||
-             tgtMesh->GetSubMesh( tgtE )->IsEmpty() )
+      for ( int iE = 0; iE < srcWire->NbEdges(); ++iE )
+      {
+        if ( srcMesh->GetSubMesh( srcWire->Edge(iE) )->IsEmpty() ||
+             tgtMesh->GetSubMesh( tgtWire->Edge(iE) )->IsEmpty() )
         {
           // add nodes on VERTEXes for a case of not meshes EDGEs
-          const TopoDS_Shape&  srcV = SMESH_MesherHelper::IthVertex( 0, srcE );
-          const TopoDS_Shape&  tgtV = shape2ShapeMap( srcV, /*isSrc=*/true );
-          const SMDS_MeshNode* srcN = SMESH_Algo::VertexNode( TopoDS::Vertex( srcV ), srcMeshDS );
-          const SMDS_MeshNode* tgtN = SMESH_Algo::VertexNode( TopoDS::Vertex( tgtV ), tgtMeshDS );
+          const SMDS_MeshNode* srcN = srcWire->VertexNode( iE );
+          const SMDS_MeshNode* tgtN = tgtWire->VertexNode( iE );
           if ( srcN && tgtN )
             src2tgtNodes.insert( make_pair( srcN, tgtN ));
         }
         else
         {
-          const bool skipMediumNodes = true;
-          map< double, const SMDS_MeshNode* > srcNodes, tgtNodes;
-          if ( !SMESH_Algo::GetSortedNodesOnEdge( srcMeshDS, srcE, skipMediumNodes, srcNodes) ||
-               !SMESH_Algo::GetSortedNodesOnEdge( tgtMeshDS, tgtE, skipMediumNodes, tgtNodes ))
-            return SMESH_ComputeError::New( COMPERR_BAD_INPUT_MESH,
-                                            "Invalid node parameters on edges");
+          const bool skipMedium = true, isFwd = true;
+          StdMeshers_FaceSide srcEdge( srcFace, srcWire->Edge(iE), srcMesh, isFwd, skipMedium);
+          StdMeshers_FaceSide tgtEdge( tgtFace, tgtWire->Edge(iE), tgtMesh, isFwd, skipMedium);
+          
+          vector< const SMDS_MeshNode* > srcNodes = srcEdge.GetOrderedNodes();
+          vector< const SMDS_MeshNode* > tgtNodes = tgtEdge.GetOrderedNodes();
 
           if (( srcNodes.size() != tgtNodes.size() ) && tgtNodes.size() > 0 )
             return SMESH_ComputeError::New( COMPERR_BAD_INPUT_MESH,
                                             "Different number of nodes on edges");
           if ( !tgtNodes.empty() )
           {
-            map< double, const SMDS_MeshNode* >::iterator u_tn = tgtNodes.begin();
-            if ( srcE.Orientation() == tgtE.Orientation() )
-            {
-              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 ));
-            }
-            else
+            vector< const SMDS_MeshNode* >::iterator tn = tgtNodes.begin();
+            //if ( srcWire->Edge(iE).Orientation() == tgtWire->Edge(iE).Orientation() )
             {
-              map< double, const SMDS_MeshNode* >::reverse_iterator u_sn = srcNodes.rbegin();
-              for ( ; u_tn != tgtNodes.end(); ++u_tn, ++u_sn)
-                src2tgtNodes.insert( make_pair( u_sn->second, u_tn->second ));
+              vector< const SMDS_MeshNode* >::iterator sn = srcNodes.begin();
+              for ( ; tn != tgtNodes.end(); ++tn, ++sn)
+                src2tgtNodes.insert( make_pair( *sn, *tn ));
             }
+            // else
+            // {
+            //   vector< const SMDS_MeshNode* >::reverse_iterator sn = srcNodes.rbegin();
+            //   for ( ; tn != tgtNodes.end(); ++tn, ++sn)
+            //     src2tgtNodes.insert( make_pair( *sn, *tn ));
+            // }
             is1DComputed = true;
           }
         }
       } // loop on EDGEs of a WIRE
 
-      tgtWires[ iW ].reset( new StdMeshers_FaceSide( tgtFace, tgtEdges, tgtMesh,
-                                                     /*theIsForward = */ true,
-                                                     /*theIgnoreMediumNodes = */false));
     } // loop on WIREs
 
     return TError();
@@ -549,18 +558,24 @@ namespace {
 
     // transformation to get location of target nodes from source ones
     StdMeshers_ProjectionUtils::TrsfFinder3D trsf;
+    bool trsfIsOK = false;
     if ( tgtFace.IsPartner( srcFace ))
     {
-      gp_Trsf srcTrsf = srcFace.Location();
-      gp_Trsf tgtTrsf = tgtFace.Location();
-      trsf.Set( srcTrsf.Inverted() * tgtTrsf );
+      gp_GTrsf srcTrsf = srcFace.Location().Transformation();
+      gp_GTrsf tgtTrsf = tgtFace.Location().Transformation();
+      gp_GTrsf t = srcTrsf.Inverted().Multiplied( tgtTrsf );
+      trsf.Set( t );
       // check
       gp_Pnt srcP = BRep_Tool::Pnt( srcWires[0]->FirstVertex() );
       gp_Pnt tgtP = BRep_Tool::Pnt( tgtWires[0]->FirstVertex() );
-      if ( tgtP.Distance( trsf.Transform( srcP )) > tol )
-        trsf.Set( tgtTrsf.Inverted() * srcTrsf );
+      trsfIsOK = ( tgtP.Distance( trsf.Transform( srcP )) < tol );
+      if ( !trsfIsOK )
+      {
+        trsf.Set( tgtTrsf.Inverted().Multiplied( srcTrsf ));
+        trsfIsOK = ( tgtP.Distance( trsf.Transform( srcP )) < tol );
+      }
     }
-    else
+    if ( !trsfIsOK )
     {
       // Try to find the 3D transformation
 
@@ -574,7 +589,7 @@ namespace {
         const double minSegLen = srcWires[iW]->Length() / totNbSeg;
         for ( int iE = 0; iE < srcWires[iW]->NbEdges(); ++iE )
         {
-          int nbSeg    = Max( 1, int( srcWires[iW]->EdgeLength( iE ) / minSegLen ));
+          size_t nbSeg = Max( 1, int( srcWires[iW]->EdgeLength( iE ) / minSegLen ));
           double srcU  = srcWires[iW]->FirstParameter( iE );
           double tgtU  = tgtWires[iW]->FirstParameter( iE );
           double srcDu = ( srcWires[iW]->LastParameter( iE )- srcU ) / nbSeg;
@@ -595,7 +610,6 @@ namespace {
 
       // check trsf
 
-      bool trsfIsOK = true;
       const int nbTestPnt = 20;
       const size_t  iStep = Max( 1, int( srcPnts.size() / nbTestPnt ));
       // check boundary
@@ -630,7 +644,7 @@ namespace {
     // Make new faces
 
     // prepare the helper to adding quadratic elements if necessary
-    helper.SetSubShape( tgtFace );
+    //helper.SetSubShape( tgtFace );
     helper.IsQuadraticSubMesh( tgtFace );
 
     SMESHDS_SubMesh* srcSubDS = srcMeshDS->MeshElements( srcFace );
@@ -814,7 +828,7 @@ namespace {
           const double minSegLen = srcWires[iW]->Length() / totNbSeg;
           for ( int iE = 0; iE < srcWires[iW]->NbEdges(); ++iE )
           {
-            int nbSeg    = Max( 1, int( srcWires[iW]->EdgeLength( iE ) / minSegLen ));
+            size_t nbSeg = Max( 1, int( srcWires[iW]->EdgeLength( iE ) / minSegLen ));
             double srcU  = srcWires[iW]->FirstParameter( iE );
             double tgtU  = tgtWires[iW]->FirstParameter( iE );
             double srcDu = ( srcWires[iW]->LastParameter( iE )- srcU ) / nbSeg;
@@ -904,6 +918,7 @@ namespace {
             tgtMeshDS->SetNodeOnVertex( n, TopoDS::Vertex( tgtV ));
             break;
           }
+          default:;
           }
           srcN_tgtN->second = n;
         }
@@ -915,10 +930,165 @@ namespace {
       case 3: helper.AddFace(tgtNodes[0], tgtNodes[2], tgtNodes[1]); break;
       case 4: helper.AddFace(tgtNodes[0], tgtNodes[3], tgtNodes[2], tgtNodes[1]); break;
       }
+    }  // loop on all mesh faces on srcFace
+
+    return true;
+  }
+
+  //================================================================================
+  /*!
+   * \brief Preform projection in case of quadrilateral faces
+   */
+  //================================================================================
+
+  bool projectQuads(const TopoDS_Face&                 tgtFace,
+                    const TopoDS_Face&                 srcFace,
+                    const TSideVector&                 tgtWires,
+                    const TSideVector&                 srcWires,
+                    const TAssocTool::TShapeShapeMap&  shape2ShapeMap,
+                    TAssocTool::TNodeNodeMap&          src2tgtNodes,
+                    const bool                         is1DComputed)
+  {
+    SMESH_Mesh * tgtMesh = tgtWires[0]->GetMesh();
+    SMESH_Mesh * srcMesh = srcWires[0]->GetMesh();
+    //SMESHDS_Mesh * tgtMeshDS = tgtMesh->GetMeshDS();
+    SMESHDS_Mesh * srcMeshDS = srcMesh->GetMeshDS();
+
+    if ( srcWires[0]->NbEdges() != 4 )
+      return false;
+    if ( !is1DComputed )
+      return false;
+    for ( int iE = 0; iE < 4; ++iE )
+    {
+      SMESHDS_SubMesh* sm = srcMeshDS->MeshElements( srcWires[0]->Edge( iE ));
+      if ( !sm ) return false;
+      if ( sm->NbNodes() + sm->NbElements() == 0 ) return false;
+    }
+    if ( BRepAdaptor_Surface( tgtFace ).GetType() != GeomAbs_Plane )
+      return false;
+    // if ( BRepAdaptor_Surface( tgtFace ).GetType() == GeomAbs_Plane &&
+    //      BRepAdaptor_Surface( srcFace ).GetType() == GeomAbs_Plane )
+    //   return false; // too easy
+
+    // load EDGEs to SMESH_Block
+
+    SMESH_Block block;
+    TopTools_IndexedMapOfOrientedShape blockSubShapes;
+    {
+      const TopoDS_Solid& box = srcMesh->PseudoShape();
+      TopoDS_Shell shell = TopoDS::Shell( TopExp_Explorer( box, TopAbs_SHELL ).Current() );
+      TopoDS_Vertex v;
+      block.LoadBlockShapes( shell, v, v, blockSubShapes ); // fill all since operator[] is missing
+    }
+    const SMESH_Block::TShapeID srcFaceBID = SMESH_Block::ID_Fxy0;
+    const SMESH_Block::TShapeID tgtFaceBID = SMESH_Block::ID_Fxy1;
+    vector< int > edgeBID;
+    block.GetFaceEdgesIDs( srcFaceBID, edgeBID ); // u0, u1, 0v, 1v
+    blockSubShapes.Substitute( edgeBID[0], srcWires[0]->Edge(0) );
+    blockSubShapes.Substitute( edgeBID[1], srcWires[0]->Edge(2) );
+    blockSubShapes.Substitute( edgeBID[2], srcWires[0]->Edge(3) );
+    blockSubShapes.Substitute( edgeBID[3], srcWires[0]->Edge(1) );
+    block.GetFaceEdgesIDs( tgtFaceBID, edgeBID ); // u0, u1, 0v, 1v
+    blockSubShapes.Substitute( edgeBID[0], tgtWires[0]->Edge(0) );
+    blockSubShapes.Substitute( edgeBID[1], tgtWires[0]->Edge(2) );
+    blockSubShapes.Substitute( edgeBID[2], tgtWires[0]->Edge(3) );
+    blockSubShapes.Substitute( edgeBID[3], tgtWires[0]->Edge(1) );
+    block.LoadFace( srcFace, srcFaceBID, blockSubShapes );
+    block.LoadFace( tgtFace, tgtFaceBID, blockSubShapes );
+
+    // remember connectivity of new faces in terms of ( node-or-XY )
+
+    typedef std::pair< const SMDS_MeshNode*, gp_XYZ > TNodeOrXY; // node-or-XY
+    typedef std::vector< TNodeOrXY* >                 TFaceConn; // face connectivity
+    std::vector< TFaceConn >                    newFacesVec;     // connectivity of all faces
+    std::map< const SMDS_MeshNode*, TNodeOrXY > srcNode2tgtNXY;  // src node -> node-or-XY
+
+    TAssocTool::TNodeNodeMap::iterator                                       srcN_tgtN;
+    std::map< const SMDS_MeshNode*, TNodeOrXY >::iterator                    srcN_tgtNXY;
+    std::pair< std::map< const SMDS_MeshNode*, TNodeOrXY >::iterator, bool > n2n_isNew;
+    TNodeOrXY nullNXY( (SMDS_MeshNode*)NULL, gp_XYZ(0,0,0) );
+
+    SMESHDS_SubMesh* srcSubDS = srcMeshDS->MeshElements( srcFace );
+    newFacesVec.resize( srcSubDS->NbElements() );
+    int iFaceSrc = 0;
+
+    SMDS_ElemIteratorPtr elemIt = srcSubDS->GetElements();
+    while ( elemIt->more() ) // loop on all mesh faces on srcFace
+    {
+      const SMDS_MeshElement* elem = elemIt->next();
+      TFaceConn& tgtNodes = newFacesVec[ iFaceSrc++ ];
+
+      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);
+        n2n_isNew = srcNode2tgtNXY.insert( make_pair( srcNode, nullNXY ));
+        TNodeOrXY & tgtNodeOrXY = n2n_isNew.first->second;
+        if ( n2n_isNew.second ) // new src node encounters
+        {
+          srcN_tgtN = src2tgtNodes.find( srcNode );
+          if ( srcN_tgtN != src2tgtNodes.end() )
+          {
+            tgtNodeOrXY.first = srcN_tgtN->second; // tgt node exists
+          }
+          else 
+          {
+            // find XY of src node withing the quadrilateral srcFace
+            if ( !block.ComputeParameters( SMESH_TNodeXYZ( srcNode ),
+                                           tgtNodeOrXY.second, srcFaceBID ))
+              return false;
+          }
+        }
+        tgtNodes[ i ] = & tgtNodeOrXY;
+      }
+    }
+
+    // as all XY are computed, create tgt nodes and faces
+
+    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 );
+
+    SMESH_MesherHelper srcHelper( *srcMesh );
+    srcHelper.SetSubShape( srcFace );
+
+    vector< const SMDS_MeshNode* > tgtNodes;
+    gp_XY uv;
+
+    for ( size_t iFaceTgt = 0; iFaceTgt < newFacesVec.size(); ++iFaceTgt )
+    {
+      TFaceConn& tgtConn = newFacesVec[ iFaceTgt ];
+      tgtNodes.resize( tgtConn.size() );
+      for ( size_t iN = 0; iN < tgtConn.size(); ++iN )
+      {
+        const SMDS_MeshNode* & tgtN = tgtConn[ iN ]->first;
+        if ( !tgtN ) // create a node
+        {
+          if ( !block.FaceUV( tgtFaceBID, tgtConn[iN]->second, uv ))
+            return false;
+          gp_Pnt p = tgtSurface->Value( uv.X(), uv.Y() );
+          tgtN = helper.AddNode( p.X(), p.Y(), p.Z(), uv.X(), uv.Y() );
+        }
+        tgtNodes[ tgtNodes.size() - iN - 1] = tgtN; // reversed orientation
+      }
+      switch ( tgtNodes.size() )
+      {
+      case 3: helper.AddFace(tgtNodes[0], tgtNodes[1], tgtNodes[2]); break;
+      case 4: helper.AddFace(tgtNodes[0], tgtNodes[1], tgtNodes[2], tgtNodes[3]); break;
+      default:
+        if ( tgtNodes.size() > 4 )
+          helper.AddPolygonalFace( tgtNodes );
+      }
     }
     return true;
 
-  } // bool projectBy2DSimilarity(...)
+  } // bool projectQuads(...)
 
   //================================================================================
   /*!
@@ -999,6 +1169,7 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
     srcMesh = tgtMesh;
 
   SMESHDS_Mesh * meshDS = theMesh.GetMeshDS();
+  SMESH_MesherHelper helper( theMesh );
 
   // ---------------------------
   // Make sub-shapes association
@@ -1015,8 +1186,8 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
   {
     if ( srcShape.ShapeType() == TopAbs_FACE )
     {
-      int nbE1 = SMESH_MesherHelper::Count( tgtFace, TopAbs_EDGE, /*ignoreSame=*/true );
-      int nbE2 = SMESH_MesherHelper::Count( srcShape, TopAbs_EDGE, /*ignoreSame=*/true );
+      int nbE1 = helper.Count( tgtFace, TopAbs_EDGE, /*ignoreSame=*/true );
+      int nbE2 = helper.Count( srcShape, TopAbs_EDGE, /*ignoreSame=*/true );
       if ( nbE1 != nbE2 )
         return error(COMPERR_BAD_SHAPE,
                      SMESH_Comment("Different number of edges in source and target faces: ")
@@ -1026,6 +1197,23 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
   }
   TopoDS_Face srcFace = TopoDS::Face( shape2ShapeMap( tgtFace ).Oriented(TopAbs_FORWARD));
 
+  // orient faces
+  // if ( srcMesh == tgtMesh )
+  // {
+  //   TopoDS_Shape solid =
+  //     helper.GetCommonAncestor( srcFace, tgtFace, *tgtMesh, TopAbs_SOLID );
+  //   if ( !solid.IsNull() )
+  //   {
+  //     srcFace.Orientation( helper.GetSubShapeOri( solid, srcFace ));
+  //     tgtFace.Orientation( helper.GetSubShapeOri( solid, tgtFace ));
+  //   }
+  //   else if ( helper.NbAncestors( srcFace, *tgtMesh, TopAbs_SOLID ) == 1 &&
+  //             helper.NbAncestors( tgtFace, *tgtMesh, TopAbs_SOLID ) == 1 )
+  //   {
+  //     srcFace.Orientation( helper.GetSubShapeOri( tgtMesh->GetShapeToMesh(), srcFace ));
+  //     tgtFace.Orientation( helper.GetSubShapeOri( tgtMesh->GetShapeToMesh(), tgtFace ));
+  //   }
+  // }
   // ----------------------------------------------
   // Assure that mesh on a source Face is computed
   // ----------------------------------------------
@@ -1071,8 +1259,13 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
     projDone = projectBy2DSimilarity( tgtFace, srcFace, tgtWires, srcWires,
                                       shape2ShapeMap, _src2tgtNodes, is1DComputed);
   }
+  if ( !projDone )
+  {
+    // projection in case of quadrilateral faces
+    // projDone = projectQuads( tgtFace, srcFace, tgtWires, srcWires,
+    //                          shape2ShapeMap, _src2tgtNodes, is1DComputed);
+  }
 
-  SMESH_MesherHelper helper( theMesh );
   helper.SetSubShape( tgtFace );
 
   // it will remove mesh built on edges and vertices in failure case
@@ -1088,20 +1281,22 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
     // 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();  ) {
+    set< const SMDS_MeshNode* > faceNodes;
+    for ( ; faceNodes.size() < 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++;
+        if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE &&
+             faceNodes.insert( node ).second )
           uvBox.Add( helper.GetNodeUV( srcFace, node ));
-        }
       }
     }
-    const bool toProjectNodes =
-      ( nbFaceNodes > 0 && ( uvBox.IsVoid() || uvBox.SquareExtent() < DBL_MIN ));
+    bool toProjectNodes = false;
+    if ( faceNodes.size() == 1 )
+      toProjectNodes = ( uvBox.IsVoid() || uvBox.CornerMin().IsEqual( gp_XY(0,0), 1e-12 ));
+    else if ( faceNodes.size() > 1 )
+      toProjectNodes = ( uvBox.IsVoid() || uvBox.SquareExtent() < DBL_MIN );
 
     // Find the corresponding source and target vertex
     // and <theReverse> flag needed to call mapper.Apply()
@@ -1109,13 +1304,10 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
     TopoDS_Vertex srcV1, tgtV1;
     bool reverse = false;
 
-    if ( _sourceHypo->HasVertexAssociation() ) {
-      srcV1 = _sourceHypo->GetSourceVertex(1);
-      tgtV1 = _sourceHypo->GetTargetVertex(1);
-    } else {
-      srcV1 = TopoDS::Vertex( TopExp_Explorer( srcFace, TopAbs_VERTEX ).Current() );
-      tgtV1 = TopoDS::Vertex( shape2ShapeMap( srcV1, /*isSrc=*/true ));
-    }
+    TopExp_Explorer vSrcExp( srcFace, TopAbs_VERTEX );
+    srcV1 = TopoDS::Vertex( vSrcExp.Current() );
+    tgtV1 = TopoDS::Vertex( shape2ShapeMap( srcV1, /*isSrc=*/true ));
+
     list< TopoDS_Edge > tgtEdges, srcEdges;
     list< int > nbEdgesInWires;
     SMESH_Block::GetOrderedEdges( tgtFace, tgtEdges, nbEdgesInWires, tgtV1 );
@@ -1127,7 +1319,7 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
       TopoDS_Shape srcE1bis = shape2ShapeMap( tgtE1 );
       reverse = ( ! srcE1.IsSame( srcE1bis ));
       if ( reverse &&
-           _sourceHypo->HasVertexAssociation() &&
+           //_sourceHypo->HasVertexAssociation() &&
            nbEdgesInWires.front() > 2 &&
            helper.IsRealSeam( tgtEdges.front() ))
       {
@@ -1136,11 +1328,66 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
         // we can't use only theReverse flag to correctly associate source
         // and target faces in the mapper. Thus we select srcV1 so that
         // GetOrderedEdges() to return EDGEs in a needed order
-        list< TopoDS_Edge >::iterator edge = srcEdges.begin();
-        for ( ; edge != srcEdges.end(); ++edge ) {
-          if ( srcE1bis.IsSame( *edge )) {
-            srcV1 = helper.IthVertex( 0, *edge );
-            break;
+        TopoDS_Face tgtFaceBis = tgtFace;
+        TopTools_MapOfShape checkedVMap( tgtEdges.size() );
+        checkedVMap.Add ( srcV1 );
+        for ( vSrcExp.Next(); vSrcExp.More(); )
+        {
+          tgtFaceBis.Reverse();
+          tgtEdges.clear();
+          SMESH_Block::GetOrderedEdges( tgtFaceBis, tgtEdges, nbEdgesInWires, tgtV1 );
+          bool ok = true;
+          list< TopoDS_Edge >::iterator edgeS = srcEdges.begin(), edgeT = tgtEdges.begin();
+          for ( ; edgeS != srcEdges.end() && ok ; ++edgeS, ++edgeT )
+            ok = edgeT->IsSame( shape2ShapeMap( *edgeS, /*isSrc=*/true ));
+          if ( ok )
+            break; // FOUND!
+
+          reverse = !reverse;
+          if ( reverse )
+          {
+            vSrcExp.Next();
+            while ( vSrcExp.More() && !checkedVMap.Add( vSrcExp.Current() ))
+              vSrcExp.Next();
+          }
+          else
+          {
+            srcV1 = TopoDS::Vertex( vSrcExp.Current() );
+            tgtV1 = TopoDS::Vertex( shape2ShapeMap( srcV1, /*isSrc=*/true ));
+            srcEdges.clear();
+            SMESH_Block::GetOrderedEdges( srcFace, srcEdges, nbEdgesInWires, srcV1 );
+          }
+        }
+      }
+      // for the case: project to a closed face from a non-closed face w/o vertex assoc;
+      // avoid projecting to a seam from two EDGEs with different nb nodes on them
+      // ( test mesh_Projection_2D_01/B1 )
+      if ( !_sourceHypo->HasVertexAssociation() &&
+           nbEdgesInWires.front() > 2 &&
+           helper.IsRealSeam( tgtEdges.front() ))
+      {
+        TopoDS_Shape srcEdge1 = shape2ShapeMap( tgtEdges.front() );
+        list< TopoDS_Edge >::iterator srcEdge2 =
+          std::find( srcEdges.begin(), srcEdges.end(), srcEdge1);
+        list< TopoDS_Edge >::iterator srcEdge3 =
+          std::find( srcEdges.begin(), srcEdges.end(), srcEdge1.Reversed());
+        if ( srcEdge2 == srcEdges.end() || srcEdge3 == srcEdges.end() ) // srcEdge1 is not a seam
+        {
+          // find srcEdge2 which also will be projected to tgtEdges.front()
+          for ( srcEdge2 = srcEdges.begin(); srcEdge2 != srcEdges.end(); ++srcEdge2 )
+            if ( !srcEdge1.IsSame( *srcEdge2 ) &&
+                 tgtEdges.front().IsSame( shape2ShapeMap( *srcEdge2, /*isSrc=*/true )))
+              break;
+          // compare nb nodes on srcEdge1 and srcEdge2
+          if ( srcEdge2 != srcEdges.end() )
+          {
+            int nbN1 = 0, nbN2 = 0;
+            if ( SMESHDS_SubMesh* sm = srcMesh->GetMeshDS()->MeshElements( srcEdge1 ))
+              nbN1 = sm->NbNodes();
+            if ( SMESHDS_SubMesh* sm = srcMesh->GetMeshDS()->MeshElements( *srcEdge2 ))
+              nbN2 = sm->NbNodes();
+            if ( nbN1 != nbN2 )
+              srcV1 = helper.IthVertex( 1, srcEdges.front() );
           }
         }
       }
@@ -1168,8 +1415,11 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
     // Compute mesh on a target face
 
     mapper.Apply( tgtFace, tgtV1, reverse );
-    if ( mapper.GetErrorCode() != SMESH_Pattern::ERR_OK )
+    if ( mapper.GetErrorCode() != SMESH_Pattern::ERR_OK ) {
+      // std::ofstream file("/tmp/Pattern.smp" );
+      // mapper.Save( file );
       return error("Can't apply source mesh pattern to the face");
+    }
 
     // Create the mesh
 
@@ -1287,8 +1537,8 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
              u2nodesOnSeam.size()            > 0 &&
              seam.ShapeType() == TopAbs_EDGE )
         {
-          int nbE1 = SMESH_MesherHelper::Count( tgtFace, TopAbs_EDGE, /*ignoreSame=*/true );
-          int nbE2 = SMESH_MesherHelper::Count( srcFace, TopAbs_EDGE, /*ignoreSame=*/true );
+          int nbE1 = helper.Count( tgtFace, TopAbs_EDGE, /*ignoreSame=*/true );
+          int nbE2 = helper.Count( srcFace, TopAbs_EDGE, /*ignoreSame=*/true );
           if ( nbE1 != nbE2 ) // 2 EDGEs are mapped to a seam EDGE
           {
             // find the 2 EDGEs of srcFace
index 878d2184900fa340be5c8eea8f0d4a2a00fe8b3b..c1586a7adb1e005c6d9cd92f8e3a0bc89d301ae6 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 93969dfeb75d9b13ed9288d91ca2e361cef84646..d8bce83cd0f1c38568cee8cfb8d72067e6736b6d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 
 #define RETURN_BAD_RESULT(msg) { MESSAGE(")-: Error: " << msg); return false; }
 #define gpXYZ(n) gp_XYZ(n->X(),n->Y(),n->Z())
-#define SHOWYXZ(msg, xyz) // {\
-// gp_Pnt p (xyz); \
-// cout << msg << " ("<< p.X() << "; " <<p.Y() << "; " <<p.Z() << ") " <<endl;\
-// }
+#define SHOWYXZ(msg, xyz)                                               \
+  //{gp_Pnt p(xyz); cout<<msg<< " ("<< p.X() << "; " <<p.Y() << "; " <<p.Z() << ") " <<endl; }
 
 namespace TAssocTool = StdMeshers_ProjectionUtils;
 
@@ -295,7 +293,7 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS
       shape2ShapeMap.Clear();
       vector< int > edgeIdVec;
       SMESH_Block::GetFaceEdgesIDs( fId, edgeIdVec );
-      for ( int i = 0; i < edgeIdVec.size(); ++i ) {
+      for ( size_t i = 0; i < edgeIdVec.size(); ++i ) {
         int eID = edgeIdVec[ i ];
         shape2ShapeMap.Bind( scrShapes( eID ), tgtShapes( eID ));
         if ( i < 2 ) {
@@ -541,3 +539,39 @@ void StdMeshers_Projection_3D::SetEventListener(SMESH_subMesh* subMesh)
                                 _sourceHypo->GetSourceMesh() );
 }
   
+//================================================================================
+/*!
+ * \brief Return true if the algorithm can mesh this shape
+ *  \param [in] aShape - shape to check
+ *  \param [in] toCheckAll - if true, this check returns OK if all shapes are OK,
+ *              else, returns OK if at least one shape is OK
+ */
+//================================================================================
+
+bool StdMeshers_Projection_3D::IsApplicable(const TopoDS_Shape & aShape, bool toCheckAll)
+{
+  TopExp_Explorer exp0( aShape, TopAbs_SOLID );
+  if ( !exp0.More() ) return false;
+
+  TopTools_IndexedMapOfOrientedShape blockShapes;
+  TopoDS_Vertex v;
+  TopoDS_Shell shell;
+  for ( ; exp0.More(); exp0.Next() )
+  {
+    int nbFoundShells = 0;
+    TopExp_Explorer exp1( exp0.Current(), TopAbs_SHELL );
+    for ( ; exp1.More(); exp1.Next(), ++nbFoundShells )
+    {
+      shell = TopoDS::Shell( exp1.Current() );
+      if ( nbFoundShells == 2 ) break;
+    }
+    if ( nbFoundShells != 1 ) {
+      if ( toCheckAll ) return false;
+      continue;
+    }   
+    bool isBlock = SMESH_Block::FindBlockShapes( shell, v, v, blockShapes );
+    if ( toCheckAll && !isBlock ) return false;
+    if ( !toCheckAll && isBlock ) return true;
+  }
+  return toCheckAll;
+}
index 363a38e93e4e34dfaa1ddde1a59d611eaa7746b4..27e177348c0cf5131378d43accad06e758756482 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -57,7 +57,9 @@ public:
    */
   virtual void SetEventListener(SMESH_subMesh* whenSetToSubMesh);
   
-protected:
+  static bool IsApplicable(const TopoDS_Shape & aShape, bool toCheckAll);
+
+ protected:
 
   const StdMeshers_ProjectionSource3D* _sourceHypo;
 
index e8a55a2458e5696822669152649bbe16896b7d2b..bf67b7a0a416096db3444d72a3695f698519d7e9 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -304,7 +304,7 @@ namespace {
         // Get ordered edges and find index of anE in a sequence
         edges.clear();
         BRepTools_WireExplorer aWE (TopoDS::Wire(itA.Value()));
-        int edgeIndex = 0;
+        size_t edgeIndex = 0;
         for (; aWE.More(); aWE.Next()) {
           TopoDS_Edge edge = aWE.Current();
           edge.Orientation( aWE.Orientation() );
@@ -325,8 +325,8 @@ namespace {
         else {
           // count nb sides
           TopoDS_Edge prevEdge = anE;
-          int nbSide = 0, eIndex = edgeIndex + 1;
-          for ( int i = 0; i < edges.size(); ++i, ++eIndex )
+          size_t nbSide = 0, eIndex = edgeIndex + 1;
+          for ( size_t i = 0; i < edges.size(); ++i, ++eIndex )
           {
             if ( eIndex == edges.size() )
               eIndex = 0;
@@ -633,7 +633,11 @@ namespace {
       }
       return;
     }
+    case MEANINGLESS_LAST: {
+      break;
+    }
     } // switch by SubMeshState
-  }
+
+  } // ProcessEvent()
 
 } // namespace
index ca697143bd042a518b1c851a912684fcf87eb297..90d04334aa76e3f5a28ffa82c6014046f6ad3162 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
diff --git a/src/StdMeshers/StdMeshers_QuadFromMedialAxis_1D2D.cxx b/src/StdMeshers/StdMeshers_QuadFromMedialAxis_1D2D.cxx
new file mode 100644 (file)
index 0000000..55e0d19
--- /dev/null
@@ -0,0 +1,2098 @@
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&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, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// 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_QuadFromMedialAxis_1D2D.cxx
+// Created   : Wed Jun  3 17:33:45 2015
+// Author    : Edward AGAPOV (eap)
+
+#include "StdMeshers_QuadFromMedialAxis_1D2D.hxx"
+
+#include "SMESH_Block.hxx"
+#include "SMESH_Gen.hxx"
+#include "SMESH_MAT2d.hxx"
+#include "SMESH_Mesh.hxx"
+#include "SMESH_MeshEditor.hxx"
+#include "SMESH_MesherHelper.hxx"
+#include "SMESH_ProxyMesh.hxx"
+#include "SMESH_subMesh.hxx"
+#include "SMESH_subMeshEventListener.hxx"
+#include "StdMeshers_FaceSide.hxx"
+#include "StdMeshers_LayerDistribution.hxx"
+#include "StdMeshers_NumberOfLayers.hxx"
+#include "StdMeshers_Regular_1D.hxx"
+#include "StdMeshers_ViscousLayers2D.hxx"
+
+#include <BRepAdaptor_Curve.hxx>
+#include <BRepBuilderAPI_MakeEdge.hxx>
+#include <BRepTools.hxx>
+#include <BRep_Tool.hxx>
+#include <GeomAPI_Interpolate.hxx>
+#include <Geom_Surface.hxx>
+#include <Precision.hxx>
+#include <TColgp_HArray1OfPnt.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopLoc_Location.hxx>
+#include <TopTools_MapOfShape.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <gp_Pnt.hxx>
+
+#include <list>
+#include <vector>
+
+//================================================================================
+/*!
+ * \brief 1D algo
+ */
+class StdMeshers_QuadFromMedialAxis_1D2D::Algo1D : public StdMeshers_Regular_1D
+{
+public:
+  Algo1D(int studyId, SMESH_Gen* gen):
+    StdMeshers_Regular_1D( gen->GetANewId(), studyId, gen )
+  {
+  }
+  void SetSegmentLength( double len )
+  {
+    SMESH_Algo::_usedHypList.clear();
+    _value[ BEG_LENGTH_IND ] = len;
+    _value[ PRECISION_IND  ] = 1e-7;
+    _hypType = LOCAL_LENGTH;
+  }
+  void SetRadialDistribution( const SMESHDS_Hypothesis* hyp )
+  {
+    SMESH_Algo::_usedHypList.clear();
+    if ( !hyp )
+      return;
+
+    if ( const StdMeshers_NumberOfLayers* nl =
+         dynamic_cast< const StdMeshers_NumberOfLayers* >( hyp ))
+    {
+      _ivalue[ NB_SEGMENTS_IND  ] = nl->GetNumberOfLayers();
+      _ivalue[ DISTR_TYPE_IND ]   = 0;
+      _hypType = NB_SEGMENTS;
+    }
+    if ( const StdMeshers_LayerDistribution* ld =
+         dynamic_cast< const StdMeshers_LayerDistribution* >( hyp ))
+    {
+      if ( SMESH_Hypothesis* h = ld->GetLayerDistribution() )
+      {
+        SMESH_Algo::_usedHypList.clear();
+        SMESH_Algo::_usedHypList.push_back( h );
+      }
+    }
+  }
+  void ComputeDistribution(SMESH_MesherHelper& theHelper,
+                           const gp_Pnt&       thePnt1,
+                           const gp_Pnt&       thePnt2,
+                           list< double >&     theParams)
+  {
+    SMESH_Mesh& mesh = *theHelper.GetMesh();
+    TopoDS_Edge edge = BRepBuilderAPI_MakeEdge( thePnt1, thePnt2 );
+
+    SMESH_Hypothesis::Hypothesis_Status aStatus;
+    CheckHypothesis( mesh, edge, aStatus );
+
+    theParams.clear();
+    BRepAdaptor_Curve C3D(edge);
+    double f = C3D.FirstParameter(), l = C3D.LastParameter(), len = thePnt1.Distance( thePnt2 );
+    if ( !StdMeshers_Regular_1D::computeInternalParameters( mesh, C3D, len, f, l, theParams, false))
+    {
+      for ( size_t i = 1; i < 15; ++i )
+        theParams.push_back( i/15 );
+    }
+    else
+    {
+      for (list<double>::iterator itU = theParams.begin(); itU != theParams.end(); ++itU )
+        *itU /= len;
+    }
+  }
+  virtual const list <const SMESHDS_Hypothesis *> &
+  GetUsedHypothesis(SMESH_Mesh &, const TopoDS_Shape &, const bool)
+  {
+    return SMESH_Algo::_usedHypList;
+  }
+  virtual bool CheckHypothesis(SMESH_Mesh&                          aMesh,
+                               const TopoDS_Shape&                  aShape,
+                               SMESH_Hypothesis::Hypothesis_Status& aStatus)
+  {
+    if ( !SMESH_Algo::_usedHypList.empty() )
+      return StdMeshers_Regular_1D::CheckHypothesis( aMesh, aShape, aStatus );
+    return true;
+  }
+};
+//================================================================================
+/*!
+ * \brief Constructor sets algo features
+ */
+//================================================================================
+
+StdMeshers_QuadFromMedialAxis_1D2D::StdMeshers_QuadFromMedialAxis_1D2D(int        hypId,
+                                                                       int        studyId,
+                                                                       SMESH_Gen* gen)
+  : StdMeshers_Quadrangle_2D(hypId, studyId, gen),
+    _regular1D( 0 )
+{
+  _name = "QuadFromMedialAxis_1D2D";
+  _shapeType = (1 << TopAbs_FACE);
+  _onlyUnaryInput          = true;  // FACE by FACE so far
+  _requireDiscreteBoundary = false; // make 1D by myself
+  _supportSubmeshes        = true; // make 1D by myself
+  _neededLowerHyps[ 1 ]    = true;  // suppress warning on hiding a global 1D algo
+  _neededLowerHyps[ 2 ]    = true;  // suppress warning on hiding a global 2D algo
+  _compatibleHypothesis.clear();
+  _compatibleHypothesis.push_back("ViscousLayers2D");
+  _compatibleHypothesis.push_back("LayerDistribution2D");
+  _compatibleHypothesis.push_back("NumberOfLayers2D");
+}
+
+//================================================================================
+/*!
+ * \brief Destructor
+ */
+//================================================================================
+
+StdMeshers_QuadFromMedialAxis_1D2D::~StdMeshers_QuadFromMedialAxis_1D2D()
+{
+  delete _regular1D;
+  _regular1D = 0;
+}
+
+//================================================================================
+/*!
+ * \brief Check if needed hypotheses are present
+ */
+//================================================================================
+
+bool StdMeshers_QuadFromMedialAxis_1D2D::CheckHypothesis(SMESH_Mesh&         aMesh,
+                                                         const TopoDS_Shape& aShape,
+                                                         Hypothesis_Status&  aStatus)
+{
+  aStatus = HYP_OK;
+
+  // get one main optional hypothesis
+  const list <const SMESHDS_Hypothesis * >& hyps = GetUsedHypothesis(aMesh, aShape);
+  _hyp2D  = hyps.empty() ? 0 : hyps.front();
+
+  return true; // does not require hypothesis
+}
+
+namespace
+{
+  typedef map< const SMDS_MeshNode*, list< const SMDS_MeshNode* > > TMergeMap;
+  
+  //================================================================================
+  /*!
+   * \brief Sinuous face
+   */
+  struct SinuousFace
+  {
+    FaceQuadStruct::Ptr          _quad;
+    vector< TopoDS_Edge >        _edges;
+    vector< TopoDS_Edge >        _sinuSide[2], _shortSide[2];
+    vector< TopoDS_Edge >        _sinuEdges;
+    vector< Handle(Geom_Curve) > _sinuCurves;
+    int                          _nbWires;
+    list< int >                  _nbEdgesInWire;
+    TMergeMap                    _nodesToMerge;
+
+    SinuousFace( const TopoDS_Face& f ): _quad( new FaceQuadStruct )
+    {
+      list< TopoDS_Edge > edges;
+      _nbWires = SMESH_Block::GetOrderedEdges (f, edges, _nbEdgesInWire);
+      _edges.assign( edges.begin(), edges.end() );
+
+      _quad->side.resize( 4 );
+      _quad->face = f;
+    }
+    const TopoDS_Face& Face() const { return _quad->face; }
+    bool IsRing() const { return _shortSide[0].empty() && !_sinuSide[0].empty(); }
+  };
+
+  //================================================================================
+  /*!
+   * \brief Temporary mesh
+   */
+  struct TmpMesh : public SMESH_Mesh
+  {
+    TmpMesh()
+    {
+      _myMeshDS = new SMESHDS_Mesh(/*id=*/0, /*isEmbeddedMode=*/true);
+    }
+  };
+
+  //================================================================================
+  /*!
+   * \brief Event listener which removes mesh from EDGEs when 2D hyps change
+   */
+  struct EdgeCleaner : public SMESH_subMeshEventListener
+  {
+    int _prevAlgoEvent;
+    EdgeCleaner():
+      SMESH_subMeshEventListener( /*isDeletable=*/true,
+                                  "StdMeshers_QuadFromMedialAxis_1D2D::EdgeCleaner")
+    {
+      _prevAlgoEvent = -1;
+    }
+    virtual void ProcessEvent(const int                       event,
+                              const int                       eventType,
+                              SMESH_subMesh*                  faceSubMesh,
+                              SMESH_subMeshEventListenerData* data,
+                              const SMESH_Hypothesis*         hyp)
+    {
+      if ( eventType == SMESH_subMesh::ALGO_EVENT )
+      {
+        _prevAlgoEvent = event;
+        return;
+      }
+      // SMESH_subMesh::COMPUTE_EVENT
+      if ( _prevAlgoEvent == SMESH_subMesh::REMOVE_HYP ||
+           _prevAlgoEvent == SMESH_subMesh::REMOVE_ALGO ||
+           _prevAlgoEvent == SMESH_subMesh::MODIF_HYP )
+      {
+        SMESH_subMeshIteratorPtr smIt = faceSubMesh->getDependsOnIterator(/*includeSelf=*/false);
+        while ( smIt->more() )
+          smIt->next()->ComputeStateEngine( SMESH_subMesh::CLEAN );
+      }
+      _prevAlgoEvent = -1;
+    }
+  };
+
+  //================================================================================
+  /*!
+   * \brief Return a member of a std::pair
+   */
+  //================================================================================
+
+  template< typename T >
+  T& get( std::pair< T, T >& thePair, bool is2nd )
+  {
+    return is2nd ? thePair.second : thePair.first;
+  }
+
+  //================================================================================
+  /*!
+   * \brief Select two EDGEs from a map, either mapped to least values or to max values
+   */
+  //================================================================================
+
+  // template< class TVal2EdgesMap >
+  // void getTwo( bool                 least,
+  //              TVal2EdgesMap&       map,
+  //              vector<TopoDS_Edge>& twoEdges,
+  //              vector<TopoDS_Edge>& otherEdges)
+  // {
+  //   twoEdges.clear();
+  //   otherEdges.clear();
+  //   if ( least )
+  //   {
+  //     TVal2EdgesMap::iterator i = map.begin();
+  //     twoEdges.push_back( i->second );
+  //     twoEdges.push_back( ++i->second );
+  //     for ( ; i != map.end(); ++i )
+  //       otherEdges.push_back( i->second );
+  //   }
+  //   else
+  //   {
+  //     TVal2EdgesMap::reverse_iterator i = map.rbegin();
+  //     twoEdges.push_back( i->second );
+  //     twoEdges.push_back( ++i->second );
+  //     for ( ; i != map.rend(); ++i )
+  //       otherEdges.push_back( i->second );
+  //   }
+  //   TopoDS_Vertex v;
+  //   if ( TopExp::CommonVertex( twoEdges[0], twoEdges[1], v ))
+  //   {
+  //     twoEdges.clear(); // two EDGEs must not be connected
+  //     otherEdges.clear();
+  //   }
+  // }
+
+  //================================================================================
+  /*!
+   * \brief Finds out a minimal segment length given EDGEs will be divided into.
+   *        This length is further used to discretize the Medial Axis
+   */
+  //================================================================================
+
+  double getMinSegLen(SMESH_MesherHelper&        theHelper,
+                      const vector<TopoDS_Edge>& theEdges)
+  {
+    TmpMesh tmpMesh;
+    SMESH_Mesh* mesh = theHelper.GetMesh();
+
+    vector< SMESH_Algo* > algos( theEdges.size() );
+    for ( size_t i = 0; i < theEdges.size(); ++i )
+    {
+      SMESH_subMesh* sm = mesh->GetSubMesh( theEdges[i] );
+      algos[i] = sm->GetAlgo();
+    }
+
+    int nbSegDflt = mesh->GetGen() ? mesh->GetGen()->GetDefaultNbSegments() : 15;
+    double minSegLen = Precision::Infinite();
+
+    for ( size_t i = 0; i < theEdges.size(); ++i )
+    {
+      SMESH_subMesh* sm = mesh->GetSubMesh( theEdges[i] );
+      if ( SMESH_Algo::IsStraight( theEdges[i], /*degenResult=*/true ))
+        continue;
+      // get algo
+      size_t iOpp = ( theEdges.size() == 4 ? (i+2)%4 : i );
+      SMESH_Algo*  algo = sm->GetAlgo();
+      if ( !algo ) algo = algos[ iOpp ];
+      // get hypo
+      SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_MISSING;
+      if ( algo )
+      {
+        if ( !algo->CheckHypothesis( *mesh, theEdges[i], status ))
+          algo->CheckHypothesis( *mesh, theEdges[iOpp], status );
+      }
+      // compute
+      if ( status != SMESH_Hypothesis::HYP_OK )
+      {
+        minSegLen = Min( minSegLen, SMESH_Algo::EdgeLength( theEdges[i] ) / nbSegDflt );
+      }
+      else
+      {
+        tmpMesh.Clear();
+        tmpMesh.ShapeToMesh( TopoDS_Shape());
+        tmpMesh.ShapeToMesh( theEdges[i] );
+        try {
+          if ( !mesh->GetGen() ) continue; // tmp mesh
+          mesh->GetGen()->Compute( tmpMesh, theEdges[i], true, true ); // make nodes on VERTEXes
+          if ( !algo->Compute( tmpMesh, theEdges[i] ))
+            continue;
+        }
+        catch (...) {
+          continue;
+        }
+        SMDS_EdgeIteratorPtr segIt = tmpMesh.GetMeshDS()->edgesIterator();
+        while ( segIt->more() )
+        {
+          const SMDS_MeshElement* seg = segIt->next();
+          double len = SMESH_TNodeXYZ( seg->GetNode(0) ).Distance( seg->GetNode(1) );
+          minSegLen = Min( minSegLen, len );
+        }
+      }
+    }
+    if ( Precision::IsInfinite( minSegLen ))
+      minSegLen = mesh->GetShapeDiagonalSize() / nbSegDflt;
+
+    return minSegLen;
+  }
+
+  //================================================================================
+  /*!
+   * \brief Returns EDGEs located between two VERTEXes at which given MA branches end
+   *  \param [in] br1 - one MA branch
+   *  \param [in] br2 - one more MA branch
+   *  \param [in] allEdges - all EDGEs of a FACE
+   *  \param [out] shortEdges - the found EDGEs
+   *  \return bool - is OK or not
+   */
+  //================================================================================
+
+  bool getConnectedEdges( const SMESH_MAT2d::Branch* br1,
+                          const SMESH_MAT2d::Branch* br2,
+                          const vector<TopoDS_Edge>& allEdges,
+                          vector<TopoDS_Edge>&       shortEdges)
+  {
+    vector< size_t > edgeIDs[4];
+    br1->getGeomEdges( edgeIDs[0], edgeIDs[1] );
+    br2->getGeomEdges( edgeIDs[2], edgeIDs[3] );
+
+    // EDGEs returned by a Branch form a connected chain with a VERTEX where
+    // the Branch ends at the chain middle. One of end EDGEs of the chain is common
+    // with either end EDGE of the chain of the other Branch, or the chains are connected
+    // at a common VERTEX;
+
+    // Get indices of end EDGEs of the branches
+    bool vAtStart1 = ( br1->getEnd(0)->_type == SMESH_MAT2d::BE_ON_VERTEX );
+    bool vAtStart2 = ( br2->getEnd(0)->_type == SMESH_MAT2d::BE_ON_VERTEX );
+    size_t iEnd[4] = {
+      vAtStart1 ? edgeIDs[0].back() : edgeIDs[0][0],
+      vAtStart1 ? edgeIDs[1].back() : edgeIDs[1][0],
+      vAtStart2 ? edgeIDs[2].back() : edgeIDs[2][0],
+      vAtStart2 ? edgeIDs[3].back() : edgeIDs[3][0]
+    };
+
+    set< size_t > connectedIDs;
+    TopoDS_Vertex vCommon;
+    // look for the same EDGEs
+    for ( int i = 0; i < 2; ++i )
+      for ( int j = 2; j < 4; ++j )
+        if ( iEnd[i] == iEnd[j] )
+        {
+          connectedIDs.insert( edgeIDs[i].begin(), edgeIDs[i].end() );
+          connectedIDs.insert( edgeIDs[j].begin(), edgeIDs[j].end() );
+          i = j = 4;
+        }
+    if ( connectedIDs.empty() )
+      // look for connected EDGEs
+      for ( int i = 0; i < 2; ++i )
+        for ( int j = 2; j < 4; ++j )
+          if ( TopExp::CommonVertex( allEdges[ iEnd[i]], allEdges[ iEnd[j]], vCommon ))
+          {
+            connectedIDs.insert( edgeIDs[i].begin(), edgeIDs[i].end() );
+            connectedIDs.insert( edgeIDs[j].begin(), edgeIDs[j].end() );
+            i = j = 4;
+          }
+    if ( connectedIDs.empty() ||                     // nothing
+         allEdges.size() - connectedIDs.size() < 2 ) // too many
+      return false;
+
+    // set shortEdges in the order as in allEdges
+    if ( connectedIDs.count( 0 ) &&
+         connectedIDs.count( allEdges.size()-1 ))
+    {
+      size_t iE = allEdges.size()-1;
+      while ( connectedIDs.count( iE-1 ))
+        --iE;
+      for ( size_t i = 0; i < connectedIDs.size(); ++i )
+      {
+        shortEdges.push_back( allEdges[ iE ]);
+        iE = ( iE + 1 ) % allEdges.size();
+      }
+    }
+    else
+    {
+      set< size_t >::iterator i = connectedIDs.begin();
+      for ( ; i != connectedIDs.end(); ++i )
+        shortEdges.push_back( allEdges[ *i ]);
+    }
+    return true;
+  }
+
+  //================================================================================
+  /*!
+   * \brief Find EDGEs to discretize using projection from MA
+   *  \param [in,out] theSinuFace - the FACE to be meshed
+   *  \return bool - OK or not
+   *
+   * It separates all EDGEs into four sides of a quadrangle connected in the order:
+   * theSinuEdges[0], theShortEdges[0], theSinuEdges[1], theShortEdges[1]
+   */
+  //================================================================================
+
+  bool getSinuousEdges( SMESH_MesherHelper& theHelper,
+                        SinuousFace&        theSinuFace)
+  {
+    vector<TopoDS_Edge> * theSinuEdges  = & theSinuFace._sinuSide [0];
+    vector<TopoDS_Edge> * theShortEdges = & theSinuFace._shortSide[0];
+    theSinuEdges[0].clear();
+    theSinuEdges[1].clear();
+    theShortEdges[0].clear();
+    theShortEdges[1].clear();
+   
+    vector<TopoDS_Edge> & allEdges = theSinuFace._edges;
+    const size_t nbEdges = allEdges.size();
+    if ( nbEdges < 4 && theSinuFace._nbWires == 1 )
+      return false;
+
+    if ( theSinuFace._nbWires == 2 ) // ring
+    {
+      size_t nbOutEdges = theSinuFace._nbEdgesInWire.front();
+      theSinuEdges[0].assign ( allEdges.begin(), allEdges.begin() + nbOutEdges );
+      theSinuEdges[1].assign ( allEdges.begin() + nbOutEdges, allEdges.end() );
+      theSinuFace._sinuEdges = allEdges;
+      return true;
+    }
+    if ( theSinuFace._nbWires > 2 )
+      return false;
+
+    // create MedialAxis to find short edges by analyzing MA branches
+    double minSegLen = getMinSegLen( theHelper, allEdges );
+    SMESH_MAT2d::MedialAxis ma( theSinuFace.Face(), allEdges, minSegLen * 3 );
+
+    // in an initial request case, theFace represents a part of a river with almost parallel banks
+    // so there should be two branch points
+    using SMESH_MAT2d::BranchEnd;
+    using SMESH_MAT2d::Branch;
+    const vector< const BranchEnd* >& braPoints = ma.getBranchPoints();
+    if ( braPoints.size() < 2 )
+      return false;
+    TopTools_MapOfShape shortMap;
+    size_t nbBranchPoints = 0;
+    for ( size_t i = 0; i < braPoints.size(); ++i )
+    {
+      vector< const Branch* > vertBranches; // branches with an end on VERTEX
+      for ( size_t ib = 0; ib < braPoints[i]->_branches.size(); ++ib )
+      {
+        const Branch* branch = braPoints[i]->_branches[ ib ];
+        if ( branch->hasEndOfType( SMESH_MAT2d::BE_ON_VERTEX ))
+          vertBranches.push_back( branch );
+      }
+      if ( vertBranches.size() != 2 || braPoints[i]->_branches.size() != 3)
+        continue;
+
+      // get common EDGEs of two branches
+      if ( !getConnectedEdges( vertBranches[0], vertBranches[1],
+                               allEdges, theShortEdges[ nbBranchPoints > 0 ] ))
+        return false;
+
+      for ( size_t iS = 0; iS < theShortEdges[ nbBranchPoints > 0 ].size(); ++iS )
+        shortMap.Add( theShortEdges[ nbBranchPoints ][ iS ]);
+
+      ++nbBranchPoints;
+    }
+
+    if ( nbBranchPoints != 2 )
+      return false;
+
+    // add to theSinuEdges all edges that are not theShortEdges
+    vector< vector<TopoDS_Edge> > sinuEdges(1);
+    TopoDS_Vertex vCommon;
+    for ( size_t i = 0; i < allEdges.size(); ++i )
+    {
+      if ( !shortMap.Contains( allEdges[i] ))
+      {
+        if ( !sinuEdges.back().empty() )
+          if ( !TopExp::CommonVertex( sinuEdges.back().back(), allEdges[ i ], vCommon ))
+            sinuEdges.resize( sinuEdges.size() + 1 );
+
+        sinuEdges.back().push_back( allEdges[i] );
+      }
+    }
+    if ( sinuEdges.size() == 3 )
+    {
+      if ( !TopExp::CommonVertex( sinuEdges.back().back(), sinuEdges[0][0], vCommon ))
+        return false;
+      vector<TopoDS_Edge>& last = sinuEdges.back();
+      last.insert( last.end(), sinuEdges[0].begin(), sinuEdges[0].end() );
+      sinuEdges[0].swap( last );
+      sinuEdges.resize( 2 );
+    }
+    if ( sinuEdges.size() != 2 )
+      return false;
+
+    theSinuEdges[0].swap( sinuEdges[0] );
+    theSinuEdges[1].swap( sinuEdges[1] );
+
+    if ( !TopExp::CommonVertex( theSinuEdges[0].back(), theShortEdges[0][0], vCommon ) ||
+         !vCommon.IsSame( theHelper.IthVertex( 1, theSinuEdges[0].back() )))
+      theShortEdges[0].swap( theShortEdges[1] );
+
+    theSinuFace._sinuEdges = theSinuEdges[0];
+    theSinuFace._sinuEdges.insert( theSinuFace._sinuEdges.end(),
+                                   theSinuEdges[1].begin(), theSinuEdges[1].end() );
+
+    return ( theShortEdges[0].size() > 0 && theShortEdges[1].size() > 0 &&
+             theSinuEdges [0].size() > 0 && theSinuEdges [1].size() > 0 );
+
+    // the sinuous EDGEs can be composite and C0 continuous,
+    // therefor we use a complex criterion to find TWO short non-sinuous EDGEs
+    // and the rest EDGEs will be treated as sinuous.
+    // A short edge should have the following features:
+    // a) straight
+    // b) short
+    // c) with convex corners at ends
+    // d) far from the other short EDGE
+
+    // vector< double > isStraightEdge( nbEdges, 0 ); // criterion value
+
+    // // a0) evaluate continuity
+    // const double contiWgt = 0.5; // weight of continuity in the criterion
+    // multimap< int, TopoDS_Edge > continuity;
+    // for ( size_t i = 0; i < nbEdges; ++I )
+    // {
+    //   BRepAdaptor_Curve curve( allEdges[i] );
+    //   GeomAbs_Shape C = GeomAbs_CN;
+    //   try:
+    //     C = curve.Continuity(); // C0, G1, C1, G2, C2, C3, CN
+    //   catch ( Standard_Failure ) {}
+    //   continuity.insert( make_pair( C, allEdges[i] ));
+    //   isStraight[i] += double( C ) / double( CN ) * contiWgt;
+    // }
+
+    // // try to choose by continuity
+    // int mostStraight = (int) continuity.rbegin()->first;
+    // int lessStraight = (int) continuity.begin()->first;
+    // if ( mostStraight != lessStraight )
+    // {
+    //   int nbStraight = continuity.count( mostStraight );
+    //   if ( nbStraight == 2 )
+    //   {
+    //     getTwo( /*least=*/false, continuity, theShortEdges, theSinuEdges );
+    //   }
+    //   else if ( nbStraight == 3 && nbEdges == 4 )
+    //   {
+    //     theSinuEdges.push_back( continuity.begin()->second );
+    //     vector<TopoDS_Edge>::iterator it =
+    //       std::find( allEdges.begin(), allEdges.end(), theSinuEdges[0] );
+    //     int i = std::distance( allEdges.begin(), it );
+    //     theSinuEdges .push_back( allEdges[( i+2 )%4 ]);
+    //     theShortEdges.push_back( allEdges[( i+1 )%4 ]);
+    //     theShortEdges.push_back( allEdges[( i+3 )%4 ]);
+    //   }
+    //   if ( theShortEdges.size() == 2 )
+    //     return true;
+    // }
+
+    // // a) curvature; evaluate aspect ratio
+    // {
+    //   const double curvWgt = 0.5;
+    //   for ( size_t i = 0; i < nbEdges; ++I )
+    //   {
+    //     BRepAdaptor_Curve curve( allEdges[i] );
+    //     double curvature = 1;
+    //     if ( !curve.IsClosed() )
+    //     {
+    //       const double f = curve.FirstParameter(), l = curve.LastParameter();
+    //       gp_Pnt pf = curve.Value( f ), pl = curve.Value( l );
+    //       gp_Lin line( pf, pl.XYZ() - pf.XYZ() );
+    //       double distMax = 0;
+    //       for ( double u = f; u < l; u += (l-f)/30. )
+    //         distMax = Max( distMax, line.SquareDistance( curve.Value( u )));
+    //       curvature = Sqrt( distMax ) / ( pf.Distance( pl ));
+    //     }
+    //     isStraight[i] += curvWgt / (              curvature + 1e-20 );
+    //   }
+    // }
+    // // b) length
+    // {
+    //   const double lenWgt = 0.5;
+    //   for ( size_t i = 0; i < nbEdges; ++I )
+    //   {
+    //     double length = SMESH_Algo::Length( allEdges[i] );
+    //     if ( length > 0 )
+    //       isStraight[i] += lenWgt / length;
+    //   }
+    // }
+    // // c) with convex corners at ends
+    // {
+    //   const double cornerWgt = 0.25;
+    //   for ( size_t i = 0; i < nbEdges; ++I )
+    //   {
+    //     double convex = 0;
+    //     int iPrev = SMESH_MesherHelper::WrapIndex( int(i)-1, nbEdges );
+    //     int iNext = SMESH_MesherHelper::WrapIndex( int(i)+1, nbEdges );
+    //     TopoDS_Vertex v = helper.IthVertex( 0, allEdges[i] );
+    //     double angle = SMESH_MesherHelper::GetAngle( allEdges[iPrev], allEdges[i], theFace, v );
+    //     if ( angle < M_PI ) // [-PI; PI]
+    //       convex += ( angle + M_PI ) / M_PI / M_PI;
+    //     v = helper.IthVertex( 1, allEdges[i] );
+    //     angle = SMESH_MesherHelper::GetAngle( allEdges[iNext], allEdges[i], theFace, v );
+    //     if ( angle < M_PI ) // [-PI; PI]
+    //       convex += ( angle + M_PI ) / M_PI / M_PI;
+    //     isStraight[i] += cornerWgt * convex;
+    //   }
+    // }
+  }
+
+  //================================================================================
+  /*!
+   * \brief Creates an EDGE from a sole branch of MA
+   */
+  //================================================================================
+
+  TopoDS_Edge makeEdgeFromMA( SMESH_MesherHelper&            theHelper,
+                              const SMESH_MAT2d::MedialAxis& theMA,
+                              const double                   theMinSegLen)
+  {
+    if ( theMA.nbBranches() != 1 )
+      return TopoDS_Edge();
+
+    vector< gp_XY > uv;
+    theMA.getPoints( theMA.getBranch(0), uv );
+    if ( uv.size() < 2 )
+      return TopoDS_Edge();
+
+    TopoDS_Face face = TopoDS::Face( theHelper.GetSubShape() );
+    Handle(Geom_Surface) surface = BRep_Tool::Surface( face );
+
+    vector< gp_Pnt > pnt;
+    pnt.reserve( uv.size() * 2 );
+    pnt.push_back( surface->Value( uv[0].X(), uv[0].Y() ));
+    for ( size_t i = 1; i < uv.size(); ++i )
+    {
+      gp_Pnt p = surface->Value( uv[i].X(), uv[i].Y() );
+      int nbDiv = int( p.Distance( pnt.back() ) / theMinSegLen );
+      for ( int iD = 1; iD < nbDiv; ++iD )
+      {
+        double  R = iD / double( nbDiv );
+        gp_XY uvR = uv[i-1] * (1 - R) + uv[i] * R;
+        pnt.push_back( surface->Value( uvR.X(), uvR.Y() ));
+      }
+      pnt.push_back( p );
+    }
+
+    // cout << "from salome.geom import geomBuilder" << endl;
+    // cout << "geompy = geomBuilder.New(salome.myStudy)" << endl;
+    Handle(TColgp_HArray1OfPnt) points = new TColgp_HArray1OfPnt(1, pnt.size());
+    for ( size_t i = 0; i < pnt.size(); ++i )
+    {
+      gp_Pnt& p = pnt[i];
+      points->SetValue( i+1, p );
+      // cout << "geompy.MakeVertex( "<< p.X()<<", " << p.Y()<<", " << p.Z()
+      //      <<" theName = 'p_" << i << "')" << endl;
+    }
+
+    GeomAPI_Interpolate interpol( points, /*isClosed=*/false, gp::Resolution());
+    interpol.Perform();
+    if ( !interpol.IsDone())
+      return TopoDS_Edge();
+
+    TopoDS_Edge branchEdge = BRepBuilderAPI_MakeEdge(interpol.Curve());
+    return branchEdge;
+  }
+
+  //================================================================================
+  /*!
+   * \brief Returns a type of shape, to which a hypothesis used to mesh a given edge is assigned
+   */
+  //================================================================================
+
+  TopAbs_ShapeEnum getHypShape( SMESH_Mesh* mesh, const TopoDS_Shape& edge )
+  {
+    TopAbs_ShapeEnum shapeType = TopAbs_SHAPE;
+
+    SMESH_subMesh* sm = mesh->GetSubMesh( edge );
+    SMESH_Algo*  algo = sm->GetAlgo();
+    if ( !algo ) return shapeType;
+
+    const list <const SMESHDS_Hypothesis *> & hyps =
+      algo->GetUsedHypothesis( *mesh, edge, /*ignoreAuxiliary=*/true );
+    if ( hyps.empty() ) return shapeType;
+
+    TopoDS_Shape shapeOfHyp =
+      SMESH_MesherHelper::GetShapeOfHypothesis( hyps.front(), edge, mesh);
+
+    return SMESH_MesherHelper::GetGroupType( shapeOfHyp, /*woCompound=*/true);
+  }
+
+  //================================================================================
+  /*!
+   * \brief Discretize a sole branch of MA an returns parameters of divisions on MA
+   */
+  //================================================================================
+
+  bool divideMA( SMESH_MesherHelper&            theHelper,
+                 const SMESH_MAT2d::MedialAxis& theMA,
+                 const SinuousFace&             theSinuFace,
+                 SMESH_Algo*                    the1dAlgo,
+                 const double                   theMinSegLen,
+                 vector<double>&                theMAParams )
+  {
+    // Check if all EDGEs of one size are meshed, then MA discretization is not needed
+    SMESH_Mesh* mesh = theHelper.GetMesh();
+    size_t nbComputedEdges[2] = { 0, 0 };
+    for ( size_t iS = 0; iS < 2; ++iS )
+      for ( size_t i = 0; i < theSinuFace._sinuSide[iS].size(); ++i )
+      {
+        const TopoDS_Edge& sinuEdge = theSinuFace._sinuSide[iS][i];
+        SMESH_subMesh*           sm = mesh->GetSubMesh( sinuEdge );
+        bool             isComputed = ( !sm->IsEmpty() );
+        if ( isComputed )
+        {
+          TopAbs_ShapeEnum shape = getHypShape( mesh, sinuEdge );
+          if ( shape == TopAbs_SHAPE || shape <= TopAbs_FACE )
+          {
+            // EDGE computed using global hypothesis -> clear it
+            bool hasComputedFace = false;
+            PShapeIteratorPtr faceIt = theHelper.GetAncestors( sinuEdge, *mesh, TopAbs_FACE );
+            while ( const TopoDS_Shape* face = faceIt->next() )
+              if (( !face->IsSame( theSinuFace.Face() )) &&
+                  ( hasComputedFace = !mesh->GetSubMesh( *face )->IsEmpty() ))
+                break;
+            if ( !hasComputedFace )
+            {
+              sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
+              isComputed = false;
+            }
+          }
+        }
+        nbComputedEdges[ iS ] += isComputed;
+      }
+    if ( nbComputedEdges[0] == theSinuFace._sinuSide[0].size() ||
+         nbComputedEdges[1] == theSinuFace._sinuSide[1].size() )
+      return true; // discretization is not needed
+
+    // Make MA EDGE
+    TopoDS_Edge branchEdge = makeEdgeFromMA( theHelper, theMA, theMinSegLen );
+    if ( branchEdge.IsNull() )
+      return false;
+
+    // const char* file = "/misc/dn25/salome/eap/salome/misc/tmp/MAedge.brep";
+    // BRepTools::Write( branchEdge, file);
+    // cout << "Write " << file << endl;
+
+
+    // Find 1D algo to mesh branchEdge
+  
+    // look for a most local 1D hyp assigned to the FACE
+    int mostSimpleShape = -1, maxShape = TopAbs_EDGE;
+    TopoDS_Edge edge;
+    for ( size_t i = 0; i < theSinuFace._sinuEdges.size(); ++i )
+    {
+      TopAbs_ShapeEnum shapeType = getHypShape( mesh, theSinuFace._sinuEdges[i] );
+      if ( mostSimpleShape < shapeType && shapeType < maxShape )
+      {
+        edge = theSinuFace._sinuEdges[i];
+        mostSimpleShape = shapeType;
+      }
+    }
+
+    SMESH_Algo* algo = the1dAlgo;
+    if ( mostSimpleShape > -1 )
+    {
+      algo = mesh->GetSubMesh( edge )->GetAlgo();
+      SMESH_Hypothesis::Hypothesis_Status status;
+      if ( !algo->CheckHypothesis( *mesh, edge, status ))
+        algo = the1dAlgo;
+    }
+
+    TmpMesh tmpMesh;
+    tmpMesh.ShapeToMesh( branchEdge );
+    try {
+      mesh->GetGen()->Compute( tmpMesh, branchEdge, true, true ); // make nodes on VERTEXes
+      if ( !algo->Compute( tmpMesh, branchEdge ))
+        return false;
+    }
+    catch (...) {
+      return false;
+    }
+    return SMESH_Algo::GetNodeParamOnEdge( tmpMesh.GetMeshDS(), branchEdge, theMAParams );
+  }
+
+  //================================================================================
+  /*!
+   * \brief Select division parameters on MA and make them coincide at ends with
+   *        projections of VERTEXes to MA for a given pair of opposite EDGEs
+   *  \param [in] theEdgePairInd - index of the EDGE pair
+   *  \param [in] theDivPoints - the BranchPoint's dividing MA into parts each
+   *         corresponding to a unique pair of opposite EDGEs
+   *  \param [in] theMAParams - the MA division parameters
+   *  \param [out] theSelectedMAParams - the selected MA parameters
+   *  \return bool - is OK
+   */
+  //================================================================================
+
+  bool getParamsForEdgePair( const size_t                              theEdgePairInd,
+                             const vector< SMESH_MAT2d::BranchPoint >& theDivPoints,
+                             const vector<double>&                     theMAParams,
+                             vector<double>&                           theSelectedMAParams)
+  {
+    if ( theDivPoints.empty() )
+    {
+      theSelectedMAParams = theMAParams;
+      return true;
+    }
+    if ( theEdgePairInd > theDivPoints.size() || theMAParams.empty() )
+      return false;
+
+    // find a range of params to copy
+
+    double par1 = 0;
+    size_t iPar1 = 0;
+    if ( theEdgePairInd > 0 )
+    {
+      const SMESH_MAT2d::BranchPoint& bp = theDivPoints[ theEdgePairInd-1 ];
+      bp._branch->getParameter( bp, par1 );
+      while ( theMAParams[ iPar1 ] < par1 ) ++iPar1;
+      if ( par1 - theMAParams[ iPar1-1 ] < theMAParams[ iPar1 ] - par1 )
+        --iPar1;
+    }
+
+    double par2 = 1;
+    size_t iPar2 = theMAParams.size() - 1;
+    if ( theEdgePairInd < theDivPoints.size() )
+    {
+      const SMESH_MAT2d::BranchPoint& bp = theDivPoints[ theEdgePairInd ];
+      bp._branch->getParameter( bp, par2 );
+      iPar2 = iPar1;
+      while ( theMAParams[ iPar2 ] < par2 ) ++iPar2;
+      if ( par2 - theMAParams[ iPar2-1 ] < theMAParams[ iPar2 ] - par2 )
+        --iPar2;
+    }
+
+    theSelectedMAParams.assign( theMAParams.begin() + iPar1,
+                                theMAParams.begin() + iPar2 + 1 );
+
+    // adjust theSelectedMAParams to fit between par1 and par2
+
+    double d = par1 - theSelectedMAParams[0];
+    double f = ( par2 - par1 ) / ( theSelectedMAParams.back() - theSelectedMAParams[0] );
+
+    for ( size_t i = 0; i < theSelectedMAParams.size(); ++i )
+    {
+      theSelectedMAParams[i] += d;
+      theSelectedMAParams[i] = par1 + ( theSelectedMAParams[i] - par1 ) * f;
+    }
+
+    return true;
+  }
+
+  //--------------------------------------------------------------------------------
+  // node or node parameter on EDGE
+  struct NodePoint
+  {
+    const SMDS_MeshNode* _node;
+    double               _u;
+    size_t               _edgeInd; // index in theSinuEdges vector
+
+    NodePoint(): _node(0), _u(0), _edgeInd(-1) {}
+    NodePoint(const SMDS_MeshNode* n, double u, size_t iEdge ): _node(n), _u(u), _edgeInd(iEdge) {}
+    NodePoint(double u, size_t iEdge) : _node(0), _u(u), _edgeInd(iEdge) {}
+    NodePoint(const SMESH_MAT2d::BoundaryPoint& p) : _node(0), _u(p._param), _edgeInd(p._edgeIndex) {}
+    gp_Pnt Point(const vector< Handle(Geom_Curve) >& curves) const
+    {
+      return _node ? SMESH_TNodeXYZ(_node) : curves[ _edgeInd ]->Value( _u );
+    }
+  };
+  typedef multimap< double, pair< NodePoint, NodePoint > > TMAPar2NPoints;
+
+  //================================================================================
+  /*!
+   * \brief Finds a VERTEX corresponding to a point on EDGE, which is also filled
+   *        with a node on the VERTEX, present or created
+   *  \param [in,out] theNodePnt - the node position on the EDGE
+   *  \param [in] theSinuEdges - the sinuous EDGEs
+   *  \param [in] theMeshDS - the mesh
+   *  \return bool - true if the \a theBndPnt is on VERTEX
+   */
+  //================================================================================
+
+  bool findVertexAndNode( NodePoint&                  theNodePnt,
+                          const vector<TopoDS_Edge>&  theSinuEdges,
+                          SMESHDS_Mesh*               theMeshDS = 0,
+                          size_t                      theEdgeIndPrev = 0,
+                          size_t                      theEdgeIndNext = 0)
+  {
+    if ( theNodePnt._edgeInd >= theSinuEdges.size() )
+      return false;
+
+    double f,l;
+    BRep_Tool::Range( theSinuEdges[ theNodePnt._edgeInd ], f,l );
+    const double tol = 1e-3 * ( l - f );
+
+    TopoDS_Vertex V;
+    if      ( Abs( f - theNodePnt._u ) < tol )
+      V = SMESH_MesherHelper::IthVertex( 0, theSinuEdges[ theNodePnt._edgeInd ], /*CumOri=*/false);
+    else if ( Abs( l - theNodePnt._u ) < tol )
+      V = SMESH_MesherHelper::IthVertex( 1, theSinuEdges[ theNodePnt._edgeInd ], /*CumOri=*/false);
+    else if ( theEdgeIndPrev != theEdgeIndNext )
+      TopExp::CommonVertex( theSinuEdges[theEdgeIndPrev], theSinuEdges[theEdgeIndNext], V );
+
+    if ( !V.IsNull() && theMeshDS )
+    {
+      theNodePnt._node = SMESH_Algo::VertexNode( V, theMeshDS );
+      if ( !theNodePnt._node )
+      {
+        gp_Pnt p = BRep_Tool::Pnt( V );
+        theNodePnt._node = theMeshDS->AddNode( p.X(), p.Y(), p.Z() );
+        theMeshDS->SetNodeOnVertex( theNodePnt._node, V );
+      }
+    }
+    return !V.IsNull();
+  }
+
+  //================================================================================
+  /*!
+   * \brief Add to the map of NodePoint's those on VERTEXes
+   *  \param [in,out] theHelper - the helper
+   *  \param [in] theMA - Medial Axis
+   *  \param [in] theMinSegLen - minimal segment length
+   *  \param [in] theDivPoints - projections of VERTEXes to MA
+   *  \param [in] theSinuEdges - the sinuous EDGEs
+   *  \param [in] theSideEdgeIDs - indices of sinuous EDGEs per side
+   *  \param [in] theIsEdgeComputed - is sinuous EGDE is meshed
+   *  \param [in,out] thePointsOnE - the map to fill
+   *  \param [out] theNodes2Merge - the map of nodes to merge
+   */
+  //================================================================================
+
+  bool projectVertices( SMESH_MesherHelper&                 theHelper,
+                        const SMESH_MAT2d::MedialAxis&      theMA,
+                        vector< SMESH_MAT2d::BranchPoint >& theDivPoints,
+                        const vector< std::size_t > &       theEdgeIDs1,
+                        const vector< std::size_t > &       theEdgeIDs2,
+                        const vector< bool >&               theIsEdgeComputed,
+                        TMAPar2NPoints &                    thePointsOnE,
+                        SinuousFace&                        theSinuFace)
+  {
+    if ( theDivPoints.empty() )
+      return true;
+
+    SMESHDS_Mesh* meshDS = theHelper.GetMeshDS();
+    const vector< TopoDS_Edge >&     theSinuEdges = theSinuFace._sinuEdges;
+    const vector< Handle(Geom_Curve) >& theCurves = theSinuFace._sinuCurves;
+
+    double uMA;
+    SMESH_MAT2d::BoundaryPoint bp[2]; // 2 sinuous sides
+    const SMESH_MAT2d::Branch& branch = *theMA.getBranch(0);
+    {
+      // add to thePointsOnE NodePoint's of ends of theSinuEdges
+      if ( !branch.getBoundaryPoints( 0., bp[0], bp[1] ) ||
+           !theMA.getBoundary().moveToClosestEdgeEnd( bp[0] )) return false;
+      if ( !theSinuFace.IsRing() &&
+           !theMA.getBoundary().moveToClosestEdgeEnd( bp[1] )) return false;
+      NodePoint np0( bp[0] ), np1( bp[1] );
+      findVertexAndNode( np0, theSinuEdges, meshDS );
+      findVertexAndNode( np1, theSinuEdges, meshDS );
+      thePointsOnE.insert( make_pair( -0.1, make_pair( np0, np1 )));
+    }
+    if ( !theSinuFace.IsRing() )
+    {
+      if ( !branch.getBoundaryPoints( 1., bp[0], bp[1] ) ||
+           !theMA.getBoundary().moveToClosestEdgeEnd( bp[0] ) ||
+           !theMA.getBoundary().moveToClosestEdgeEnd( bp[1] )) return false;
+      NodePoint np0( bp[0] ), np1( bp[1] );
+      findVertexAndNode( np0, theSinuEdges, meshDS );
+      findVertexAndNode( np1, theSinuEdges, meshDS );
+      thePointsOnE.insert( make_pair( 1.1, make_pair( np0, np1)));
+    }
+    else
+    {
+      // project a VERTEX of outer sinuous side corresponding to branch(0.)
+      // which is not included into theDivPoints
+      if ( ! ( theDivPoints[0]._iEdge     == 0 &&
+               theDivPoints[0]._edgeParam == 0. )) // recursive call
+      {
+        SMESH_MAT2d::BranchPoint brp( &branch, 0, 0 );
+        vector< SMESH_MAT2d::BranchPoint > divPoint( 1, brp );
+        vector< std::size_t > edgeIDs1(2), edgeIDs2(2);
+        edgeIDs1[0] = theEdgeIDs1.back();
+        edgeIDs1[1] = theEdgeIDs1[0];
+        edgeIDs2[0] = theEdgeIDs2.back();
+        edgeIDs2[1] = theEdgeIDs2[0];
+        projectVertices( theHelper, theMA, divPoint, edgeIDs1, edgeIDs2,
+                         theIsEdgeComputed, thePointsOnE, theSinuFace );
+      }
+    }
+
+    // project theDivPoints
+
+    TMAPar2NPoints::iterator u2NP;
+    for ( size_t i = 0; i < theDivPoints.size(); ++i )
+    {
+      if ( !branch.getParameter( theDivPoints[i], uMA ))
+        return false;
+      if ( !branch.getBoundaryPoints( theDivPoints[i], bp[0], bp[1] ))
+        return false;
+
+      NodePoint  np[2] = {
+        NodePoint( bp[0] ),
+        NodePoint( bp[1] )
+      };
+      bool isVertex[2] = {
+        findVertexAndNode( np[0], theSinuEdges, meshDS, theEdgeIDs1[i], theEdgeIDs1[i+1] ),
+        findVertexAndNode( np[1], theSinuEdges, meshDS, theEdgeIDs2[i], theEdgeIDs2[i+1] )
+      };
+      const size_t iVert = isVertex[0] ? 0 : 1; // side with a VERTEX
+      const size_t iNode = 1 - iVert;           // opposite (meshed?) side
+
+      if ( isVertex[0] != isVertex[1] ) // try to find an opposite VERTEX
+      {
+        theMA.getBoundary().moveToClosestEdgeEnd( bp[iNode] ); // EDGE -> VERTEX
+        SMESH_MAT2d::BranchPoint brp;
+        theMA.getBoundary().getBranchPoint( bp[iNode], brp );  // WIRE -> MA
+        SMESH_MAT2d::BoundaryPoint bp2[2];
+        branch.getBoundaryPoints( brp, bp2[0], bp2[1] );       // MA -> WIRE
+        NodePoint np2[2] = { NodePoint( bp2[0]), NodePoint( bp2[1]) };
+        findVertexAndNode( np2[0], theSinuEdges, meshDS );
+        findVertexAndNode( np2[1], theSinuEdges, meshDS );
+        if ( np2[ iVert ]._node == np[ iVert ]._node &&
+             np2[ iNode ]._node)
+        {
+          np[ iNode ] = np2[ iNode ];
+          isVertex[ iNode ] = true;
+        }
+      }
+
+      u2NP = thePointsOnE.insert( make_pair( uMA, make_pair( np[0], np[1])));
+
+      if ( !isVertex[0] && !isVertex[1] ) return false; // error
+      if ( isVertex[0] && isVertex[1] )
+        continue;
+
+      bool isOppComputed = theIsEdgeComputed[ np[ iNode ]._edgeInd ];
+      if ( !isOppComputed )
+        continue;
+
+      // a VERTEX is projected on a meshed EDGE; there are two options:
+      // 1) a projected point is joined with a closet node if a strip between this and neighbor
+      // projection is WIDE enough; joining is done by creating a node coincident with the
+      //  existing node which will be merged together after all;
+      // 2) a neighbor projection is merged with this one if it is TOO CLOSE; a node of deleted
+      // projection is set to the BoundaryPoint of this projection
+
+      // evaluate distance to neighbor projections
+      const double rShort = 0.33;
+      bool isShortPrev[2], isShortNext[2], isPrevCloser[2];
+      TMAPar2NPoints::iterator u2NPPrev = u2NP, u2NPNext = u2NP;
+      --u2NPPrev; ++u2NPNext;
+      // bool hasPrev = ( u2NP     != thePointsOnE.begin() );
+      // bool hasNext = ( u2NPNext != thePointsOnE.end() );
+      // if ( !hasPrev ) u2NPPrev = u2NP0;
+      // if ( !hasNext ) u2NPNext = u2NP1;
+      for ( int iS = 0; iS < 2; ++iS ) // side with Vertex and side with Nodes
+      {
+        NodePoint np     = get( u2NP->second,     iS );
+        NodePoint npPrev = get( u2NPPrev->second, iS );
+        NodePoint npNext = get( u2NPNext->second, iS );
+        gp_Pnt     p     = np    .Point( theCurves );
+        gp_Pnt     pPrev = npPrev.Point( theCurves );
+        gp_Pnt     pNext = npNext.Point( theCurves );
+        double  distPrev = p.Distance( pPrev );
+        double  distNext = p.Distance( pNext );
+        double         r = distPrev / ( distPrev + distNext );
+        isShortPrev [iS] = ( r < rShort );
+        isShortNext [iS] = (( 1 - r ) > ( 1 - rShort ));
+        isPrevCloser[iS] = (( r < 0.5 ) && ( u2NPPrev->first > 0 ));
+      }
+      // if ( !hasPrev ) isShortPrev[0] = isShortPrev[1] = false;
+      // if ( !hasNext ) isShortNext[0] = isShortNext[1] = false;
+
+      TMAPar2NPoints::iterator u2NPClose;
+
+      if (( isShortPrev[0] && isShortPrev[1] ) || // option 2) -> remove a too close projection
+          ( isShortNext[0] && isShortNext[1] ))
+      {
+        u2NPClose = isPrevCloser[0] ? u2NPPrev : u2NPNext;
+        NodePoint& npProj  = get( u2NP->second,      iNode ); // NP of VERTEX projection
+        NodePoint npCloseN = get( u2NPClose->second, iNode ); // NP close to npProj
+        NodePoint npCloseV = get( u2NPClose->second, iVert ); // NP close to VERTEX
+        if ( !npCloseV._node )
+        {
+          npProj = npCloseN;
+          thePointsOnE.erase( isPrevCloser[0] ? u2NPPrev : u2NPNext );
+          continue;
+        }
+        else
+        {
+          // can't remove the neighbor projection as it is also from VERTEX, -> option 1)
+        }
+      }
+      // else: option 1) - wide enough -> "duplicate" existing node
+      {
+        u2NPClose = isPrevCloser[ iNode ] ? u2NPPrev : u2NPNext;
+        NodePoint& npProj   = get( u2NP->second,      iNode ); // NP of VERTEX projection
+        NodePoint& npCloseN = get( u2NPClose->second, iNode ); // NP close to npProj
+        npProj = npCloseN;
+        npProj._node = 0;
+        //npProj._edgeInd = npCloseN._edgeInd;
+        // npProj._u       = npCloseN._u + 1e-3 * Abs( get( u2NPPrev->second, iNode )._u -
+        //                                             get( u2NPNext->second, iNode )._u );
+        // gp_Pnt        p = npProj.Point( theCurves );
+        // npProj._node    = meshDS->AddNode( p.X(), p.Y(), p.Z() );
+        // meshDS->SetNodeOnEdge( npProj._node, theSinuEdges[ npProj._edgeInd ], npProj._u  );
+
+        //theNodes2Merge[ npCloseN._node ].push_back( npProj._node );
+      }
+    }
+
+    // remove auxiliary NodePoint's of ends of theSinuEdges
+    for ( u2NP = thePointsOnE.begin(); u2NP->first < 0; )
+      thePointsOnE.erase( u2NP++ );
+    thePointsOnE.erase( 1.1 );
+
+    return true;
+  }
+
+  double getUOnEdgeByPoint( const size_t     iEdge,
+                            const NodePoint* point,
+                            SinuousFace&     sinuFace )
+  {
+    if ( point->_edgeInd == iEdge )
+      return point->_u;
+
+    TopoDS_Vertex V0 = TopExp::FirstVertex( sinuFace._sinuEdges[ iEdge ]);
+    TopoDS_Vertex V1 = TopExp::LastVertex ( sinuFace._sinuEdges[ iEdge ]);
+    gp_Pnt p0 = BRep_Tool::Pnt( V0 );
+    gp_Pnt p1 = BRep_Tool::Pnt( V1 );
+    gp_Pnt  p = point->Point( sinuFace._sinuCurves );
+
+    double f,l;
+    BRep_Tool::Range( sinuFace._sinuEdges[ iEdge ], f,l );
+    return p.SquareDistance( p0 ) < p.SquareDistance( p1 ) ? f : l;
+  }
+
+  //================================================================================
+  /*!
+   * \brief Move coincident nodes to make node params on EDGE unique
+   *  \param [in] theHelper - the helper
+   *  \param [in] thePointsOnE - nodes on two opposite river sides
+   *  \param [in] theSinuFace - the sinuous FACE
+   *  \param [out] theNodes2Merge - the map of nodes to merge
+   */
+  //================================================================================
+
+  void separateNodes( SMESH_MesherHelper&            theHelper,
+                      const SMESH_MAT2d::MedialAxis& theMA,
+                      TMAPar2NPoints &               thePointsOnE,
+                      SinuousFace&                   theSinuFace,
+                      const vector< bool >&          theIsComputedEdge)
+  {
+    if ( thePointsOnE.size() < 2 )
+      return;
+
+    SMESHDS_Mesh* meshDS = theHelper.GetMeshDS();
+    const vector<TopoDS_Edge>&    theSinuEdges = theSinuFace._sinuEdges;
+    const vector< Handle(Geom_Curve) >& curves = theSinuFace._sinuCurves;
+
+    //SMESH_MAT2d::BoundaryPoint bp[2];
+    //const SMESH_MAT2d::Branch& branch = *theMA.getBranch(0);
+
+    typedef TMAPar2NPoints::iterator TIterator;
+
+    for ( int iSide = 0; iSide < 2; ++iSide ) // loop on two sinuous sides
+    {
+      // get a tolerance to compare points
+      double tol = Precision::Confusion();
+      for ( size_t i = 0; i < theSinuFace._sinuSide[ iSide ].size(); ++i )
+        tol = Max( tol , BRep_Tool::Tolerance( theSinuFace._sinuSide[ iSide ][ i ]));
+
+      // find coincident points
+      TIterator u2NP = thePointsOnE.begin();
+      vector< TIterator > sameU2NP( 1, u2NP++ );
+      while ( u2NP != thePointsOnE.end() )
+      {
+        for ( ; u2NP != thePointsOnE.end(); ++u2NP )
+        {
+          NodePoint& np1 = get( sameU2NP.back()->second, iSide );
+          NodePoint& np2 = get( u2NP           ->second, iSide );
+
+          if (( !np1._node || !np2._node ) &&
+              ( np1.Point( curves ).SquareDistance( np2.Point( curves )) < tol*tol ))
+          {
+            sameU2NP.push_back( u2NP );
+          }
+          else if ( sameU2NP.size() == 1 )
+          {
+            sameU2NP[ 0 ] = u2NP;
+          }
+          else
+          {
+            break;
+          }
+        }
+
+        if ( sameU2NP.size() > 1 )
+        {
+          // find an existing node on VERTEX among sameU2NP and get underlying EDGEs
+          const SMDS_MeshNode* existingNode = 0;
+          set< size_t > edgeInds;
+          NodePoint* np;
+          for ( size_t i = 0; i < sameU2NP.size(); ++i )
+          {
+            np = &get( sameU2NP[i]->second, iSide );
+            if ( np->_node )
+              if ( !existingNode || np->_node->GetPosition()->GetDim() == 0 )
+                existingNode = np->_node;
+            edgeInds.insert( np->_edgeInd );
+          }
+          list< const SMDS_MeshNode* >& mergeNodes = theSinuFace._nodesToMerge[ existingNode ];
+
+          TIterator u2NPprev = sameU2NP.front();
+          TIterator u2NPnext = sameU2NP.back() ;
+          if ( u2NPprev->first < 0. ) ++u2NPprev;
+          if ( u2NPnext->first > 1. ) --u2NPnext;
+
+          set< size_t >::iterator edgeID = edgeInds.begin();
+          for ( ; edgeID != edgeInds.end(); ++edgeID )
+          {
+            // get U range on iEdge within which the equal points will be distributed
+            double u0, u1;
+            np = &get( u2NPprev->second, iSide );
+            u0 = getUOnEdgeByPoint( *edgeID, np, theSinuFace );
+
+            np = &get( u2NPnext->second, iSide );
+            u1 = getUOnEdgeByPoint( *edgeID, np, theSinuFace );
+
+            if ( u0 == u1 )
+            {
+              if ( u2NPprev != thePointsOnE.begin() ) --u2NPprev;
+              if ( u2NPnext != --thePointsOnE.end() ) ++u2NPnext;
+              np = &get( u2NPprev->second, iSide );
+              u0 = getUOnEdgeByPoint( *edgeID, np, theSinuFace );
+              np = &get( u2NPnext->second, iSide );
+              u1 = getUOnEdgeByPoint( *edgeID, np, theSinuFace );
+            }
+
+            // distribute points and create nodes
+            double du = ( u1 - u0 ) / ( sameU2NP.size() + 1 /*!existingNode*/ );
+            double u  = u0 + du;
+            for ( size_t i = 0; i < sameU2NP.size(); ++i )
+            {
+              np = &get( sameU2NP[i]->second, iSide );
+              if ( !np->_node && *edgeID == np->_edgeInd )
+              {
+                np->_u = u;
+                u += du;
+                gp_Pnt p = np->Point( curves );
+                np->_node = meshDS->AddNode( p.X(), p.Y(), p.Z() );
+                meshDS->SetNodeOnEdge( np->_node, theSinuEdges[ *edgeID ], np->_u  );
+
+                if ( theIsComputedEdge[ *edgeID ])
+                  mergeNodes.push_back( np->_node );
+              }
+            }
+          }
+
+          sameU2NP.resize( 1 );
+          u2NP = ++sameU2NP.back();
+          sameU2NP[ 0 ] = u2NP;
+
+        } // if ( sameU2NP.size() > 1 )
+      } // while ( u2NP != thePointsOnE.end() )
+    } // for ( int iSide = 0; iSide < 2; ++iSide )
+
+    return;
+  } // separateNodes()
+
+  //================================================================================
+  /*!
+   * \brief Setup sides of SinuousFace::_quad
+   *  \param [in] theHelper - helper
+   *  \param [in] thePointsOnEdges - NodePoint's on sinuous sides
+   *  \param [in,out] theSinuFace - the FACE
+   *  \param [in] the1dAlgo - algorithm to use for radial discretization of a ring FACE
+   *  \return bool - is OK
+   */
+  //================================================================================
+
+  bool setQuadSides(SMESH_MesherHelper&   theHelper,
+                    const TMAPar2NPoints& thePointsOnEdges,
+                    SinuousFace&          theFace,
+                    SMESH_Algo*           the1dAlgo)
+  {
+    SMESH_Mesh*               mesh = theHelper.GetMesh();
+    const TopoDS_Face&        face = theFace._quad->face;
+    SMESH_ProxyMesh::Ptr proxyMesh = StdMeshers_ViscousLayers2D::Compute( *mesh, face );
+    if ( !proxyMesh )
+      return false;
+
+    list< TopoDS_Edge > side[4];
+    side[0].insert( side[0].end(), theFace._shortSide[0].begin(), theFace._shortSide[0].end() );
+    side[1].insert( side[1].end(), theFace._sinuSide[1].begin(),  theFace._sinuSide[1].end() );
+    side[2].insert( side[2].end(), theFace._shortSide[1].begin(), theFace._shortSide[1].end() );
+    side[3].insert( side[3].end(), theFace._sinuSide[0].begin(),  theFace._sinuSide[0].end() );
+
+    for ( int i = 0; i < 4; ++i )
+    {
+      theFace._quad->side[i] = StdMeshers_FaceSide::New( face, side[i], mesh, i < QUAD_TOP_SIDE,
+                                                         /*skipMediumNodes=*/true, proxyMesh );
+    }
+
+    if ( theFace.IsRing() )
+    {
+      // --------------------------------------
+      // Discretize a ring in radial direction
+      // --------------------------------------
+
+      if ( thePointsOnEdges.size() < 4 )
+        return false;
+
+      // find most distant opposite nodes
+      double maxDist = 0, dist;
+      TMAPar2NPoints::const_iterator u2NPdist, u2NP = thePointsOnEdges.begin();
+      for ( ; u2NP != thePointsOnEdges.end(); ++u2NP )
+      {
+        SMESH_TNodeXYZ        xyz( u2NP->second.first._node ); // node out
+        dist = xyz.SquareDistance( u2NP->second.second._node );// node in
+        if ( dist > maxDist )
+        {
+          u2NPdist = u2NP;
+          maxDist = dist;
+        }
+      }
+      // compute distribution of radial nodes
+      list< double > params; // normalized params
+      static_cast< StdMeshers_QuadFromMedialAxis_1D2D::Algo1D* >
+        ( the1dAlgo )->ComputeDistribution( theHelper,
+                                            SMESH_TNodeXYZ( u2NPdist->second.first._node ),
+                                            SMESH_TNodeXYZ( u2NPdist->second.second._node ),
+                                            params );
+
+      // add a radial quad side
+      u2NP = thePointsOnEdges.begin();
+      const SMDS_MeshNode* nOut = u2NP->second.first._node;
+      const SMDS_MeshNode*  nIn = u2NP->second.second._node;
+      nOut = proxyMesh->GetProxyNode( nOut );
+      nIn  = proxyMesh->GetProxyNode( nIn );
+      gp_XY uvOut = theHelper.GetNodeUV( face, nOut );
+      gp_XY uvIn  = theHelper.GetNodeUV( face, nIn );
+      Handle(Geom_Surface) surface = BRep_Tool::Surface( face );
+      UVPtStructVec uvsNew; UVPtStruct uvPt;
+      uvPt.node = nOut;
+      uvPt.u    = uvOut.X();
+      uvPt.v    = uvOut.Y();
+      uvsNew.push_back( uvPt );
+      for (list<double>::iterator itU = params.begin(); itU != params.end(); ++itU )
+      {
+        gp_XY uv  = ( 1 - *itU ) * uvOut + *itU * uvIn;
+        gp_Pnt p  = surface->Value( uv.X(), uv.Y() );
+        uvPt.node = theHelper.AddNode( p.X(), p.Y(), p.Z(), /*id=*/0, uv.X(), uv.Y() );
+        uvPt.u    = uv.X();
+        uvPt.v    = uv.Y();
+        uvsNew.push_back( uvPt );
+      }
+      uvPt.node = nIn;
+      uvPt.u    = uvIn.X();
+      uvPt.v    = uvIn.Y();
+      uvsNew.push_back( uvPt );
+
+      theFace._quad->side[ 0 ] = StdMeshers_FaceSide::New( uvsNew );
+      theFace._quad->side[ 2 ] = theFace._quad->side[ 0 ];
+
+      if ( theFace._quad->side[ 1 ].GetUVPtStruct().empty() ||
+           theFace._quad->side[ 3 ].GetUVPtStruct().empty() )
+        return false;
+
+      // assure that the outer sinuous side starts at nOut
+      if ( theFace._sinuSide[0].size() > 1 )
+      {
+        const UVPtStructVec& uvsOut = theFace._quad->side[ 3 ].GetUVPtStruct(); // _sinuSide[0]
+        size_t i; // find UVPtStruct holding nOut
+        for ( i = 0; i < uvsOut.size(); ++i )
+          if ( nOut == uvsOut[i].node )
+            break;
+        if ( i == uvsOut.size() )
+          return false;
+
+        if ( i != 0  &&  i != uvsOut.size()-1 )
+        {
+          // create a new OUT quad side
+          uvsNew.clear();
+          uvsNew.reserve( uvsOut.size() );
+          uvsNew.insert( uvsNew.end(), uvsOut.begin() + i, uvsOut.end() );
+          uvsNew.insert( uvsNew.end(), uvsOut.begin() + 1, uvsOut.begin() + i + 1);
+          theFace._quad->side[ 3 ] = StdMeshers_FaceSide::New( uvsNew );
+        }
+      }
+
+      // rotate the IN side if opposite nodes of IN and OUT sides don't match
+      const SMDS_MeshNode * nIn0 = theFace._quad->side[ 1 ].First().node;
+      if ( nIn0 != nIn )
+      {
+        nIn  = proxyMesh->GetProxyNode( nIn );
+        const UVPtStructVec& uvsIn = theFace._quad->side[ 1 ].GetUVPtStruct(); // _sinuSide[1]
+        size_t i; // find UVPtStruct holding nIn
+        for ( i = 0; i < uvsIn.size(); ++i )
+          if ( nIn == uvsIn[i].node )
+            break;
+        if ( i == uvsIn.size() )
+          return false;
+
+        // create a new IN quad side
+        uvsNew.clear();
+        uvsNew.reserve( uvsIn.size() );
+        uvsNew.insert( uvsNew.end(), uvsIn.begin() + i, uvsIn.end() );
+        uvsNew.insert( uvsNew.end(), uvsIn.begin() + 1, uvsIn.begin() + i + 1);
+        theFace._quad->side[ 1 ] = StdMeshers_FaceSide::New( uvsNew );
+      }
+
+      if ( theFace._quad->side[ 1 ].GetUVPtStruct().empty() ||
+           theFace._quad->side[ 3 ].GetUVPtStruct().empty() )
+        return false;
+
+    } // if ( theFace.IsRing() )
+
+    return true;
+
+  } // setQuadSides()
+
+  //================================================================================
+  /*!
+   * \brief Divide the sinuous EDGEs by projecting the division point of Medial
+   *        Axis to the EGDEs
+   *  \param [in] theHelper - the helper
+   *  \param [in] theMinSegLen - minimal segment length
+   *  \param [in] theMA - the Medial Axis
+   *  \param [in] theMAParams - parameters of division points of \a theMA
+   *  \param [in] theSinuEdges - the EDGEs to make nodes on
+   *  \param [in] theSinuSide0Size - the number of EDGEs in the 1st sinuous side
+   *  \param [in] the1dAlgo - algorithm to use for radial discretization of a ring FACE
+   *  \return bool - is OK or not
+   */
+  //================================================================================
+
+  bool computeSinuEdges( SMESH_MesherHelper&        theHelper,
+                         double                     /*theMinSegLen*/,
+                         SMESH_MAT2d::MedialAxis&   theMA,
+                         vector<double>&            theMAParams,
+                         SinuousFace&               theSinuFace,
+                         SMESH_Algo*                the1dAlgo)
+  {
+    if ( theMA.nbBranches() != 1 )
+      return false;
+
+    // normalize theMAParams
+    for ( size_t i = 0; i < theMAParams.size(); ++i )
+      theMAParams[i] /= theMAParams.back();
+
+
+    SMESH_Mesh*     mesh = theHelper.GetMesh();
+    SMESHDS_Mesh* meshDS = theHelper.GetMeshDS();
+    double f,l;
+
+    // get data of sinuous EDGEs and remove unnecessary nodes
+    const vector< TopoDS_Edge >& theSinuEdges = theSinuFace._sinuEdges;
+    vector< Handle(Geom_Curve) >& curves      = theSinuFace._sinuCurves;
+    vector< int >                edgeIDs   ( theSinuEdges.size() ); // IDs in the main shape
+    vector< bool >               isComputed( theSinuEdges.size() );
+    curves.resize( theSinuEdges.size(), 0 );
+    bool                         allComputed = true;
+    for ( size_t i = 0; i < theSinuEdges.size(); ++i )
+    {
+      curves[i] = BRep_Tool::Curve( theSinuEdges[i], f,l );
+      if ( !curves[i] )
+        return false;
+      SMESH_subMesh* sm = mesh->GetSubMesh( theSinuEdges[i] );
+      edgeIDs   [i] = sm->GetId();
+      isComputed[i] = ( !sm->IsEmpty() );
+      if ( !isComputed[i] )
+        allComputed = false;
+    }
+
+    const SMESH_MAT2d::Branch& branch = *theMA.getBranch(0);
+    SMESH_MAT2d::BoundaryPoint bp[2];
+
+    vector< std::size_t > edgeIDs1, edgeIDs2; // indices in theSinuEdges
+    vector< SMESH_MAT2d::BranchPoint > divPoints;
+    if ( !allComputed )
+      branch.getOppositeGeomEdges( edgeIDs1, edgeIDs2, divPoints );
+
+    for ( size_t i = 0; i < edgeIDs1.size(); ++i )
+      if ( isComputed[ edgeIDs1[i]] &&
+           isComputed[ edgeIDs2[i]] )
+      {
+        int nbNodes1 = meshDS->MeshElements(edgeIDs[ edgeIDs1[i]] )->NbNodes();
+        int nbNodes2 = meshDS->MeshElements(edgeIDs[ edgeIDs2[i]] )->NbNodes();
+        if ( nbNodes1 != nbNodes2 )
+          return false;
+        if (( i-1 >= 0 ) &&
+            ( edgeIDs1[i-1] == edgeIDs1[i] ||
+              edgeIDs2[i-1] == edgeIDs2[i] ))
+          return false;
+        if (( i+1 < edgeIDs1.size() ) &&
+            ( edgeIDs1[i+1] == edgeIDs1[i] ||
+              edgeIDs2[i+1] == edgeIDs2[i] ))
+          return false;
+      }
+
+    // map (param on MA) to (parameters of nodes on a pair of theSinuEdges)
+    TMAPar2NPoints pointsOnE;
+    vector<double> maParams;
+    set<int>       projectedEdges; // treated EDGEs which 'isComputed'
+
+    // compute params of nodes on EDGEs by projecting division points from MA
+
+    for ( size_t iEdgePair = 0; iEdgePair < edgeIDs1.size(); ++iEdgePair )
+      // loop on pairs of opposite EDGEs
+    {
+      if ( projectedEdges.count( edgeIDs1[ iEdgePair ]) ||
+           projectedEdges.count( edgeIDs2[ iEdgePair ]) )
+        continue;
+
+      // --------------------------------------------------------------------------------
+      if ( isComputed[ edgeIDs1[ iEdgePair ]] !=                    // one EDGE is meshed
+           isComputed[ edgeIDs2[ iEdgePair ]])
+      {
+        // "projection" from one side to the other
+
+        size_t iEdgeComputed = edgeIDs1[iEdgePair], iSideComputed = 0;
+        if ( !isComputed[ iEdgeComputed ])
+          ++iSideComputed, iEdgeComputed = edgeIDs2[iEdgePair];
+
+        map< double, const SMDS_MeshNode* > nodeParams; // params of existing nodes
+        if ( !SMESH_Algo::GetSortedNodesOnEdge( meshDS, theSinuEdges[ iEdgeComputed ], /*skipMedium=*/true, nodeParams ))
+          return false;
+
+        projectedEdges.insert( iEdgeComputed );
+
+        SMESH_MAT2d::BoundaryPoint& bndPnt = bp[ 1-iSideComputed ];
+        SMESH_MAT2d::BranchPoint brp;
+        NodePoint npN, npB; // NodePoint's initialized by node and BoundaryPoint
+        NodePoint& np0 = iSideComputed ? npB : npN;
+        NodePoint& np1 = iSideComputed ? npN : npB;
+
+        double maParam1st, maParamLast, maParam;
+        if ( !theMA.getBoundary().getBranchPoint( iEdgeComputed, nodeParams.begin()->first, brp ))
+          return false;
+        branch.getParameter( brp, maParam1st );
+        if ( !theMA.getBoundary().getBranchPoint( iEdgeComputed, nodeParams.rbegin()->first, brp ))
+          return false;
+        branch.getParameter( brp, maParamLast );
+
+        map< double, const SMDS_MeshNode* >::iterator u2n = nodeParams.begin(), u2nEnd = nodeParams.end();
+        TMAPar2NPoints::iterator end = pointsOnE.end(), pos = end;
+        TMAPar2NPoints::iterator & hint = (maParamLast > maParam1st) ? end : pos;
+        for ( ++u2n, --u2nEnd; u2n != u2nEnd; ++u2n )
+        {
+          // point on EDGE (u2n) --> MA point (brp)
+          if ( !theMA.getBoundary().getBranchPoint( iEdgeComputed, u2n->first, brp ))
+            return false;
+          // MA point --> points on 2 EDGEs (bp)
+          if ( !branch.getBoundaryPoints( brp, bp[0], bp[1] ) ||
+               !branch.getParameter( brp, maParam ))
+            return false;
+
+          npN = NodePoint( u2n->second, u2n->first, iEdgeComputed );
+          npB = NodePoint( bndPnt );
+          pos = pointsOnE.insert( hint, make_pair( maParam, make_pair( np0, np1 )));
+        }
+      }
+      // --------------------------------------------------------------------------------
+      else if ( !isComputed[ edgeIDs1[ iEdgePair ]] &&         // none of EDGEs is meshed
+                !isComputed[ edgeIDs2[ iEdgePair ]])
+      {
+        // "projection" from MA
+        maParams.clear();
+        if ( !getParamsForEdgePair( iEdgePair, divPoints, theMAParams, maParams ))
+          return false;
+
+        for ( size_t i = 1; i < maParams.size()-1; ++i )
+        {
+          if ( !branch.getBoundaryPoints( maParams[i], bp[0], bp[1] ))
+            return false;
+
+          pointsOnE.insert( pointsOnE.end(), make_pair( maParams[i], make_pair( NodePoint(bp[0]),
+                                                                                NodePoint(bp[1]))));
+        }
+      }
+      // --------------------------------------------------------------------------------
+      else if ( isComputed[ edgeIDs1[ iEdgePair ]] &&             // equally meshed EDGES
+                isComputed[ edgeIDs2[ iEdgePair ]])
+      {
+        // add existing nodes
+
+        size_t iE0 = edgeIDs1[ iEdgePair ];
+        size_t iE1 = edgeIDs2[ iEdgePair ];
+        map< double, const SMDS_MeshNode* > nodeParams[2]; // params of existing nodes
+        if ( !SMESH_Algo::GetSortedNodesOnEdge( meshDS, theSinuEdges[ iE0 ],
+                                                /*skipMedium=*/false, nodeParams[0] ) ||
+             !SMESH_Algo::GetSortedNodesOnEdge( meshDS, theSinuEdges[ iE1 ],
+                                                /*skipMedium=*/false, nodeParams[1] ) ||
+             nodeParams[0].size() != nodeParams[1].size() )
+          return false;
+
+        if ( nodeParams[0].size() <= 2 )
+          continue; // nodes on VERTEXes only
+
+        bool reverse = ( theSinuEdges[0].Orientation() == theSinuEdges[1].Orientation() );
+        double maParam;
+        SMESH_MAT2d::BranchPoint brp;
+        std::pair< NodePoint, NodePoint > npPair;
+
+        map< double, const SMDS_MeshNode* >::iterator
+          u2n0F = ++nodeParams[0].begin(),
+          u2n1F = ++nodeParams[1].begin();
+        map< double, const SMDS_MeshNode* >::reverse_iterator
+          u2n1R = ++nodeParams[1].rbegin();
+        for ( ; u2n0F != nodeParams[0].end(); ++u2n0F )
+        {
+          if ( !theMA.getBoundary().getBranchPoint( iE0, u2n0F->first, brp ) ||
+               !branch.getParameter( brp, maParam ))
+            return false;
+
+          npPair.first = NodePoint( u2n0F->second, u2n0F->first, iE0 );
+          if ( reverse )
+          {
+            npPair.second = NodePoint( u2n1R->second, u2n1R->first, iE1 );
+            ++u2n1R;
+          }
+          else
+          {
+            npPair.second = NodePoint( u2n1F->second, u2n1F->first, iE1 );
+            ++u2n1F;
+          }
+          pointsOnE.insert( make_pair( maParam, npPair ));
+        }
+      }
+    }  // loop on pairs of opposite EDGEs
+
+    if ( !projectVertices( theHelper, theMA, divPoints, edgeIDs1, edgeIDs2,
+                           isComputed, pointsOnE, theSinuFace ))
+      return false;
+
+    separateNodes( theHelper, theMA, pointsOnE, theSinuFace, isComputed );
+
+    // create nodes
+    TMAPar2NPoints::iterator u2np = pointsOnE.begin();
+    for ( ; u2np != pointsOnE.end(); ++u2np )
+    {
+      NodePoint* np[2] = { & u2np->second.first, & u2np->second.second };
+      for ( int iSide = 0; iSide < 2; ++iSide )
+      {
+        if ( np[ iSide ]->_node ) continue;
+        size_t       iEdge = np[ iSide ]->_edgeInd;
+        double           u = np[ iSide ]->_u;
+        gp_Pnt           p = curves[ iEdge ]->Value( u );
+        np[ iSide ]->_node = meshDS->AddNode( p.X(), p.Y(), p.Z() );
+        meshDS->SetNodeOnEdge( np[ iSide ]->_node, edgeIDs[ iEdge ], u );
+      }
+    }
+
+    // create mesh segments on EDGEs
+    theHelper.SetElementsOnShape( false );
+    TopoDS_Face face = TopoDS::Face( theHelper.GetSubShape() );
+    for ( size_t i = 0; i < theSinuEdges.size(); ++i )
+    {
+      SMESH_subMesh* sm = mesh->GetSubMesh( theSinuEdges[i] );
+      if ( sm->GetSubMeshDS() && sm->GetSubMeshDS()->NbElements() > 0 )
+        continue;
+
+      StdMeshers_FaceSide side( face, theSinuEdges[i], mesh,
+                                /*isFwd=*/true, /*skipMediumNodes=*/true );
+      vector<const SMDS_MeshNode*> nodes = side.GetOrderedNodes();
+      for ( size_t in = 1; in < nodes.size(); ++in )
+      {
+        const SMDS_MeshElement* seg = theHelper.AddEdge( nodes[in-1], nodes[in], 0, false );
+        meshDS->SetMeshElementOnShape( seg, edgeIDs[ i ] );
+      }
+    }
+
+    // update sub-meshes on VERTEXes
+    for ( size_t i = 0; i < theSinuEdges.size(); ++i )
+    {
+      mesh->GetSubMesh( theHelper.IthVertex( 0, theSinuEdges[i] ))
+        ->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
+      mesh->GetSubMesh( theHelper.IthVertex( 1, theSinuEdges[i] ))
+        ->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
+    }
+
+    // Setup sides of a quadrangle
+    if ( !setQuadSides( theHelper, pointsOnE, theSinuFace, the1dAlgo ))
+      return false;
+
+    return true;
+  }
+
+  //================================================================================
+  /*!
+   * \brief Mesh short EDGEs
+   */
+  //================================================================================
+
+  bool computeShortEdges( SMESH_MesherHelper&        theHelper,
+                          const vector<TopoDS_Edge>& theShortEdges,
+                          SMESH_Algo*                the1dAlgo,
+                          const bool                 theHasRadialHyp,
+                          const bool                 theIs2nd)
+  {
+    SMESH_Hypothesis::Hypothesis_Status aStatus;
+    for ( size_t i = 0; i < theShortEdges.size(); ++i )
+    {
+      if ( !theHasRadialHyp )
+        // use global hyps
+        theHelper.GetGen()->Compute( *theHelper.GetMesh(), theShortEdges[i], true, true );
+
+      SMESH_subMesh* sm = theHelper.GetMesh()->GetSubMesh(theShortEdges[i] );
+      if ( sm->IsEmpty() )
+      {
+        // use 2D hyp or minSegLen
+        try {
+          // compute VERTEXes
+          SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(/*includeSelf=*/false);
+          while ( smIt->more() )
+            smIt->next()->ComputeStateEngine( SMESH_subMesh::COMPUTE );
+
+          // compute EDGE
+          the1dAlgo->CheckHypothesis( *theHelper.GetMesh(), theShortEdges[i], aStatus );
+          if ( !the1dAlgo->Compute( *theHelper.GetMesh(), theShortEdges[i] ))
+            return false;
+        }
+        catch (...) {
+          return false;
+        }
+        sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
+        if ( sm->IsEmpty() )
+          return false;
+      }
+    }
+    return true;
+  }
+
+  inline double area( const UVPtStruct& p1, const UVPtStruct& p2, const UVPtStruct& p3 )
+  {
+    gp_XY v1 = p2.UV() - p1.UV();
+    gp_XY v2 = p3.UV() - p1.UV();
+    return v2 ^ v1;
+  }
+
+  bool ellipticSmooth( FaceQuadStruct::Ptr quad, int nbLoops )
+  {
+    //nbLoops = 10;
+    if ( quad->uv_grid.empty() )
+      return true;
+
+    int nbhoriz  = quad->iSize;
+    int nbvertic = quad->jSize;
+
+    const double dksi = 0.5, deta = 0.5;
+    const double  dksi2 = dksi*dksi, deta2 = deta*deta;
+    double err = 0., g11, g22, g12;
+    //int nbErr = 0;
+
+    FaceQuadStruct& q = *quad;
+    UVPtStruct pNew;
+
+    //double refArea = area( q.UVPt(0,0), q.UVPt(1,0), q.UVPt(1,1) );
+
+    for ( int iLoop = 0; iLoop < nbLoops; ++iLoop )
+    {
+      err = 0;
+      for ( int i = 1; i < nbhoriz - 1; i++ )
+        for ( int j = 1; j < nbvertic - 1; j++ )
+        {
+          g11 = ( (q.U(i,j+1) - q.U(i,j-1))*(q.U(i,j+1) - q.U(i,j-1))/dksi2 +
+                  (q.V(i,j+1) - q.V(i,j-1))*(q.V(i,j+1) - q.V(i,j-1))/deta2 )/4;
+
+          g22 = ( (q.U(i+1,j) - q.U(i-1,j))*(q.U(i+1,j) - q.U(i-1,j))/dksi2 +
+                  (q.V(i+1,j) - q.V(i-1,j))*(q.V(i+1,j) - q.V(i-1,j))/deta2 )/4;
+
+          g12 = ( (q.U(i+1,j) - q.U(i-1,j))*(q.U(i,j+1) - q.U(i,j-1))/dksi2 +
+                  (q.V(i+1,j) - q.V(i-1,j))*(q.V(i,j+1) - q.V(i,j-1))/deta2 )/(4*dksi*deta);
+
+          pNew.u = dksi2/(2*(g11+g22)) * (g11*(q.U(i+1,j) + q.U(i-1,j))/dksi2 +
+                                          g22*(q.U(i,j+1) + q.U(i,j-1))/dksi2
+                                          - 0.5*g12*q.U(i+1,j+1) + 0.5*g12*q.U(i-1,j+1) +
+                                          - 0.5*g12*q.U(i-1,j-1) + 0.5*g12*q.U(i+1,j-1));
+
+          pNew.v = deta2/(2*(g11+g22)) * (g11*(q.V(i+1,j) + q.V(i-1,j))/deta2 +
+                                          g22*(q.V(i,j+1) + q.V(i,j-1))/deta2
+                                          - 0.5*g12*q.V(i+1,j+1) + 0.5*g12*q.V(i-1,j+1) +
+                                          - 0.5*g12*q.V(i-1,j-1) + 0.5*g12*q.V(i+1,j-1));
+
+          // if (( refArea * area( q.UVPt(i-1,j-1), q.UVPt(i,j-1), pNew ) > 0 ) &&
+          //     ( refArea * area( q.UVPt(i+1,j-1), q.UVPt(i+1,j), pNew ) > 0 ) &&
+          //     ( refArea * area( q.UVPt(i+1,j+1), q.UVPt(i,j+1), pNew ) > 0 ) &&
+          //     ( refArea * area( q.UVPt(i-1,j), q.UVPt(i-1,j-1), pNew ) > 0 ))
+          {
+            err += sqrt(( q.U(i,j) - pNew.u ) * ( q.U(i,j) - pNew.u ) +
+                        ( q.V(i,j) - pNew.v ) * ( q.V(i,j) - pNew.v ));
+            q.U(i,j) = pNew.u;
+            q.V(i,j) = pNew.v;
+          }
+          // else if ( ++nbErr < 10 )
+          // {
+          //   cout << i << ", " << j << endl;
+          //   cout << "x = ["
+          //        << "[ " << q.U(i-1,j-1) << ", " <<q.U(i,j-1) << ", " << q.U(i+1,j-1) << " ],"
+          //        << "[ " << q.U(i-1,j-0) << ", " <<q.U(i,j-0) << ", " << q.U(i+1,j-0) << " ],"
+          //        << "[ " << q.U(i-1,j+1) << ", " <<q.U(i,j+1) << ", " << q.U(i+1,j+1) << " ]]" << endl;
+          //   cout << "y = ["
+          //        << "[ " << q.V(i-1,j-1) << ", " <<q.V(i,j-1) << ", " << q.V(i+1,j-1) << " ],"
+          //        << "[ " << q.V(i-1,j-0) << ", " <<q.V(i,j-0) << ", " << q.V(i+1,j-0) << " ],"
+          //        << "[ " << q.V(i-1,j+1) << ", " <<q.V(i,j+1) << ", " << q.V(i+1,j+1) << " ]]" << endl<<endl;
+          // }
+        }
+
+      if ( err / ( nbhoriz - 2 ) / ( nbvertic - 2 ) < 1e-6 )
+        break;
+    }
+    //cout << " ERR " << err / ( nbhoriz - 2 ) / ( nbvertic - 2 ) << endl;
+
+    return true;
+  }
+
+  //================================================================================
+  /*!
+   * \brief Remove temporary node
+   */
+  //================================================================================
+
+  void mergeNodes( SMESH_MesherHelper& theHelper,
+                   SinuousFace&        theSinuFace )
+  {
+    SMESH_MeshEditor editor( theHelper.GetMesh() );
+    SMESH_MeshEditor::TListOfListOfNodes nodesGroups;
+
+    TMergeMap::iterator n2nn = theSinuFace._nodesToMerge.begin();
+    for ( ; n2nn != theSinuFace._nodesToMerge.end(); ++n2nn )
+    {
+      if ( !n2nn->first ) continue;
+      nodesGroups.push_back( list< const SMDS_MeshNode* >() );
+      list< const SMDS_MeshNode* > & group = nodesGroups.back();
+
+      group.push_back( n2nn->first );
+      group.splice( group.end(), n2nn->second );
+    }
+    editor.MergeNodes( nodesGroups );
+  }
+
+} // namespace
+
+//================================================================================
+/*!
+ * \brief Sets event listener which removes mesh from EDGEs when 2D hyps change
+ */
+//================================================================================
+
+void StdMeshers_QuadFromMedialAxis_1D2D::SetEventListener(SMESH_subMesh* faceSubMesh)
+{
+  faceSubMesh->SetEventListener( new EdgeCleaner, 0, faceSubMesh );
+}
+
+//================================================================================
+/*!
+ * \brief Create quadrangle elements
+ *  \param [in] theHelper - the helper
+ *  \param [in] theFace - the face to mesh
+ *  \param [in] theSinuEdges - the sinuous EDGEs
+ *  \param [in] theShortEdges - the short EDGEs
+ *  \return bool - is OK or not
+ */
+//================================================================================
+
+bool StdMeshers_QuadFromMedialAxis_1D2D::computeQuads( SMESH_MesherHelper& theHelper,
+                                                       FaceQuadStruct::Ptr theQuad)
+{
+  StdMeshers_Quadrangle_2D::myHelper     = &theHelper;
+  StdMeshers_Quadrangle_2D::myNeedSmooth = false;
+  StdMeshers_Quadrangle_2D::myCheckOri   = false;
+  StdMeshers_Quadrangle_2D::myQuadList.clear();
+
+  int nbNodesShort0 = theQuad->side[0].NbPoints();
+  int nbNodesShort1 = theQuad->side[2].NbPoints();
+
+  // compute UV of internal points
+  myQuadList.push_back( theQuad );
+  if ( !StdMeshers_Quadrangle_2D::setNormalizedGrid( theQuad ))
+    return false;
+
+  // elliptic smooth of internal points to get boundary cell normal to the boundary
+  bool isRing = theQuad->side[0].grid->Edge(0).IsNull();
+  if ( !isRing )
+    ellipticSmooth( theQuad, 1 );
+
+  // create quadrangles
+  bool ok;
+  theHelper.SetElementsOnShape( true );
+  if ( nbNodesShort0 == nbNodesShort1 )
+    ok = StdMeshers_Quadrangle_2D::computeQuadDominant( *theHelper.GetMesh(),
+                                                        theQuad->face, theQuad );
+  else
+    ok = StdMeshers_Quadrangle_2D::computeTriangles( *theHelper.GetMesh(),
+                                                     theQuad->face, theQuad );
+
+  StdMeshers_Quadrangle_2D::myHelper = 0;
+
+  return ok;
+}
+
+//================================================================================
+/*!
+ * \brief Generate quadrangle mesh
+ */
+//================================================================================
+
+bool StdMeshers_QuadFromMedialAxis_1D2D::Compute(SMESH_Mesh&         theMesh,
+                                                 const TopoDS_Shape& theShape)
+{
+  SMESH_MesherHelper helper( theMesh );
+  helper.SetSubShape( theShape );
+
+  TopoDS_Face F = TopoDS::Face( theShape );
+  if ( F.Orientation() >= TopAbs_INTERNAL ) F.Orientation( TopAbs_FORWARD );
+
+  SinuousFace sinuFace( F );
+
+  _progress = 0.01;
+
+  if ( getSinuousEdges( helper, sinuFace ))
+  {
+    _progress = 0.4;
+
+    double minSegLen = getMinSegLen( helper, sinuFace._sinuEdges );
+    SMESH_MAT2d::MedialAxis ma( F, sinuFace._sinuEdges, minSegLen, /*ignoreCorners=*/true );
+
+    if ( !_regular1D )
+      _regular1D = new Algo1D( _studyId, _gen );
+    _regular1D->SetSegmentLength( minSegLen );
+
+    vector<double> maParams;
+    if ( ! divideMA( helper, ma, sinuFace, _regular1D, minSegLen, maParams ))
+      return error(COMPERR_BAD_SHAPE);
+
+    _progress = 0.8;
+    if ( _hyp2D )
+      _regular1D->SetRadialDistribution( _hyp2D );
+
+    if ( !computeShortEdges( helper, sinuFace._shortSide[0], _regular1D, _hyp2D, 0 ) ||
+         !computeShortEdges( helper, sinuFace._shortSide[1], _regular1D, _hyp2D, 1 ))
+      return error("Failed to mesh short edges");
+
+    _progress = 0.85;
+
+    if ( !computeSinuEdges( helper, minSegLen, ma, maParams, sinuFace, _regular1D ))
+      return error("Failed to mesh sinuous edges");
+
+    _progress = 0.9;
+
+    bool ok = computeQuads( helper, sinuFace._quad );
+
+    if ( ok )
+      mergeNodes( helper, sinuFace );
+
+    _progress = 1.;
+
+    return ok;
+  }
+
+  return error(COMPERR_BAD_SHAPE, "Not implemented so far");
+}
+
+//================================================================================
+/*!
+ * \brief Predict nb of elements
+ */
+//================================================================================
+
+bool StdMeshers_QuadFromMedialAxis_1D2D::Evaluate(SMESH_Mesh &         theMesh,
+                                                  const TopoDS_Shape & theShape,
+                                                  MapShapeNbElems&     theResMap)
+{
+  return StdMeshers_Quadrangle_2D::Evaluate(theMesh,theShape,theResMap);
+}
+
+//================================================================================
+/*!
+ * \brief Return true if the algorithm can mesh this shape
+ *  \param [in] aShape - shape to check
+ *  \param [in] toCheckAll - if true, this check returns OK if all shapes are OK,
+ *              else, returns OK if at least one shape is OK
+ */
+//================================================================================
+
+bool StdMeshers_QuadFromMedialAxis_1D2D::IsApplicable( const TopoDS_Shape & aShape,
+                                                       bool                 toCheckAll )
+{
+  TmpMesh tmpMesh;
+  SMESH_MesherHelper helper( tmpMesh );
+
+  int nbFoundFaces = 0;
+  for (TopExp_Explorer exp( aShape, TopAbs_FACE ); exp.More(); exp.Next(), ++nbFoundFaces )
+  {
+    const TopoDS_Face& face = TopoDS::Face( exp.Current() );
+    SinuousFace sinuFace( face );
+    bool isApplicable = getSinuousEdges( helper, sinuFace );
+
+    if ( toCheckAll  && !isApplicable ) return false;
+    if ( !toCheckAll &&  isApplicable ) return true;
+  }
+  return ( toCheckAll && nbFoundFaces != 0 );
+}
+
diff --git a/src/StdMeshers/StdMeshers_QuadFromMedialAxis_1D2D.hxx b/src/StdMeshers/StdMeshers_QuadFromMedialAxis_1D2D.hxx
new file mode 100644 (file)
index 0000000..aec59a2
--- /dev/null
@@ -0,0 +1,69 @@
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&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, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// 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_QuadFromMedialAxis_1D2D.hxx
+// Created   : Wed Jun  3 17:22:35 2015
+// Author    : Edward AGAPOV (eap)
+
+
+#ifndef __StdMeshers_QuadFromMedialAxis_1D2D_HXX__
+#define __StdMeshers_QuadFromMedialAxis_1D2D_HXX__
+
+#include "StdMeshers_Quadrangle_2D.hxx"
+
+#include <vector>
+
+/*!
+ * \brief Quadrangle mesher using Medial Axis
+ */
+class STDMESHERS_EXPORT StdMeshers_QuadFromMedialAxis_1D2D: public StdMeshers_Quadrangle_2D
+{
+ public:
+  StdMeshers_QuadFromMedialAxis_1D2D(int hypId, int studyId, SMESH_Gen* gen);
+  virtual ~StdMeshers_QuadFromMedialAxis_1D2D();
+
+  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);
+
+  static bool IsApplicable(const TopoDS_Shape & aShape, bool toCheckAll);
+
+  class Algo1D;
+
+ private:
+
+  bool computeQuads( SMESH_MesherHelper& theHelper,
+                     FaceQuadStruct::Ptr theQuad);
+
+  Algo1D*                   _regular1D;
+  const SMESHDS_Hypothesis* _hyp2D;
+};
+
+#endif
index 6a0e88c61d9376d97bdc1385454a11d6beb53ff4..3c3abe38574871c2401e17bfe9820f3787d71bf6 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
@@ -548,7 +548,7 @@ bool StdMeshers_QuadToTriaAdaptor::CheckIntersection (const gp_Pnt&       P,
 
   //SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
   //cout<<"    CheckIntersection: meshDS->NbFaces() = "<<meshDS->NbFaces()<<endl;
-  bool res = false;
+  bool    res = false;
   double dist = RealLast(); // find intersection closest to the segment
   gp_Pnt Pres;
 
@@ -556,9 +556,9 @@ bool StdMeshers_QuadToTriaAdaptor::CheckIntersection (const gp_Pnt&       P,
   vector< const SMDS_MeshElement* > suspectElems;
   searcher->GetElementsNearLine( line, SMDSAbs_Face, suspectElems);
 
-  for ( int i = 0; i < suspectElems.size(); ++i )
+  for ( size_t iF = 0; iF < suspectElems.size(); ++iF )
   {
-    const SMDS_MeshElement* face = suspectElems[i];
+    const SMDS_MeshElement* face = suspectElems[iF];
     if ( face == NotCheckedFace ) continue;
     Handle(TColgp_HSequenceOfPnt) aContour = new TColgp_HSequenceOfPnt;
     for ( int i = 0; i < face->NbCornerNodes(); ++i )
@@ -566,7 +566,7 @@ bool StdMeshers_QuadToTriaAdaptor::CheckIntersection (const gp_Pnt&       P,
     if( HasIntersection(P, PC, Pres, aContour) ) {
       res = true;
       double tmp = PC.Distance(Pres);
-      if(tmp<dist) {
+      if ( tmp < dist ) {
         Pint = Pres;
         dist = tmp;
       }
@@ -986,25 +986,25 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh)
       vector< const SMDS_MeshElement* > suspectElems;
       searcher->GetElementsNearLine( line, SMDSAbs_Face, suspectElems);
 
-      for ( int iF = 0; iF < suspectElems.size(); ++iF ) {
+      for ( size_t iF = 0; iF < suspectElems.size(); ++iF ) {
         const SMDS_MeshElement* F = suspectElems[iF];
-        if(F==face) continue;
+        if ( F == face ) continue;
         Handle(TColgp_HSequenceOfPnt) aContour = new TColgp_HSequenceOfPnt;
         for ( int i = 0; i < 4; ++i )
           aContour->Append( SMESH_TNodeXYZ( F->GetNode(i) ));
         gp_Pnt PPP;
-        if( !volumes[0] && HasIntersection(Ptmp1, PC, PPP, aContour) ) {
+        if ( !volumes[0] && HasIntersection( Ptmp1, PC, PPP, aContour )) {
           IsOK1 = true;
           double tmp = PC.Distance(PPP);
-          if(tmp<dist1) {
+          if ( tmp < dist1 ) {
             Pres1 = PPP;
             dist1 = tmp;
           }
         }
-        if( !volumes[1] && HasIntersection(Ptmp2, PC, PPP, aContour) ) {
+        if ( !volumes[1] && HasIntersection( Ptmp2, PC, PPP, aContour )) {
           IsOK2 = true;
           double tmp = PC.Distance(PPP);
-          if(tmp<dist2) {
+          if ( tmp < dist2 ) {
             Pres2 = PPP;
             dist2 = tmp;
           }
@@ -1044,7 +1044,7 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh)
 
     gp_XYZ PCbest(0., 0., 0.); // pyramid peak
     int i = 1;
-    for(; i<=4; i++) {
+    for ( ; i <= 4; i++ ) {
       gp_Pnt Pbest = FindBestPoint(PN->Value(i), PN->Value(i+1), PC, VN->Value(i));
       PCbest += Pbest.XYZ();
     }
@@ -1074,10 +1074,10 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh)
     vector< const SMDS_MeshElement* > suspectElems;
     searcher->GetElementsNearLine( line, SMDSAbs_Face, suspectElems);
 
-    for ( int iF = 0; iF < suspectElems.size(); ++iF )
+    for ( size_t iF = 0; iF < suspectElems.size(); ++iF )
     {
       const SMDS_MeshElement* F = suspectElems[iF];
-      if(F==face) continue;
+      if ( F == face ) continue;
       Handle(TColgp_HSequenceOfPnt) aContour = new TColgp_HSequenceOfPnt;
       int nbN = F->NbNodes() / ( F->IsQuadratic() ? 2 : 1 );
       for ( i = 0; i < nbN; ++i )
@@ -1162,7 +1162,8 @@ bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh&
     return true;
 
   SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
-  int i, j, k, myShapeID = myPyramids[0]->GetNode(4)->getshapeId();
+  size_t i, j, k;
+  int myShapeID = myPyramids[0]->GetNode(4)->getshapeId();
 
   if ( myElemSearcher ) delete myElemSearcher;
   myElemSearcher = SMESH_MeshAlgos::GetElementSearcher( *meshDS );
index 0cdb63fd14de6b8c2bcdb5986fa25e4b7c8948f7..c1082f7ce8625b481498130842aef10f03e191a1 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index 4ed750b13e96d5675c51190ed6a0c0a752906a88..708b9a2fabdf3777285dd0baf4f0da7d7afa350a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index 9dc1641f5d1d536f67f08429c745ac0e533da3b5..0881615165040ebb3eb1223ab25616d1807ff957 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index 61260eff437da70734ff77bac3c1d015a1ae9a5a..1ab6d8cbeade3204685cfe88e4281491e0e27d95 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 2657ac8aaa7db497a6f5ccf0b85d74fb5a907320..6abddcc2f5001c56e7c3dfeac8bc3d56df494431 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 4d1321497a6d08eb6ad1fe25b8c4b43227dc3647..a3bf670cbdc644d54a26b46a6a824621ec5326bd 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -132,8 +132,7 @@ bool StdMeshers_Quadrangle_2D::CheckHypothesis
   myParams               = NULL;
   myQuadList.clear();
 
-  bool isOk = true;
-  aStatus   = SMESH_Hypothesis::HYP_OK;
+  aStatus = SMESH_Hypothesis::HYP_OK;
 
   const list <const SMESHDS_Hypothesis * >& hyps =
     GetUsedHypothesis(aMesh, aShape, false);
@@ -228,6 +227,7 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh&         aMesh,
   myHelper = &helper;
 
   _quadraticMesh = myHelper->IsQuadraticSubMesh(aShape);
+  myHelper->SetElementsOnShape( true );
   myNeedSmooth = false;
   myCheckOri   = false;
 
@@ -249,7 +249,7 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh&         aMesh,
 
   enum { NOT_COMPUTED = -1, COMPUTE_FAILED = 0, COMPUTE_OK = 1 };
   int res = NOT_COMPUTED;
-  if (myQuadranglePreference)
+  if ( myQuadranglePreference )
   {
     int nfull = n1+n2+n3+n4;
     if ((nfull % 2) == 0 && ((n1 != n3) || (n2 != n4)))
@@ -258,7 +258,7 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh&         aMesh,
       res = computeQuadPref( aMesh, F, quad );
     }
   }
-  else if (myQuadType == QUAD_REDUCED)
+  else if ( myQuadType == QUAD_REDUCED )
   {
     int n13    = n1 - n3;
     int n24    = n2 - n4;
@@ -471,10 +471,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(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 = myHelper->AddFace(a, b, c, d);
-      if (face) {
-        meshDS->SetMeshElementOnShape(face, geomFaceID);
-      }
+      myHelper->AddFace(a, b, c, d);
     }
   }
 
@@ -558,8 +555,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh&         aMesh,
       }
 
       if (near == g) { // make triangle
-        SMDS_MeshFace* face = myHelper->AddFace(a, b, c);
-        if (face) meshDS->SetMeshElementOnShape(face, geomFaceID);
+        myHelper->AddFace(a, b, c);
       }
       else { // make quadrangle
         if (near - 1 < ilow)
@@ -569,8 +565,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh&         aMesh,
         //SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d);
         
         if (!myTrianglePreference){
-          SMDS_MeshFace* face = myHelper->AddFace(a, b, c, d);
-          if (face) meshDS->SetMeshElementOnShape(face, geomFaceID);
+          myHelper->AddFace(a, b, c, d);
         }
         else {
           splitQuadFace(meshDS, geomFaceID, a, b, c, d);
@@ -584,8 +579,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh&         aMesh,
               d = uv_e3[1].node;
             else
               d = quad->uv_grid[nbhoriz + k - 1].node;
-            SMDS_MeshFace* face = myHelper->AddFace(a, c, d);
-            if (face) meshDS->SetMeshElementOnShape(face, geomFaceID);
+            myHelper->AddFace(a, c, d);
           }
         }
         g = near;
@@ -609,7 +603,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh&         aMesh,
       int g = nbhoriz - 1; // last processed node in the regular grid
 
       ilow = 0;
-      iup = nbhoriz - 1;
+      iup  = nbhoriz - 1;
 
       int stop = 0;
       if ( quad->side[3].grid->Edge(0).IsNull() ) // left side is simulated one
@@ -642,14 +636,12 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh&         aMesh,
           d = quad->UVPt( g, nbvertic-2 ).node;
           if ( myTrianglePreference )
           {
-            if ( SMDS_MeshFace* face = myHelper->AddFace(a, d, c))
-              meshDS->SetMeshElementOnShape(face, geomFaceID);
+            myHelper->AddFace(a, d, c);
           }
           else
           {
             if ( SMDS_MeshFace* face = myHelper->AddFace(a, b, d, c))
             {
-              meshDS->SetMeshElementOnShape(face, geomFaceID);
               SMESH_ComputeErrorPtr& err = aMesh.GetSubMesh( aFace )->GetComputeError();
               if ( !err || err->IsOK() || err->myName < COMPERR_WARNING )
               {
@@ -667,7 +659,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh&         aMesh,
       for ( ; i > stop; i--) {
         a = uv_e2[i].node;
         b = uv_e2[i - 1].node;
-        gp_Pnt pb (b->X(), b->Y(), b->Z());
+        gp_Pnt pb = SMESH_TNodeXYZ( b );
 
         // find node c in the grid, which will be linked with node b
         int near = g;
@@ -683,7 +675,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh&         aMesh,
               nk = uv_e1[nbright - 2].node;
             else
               nk = quad->uv_grid[nbhoriz*(nbvertic - 2) + k].node;
-            gp_Pnt pnk (nk->X(), nk->Y(), nk->Z());
+            gp_Pnt pnk = SMESH_TNodeXYZ( nk );
             double dist = pb.Distance(pnk);
             if (dist < mind - eps) {
               c = nk;
@@ -696,8 +688,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh&         aMesh,
         }
 
         if (near == g) { // make triangle
-          SMDS_MeshFace* face = myHelper->AddFace(a, b, c);
-          if (face) meshDS->SetMeshElementOnShape(face, geomFaceID);
+          myHelper->AddFace(a, b, c);
         }
         else { // make quadrangle
           if (near + 1 > iup)
@@ -706,8 +697,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh&         aMesh,
             d = quad->uv_grid[nbhoriz*(nbvertic - 2) + near + 1].node;
           //SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d);
           if (!myTrianglePreference){
-            SMDS_MeshFace* face = myHelper->AddFace(a, b, c, d);
-            if (face) meshDS->SetMeshElementOnShape(face, geomFaceID);
+            myHelper->AddFace(a, b, c, d);
           }
           else {
             splitQuadFace(meshDS, geomFaceID, a, b, c, d);
@@ -720,8 +710,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh&         aMesh,
                 d = uv_e1[nbright - 2].node;
               else
                 d = quad->uv_grid[nbhoriz*(nbvertic - 2) + k + 1].node;
-              SMDS_MeshFace* face = myHelper->AddFace(a, c, d);
-              if (face) meshDS->SetMeshElementOnShape(face, geomFaceID);
+              myHelper->AddFace(a, c, d);
             }
           }
           g = near;
@@ -770,8 +759,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh&         aMesh,
       }
 
       if (near == g) { // make triangle
-        SMDS_MeshFace* face = myHelper->AddFace(a, b, c);
-        if (face) meshDS->SetMeshElementOnShape(face, geomFaceID);
+        myHelper->AddFace(a, b, c);
       }
       else { // make quadrangle
         if (near - 1 < jlow)
@@ -781,8 +769,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh&         aMesh,
         //SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d);
 
         if (!myTrianglePreference){
-          SMDS_MeshFace* face = myHelper->AddFace(a, b, c, d);
-          if (face) meshDS->SetMeshElementOnShape(face, geomFaceID);
+          myHelper->AddFace(a, b, c, d);
         }
         else {
           splitQuadFace(meshDS, geomFaceID, a, b, c, d);
@@ -795,8 +782,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh&         aMesh,
               d = uv_e0[nbdown - 2].node;
             else
               d = quad->uv_grid[nbhoriz*k - 2].node;
-            SMDS_MeshFace* face = myHelper->AddFace(a, c, d);
-            if (face) meshDS->SetMeshElementOnShape(face, geomFaceID);
+            myHelper->AddFace(a, c, d);
           }
         }
         g = near;
@@ -823,14 +809,12 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh&         aMesh,
           d = quad->UVPt( 1, g ).node;
           if ( myTrianglePreference )
           {
-            if ( SMDS_MeshFace* face = myHelper->AddFace(a, d, c))
-              meshDS->SetMeshElementOnShape(face, geomFaceID);
+            myHelper->AddFace(a, d, c);
           }
           else
           {
             if ( SMDS_MeshFace* face = myHelper->AddFace(a, b, d, c))
             {
-              meshDS->SetMeshElementOnShape(face, geomFaceID);
               SMESH_ComputeErrorPtr& err = aMesh.GetSubMesh( aFace )->GetComputeError();
               if ( !err || err->IsOK() || err->myName < COMPERR_WARNING )
               {
@@ -876,8 +860,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh&         aMesh,
         }
 
         if (near == g) { // make triangle
-          SMDS_MeshFace* face = myHelper->AddFace(a, b, c);
-          if (face) meshDS->SetMeshElementOnShape(face, geomFaceID);
+          myHelper->AddFace(a, b, c);
         }
         else { // make quadrangle
           if (near + 1 > jup)
@@ -885,8 +868,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh&         aMesh,
           else
             d = quad->uv_grid[nbhoriz*(near + 1) + 1].node;
           if (!myTrianglePreference) {
-            SMDS_MeshFace* face = myHelper->AddFace(a, b, c, d);
-            if (face) meshDS->SetMeshElementOnShape(face, geomFaceID);
+            myHelper->AddFace(a, b, c, d);
           }
           else {
             splitQuadFace(meshDS, geomFaceID, a, b, c, d);
@@ -899,8 +881,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh&         aMesh,
                 d = quad->uv_grid[nbhoriz*jup + 1].node; //uv_e2[1].node;
               else
                 d = quad->uv_grid[nbhoriz*(k + 1) + 1].node;
-              SMDS_MeshFace* face = myHelper->AddFace(a, c, d);
-              if (face) meshDS->SetMeshElementOnShape(face, geomFaceID);
+              myHelper->AddFace(a, c, d);
             }
           }
           g = near;
@@ -1453,6 +1434,8 @@ bool StdMeshers_Quadrangle_2D::setNormalizedGrid (FaceQuadStruct::Ptr quad)
 
   int nbhoriz  = Min( bSide.NbPoints(), tSide.NbPoints() );
   int nbvertic = Min( rSide.NbPoints(), lSide.NbPoints() );
+  if ( nbhoriz < 1 || nbvertic < 1 )
+    return error("Algo error: empty quad");
 
   if ( myQuadList.size() == 1 )
   {
@@ -1599,7 +1582,7 @@ void StdMeshers_Quadrangle_2D::shiftQuad(FaceQuadStruct::Ptr& quad, const int nu
 
 //================================================================================
 /*!
- * \brief Rotate sides of a quad by given nb of quartes
+ * \brief Rotate sides of a quad CCW by given nb of quartes
  *  \param nb  - number of rotation quartes
  *  \param ori - to keep orientation of sides as in an unit quad or not
  *  \param keepGrid - if \c true Side::grid is not changed, Side::from and Side::to
@@ -1611,6 +1594,8 @@ void FaceQuadStruct::shift( size_t nb, bool ori, bool keepGrid )
 {
   if ( nb == 0 ) return;
 
+  nb = nb % NB_QUAD_SIDES;
+
   vector< Side > newSides( side.size() );
   vector< Side* > sidePtrs( side.size() );
   for (int i = QUAD_BOTTOM_SIDE; i < NB_QUAD_SIDES; ++i)
@@ -1640,7 +1625,33 @@ void FaceQuadStruct::shift( size_t nb, bool ori, bool keepGrid )
   }
   newSides.swap( side );
 
-  uv_grid.clear();
+  if ( keepGrid && !uv_grid.empty() )
+  {
+    if ( nb == 2 ) // "PI"
+    {
+      std::reverse( uv_grid.begin(), uv_grid.end() );
+    }
+    else
+    {
+      FaceQuadStruct newQuad;
+      newQuad.uv_grid.resize( uv_grid.size() );
+      newQuad.iSize = jSize;
+      newQuad.jSize = iSize;
+      int i, j, iRev, jRev;
+      int *iNew = ( nb == 1 ) ? &jRev : &j;
+      int *jNew = ( nb == 1 ) ? &i : &iRev;
+      for ( i = 0, iRev = iSize-1; i < iSize; ++i, --iRev )
+        for ( j = 0, jRev = jSize-1; j < jSize; ++j, --jRev )
+          newQuad.UVPt( *iNew, *jNew ) = UVPt( i, j );
+
+      std::swap( iSize, jSize );
+      std::swap( uv_grid, newQuad.uv_grid );
+    }
+  }
+  else
+  {
+    uv_grid.clear();
+  }
 }
 
 //=======================================================================
@@ -1825,6 +1836,10 @@ bool StdMeshers_Quadrangle_2D::computeQuadPref (SMESH_Mesh &        aMesh,
         }
         sideLCb = StdMeshers_FaceSide::New( pointsLCb, aFace );
         p3dom   = pointsLCb.back();
+
+        gp_Pnt xyz = S->Value( p3dom.u, p3dom.v );
+        p3dom.node = myHelper->AddNode( xyz.X(), xyz.Y(), xyz.Z(), 0, p3dom.u, p3dom.v );
+        pointsLCb.back() = p3dom;
       }
       // Make a side separating domains L and Ct
       StdMeshers_FaceSidePtr sideLCt;
@@ -1976,6 +1991,16 @@ bool StdMeshers_Quadrangle_2D::computeQuadPref (SMESH_Mesh &        aMesh,
       sideRCb = StdMeshers_FaceSide::New( pointsRCb, aFace );
       pTBL    = pointsLCb.back();
       pTBR    = pointsRCb.back();
+      {
+        gp_Pnt xyz = S->Value( pTBL.u, pTBL.v );
+        pTBL.node = myHelper->AddNode( xyz.X(), xyz.Y(), xyz.Z(), 0, pTBL.u, pTBL.v );
+        pointsLCb.back() = pTBL;
+      }
+      {
+        gp_Pnt xyz = S->Value( pTBR.u, pTBR.v );
+        pTBR.node = myHelper->AddNode( xyz.X(), xyz.Y(), xyz.Z(), 0, pTBR.u, pTBR.v );
+        pointsRCb.back() = pTBR;
+      }
     }
     // Make sides separating domains Ct and L and R
     StdMeshers_FaceSidePtr sideLCt, sideRCt;
@@ -2179,10 +2204,8 @@ bool StdMeshers_Quadrangle_2D::computeQuadPref (SMESH_Mesh &        aMesh,
       for (i=1; i<=dl; i++) {
         for (j=1; j<nl; j++) {
           if (WisF) {
-            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);
+            myHelper->AddFace(NodesL.Value(i,j), NodesL.Value(i+1,j),
+                              NodesL.Value(i+1,j+1), NodesL.Value(i,j+1));
           }
         }
       }
@@ -2236,10 +2259,8 @@ bool StdMeshers_Quadrangle_2D::computeQuadPref (SMESH_Mesh &        aMesh,
       for (i=1; i<=dr; i++) {
         for (j=1; j<nr; j++) {
           if (WisF) {
-            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);
+            myHelper->AddFace(NodesR.Value(i,j), NodesR.Value(i+1,j),
+                              NodesR.Value(i+1,j+1), NodesR.Value(i,j+1));
           }
         }
       }
@@ -2309,10 +2330,8 @@ bool StdMeshers_Quadrangle_2D::computeQuadPref (SMESH_Mesh &        aMesh,
     for (i=1; i<nb; i++) {
       for (j=1; j<nbv; j++) {
         if (WisF) {
-          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);
+          myHelper->AddFace(NodesC.Value(i,j), NodesC.Value(i+1,j),
+                            NodesC.Value(i+1,j+1), NodesC.Value(i,j+1));
         }
       }
     }
@@ -2341,10 +2360,8 @@ bool StdMeshers_Quadrangle_2D::computeQuadPref (SMESH_Mesh &        aMesh,
     for (j=1; j<nnn-1; j++) {
       for (i=1; i<nb; i++) {
         if (WisF) {
-          SMDS_MeshFace* F =
-            myHelper->AddFace(NodesBRD.Value(i,j), NodesBRD.Value(i+1,j),
-                              NodesBRD.Value(i+1,j+1), NodesBRD.Value(i,j+1));
-          if (F) meshDS->SetMeshElementOnShape(F, geomFaceID);
+          myHelper->AddFace(NodesBRD.Value(i,j), NodesBRD.Value(i+1,j),
+                            NodesBRD.Value(i+1,j+1), NodesBRD.Value(i,j+1));
         }
       }
     }
@@ -2447,10 +2464,8 @@ bool StdMeshers_Quadrangle_2D::computeQuadPref (SMESH_Mesh &        aMesh,
       for (j=1; j<=drl+addv; j++) {
         for (i=1; i<nb; i++) {
           if (WisF) {
-            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);
+            myHelper->AddFace(NodesC.Value(i,j), NodesC.Value(i+1,j),
+                              NodesC.Value(i+1,j+1), NodesC.Value(i,j+1));
           }
         }
       } // end nr<nl
@@ -2474,10 +2489,8 @@ bool StdMeshers_Quadrangle_2D::computeQuadPref (SMESH_Mesh &        aMesh,
       }
       for (i=1; i<nt; i++) {
         if (WisF) {
-          SMDS_MeshFace* F =
-            myHelper->AddFace(NodesLast.Value(i,1), NodesLast.Value(i+1,1),
-                              NodesLast.Value(i+1,2), NodesLast.Value(i,2));
-          if (F) meshDS->SetMeshElementOnShape(F, geomFaceID);
+          myHelper->AddFace(NodesLast.Value(i,1), NodesLast.Value(i+1,1),
+                            NodesLast.Value(i+1,2), NodesLast.Value(i,2));
         }
       }
     } // if ((drl+addv) > 0)
@@ -2636,21 +2649,16 @@ void StdMeshers_Quadrangle_2D::splitQuadFace(SMESHDS_Mesh *       theMeshDS,
                                              const SMDS_MeshNode* theNode3,
                                              const SMDS_MeshNode* theNode4)
 {
-  SMDS_MeshFace* face;
   if ( SMESH_TNodeXYZ( theNode1 ).SquareDistance( theNode3 ) >
        SMESH_TNodeXYZ( theNode2 ).SquareDistance( theNode4 ) )
   {
-    face = myHelper->AddFace(theNode2, theNode4 , theNode1);
-    if (face) theMeshDS->SetMeshElementOnShape(face, theFaceID);
-    face = myHelper->AddFace(theNode2, theNode3, theNode4);
-    if (face) theMeshDS->SetMeshElementOnShape(face, theFaceID);
+    myHelper->AddFace(theNode2, theNode4 , theNode1);
+    myHelper->AddFace(theNode2, theNode3, theNode4);
   }
   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);
+    myHelper->AddFace(theNode1, theNode2 ,theNode3);
+    myHelper->AddFace(theNode1, theNode3, theNode4);
   }
 }
 
@@ -3062,10 +3070,8 @@ bool StdMeshers_Quadrangle_2D::computeReduced (SMESH_Mesh &        aMesh,
       // 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);
+          myHelper->AddFace(NodesL.Value(i,j), NodesL.Value(i+1,j),
+                            NodesL.Value(i+1,j+1), NodesL.Value(i,j+1));
         }
       }
     }
@@ -3117,10 +3123,8 @@ bool StdMeshers_Quadrangle_2D::computeReduced (SMESH_Mesh &        aMesh,
       // 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);
+          myHelper->AddFace(NodesR.Value(i,j), NodesR.Value(i+1,j),
+                            NodesR.Value(i+1,j+1), NodesR.Value(i,j+1));
         }
       }
     }
@@ -3181,10 +3185,8 @@ bool StdMeshers_Quadrangle_2D::computeReduced (SMESH_Mesh &        aMesh,
     // 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);
+        myHelper->AddFace(NodesC.Value(i,j), NodesC.Value(i+1,j),
+                          NodesC.Value(i+1,j+1), NodesC.Value(i,j+1));
       }
     }
   } // end Multiple Reduce implementation
@@ -3284,8 +3286,6 @@ bool StdMeshers_Quadrangle_2D::computeReduced (SMESH_Mesh &        aMesh,
     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 );
@@ -3847,7 +3847,7 @@ void StdMeshers_Quadrangle_2D::updateDegenUV(FaceQuadStruct::Ptr quad)
 
     // Set number of nodes on a degenerated side to be same as on an opposite side
     // ----------------------------------------------------------------------------
-    for ( unsigned i = 0; i < quad->side.size(); ++i )
+    for ( size_t i = 0; i < quad->side.size(); ++i )
     {
       StdMeshers_FaceSidePtr degSide = quad->side[i];
       if ( !myHelper->IsDegenShape( degSide->EdgeID(0) ))
@@ -3878,29 +3878,72 @@ void StdMeshers_Quadrangle_2D::smooth (FaceQuadStruct::Ptr quad)
 {
   if ( !myNeedSmooth ) return;
 
-  // Get nodes to smooth
+  SMESHDS_Mesh* meshDS = myHelper->GetMeshDS();
+  const double     tol = BRep_Tool::Tolerance( quad->face );
+  Handle(ShapeAnalysis_Surface) surface = myHelper->GetSurface( quad->face );
+
+  if ( myHelper->HasDegeneratedEdges() && myForcedPnts.empty() )
+  {
+    // "smooth" by computing node positions using 3D TFI and further projection
+
+    int nbhoriz  = quad->iSize;
+    int nbvertic = quad->jSize;
+
+    SMESH_TNodeXYZ a0( quad->UVPt( 0,         0          ).node );
+    SMESH_TNodeXYZ a1( quad->UVPt( nbhoriz-1, 0          ).node );
+    SMESH_TNodeXYZ a2( quad->UVPt( nbhoriz-1, nbvertic-1 ).node );
+    SMESH_TNodeXYZ a3( quad->UVPt( 0,         nbvertic-1 ).node );
+
+    for (int i = 1; i < nbhoriz-1; i++)
+    {
+      SMESH_TNodeXYZ p0( quad->UVPt( i, 0          ).node );
+      SMESH_TNodeXYZ p2( quad->UVPt( i, nbvertic-1 ).node );
+      for (int j = 1; j < nbvertic-1; j++)
+      {
+        SMESH_TNodeXYZ p1( quad->UVPt( nbhoriz-1, j ).node );
+        SMESH_TNodeXYZ p3( quad->UVPt( 0,         j ).node );
 
-  // TODO: do not smooth fixed nodes
+        UVPtStruct& uvp = quad->UVPt( i, j );
+
+        gp_Pnt    p = myHelper->calcTFI(uvp.x,uvp.y, a0,a1,a2,a3, p0,p1,p2,p3);
+        gp_Pnt2d uv = surface->NextValueOfUV( uvp.UV(), p, 10*tol );
+        gp_Pnt pnew = surface->Value( uv );
+
+        meshDS->MoveNode( uvp.node, pnew.X(), pnew.Y(), pnew.Z() );
+        uvp.u = uv.X();
+        uvp.v = uv.Y();
+      }
+    }
+    return;
+  }
+
+  // Get nodes to smooth
 
   typedef map< const SMDS_MeshNode*, TSmoothNode, TIDCompare > TNo2SmooNoMap;
   TNo2SmooNoMap smooNoMap;
 
-  const TopoDS_Face&  geomFace = TopoDS::Face( myHelper->GetSubShape() );
-  Handle(Geom_Surface) surface = BRep_Tool::Surface( geomFace );
-  double U1, U2, V1, V2;
-  surface->Bounds(U1, U2, V1, V2);
-  GeomAPI_ProjectPointOnSurf proj;
-  proj.Init( surface, U1, U2, V1, V2, BRep_Tool::Tolerance( geomFace ) );
-
-  SMESHDS_Mesh*        meshDS = myHelper->GetMeshDS();
-  SMESHDS_SubMesh*   fSubMesh = meshDS->MeshElements( geomFace );
-  SMDS_NodeIteratorPtr    nIt = fSubMesh->GetNodes();
+  // fixed nodes
+  set< const SMDS_MeshNode* > fixedNodes;
+  for ( size_t i = 0; i < myForcedPnts.size(); ++i )
+  {
+    fixedNodes.insert( myForcedPnts[i].node );
+    if ( myForcedPnts[i].node->getshapeId() != myHelper->GetSubShapeID() )
+    {
+      TSmoothNode & sNode = smooNoMap[ myForcedPnts[i].node ];
+      sNode._uv  = myForcedPnts[i].uv;
+      sNode._xyz = SMESH_TNodeXYZ( myForcedPnts[i].node );
+    }
+  }
+  SMESHDS_SubMesh* fSubMesh = meshDS->MeshElements( quad->face );
+  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 );
+    sNode._uv  = myHelper->GetNodeUV( quad->face, node );
     sNode._xyz = SMESH_TNodeXYZ( node );
+    if ( fixedNodes.count( node ))
+      continue; // fixed - no triangles
 
     // set sNode._triangles
     SMDS_ElemIteratorPtr fIt = node->GetInverseElementIterator( SMDSAbs_Face );
@@ -3918,16 +3961,22 @@ void StdMeshers_Quadrangle_2D::smooth (FaceQuadStruct::Ptr quad)
     }
   }
   // 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  = uvVec[j].UV();
-      sNode._xyz = SMESH_TNodeXYZ( uvVec[j].node );
-    }
-  }
+  set< StdMeshers_FaceSide* > sidesOnEdge;
+  list< FaceQuadStruct::Ptr >::iterator q = myQuadList.begin();
+  for ( ; q != myQuadList.end() ; ++q )
+    for ( size_t i = 0; i < (*q)->side.size(); ++i )
+      if ( ! (*q)->side[i].grid->Edge(0).IsNull() &&
+           //(*q)->nbNodeOut( i ) == 0 &&
+           sidesOnEdge.insert( (*q)->side[i].grid.get() ).second )
+      {
+        const vector<UVPtStruct>& uvVec = (*q)->side[i].grid->GetUVPtStruct();
+        for ( unsigned j = 0; j < uvVec.size(); ++j )
+        {
+          TSmoothNode & sNode = smooNoMap[ uvVec[j].node ];
+          sNode._uv  = uvVec[j].UV();
+          sNode._xyz = SMESH_TNodeXYZ( uvVec[j].node );
+        }
+      }
 
   // define refernce orientation in 2D
   TNo2SmooNoMap::iterator n2sn = smooNoMap.begin();
@@ -3956,22 +4005,16 @@ void StdMeshers_Quadrangle_2D::smooth (FaceQuadStruct::Ptr quad)
       {
         // compute a new XYZ
         gp_XYZ newXYZ (0,0,0);
-        for ( unsigned i = 0; i < sNode._triangles.size(); ++i )
+        for ( size_t i = 0; i < sNode._triangles.size(); ++i )
           newXYZ += sNode._triangles[i]._n1->_xyz;
         newXYZ /= sNode._triangles.size();
 
         // compute a new UV by projection
-        proj.Perform( newXYZ );
-        isValid = ( proj.IsDone() && proj.NbPoints() > 0 );
-        if ( isValid )
-        {
-          // check validity of the newUV
-          Quantity_Parameter u,v;
-          proj.LowerDistanceParameters( u, v );
-          newUV.SetCoord( u, v );
-          for ( unsigned i = 0; i < sNode._triangles.size() && isValid; ++i )
-            isValid = ( sNode._triangles[i].IsForward( newUV ) == refForward );
-        }
+        newUV = surface->NextValueOfUV( sNode._uv, newXYZ, 10*tol ).XY();
+
+        // check validity of the newUV
+        for ( size_t i = 0; i < sNode._triangles.size() && isValid; ++i )
+          isValid = ( sNode._triangles[i].IsForward( newUV ) == refForward );
       }
       if ( !isValid )
       {
@@ -3989,7 +4032,7 @@ void StdMeshers_Quadrangle_2D::smooth (FaceQuadStruct::Ptr quad)
       if ( isValid )
       {
         sNode._uv = newUV;
-        sNode._xyz = surface->Value( newUV.X(), newUV.Y() ).XYZ();
+        sNode._xyz = surface->Value( newUV ).XYZ();
       }
     }
   }
@@ -4003,7 +4046,7 @@ void StdMeshers_Quadrangle_2D::smooth (FaceQuadStruct::Ptr quad)
       continue; // not movable node
 
     SMDS_MeshNode* node = const_cast< SMDS_MeshNode*>( n2sn->first );
-    gp_Pnt xyz = surface->Value( sNode._uv.X(), sNode._uv.Y() );
+    gp_Pnt xyz = surface->Value( sNode._uv );
     meshDS->MoveNode( node, xyz.X(), xyz.Y(), xyz.Z() );
 
     // store the new UV
@@ -4023,13 +4066,13 @@ void StdMeshers_Quadrangle_2D::smooth (FaceQuadStruct::Ptr quad)
       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_XYZ pm = 0.5 * ( SMESH_TNodeXYZ( link.node1() ) + SMESH_TNodeXYZ( link.node2() ));
+      gp_XY uvm = myHelper->GetNodeUV( quad->face, node );
+
+      gp_Pnt2d uv = surface->NextValueOfUV( uvm, pm, 10*tol );
+      gp_Pnt  xyz = surface->Value( uv );
 
-      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() );
     }
   }
@@ -4130,6 +4173,7 @@ bool StdMeshers_Quadrangle_2D::check()
         if ( !myHelper->IsSeamShape( nn[i]->getshapeId() ))
           nInFace = nn[i];
 
+    toCheckUV = true;
     for ( int i = 0; i < nbN; ++i )
       uv[ i ] = myHelper->GetNodeUV( geomFace, nn[i], nInFace, &toCheckUV );
 
@@ -4174,7 +4218,7 @@ bool StdMeshers_Quadrangle_2D::check()
   return isOK;
 }
 
-/*//================================================================================
+//================================================================================
 /*!
  * \brief Finds vertices at the most sharp face corners
  *  \param [in] theFace - the FACE
@@ -4199,10 +4243,11 @@ int StdMeshers_Quadrangle_2D::getCorners(const TopoDS_Face&          theFace,
   theNbDegenEdges = 0;
 
   SMESH_MesherHelper helper( theMesh );
+  StdMeshers_FaceSide faceSide( theFace, theWire, &theMesh, /*isFwd=*/true, /*skipMedium=*/true);
 
   // sort theVertices by angle
   multimap<double, TopoDS_Vertex> vertexByAngle;
-  TopTools_DataMapOfShapeReal angleByVertex;
+  TopTools_DataMapOfShapeReal     angleByVertex;
   TopoDS_Edge prevE = theWire.back();
   if ( SMESH_Algo::isDegenerated( prevE ))
   {
@@ -4214,17 +4259,17 @@ int StdMeshers_Quadrangle_2D::getCorners(const TopoDS_Face&          theFace,
     prevE = *edge;
   }
   list<TopoDS_Edge>::iterator edge = theWire.begin();
-  for ( ; edge != theWire.end(); ++edge )
+  for ( int iE = 0; edge != theWire.end(); ++edge, ++iE )
   {
     if ( SMESH_Algo::isDegenerated( *edge ))
     {
       ++theNbDegenEdges;
       continue;
     }
-    TopoDS_Vertex v = helper.IthVertex( 0, *edge );
-    if ( !theConsiderMesh || SMESH_Algo::VertexNode( v, helper.GetMeshDS() ))
+    if ( !theConsiderMesh || faceSide.VertexNode( iE ))
     {
-      double angle = SMESH_MesherHelper::GetAngle( prevE, *edge, theFace, v );
+      TopoDS_Vertex v = helper.IthVertex( 0, *edge );
+      double    angle = helper.GetAngle( prevE, *edge, theFace, v );
       vertexByAngle.insert( make_pair( angle, v ));
       angleByVertex.Bind( v, angle );
     }
@@ -4243,6 +4288,17 @@ int StdMeshers_Quadrangle_2D::getCorners(const TopoDS_Face&          theFace,
     triaVertex.Nullify();
 
   // check nb of available corners
+  if ( faceSide.NbEdges() < nbCorners )
+    return error(COMPERR_BAD_SHAPE,
+                 TComm("Face must have 4 sides but not ") << faceSide.NbEdges() );
+
+  if ( theConsiderMesh )
+  {
+    const int nbSegments = Max( faceSide.NbPoints()-1, faceSide.NbSegments() );
+    if ( nbSegments < nbCorners )
+      return error(COMPERR_BAD_INPUT_MESH, TComm("Too few boundary nodes: ") << nbSegments);
+  }
+
   if ( nbCorners == 3 )
   {
     if ( vertexByAngle.size() < 3 )
@@ -4547,7 +4603,7 @@ int StdMeshers_Quadrangle_2D::getCorners(const TopoDS_Face&          theFace,
 //================================================================================
 
 FaceQuadStruct::Side::Side(StdMeshers_FaceSidePtr theGrid)
-  : grid(theGrid), nbNodeOut(0), from(0), to(theGrid ? theGrid->NbPoints() : 0 ), di(1)
+  : grid(theGrid), from(0), to(theGrid ? theGrid->NbPoints() : 0 ), di(1), nbNodeOut(0)
 {
 }
 
@@ -4605,49 +4661,66 @@ bool StdMeshers_Quadrangle_2D::getEnforcedUV()
   Standard_Real u1,u2,v1,v2;
   const TopoDS_Face&   face = TopoDS::Face( myHelper->GetSubShape() );
   const double          tol = BRep_Tool::Tolerance( face );
-  Handle(Geom_Surface) surf = BRep_Tool::Surface( face );
-  surf->Bounds( u1,u2,v1,v2 );
-  GeomAPI_ProjectPointOnSurf project;
-  project.Init(surf, u1,u2, v1,v2, tol );
+  Handle(ShapeAnalysis_Surface) project = myHelper->GetSurface( face );
+  project->Bounds( u1,u2,v1,v2 );
   Bnd_Box bbox;
   BRepBndLib::Add( face, bbox );
   double farTol = 0.01 * sqrt( bbox.SquareExtent() );
 
+  // get internal VERTEXes of the FACE to use them instead of equal points
+  typedef map< pair< double, double >, TopoDS_Vertex > TUV2VMap;
+  TUV2VMap uv2intV;
+  for ( TopExp_Explorer vExp( face, TopAbs_VERTEX, TopAbs_EDGE ); vExp.More(); vExp.Next() )
+  {
+    TopoDS_Vertex v = TopoDS::Vertex( vExp.Current() );
+    gp_Pnt2d     uv = project->ValueOfUV( BRep_Tool::Pnt( v ), tol );
+    uv2intV.insert( make_pair( make_pair( uv.X(), uv.Y() ), v ));
+  }
+
   for ( size_t iP = 0; iP < points.size(); ++iP )
   {
-    project.Perform( points[ iP ]);
-    if ( !project.IsDone() )
-    {
-      if ( isStrictCheck && iP < nbPoints )
-        return error
-          (TComm("Projection of an enforced point to the face failed - (")
-           << points[ iP ].X() << ", "<< points[ iP ].Y() << ", "<< points[ iP ].Z() << " )");
-      continue;
-    }
-    if ( project.LowerDistance() > farTol )
+    gp_Pnt2d uv = project->ValueOfUV( points[ iP ], tol );
+    if ( project->Gap() > farTol )
     {
       if ( isStrictCheck && iP < nbPoints )
         return error
           (COMPERR_BAD_PARMETERS, TComm("An enforced point is too far from the face, dist = ")
-           << project.LowerDistance() << " - ("
+           << points[ iP ].Distance( project->Value( uv )) << " - ("
            << points[ iP ].X() << ", "<< points[ iP ].Y() << ", "<< points[ iP ].Z() << " )");
       continue;
     }
-    Quantity_Parameter u, v;
-    project.LowerDistanceParameters(u, v);
-    gp_Pnt2d uv( u, v );
     BRepClass_FaceClassifier clsf ( face, uv, tol );
     switch ( clsf.State() ) {
     case TopAbs_IN:
     {
-      double edgeDist =  ( Min( Abs( u - u1 ), Abs( u - u2 )) +
-                           Min( Abs( v - v1 ), Abs( v - v2 )));
+      double edgeDist = ( Min( Abs( uv.X() - u1 ), Abs( uv.X() - u2 )) +
+                          Min( Abs( uv.Y() - v1 ), Abs( uv.Y() - v2 )));
       ForcedPoint fp;
       fp.uv  = uv.XY();
       fp.xyz = points[ iP ].XYZ();
       if ( iP >= nbPoints )
         fp.vertex = TopoDS::Vertex( vMap( iP - nbPoints + 1 ));
 
+      TUV2VMap::iterator uv2v = uv2intV.lower_bound( make_pair( uv.X()-tol, uv.Y()-tol ));
+      for ( ; uv2v != uv2intV.end() && uv2v->first.first <= uv.X()+tol;  ++uv2v )
+        if ( uv.SquareDistance( gp_Pnt2d( uv2v->first.first, uv2v->first.second )) < tol*tol )
+        {
+          fp.vertex = uv2v->second;
+          break;
+        }
+
+      fp.node = 0;
+      if ( myHelper->IsSubShape( fp.vertex, myHelper->GetMesh() ))
+      {
+        SMESH_subMesh* sm = myHelper->GetMesh()->GetSubMesh( fp.vertex );
+        sm->ComputeStateEngine( SMESH_subMesh::COMPUTE );
+        fp.node = SMESH_Algo::VertexNode( fp.vertex, myHelper->GetMeshDS() );
+      }
+      else
+      {
+        fp.node = myHelper->AddNode( fp.xyz.X(), fp.xyz.Y(), fp.xyz.Z(),
+                                     0, fp.uv.X(), fp.uv.Y() );
+      }
       sortedFP.insert( make_pair( edgeDist, fp ));
       break;
     }
@@ -4716,7 +4789,7 @@ bool StdMeshers_Quadrangle_2D::addEnforcedNodes()
   {
     bool isNodeEnforced = false;
 
-    // look for a quad enclosing a enforced point
+    // look for a quad enclosing an enforced point
     for ( quadIt = myQuadList.begin(); quadIt != myQuadList.end(); ++quadIt )
     {
       FaceQuadStruct::Ptr quad = *quadIt;
@@ -4771,8 +4844,9 @@ bool StdMeshers_Quadrangle_2D::addEnforcedNodes()
           }
           // make a node of a side forced
           vector<UVPtStruct>& points = (vector<UVPtStruct>&) side.GetUVPtStruct();
-          points[ sideNodeIndex ].u = myForcedPnts[ iFP ].U();
-          points[ sideNodeIndex ].v = myForcedPnts[ iFP ].V();
+          points[ sideNodeIndex ].u    = myForcedPnts[ iFP ].U();
+          points[ sideNodeIndex ].v    = myForcedPnts[ iFP ].V();
+          points[ sideNodeIndex ].node = myForcedPnts[ iFP ].node;
 
           updateSideUV( side, sideNodeIndex, quadsBySide );
 
@@ -4819,6 +4893,9 @@ bool StdMeshers_Quadrangle_2D::addEnforcedNodes()
           FaceQuadStruct::Ptr   newQuad = myQuadList.back();
           FaceQuadStruct::Side& newSide = newQuad->side[ iNewSide ];
 
+          vector<UVPtStruct>& points = (vector<UVPtStruct>&) newSide.GetUVPtStruct();
+          points[ indForced ].node = myForcedPnts[ iFP ].node;
+
           newSide.forced_nodes.insert( indForced );
           quad->side[( iNewSide+2 ) % 4 ].forced_nodes.insert( indForced );
 
@@ -4855,6 +4932,7 @@ bool StdMeshers_Quadrangle_2D::addEnforcedNodes()
                      << myForcedPnts[iFP].xyz.Y() << ", "
                      << myForcedPnts[iFP].xyz.Z() << " )");
     }
+    myNeedSmooth = true;
 
   } // loop on enforced points
 
@@ -4872,25 +4950,31 @@ bool StdMeshers_Quadrangle_2D::addEnforcedNodes()
       if ( quadVec.size() <= 1 )
         continue; // outer side
 
-      bool missedNodesOnSide = false;
       const vector<UVPtStruct>& points = side.grid->GetUVPtStruct();
       for ( size_t iC = 0; iC < side.contacts.size(); ++iC )
       {
+        if ( side.contacts[iC].point <  side.from ||
+             side.contacts[iC].point >= side.to )
+          continue;
+        if ( side.contacts[iC].other_point <  side.contacts[iC].other_side->from ||
+             side.contacts[iC].other_point >= side.contacts[iC].other_side->to )
+          continue;
         const vector<UVPtStruct>& oGrid = side.contacts[iC].other_side->grid->GetUVPtStruct();
         const UVPtStruct&         uvPt  = points[ side.contacts[iC].point ];
-        if ( side.contacts[iC].other_point >= oGrid.size()      ||
+        if ( side.contacts[iC].other_point >= oGrid .size() ||
              side.contacts[iC].point       >= points.size() )
           throw SALOME_Exception( "StdMeshers_Quadrangle_2D::addEnforcedNodes(): wrong contact" );
         if ( oGrid[ side.contacts[iC].other_point ].node )
           (( UVPtStruct& ) uvPt).node = oGrid[ side.contacts[iC].other_point ].node;
       }
+
+      bool missedNodesOnSide = false;
       for ( size_t iP = 0; iP < points.size(); ++iP )
         if ( !points[ iP ].node )
         {
           UVPtStruct& uvPnt = ( UVPtStruct& ) points[ iP ];
-          gp_Pnt P = surf->Value( uvPnt.u, uvPnt.v );
-          uvPnt.node = meshDS->AddNode(P.X(), P.Y(), P.Z());
-          meshDS->SetNodeOnFace( uvPnt.node, myHelper->GetSubShapeID(), uvPnt.u, uvPnt.v );
+          gp_Pnt          P = surf->Value( uvPnt.u, uvPnt.v );
+          uvPnt.node = myHelper->AddNode(P.X(), P.Y(), P.Z(), 0, uvPnt.u, uvPnt.v );
           missedNodesOnSide = true;
         }
       if ( missedNodesOnSide )
@@ -4950,8 +5034,10 @@ int StdMeshers_Quadrangle_2D::splitQuad(FaceQuadStruct::Ptr quad, int I, int J)
     newQuad->side[ QUAD_TOP_SIDE    ].from = iTop;
     newQuad->name = ( TComm("Right of I=") << I );
 
-    quad->side[ QUAD_BOTTOM_SIDE ].to = iBot + 1;
-    quad->side[ QUAD_TOP_SIDE    ].to = iTop + 1;
+    bool bRev = quad->side[ QUAD_BOTTOM_SIDE ].IsReversed();
+    bool tRev = quad->side[ QUAD_TOP_SIDE    ].IsReversed();
+    quad->side[ QUAD_BOTTOM_SIDE ].to = iBot + ( bRev ? -1 : +1 );
+    quad->side[ QUAD_TOP_SIDE    ].to = iTop + ( tRev ? -1 : +1 );
     quad->uv_grid.clear();
 
     return QUAD_LEFT_SIDE;
@@ -4985,8 +5071,10 @@ int StdMeshers_Quadrangle_2D::splitQuad(FaceQuadStruct::Ptr quad, int I, int J)
     //      << " L " << &quad->side[ QUAD_LEFT_SIDE ] << " "<< quad->side[ QUAD_LEFT_SIDE].NbPoints()
     //      << " R " << &quad->side[ QUAD_RIGHT_SIDE ]  << " "<< quad->side[ QUAD_RIGHT_SIDE].NbPoints()<< endl;
 
-    newQuad->side[ QUAD_RIGHT_SIDE ].to = iRgt+1;
-    newQuad->side[ QUAD_LEFT_SIDE  ].to = iLft+1;
+    bool rRev = newQuad->side[ QUAD_RIGHT_SIDE ].IsReversed();
+    bool lRev = newQuad->side[ QUAD_LEFT_SIDE  ].IsReversed();
+    newQuad->side[ QUAD_RIGHT_SIDE ].to = iRgt + ( rRev ? -1 : +1 );
+    newQuad->side[ QUAD_LEFT_SIDE  ].to = iLft + ( lRev ? -1 : +1 );
     newQuad->name = ( TComm("Below J=") << J );
 
     quad->side[ QUAD_RIGHT_SIDE ].from = iRgt;
@@ -5539,6 +5627,8 @@ void FaceQuadStruct::Side::AddContact( int ip, Side* side, int iop )
   if ( ip  >= GetUVPtStruct().size()      ||
        iop >= side->GetUVPtStruct().size() )
     throw SALOME_Exception( "FaceQuadStruct::Side::AddContact(): wrong point" );
+  if ( ip < from || ip >= to )
+    return;
   {
     contacts.resize( contacts.size() + 1 );
     Contact&    c = contacts.back();
index b17fd7fa71a52376fa2147f5e616188211064307..460a5e4ab7fbbd948b0f064face9a77f1f42be1b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -119,6 +119,8 @@ struct FaceQuadStruct
 
   FaceQuadStruct ( const TopoDS_Face& F = TopoDS_Face(), const std::string& nm="main" );
   UVPtStruct& UVPt( int i, int j ) { return uv_grid[ i + j * iSize ]; }
+  double&        U( int i, int j ) { return UVPt( i, j ).u; }
+  double&        V( int i, int j ) { return UVPt( i, j ).v; }
   void  shift    ( size_t nb, bool keepUnitOri, bool keepGrid=false );
   int & nbNodeOut( int iSide ) { return side[ iSide ].nbNodeOut; }
   bool  findCell ( const gp_XY& uv, int & i, int & j );
@@ -242,9 +244,10 @@ class STDMESHERS_EXPORT StdMeshers_Quadrangle_2D: public SMESH_2D_Algo
 
   struct ForcedPoint
   {
-    gp_XY         uv;
-    gp_XYZ        xyz;
-    TopoDS_Vertex vertex;
+    gp_XY                uv;
+    gp_XYZ               xyz;
+    TopoDS_Vertex        vertex;
+    const SMDS_MeshNode* node;
 
     double U() const { return uv.X(); }
     double V() const { return uv.Y(); }
index 5821911837e3ff7bc5f3e9d301001a57dac1b18d..5d8d7632f32e93dfde1bf527a013fb6546e4fda2 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 866b120ad4976a055bdbffc799b462f0510cd6a7..7b2d826ea90d61cebd61c1d64b752e3e7769c879 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 5ef61aab9cdfc9fb6404afb92aa86410db218f8b..9ac099c2d5796921329dfc1de0c10729e0d9914f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -598,7 +598,6 @@ bool StdMeshers_RadialPrism_3D::Evaluate(SMESH_Mesh& aMesh,
 
 bool StdMeshers_RadialPrism_3D::IsApplicable( const TopoDS_Shape & aShape, bool toCheckAll )
 {
-  bool isCurShellApp;
   int nbFoundSolids = 0;
   for (TopExp_Explorer exp( aShape, TopAbs_SOLID ); exp.More(); exp.Next(), ++nbFoundSolids )
   {
index e1b1f21f4b3b57aa01d88080249ecfa0b30bafa3..9f1ac2a103c8b2cfec5d4e16ccfaf66a3fbef616 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index cb6aa8f7fa83e2b978a51e5d1ddb72f8dedda9ea..e9aab2b2953c5c9b5c73083bb234042592aa457f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
@@ -75,10 +75,12 @@ StdMeshers_RadialQuadrangle_1D2D::StdMeshers_RadialQuadrangle_1D2D(int hypId,
 
   _compatibleHypothesis.push_back("LayerDistribution2D");
   _compatibleHypothesis.push_back("NumberOfLayers2D");
-  myNbLayerHypo = 0;
-  myDistributionHypo = 0;
   _requireDiscreteBoundary = false;
   _supportSubmeshes = true;
+  _neededLowerHyps[ 1 ] = true;  // suppress warning on hiding a global 1D algo
+
+  myNbLayerHypo      = 0;
+  myDistributionHypo = 0;
 }
 
 
@@ -278,6 +280,38 @@ namespace
     }
     return nbe;
   }
+  //================================================================================
+  /*!
+   * \brief Checks if the common vertex between LinEdge's lies inside the circle
+   *  and not outside
+   *  \param [in] CircEdge - 
+   *  \param [in] LinEdge1 - 
+   *  \param [in] LinEdge2 - 
+   *  \return bool - false if there are 3 EDGEs and the corner is outside
+   */
+  //================================================================================
+
+  bool isCornerInsideCircle(const TopoDS_Edge& CircEdge,
+                            const TopoDS_Edge& LinEdge1,
+                            const TopoDS_Edge& LinEdge2)
+  {
+    if ( !CircEdge.IsNull() &&
+         !LinEdge1.IsNull() &&
+         !LinEdge2.IsNull() )
+    {
+      Handle(Geom_Circle) aCirc = Handle(Geom_Circle)::DownCast( getCurve( CircEdge ));
+      TopoDS_Vertex aCommonV;
+      if ( !aCirc.IsNull() &&
+           TopExp::CommonVertex( LinEdge1, LinEdge2, aCommonV ))
+      {
+        gp_Pnt aCommonP = BRep_Tool::Pnt( aCommonV );
+        gp_Pnt  aCenter = aCirc->Location();
+        double     dist = aCenter.Distance( aCommonP );
+        return dist < 0.1 * aCirc->Radius();
+      }
+    }
+    return true;
+  }
 
 //================================================================================
 //================================================================================
@@ -436,7 +470,7 @@ bool StdMeshers_RadialQuadrangle_1D2D::Compute(SMESH_Mesh&         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() )
+  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)");
 
@@ -669,15 +703,17 @@ bool StdMeshers_RadialQuadrangle_1D2D::Compute(SMESH_Mesh&         aMesh,
     // 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() )
+    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 ( !isCornerInsideCircle( CircEdge, LinEdge1, LinEdge2 ))
       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))
+    if ( !GetSortedNodesOnEdge( aMesh.GetMeshDS(), CircEdge, true, theNodes ))
       return error("Circular edge is incorrectly meshed");
 
     myHelper->IsQuadraticSubMesh( aShape );
@@ -895,7 +931,6 @@ bool StdMeshers_RadialQuadrangle_1D2D::Compute(SMESH_Mesh&         aMesh,
   //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) );
@@ -913,10 +948,10 @@ bool StdMeshers_RadialQuadrangle_1D2D::Compute(SMESH_Mesh&         aMesh,
       aTrsf2d.Transforms( cx, cy );
       // set node on face
       meshDS->SetNodeOnFace( node, faceID, cx, cy );
-      tmpNodes[j-1] = node;
+      tmpNodes.push_back(node);
     }
     // create faces
-    tmpNodes[Points.Length()] = CNodes[i];
+    tmpNodes.push_back( CNodes[i] );
     // quad
     for(j=0; j<Nodes1.size()-1; j++) {
       SMDS_MeshFace* MF;
@@ -1290,18 +1325,20 @@ bool StdMeshers_RadialQuadrangle_1D2D::Evaluate(SMESH_Mesh& aMesh,
 
 //================================================================================
 /*!
- * \brief Return true if applied compute mesh on this shape
+ * \brief Return true if the algorithm can compute mesh on this shape
  */
 //================================================================================
 
 bool StdMeshers_RadialQuadrangle_1D2D::IsApplicable( const TopoDS_Shape & aShape, bool toCheckAll )
 {
   int nbFoundFaces = 0;
-  for (TopExp_Explorer exp( aShape, TopAbs_FACE ); exp.More(); exp.Next(), ++nbFoundFaces ){
+  for (TopExp_Explorer exp( aShape, TopAbs_FACE ); exp.More(); exp.Next(), ++nbFoundFaces )
+  {
     TopoDS_Edge CircEdge, LinEdge1, LinEdge2;
     int nbe = analyseFace( exp.Current(), CircEdge, LinEdge1, LinEdge2 );
     Handle(Geom_Circle) aCirc = Handle(Geom_Circle)::DownCast( getCurve( CircEdge ));
-    bool ok = ( nbe <= 3 && nbe >= 1 && !aCirc.IsNull() );
+    bool ok = ( nbe <= 3 && nbe >= 1 && !aCirc.IsNull() &&
+                isCornerInsideCircle( CircEdge, LinEdge1, LinEdge2 ));
     if( toCheckAll  && !ok ) return false;
     if( !toCheckAll && ok  ) return true;
   }
index 80f117f1494de3242778591974035abe444c3cee..9275b85f9f103ef279f29648e21595750cb8c576 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index a7e67cfeb6fc3c1e2db18cd06ef0acb49c57c714..413a9249439750c71c91cc85d961dfc3a2a1935c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -343,9 +343,9 @@ bool StdMeshers_Regular_1D::CheckHypothesis( SMESH_Mesh&         aMesh,
   return ( aStatus == SMESH_Hypothesis::HYP_OK );
 }
 
-static bool computeParamByFunc(Adaptor3d_Curve& C3d, double first, double last,
-                               double length, bool theReverse,
-                               int nbSeg, Function& func,
+static bool computeParamByFunc(Adaptor3d_Curve& C3d,
+                               double first, double last, double length,
+                               bool theReverse, int nbSeg, Function& func,
                                list<double>& theParams)
 {
   // never do this way
@@ -359,31 +359,23 @@ static bool computeParamByFunc(Adaptor3d_Curve& C3d, double first, double last,
   int nbPnt = 1 + nbSeg;
   vector<double> x(nbPnt, 0.);
 
-  if (!buildDistribution(func, 0.0, 1.0, nbSeg, x, 1E-4))
+  if ( !buildDistribution( func, 0.0, 1.0, nbSeg, x, 1E-4 ))
      return false;
 
-  MESSAGE( "Points:\n" );
-  char buf[1024];
-  for ( int i=0; i<=nbSeg; i++ )
-  {
-    sprintf(  buf, "%f\n", float(x[i] ) );
-    MESSAGE( buf );
-  }
-
-
-
   // apply parameters in range [0,1] to the space of the curve
   double prevU = first;
-  double sign = 1.;
-  if (theReverse)
+  double  sign = 1.;
+  if ( theReverse )
   {
     prevU = last;
-    sign = -1.;
+    sign  = -1.;
   }
-  for( int i = 1; i < nbSeg; i++ )
+
+  for ( int i = 1; i < nbSeg; i++ )
   {
     double curvLength = length * (x[i] - x[i-1]) * sign;
-    GCPnts_AbscissaPoint Discret( C3d, curvLength, prevU );
+    double tol         = Min( Precision::Confusion(), curvLength / 100. );
+    GCPnts_AbscissaPoint Discret( tol, C3d, curvLength, prevU );
     if ( !Discret.IsDone() )
       return false;
     double U = Discret.Parameter();
@@ -690,27 +682,30 @@ bool StdMeshers_Regular_1D::computeInternalParameters(SMESH_Mesh &     theMesh,
     if ( smDS->NbNodes() < 1 )
       return true; // 1 segment
 
-    vector< double > mainEdgeParams;
-    if ( ! SMESH_Algo::GetNodeParamOnEdge( theMesh.GetMeshDS(), mainEdge, mainEdgeParams ))
+    map< double, const SMDS_MeshNode* > mainEdgeParamsOfNodes;
+    if ( ! SMESH_Algo::GetSortedNodesOnEdge( theMesh.GetMeshDS(), mainEdge, _quadraticMesh,
+                                             mainEdgeParamsOfNodes, SMDSAbs_Edge ))
       return error("Bad node parameters on the source edge of Propagation Of Distribution");
 
-    vector< double > segLen( mainEdgeParams.size() - 1 );
+    vector< double > segLen( mainEdgeParamsOfNodes.size() - 1 );
     double totalLen = 0;
     BRepAdaptor_Curve mainEdgeCurve( mainEdge );
-    for ( size_t i = 1; i < mainEdgeParams.size(); ++i )
+    map< double, const SMDS_MeshNode* >::iterator
+      u_n2 = mainEdgeParamsOfNodes.begin(), u_n1 = u_n2++;
+    for ( size_t i = 1; i < mainEdgeParamsOfNodes.size(); ++i, ++u_n1, ++u_n2 )
     {
       segLen[ i-1 ] = GCPnts_AbscissaPoint::Length( mainEdgeCurve,
-                                                    mainEdgeParams[i-1],
-                                                    mainEdgeParams[i]);
+                                                    u_n1->first,
+                                                    u_n2->first);
       totalLen += segLen[ i-1 ];
     }
     for ( size_t i = 0; i < segLen.size(); ++i )
       segLen[ i ] *= theLength / totalLen;
 
-    size_t iSeg = theReverse ? segLen.size()-1 : 0;
-    size_t dSeg = theReverse ? -1 : +1;
+    size_t  iSeg = theReverse ? segLen.size()-1 : 0;
+    size_t  dSeg = theReverse ? -1 : +1;
     double param = theFirstU;
-    int nbParams = 0;
+    size_t nbParams = 0;
     for ( int i = 0, nb = segLen.size()-1; i < nb; ++i, iSeg += dSeg )
     {
       GCPnts_AbscissaPoint Discret( theC3d, segLen[ iSeg ], param );
@@ -968,13 +963,13 @@ bool StdMeshers_Regular_1D::computeInternalParameters(SMESH_Mesh &     theMesh,
     {
       if ( Abs( param - Un ) < 0.2 * Abs( param - theParams.back() ))
       {
-        compensateError( a1, eltSize, U1, Un, theLength, theC3d, theParams );
+        compensateError( a1, Abs(eltSize), U1, Un, theLength, theC3d, theParams );
       }
       else if ( Abs( Un - theParams.back() ) <
-                0.2 * Abs( theParams.back() - *(--theParams.rbegin())))
+                0.2 * Abs( theParams.back() - *(++theParams.rbegin())))
       {
         theParams.pop_back();
-        compensateError( a1, an, U1, Un, theLength, theC3d, theParams );
+        compensateError( a1, Abs(an), U1, Un, theLength, theC3d, theParams );
       }
     }
     if (theReverse) theParams.reverse(); // NPAL18025
@@ -985,9 +980,9 @@ bool StdMeshers_Regular_1D::computeInternalParameters(SMESH_Mesh &     theMesh,
   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++) {
+    for ( size_t i = 0; i < aPnts.size(); i++ )
+    {
       if( aPnts[i]<0.0001 || aPnts[i]>0.9999 ) continue;
       int j=1;
       bool IsExist = false;
@@ -1011,8 +1006,9 @@ bool StdMeshers_Regular_1D::computeInternalParameters(SMESH_Mesh &     theMesh,
     }
     double eltSize, segmentSize = 0.;
     double currAbscissa = 0;
-    for(i=0; i<Params.Length(); i++) {
-      int nbseg = ( i > nbsegs.size()-1 ) ? nbsegs[0] : nbsegs[i];
+    for ( int i = 0; i < Params.Length(); i++ )
+    {
+      int nbseg = ( i > (int)nbsegs.size()-1 ) ? nbsegs[0] : nbsegs[i];
       segmentSize = Params.Value(i+1)*theLength - currAbscissa;
       currAbscissa += segmentSize;
       GCPnts_AbscissaPoint APnt(theC3d, sign*segmentSize, par1);
@@ -1049,7 +1045,7 @@ bool StdMeshers_Regular_1D::computeInternalParameters(SMESH_Mesh &     theMesh,
       par1 = par2;
     }
     // add for last
-    int nbseg = ( nbsegs.size() > Params.Length() ) ? nbsegs[Params.Length()] : nbsegs[0];
+    int nbseg = ( (int)nbsegs.size() > Params.Length() ) ? nbsegs[Params.Length()] : nbsegs[0];
     segmentSize = theLength - currAbscissa;
     eltSize = segmentSize/nbseg;
     GCPnts_UniformAbscissa Discret;
@@ -1170,10 +1166,13 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t
     }
     if ( !_mainEdge.IsNull() ) {
       // take into account reversing the edge the hypothesis is propagated from
+      // (_mainEdge.Orientation() marks mutual orientation of EDGEs in propagation chain)
       reversed = ( _mainEdge.Orientation() == TopAbs_REVERSED );
-      int mainID = meshDS->ShapeToIndex(_mainEdge);
-      if ( std::find( _revEdgesIDs.begin(), _revEdgesIDs.end(), mainID) != _revEdgesIDs.end())
-        reversed = !reversed;
+      if ( !_isPropagOfDistribution ) {
+        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())
index 7db04d4afee4dc75d2449d98c1de44634ebbebba..0f270b9c8872ea324715bbf08dd327b37e810ffe 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index fe589a9dcbe94580fed3ff2abbe847286b6291fb..6a088119b25f94a429b4b0869522510102733b28 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 5a2588c4e5ab4d39dd2aeca42c7e5e500615e8d0..2e7a8bb907b430fca7ba4aab5a65c843541c6c69 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 845f7c65a3614e52d3842f56a55f1c53f5857090..9036dc18bc6965b99d2c8df29a44324f40a1a1e9 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index c863445d0afc8a6b56bef0030c71b5dd48cc7925..6fe0982c0c609c9c3ded3cd2b3f2ae1759d92a70 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 4e2db58e041fac22f6fc9fe933f773ab6c6a742c..e53ca623138910b6c0da526b8fcc4946dbb3edcc 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index a3843758ede3b56b99273e3db150b47018b80f75..580d1eeb8320cd506cd9cc2c931a6cbaec9819a6 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 7f0e4659294dff3cc151b3d0f0dc43be341da055..dffe92e9a229cae73566fe1ff030db66fcbc3e21 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -153,11 +153,11 @@ istream & StdMeshers_StartEndLength::LoadFrom(istream & load)
 
   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++) {
+    for ( size_t i = 0; i < _edgeIDs.capacity() && isOK; i++) {
       isOK = (load >> intVal);
       if ( isOK ) _edgeIDs.push_back( intVal );
     }
@@ -169,7 +169,7 @@ istream & StdMeshers_StartEndLength::LoadFrom(istream & load)
 
 //=============================================================================
 /*!
- *  
+ *
  */
 //=============================================================================
 
index 8f3274db84064c3bc802fda306ca64de030906e7..82f9096beabad1fdda30c9909bce319399983619 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 8dea8bf197d6be5e288c01f582f16bbf9da7aadd..6164ef2cf00330b8350a566dc671a4562a1e263a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index 4b708461ee04b2ef224984089c3dd5e43ed98678..91337a917aa61e4f5ebba8a3ac5c8ffbf2845562 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index 704144d7a6d3a5c74f9315050c0640226ff920a7..f19ea54b83d7a13df97d7249444ba99b2ed0dc23 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
@@ -324,6 +324,7 @@ namespace VISCOUS_3D
 
   struct _2NearEdges;
   struct _LayerEdge;
+  struct _EdgesOnShape;
   typedef map< const SMDS_MeshNode*, _LayerEdge*, TIDCompare > TNode2Edge;
 
   //--------------------------------------------------------------------------------
@@ -344,7 +345,7 @@ namespace VISCOUS_3D
     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;
+    //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;
@@ -355,14 +356,16 @@ namespace VISCOUS_3D
     _Curvature*         _curvature;
     // TODO:: detele _Curvature, _plnNorm
 
-    void SetNewLength( double len, SMESH_MesherHelper& helper );
+    void SetNewLength( double len, _EdgesOnShape& eos, SMESH_MesherHelper& helper );
     bool SetNewLength2d( Handle(Geom_Surface)& surface,
                          const TopoDS_Face&    F,
+                         _EdgesOnShape&        eos,
                          SMESH_MesherHelper&   helper );
     void SetDataByNeighbors( const SMDS_MeshNode* n1,
                              const SMDS_MeshNode* n2,
+                             const _EdgesOnShape& eos,
                              SMESH_MesherHelper&  helper);
-    void InvalidateStep( int curStep, bool restoreLength=false );
+    void InvalidateStep( int curStep, const _EdgesOnShape& eos, bool restoreLength=false );
     void ChooseSmooFunction(const set< TGeomID >& concaveVertices,
                             const TNode2Edge&     n2eMap);
     int  Smooth(const int step, const bool isConcaveFace, const bool findBest);
@@ -372,6 +375,7 @@ namespace VISCOUS_3D
     bool FindIntersection( SMESH_ElementSearcher&   searcher,
                            double &                 distance,
                            const double&            epsilon,
+                           _EdgesOnShape&           eos,
                            const SMDS_MeshElement** face = 0);
     bool SegTriaInter( const gp_Ax1&        lastSegment,
                        const SMDS_MeshNode* n0,
@@ -379,10 +383,10 @@ namespace VISCOUS_3D
                        const SMDS_MeshNode* n2,
                        double&              dist,
                        const double&        epsilon) const;
-    gp_Ax1 LastSegment(double& segLen) const;
-    gp_XY  LastUV( const TopoDS_Face& F ) const;
+    gp_Ax1 LastSegment(double& segLen, _EdgesOnShape& eos) const;
+    gp_XY  LastUV( const TopoDS_Face& F, _EdgesOnShape& eos ) const;
     bool   IsOnEdge() const { return _2neibors; }
-    gp_XYZ Copy( _LayerEdge& other, SMESH_MesherHelper& helper );
+    gp_XYZ Copy( _LayerEdge& other, _EdgesOnShape& eos, SMESH_MesherHelper& helper );
     void   SetCosin( double cosin );
     int    NbSteps() const { return _pos.size() - 1; } // nb inlation steps
 
@@ -464,30 +468,7 @@ namespace VISCOUS_3D
       std::swap( _edges[0], _edges[1] );
     }
   };
-  //--------------------------------------------------------------------------------
-  /*!
-   * \brief Convex FACE whose radius of curvature is less than the thickness of 
-   *        layers. It is used to detect distortion of prisms based on a convex
-   *        FACE and to update normals to enable further increasing the thickness
-   */
-  struct _ConvexFace
-  {
-    TopoDS_Face                     _face;
-
-    // edges whose _simplices are used to detect prism destorsion
-    vector< _LayerEdge* >           _simplexTestEdges;
 
-    // map a sub-shape to it's index in _SolidData::_endEdgeOnShape vector
-    map< TGeomID, int >             _subIdToEdgeEnd;
-
-    bool                            _normalsFixed;
-
-    bool GetCenterOfCurvature( _LayerEdge*         ledge,
-                               BRepLProp_SLProps&  surfProp,
-                               SMESH_MesherHelper& helper,
-                               gp_Pnt &            center ) const;
-    bool CheckPrisms() const;
-  };
 
   //--------------------------------------------------------------------------------
   /*!
@@ -496,7 +477,7 @@ namespace VISCOUS_3D
   struct AverageHyp
   {
     AverageHyp( const StdMeshers_ViscousLayers* hyp = 0 )
-      :_nbLayers(0), _nbHyps(0), _thickness(0), _stretchFactor(0)
+      :_nbLayers(0), _nbHyps(0), _thickness(0), _stretchFactor(0), _method(0)
     {
       Add( hyp );
     }
@@ -509,16 +490,78 @@ namespace VISCOUS_3D
         //_thickness     += hyp->GetTotalThickness();
         _thickness      = Max( _thickness, hyp->GetTotalThickness() );
         _stretchFactor += hyp->GetStretchFactor();
+        _method         = hyp->GetMethod();
       }
     }
     double GetTotalThickness() const { return _thickness; /*_nbHyps ? _thickness / _nbHyps : 0;*/ }
     double GetStretchFactor()  const { return _nbHyps ? _stretchFactor / _nbHyps : 0; }
     int    GetNumberLayers()   const { return _nbLayers; }
+    int    GetMethod()         const { return _method; }
+
+    bool   UseSurfaceNormal()  const
+    { return _method == StdMeshers_ViscousLayers::SURF_OFFSET_SMOOTH; }
+    bool   ToSmooth()          const
+    { return _method == StdMeshers_ViscousLayers::SURF_OFFSET_SMOOTH; }
+    bool   IsOffsetMethod()    const
+    { return _method == StdMeshers_ViscousLayers::FACE_OFFSET; }
+
   private:
-    int     _nbLayers, _nbHyps;
+    int     _nbLayers, _nbHyps, _method;
     double  _thickness, _stretchFactor;
   };
 
+  //--------------------------------------------------------------------------------
+  /*!
+   * \brief _LayerEdge's on a shape and other shape data
+   */
+  struct _EdgesOnShape
+  {
+    vector< _LayerEdge* > _edges;
+
+    TopoDS_Shape          _shape;
+    TGeomID               _shapeID;
+    SMESH_subMesh *       _subMesh;
+    // face or edge w/o layer along or near which _edges are inflated
+    TopoDS_Shape          _sWOL;
+    // averaged StdMeshers_ViscousLayers parameters
+    AverageHyp            _hyp;
+    bool                  _toSmooth;
+
+    vector< gp_XYZ >      _faceNormals; // if _shape is FACE
+    vector< _EdgesOnShape* > _faceEOS; // to get _faceNormals of adjacent FACEs
+
+    TopAbs_ShapeEnum ShapeType() const
+    { return _shape.IsNull() ? TopAbs_SHAPE : _shape.ShapeType(); }
+    TopAbs_ShapeEnum SWOLType() const
+    { return _sWOL.IsNull() ? TopAbs_SHAPE : _sWOL.ShapeType(); }
+    bool             GetNormal( const SMDS_MeshElement* face, gp_Vec& norm );
+  };
+
+  //--------------------------------------------------------------------------------
+  /*!
+   * \brief Convex FACE whose radius of curvature is less than the thickness of 
+   *        layers. It is used to detect distortion of prisms based on a convex
+   *        FACE and to update normals to enable further increasing the thickness
+   */
+  struct _ConvexFace
+  {
+    TopoDS_Face                     _face;
+
+    // edges whose _simplices are used to detect prism destorsion
+    vector< _LayerEdge* >           _simplexTestEdges;
+
+    // map a sub-shape to _SolidData::_edgesOnShape
+    map< TGeomID, _EdgesOnShape* >  _subIdToEOS;
+
+    bool                            _normalsFixed;
+
+    bool GetCenterOfCurvature( _LayerEdge*         ledge,
+                               BRepLProp_SLProps&  surfProp,
+                               SMESH_MesherHelper& helper,
+                               gp_Pnt &            center ) const;
+    bool CheckPrisms() const;
+  };
+
   //--------------------------------------------------------------------------------
   /*!
    * \brief Data of a SOLID
@@ -542,9 +585,8 @@ namespace VISCOUS_3D
 
     // map to find _n2eMap of another _SolidData by a shrink shape shared by two _SolidData's
     map< TGeomID, TNode2Edge* >     _s2neMap;
-    // edges of _n2eMap. We keep same data in two containers because
-    // iteration over the map is 5 times longer than over the vector
-    vector< _LayerEdge* >           _edges;
+    // _LayerEdge's with underlying shapes
+    vector< _EdgesOnShape >         _edgesOnShape;
 
     // key:   an id of shape (EDGE or VERTEX) shared by a FACE with
     //        layers and a FACE w/o layers
@@ -559,16 +601,13 @@ namespace VISCOUS_3D
     // the adjacent SOLID
     set< TGeomID >                   _noShrinkShapes;
 
+    int                              _nbShapesToSmooth;
+
     // <EDGE to smooth on> to <it's curve> -- for analytic smooth
     map< TGeomID,Handle(Geom_Curve)> _edge2curve;
 
-    // end indices in _edges of _LayerEdge on each shape, first go shapes to smooth
-    vector< int >                    _endEdgeOnShape;
-    int                              _nbShapesToSmooth;
     set< TGeomID >                   _concaveFaces;
 
-    // data of averaged StdMeshers_ViscousLayers parameters for each shape with _LayerEdge's
-    vector< AverageHyp >             _hypOnShape;
     double                           _maxThickness; // of all _hyps
     double                           _minThickness; // of all _hyps
 
@@ -580,38 +619,28 @@ namespace VISCOUS_3D
     ~_SolidData();
 
     Handle(Geom_Curve) CurveForSmooth( const TopoDS_Edge&    E,
-                                       const int             iFrom,
-                                       const int             iTo,
-                                       const TopoDS_Face&    F,
-                                       SMESH_MesherHelper&   helper,
-                                       vector<_LayerEdge* >* edges=0);
+                                       _EdgesOnShape&        eos,
+                                       SMESH_MesherHelper&   helper);
 
-    void SortOnEdge( const TopoDS_Edge&  E,
-                     const int           iFrom,
-                     const int           iTo,
-                     SMESH_MesherHelper& helper);
+    void SortOnEdge( const TopoDS_Edge&     E,
+                     vector< _LayerEdge* >& edges,
+                     SMESH_MesherHelper&    helper);
 
-    void Sort2NeiborsOnEdge( const int iFrom, const int iTo);
+    void Sort2NeiborsOnEdge( vector< _LayerEdge* >& edges );
 
     _ConvexFace* GetConvexFace( const TGeomID faceID )
     {
       map< TGeomID, _ConvexFace >::iterator id2face = _convexFaces.find( faceID );
       return id2face == _convexFaces.end() ? 0 : & id2face->second;
     }
-    void GetEdgesOnShape( size_t end, int &  iBeg, int &  iEnd )
-    {
-      iBeg = end > 0 ? _endEdgeOnShape[ end-1 ] : 0;
-      iEnd = _endEdgeOnShape[ end ];
-    }
+    _EdgesOnShape* GetShapeEdges(const TGeomID       shapeID );
+    _EdgesOnShape* GetShapeEdges(const TopoDS_Shape& shape );
+    _EdgesOnShape* GetShapeEdges(const _LayerEdge*   edge )
+    { return GetShapeEdges( edge->_nodes[0]->getshapeId() ); }
 
-    bool GetShapeEdges(const TGeomID shapeID, size_t& iEdgeEnd, int* iBeg=0, int* iEnd=0 ) const;
+    void AddShapesToSmooth( const set< _EdgesOnShape* >& shape );
 
-    void AddShapesToSmooth( const set< TGeomID >& shapeIDs );
-
-    void PrepareEdgesToSmoothOnFace( _LayerEdge**       edgeBeg,
-                                     _LayerEdge**       edgeEnd,
-                                     const TopoDS_Face& face,
-                                     bool               substituteSrcNodes );
+    void PrepareEdgesToSmoothOnFace( _EdgesOnShape* eof, bool substituteSrcNodes );
   };
   //--------------------------------------------------------------------------------
   /*!
@@ -640,7 +669,7 @@ namespace VISCOUS_3D
     bool FindNewNormal( const gp_Pnt& center, gp_XYZ& newNormal );
     void SetShapes( const TopoDS_Edge&  edge,
                     const _ConvexFace&  convFace,
-                    const _SolidData&   data,
+                    _SolidData&         data,
                     SMESH_MesherHelper& helper);
   };
   //--------------------------------------------------------------------------------
@@ -695,7 +724,8 @@ namespace VISCOUS_3D
                         const TopoDS_Shape&             hypShape,
                         set<TGeomID>&                   ignoreFaces);
     bool makeLayer(_SolidData& data);
-    bool setEdgeData(_LayerEdge& edge, const set<TGeomID>& subIds,
+    void setShapeData( _EdgesOnShape& eos, SMESH_subMesh* sm, _SolidData& data );
+    bool setEdgeData(_LayerEdge& edge, _EdgesOnShape& eos, const set<TGeomID>& subIds,
                      SMESH_MesherHelper& helper, _SolidData& data);
     gp_XYZ getFaceNormal(const SMDS_MeshNode* n,
                          const TopoDS_Face&   face,
@@ -712,12 +742,12 @@ namespace VISCOUS_3D
     bool findNeiborsOnEdge(const _LayerEdge*     edge,
                            const SMDS_MeshNode*& n1,
                            const SMDS_MeshNode*& n2,
+                           _EdgesOnShape&        eos,
                            _SolidData&           data);
     void findSimplexTestEdges( _SolidData&                    data,
                                vector< vector<_LayerEdge*> >& edgesByGeom);
     void computeGeomSize( _SolidData& data );
-    bool sortEdges( _SolidData&                    data,
-                    vector< vector<_LayerEdge*> >& edgesByGeom);
+    bool findShapesToSmooth( _SolidData& data);
     void limitStepSizeByCurvature( _SolidData&  data );
     void limitStepSize( _SolidData&             data,
                         const SMDS_MeshElement* face,
@@ -726,8 +756,7 @@ namespace VISCOUS_3D
     bool inflate(_SolidData& data);
     bool smoothAndCheck(_SolidData& data, const int nbSteps, double & distToIntersection);
     bool smoothAnalyticEdge( _SolidData&           data,
-                             const int             iFrom,
-                             const int             iTo,
+                             _EdgesOnShape&        eos,
                              Handle(Geom_Surface)& surface,
                              const TopoDS_Face&    F,
                              SMESH_MesherHelper&   helper);
@@ -737,7 +766,7 @@ namespace VISCOUS_3D
                                      int                 stepNb );
     bool refine(_SolidData& data);
     bool shrink();
-    bool prepareEdgeToShrink( _LayerEdge& edge, const TopoDS_Face& F,
+    bool prepareEdgeToShrink( _LayerEdge& edge, _EdgesOnShape& eos,
                               SMESH_MesherHelper& helper,
                               const SMESHDS_SubMesh* faceSubMesh );
     void restoreNoShrink( _LayerEdge& edge ) const;
@@ -766,13 +795,14 @@ namespace VISCOUS_3D
    */
   class _Shrinker1D
   {
+    TopoDS_Edge                   _geomEdge;
     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 AddEdge( const _LayerEdge* e, _EdgesOnShape& eos, SMESH_MesherHelper& helper );
     void Compute(bool set3D, SMESH_MesherHelper& helper);
     void RestoreParams();
     void SwapSrcTgtNodes(SMESHDS_Mesh* mesh);
@@ -815,7 +845,7 @@ namespace VISCOUS_3D
   };
   //--------------------------------------------------------------------------------
   /*!
-   * \brief Retriever of node coordinates either directly of from a surface by node UV.
+   * \brief Retriever of node coordinates either directly or from a surface by node UV.
    * \warning Location of a surface is ignored
    */
   struct _NodeCoordHelper
@@ -861,7 +891,8 @@ namespace VISCOUS_3D
 //
 StdMeshers_ViscousLayers::StdMeshers_ViscousLayers(int hypId, int studyId, SMESH_Gen* gen)
   :SMESH_Hypothesis(hypId, studyId, gen),
-   _isToIgnoreShapes(1), _nbLayers(1), _thickness(1), _stretchFactor(1)
+   _isToIgnoreShapes(1), _nbLayers(1), _thickness(1), _stretchFactor(1),
+   _method( SURF_OFFSET_SMOOTH )
 {
   _name = StdMeshers_ViscousLayers::GetHypType();
   _param_algo_dim = -3; // auxiliary hyp used by 3D algos
@@ -888,6 +919,11 @@ void StdMeshers_ViscousLayers::SetStretchFactor(double factor)
   if ( _stretchFactor != factor )
     _stretchFactor = factor, NotifySubMeshesHypothesisModification();
 } // --------------------------------------------------------------------------------
+void StdMeshers_ViscousLayers::SetMethod( ExtrusionMethod method )
+{
+  if ( _method != method )
+    _method = method, NotifySubMeshesHypothesisModification();
+} // --------------------------------------------------------------------------------
 SMESH_ProxyMesh::Ptr
 StdMeshers_ViscousLayers::Compute(SMESH_Mesh&         theMesh,
                                   const TopoDS_Shape& theShape,
@@ -941,18 +977,23 @@ std::ostream & StdMeshers_ViscousLayers::SaveTo(std::ostream & save)
   for ( size_t i = 0; i < _shapeIds.size(); ++i )
     save << " " << _shapeIds[i];
   save << " " << !_isToIgnoreShapes; // negate to keep the behavior in old studies.
+  save << " " << _method;
   return save;
 } // --------------------------------------------------------------------------------
 std::istream & StdMeshers_ViscousLayers::LoadFrom(std::istream & load)
 {
-  int nbFaces, faceID, shapeToTreat;
+  int nbFaces, faceID, shapeToTreat, method;
   load >> _nbLayers >> _thickness >> _stretchFactor >> nbFaces;
   while ( _shapeIds.size() < nbFaces && load >> faceID )
     _shapeIds.push_back( faceID );
-  if ( load >> shapeToTreat )
+  if ( load >> shapeToTreat ) {
     _isToIgnoreShapes = !shapeToTreat;
-  else
+    if ( load >> method )
+      _method = (ExtrusionMethod) method;
+  }
+  else {
     _isToIgnoreShapes = true; // old behavior
+  }
   return load;
 } // --------------------------------------------------------------------------------
 bool StdMeshers_ViscousLayers::SetParametersByMesh(const SMESH_Mesh*   theMesh,
@@ -1513,7 +1554,7 @@ SMESH_ComputeErrorPtr _ViscousBuilder::Compute(SMESH_Mesh&         theMesh,
     if ( ! makeLayer(_sdVec[i]) )
       return _error;
 
-    if ( _sdVec[i]._edges.size() == 0 )
+    if ( _sdVec[i]._n2eMap.size() == 0 )
       continue;
     
     if ( ! inflate(_sdVec[i]) )
@@ -1549,7 +1590,7 @@ SMESH_ComputeErrorPtr _ViscousBuilder::CheckHypotheses( SMESH_Mesh&         mesh
 
 
   findSolidsWithLayers();
-  bool ok = findFacesWithLayers();
+  bool ok = findFacesWithLayers( true );
 
   // remove _MeshOfSolid's of _SolidData's
   for ( size_t i = 0; i < _sdVec.size(); ++i )
@@ -1626,12 +1667,12 @@ bool _ViscousBuilder::findFacesWithLayers(const bool onlyWith)
   TopExp_Explorer exp;
   TopTools_IndexedMapOfShape solids;
 
-  // collect all faces to ignore defined by hyp
+  // collect all faces-to-ignore defined by hyp
   for ( size_t i = 0; i < _sdVec.size(); ++i )
   {
     solids.Add( _sdVec[i]._solid );
 
-    // get faces to ignore defined by each hyp
+    // get faces-to-ignore defined by each hyp
     typedef const StdMeshers_ViscousLayers* THyp;
     typedef std::pair< set<TGeomID>, THyp > TFacesOfHyp;
     list< TFacesOfHyp > ignoreFacesOfHyps;
@@ -2052,18 +2093,34 @@ bool _ViscousBuilder::makeLayer(_SolidData& data)
   TNode2Edge::iterator n2e2;
 
   // collect _LayerEdge's of shapes they are based on
+  vector< _EdgesOnShape >& edgesByGeom = data._edgesOnShape;
   const int nbShapes = getMeshDS()->MaxShapeIndex();
-  vector< vector<_LayerEdge*> > edgesByGeom( nbShapes+1 );
+  edgesByGeom.resize( nbShapes+1 );
 
+  // set data of _EdgesOnShape's
+  if ( SMESH_subMesh* sm = _mesh->GetSubMesh( data._solid ))
+  {
+    SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(/*includeSelf=*/false);
+    while ( smIt->more() )
+    {
+      sm = smIt->next();
+      if ( sm->GetSubShape().ShapeType() == TopAbs_FACE &&
+           !faceIds.count( sm->GetId() ))
+        continue;
+      setShapeData( edgesByGeom[ sm->GetId() ], sm, data );
+    }
+  }
+  // make _LayerEdge's
   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_subMesh* sm = _mesh->GetSubMesh( F );
     SMESH_ProxyMesh::SubMesh* proxySub =
       data._proxyMesh->getFaceSubM( F, /*create=*/true);
 
+    SMESHDS_SubMesh* smDS = sm->GetSubMeshDS();
+    if ( !smDS ) return error(SMESH_Comment("Not meshed face ") << *id, data._index );
+
     SMDS_ElemIteratorPtr eIt = smDS->GetElements();
     while ( eIt->more() )
     {
@@ -2103,7 +2160,7 @@ bool _ViscousBuilder::makeLayer(_SolidData& data)
           _LayerEdge* edge = new _LayerEdge();
           edge->_nodes.push_back( n );
           n2e->second = edge;
-          edgesByGeom[ shapeID ].push_back( edge );
+          edgesByGeom[ shapeID ]._edges.push_back( edge );
           const bool noShrink = data._noShrinkShapes.count( shapeID );
 
           SMESH_TNodeXYZ xyz( n );
@@ -2115,7 +2172,7 @@ bool _ViscousBuilder::makeLayer(_SolidData& data)
               (( n2e2 = (*s2ne).second->find( n )) != s2ne->second->end()     ))
           {
             _LayerEdge* foundEdge = (*n2e2).second;
-            gp_XYZ        lastPos = edge->Copy( *foundEdge, helper );
+            gp_XYZ        lastPos = edge->Copy( *foundEdge, edgesByGeom[ shapeID ], helper );
             foundEdge->_pos.push_back( lastPos );
             // location of the last node is modified and we restore it by foundEdge->_pos.back()
             const_cast< SMDS_MeshNode* >
@@ -2127,7 +2184,7 @@ bool _ViscousBuilder::makeLayer(_SolidData& data)
             {
               edge->_nodes.push_back( helper.AddNode( xyz.X(), xyz.Y(), xyz.Z() ));
             }
-            if ( !setEdgeData( *edge, subIds, helper, data ))
+            if ( !setEdgeData( *edge, edgesByGeom[ shapeID ], subIds, helper, data ))
               return false;
           }
           dumpMove(edge->_nodes.back());
@@ -2162,8 +2219,7 @@ bool _ViscousBuilder::makeLayer(_SolidData& data)
   if ( data._stepSize < 1. )
     data._epsilon *= data._stepSize;
 
-  // Put _LayerEdge's into the vector data._edges
-  if ( !sortEdges( data, edgesByGeom ))
+  if ( !findShapesToSmooth( data ))
     return false;
 
   // limit data._stepSize depending on surface curvature and fill data._convexFaces
@@ -2172,57 +2228,61 @@ bool _ViscousBuilder::makeLayer(_SolidData& data)
   // Set target nodes into _Simplex and _LayerEdge's to _2NearEdges
   TNode2Edge::iterator n2e;
   const SMDS_MeshNode* nn[2];
-  for ( size_t i = 0; i < data._edges.size(); ++i )
+  for ( size_t iS = 0; iS < data._edgesOnShape.size(); ++iS )
   {
-    _LayerEdge* edge = data._edges[i];
-    if ( edge->IsOnEdge() )
+    _EdgesOnShape& eos = data._edgesOnShape[iS];
+    vector< _LayerEdge* >& localEdges = eos._edges;
+    for ( size_t i = 0; i < localEdges.size(); ++i )
     {
-      // get neighbor nodes
-      bool hasData = ( edge->_2neibors->_edges[0] );
-      if ( hasData ) // _LayerEdge is a copy of another one
+      _LayerEdge* edge = localEdges[i];
+      if ( edge->IsOnEdge() )
       {
-        nn[0] = edge->_2neibors->srcNode(0);
-        nn[1] = edge->_2neibors->srcNode(1);
+        // get neighbor nodes
+        bool hasData = ( edge->_2neibors->_edges[0] );
+        if ( hasData ) // _LayerEdge is a copy of another one
+        {
+          nn[0] = edge->_2neibors->srcNode(0);
+          nn[1] = edge->_2neibors->srcNode(1);
+        }
+        else if ( !findNeiborsOnEdge( edge, nn[0],nn[1], eos, data ))
+        {
+          return false;
+        }
+        // set neighbor _LayerEdge's
+        for ( int j = 0; j < 2; ++j )
+        {
+          if (( n2e = data._n2eMap.find( nn[j] )) == data._n2eMap.end() )
+            return error("_LayerEdge not found by src node", data._index);
+          edge->_2neibors->_edges[j] = n2e->second;
+        }
+        if ( !hasData )
+          edge->SetDataByNeighbors( nn[0], nn[1], eos, helper );
       }
-      else if ( !findNeiborsOnEdge( edge, nn[0],nn[1], data ))
+
+      for ( size_t j = 0; j < edge->_simplices.size(); ++j )
       {
-        return false;
+        _Simplex& s = edge->_simplices[j];
+        s._nNext = data._n2eMap[ s._nNext ]->_nodes.back();
+        s._nPrev = data._n2eMap[ s._nPrev ]->_nodes.back();
       }
-      // set neighbor _LayerEdge's
-      for ( int j = 0; j < 2; ++j )
+
+      // For an _LayerEdge on a degenerated EDGE, copy some data from
+      // a corresponding _LayerEdge on a VERTEX
+      // (issue 52453, pb on a downloaded SampleCase2-Tet-netgen-mephisto.hdf)
+      if ( helper.IsDegenShape( edge->_nodes[0]->getshapeId() ))
       {
-        if (( n2e = data._n2eMap.find( nn[j] )) == data._n2eMap.end() )
-          return error("_LayerEdge not found by src node", data._index);
-        edge->_2neibors->_edges[j] = n2e->second;
+        // Generally we should not get here
+        if ( eos.ShapeType() != TopAbs_EDGE )
+          continue;
+        TopoDS_Vertex V = helper.IthVertex( 0, TopoDS::Edge( eos._shape ));
+        const SMDS_MeshNode* vN = SMESH_Algo::VertexNode( V, getMeshDS() );
+        if (( n2e = data._n2eMap.find( vN )) == data._n2eMap.end() )
+          continue;
+        const _LayerEdge* vEdge = n2e->second;
+        edge->_normal    = vEdge->_normal;
+        edge->_lenFactor = vEdge->_lenFactor;
+        edge->_cosin     = vEdge->_cosin;
       }
-      if ( !hasData )
-        edge->SetDataByNeighbors( nn[0], nn[1], helper);
-    }
-
-    for ( size_t j = 0; j < edge->_simplices.size(); ++j )
-    {
-      _Simplex& s = edge->_simplices[j];
-      s._nNext = data._n2eMap[ s._nNext ]->_nodes.back();
-      s._nPrev = data._n2eMap[ s._nPrev ]->_nodes.back();
-    }
-
-    // For an _LayerEdge on a degenerated EDGE, copy some data from
-    // a corresponding _LayerEdge on a VERTEX
-    // (issue 52453, pb on a downloaded SampleCase2-Tet-netgen-mephisto.hdf)
-    if ( helper.IsDegenShape( edge->_nodes[0]->getshapeId() ))
-    {
-      // Generally we should not get here
-      const TopoDS_Shape& E = getMeshDS()->IndexToShape( edge->_nodes[0]->getshapeId() );
-      if ( E.ShapeType() != TopAbs_EDGE )
-        continue;
-      TopoDS_Vertex V = helper.IthVertex( 0, TopoDS::Edge( E ));
-      const SMDS_MeshNode* vN = SMESH_Algo::VertexNode( V, getMeshDS() );
-      if (( n2e = data._n2eMap.find( vN )) == data._n2eMap.end() )
-        continue;
-      const _LayerEdge* vEdge = n2e->second;
-      edge->_normal    = vEdge->_normal;
-      edge->_lenFactor = vEdge->_lenFactor;
-      edge->_cosin     = vEdge->_cosin;
     }
   }
 
@@ -2231,9 +2291,8 @@ bool _ViscousBuilder::makeLayer(_SolidData& data)
   for ( ; e2c != data._edge2curve.end(); ++e2c )
     if ( !e2c->second.IsNull() )
     {
-      size_t iEdgeEnd; int iBeg, iEnd;
-      if ( data.GetShapeEdges( e2c->first, iEdgeEnd, &iBeg, &iEnd ))
-        data.Sort2NeiborsOnEdge( iBeg, iEnd );
+      if ( _EdgesOnShape* eos = data.GetShapeEdges( e2c->first ))
+        data.Sort2NeiborsOnEdge( eos->_edges );
     }
 
   dumpFunctionEnd();
@@ -2310,19 +2369,21 @@ void _ViscousBuilder::limitStepSizeByCurvature( _SolidData& data )
 
   data._convexFaces.clear();
 
-  TopExp_Explorer face( data._solid, TopAbs_FACE );
-  for ( ; face.More(); face.Next() )
+  for ( size_t iS = 0; iS < data._edgesOnShape.size(); ++iS )
   {
-    const TopoDS_Face& F = TopoDS::Face( face.Current() );
-    SMESH_subMesh *   sm = _mesh->GetSubMesh( F );
-    const TGeomID faceID = sm->GetId();
-    if ( data._ignoreFaceIds.count( faceID )) continue;
+    _EdgesOnShape& eof = data._edgesOnShape[iS];
+    if ( eof.ShapeType() != TopAbs_FACE ||
+         data._ignoreFaceIds.count( eof._shapeID ))
+      continue;
+
+    TopoDS_Face        F = TopoDS::Face( eof._shape );
+    SMESH_subMesh *   sm = eof._subMesh;
+    const TGeomID faceID = eof._shapeID;
 
     BRepAdaptor_Surface surface( F, false );
     surfProp.SetSurface( surface );
 
     bool isTooCurved = false;
-    int iBeg, iEnd;
 
     _ConvexFace cnvFace;
     const double        oriFactor = ( F.Orientation() == TopAbs_REVERSED ? +1. : -1. );
@@ -2332,19 +2393,18 @@ void _ViscousBuilder::limitStepSizeByCurvature( _SolidData& data )
       sm = smIt->next();
       const TGeomID subID = sm->GetId();
       // find _LayerEdge's of a sub-shape
-      size_t edgesEnd;
-      if ( data.GetShapeEdges( subID, edgesEnd, &iBeg, &iEnd ))
-        cnvFace._subIdToEdgeEnd.insert( make_pair( subID, edgesEnd ));
+      _EdgesOnShape* eos;
+      if (( eos = data.GetShapeEdges( subID )))
+        cnvFace._subIdToEOS.insert( make_pair( subID, eos ));
       else
         continue;
       // check concavity and curvature and limit data._stepSize
       const double minCurvature =
-        1. / ( data._hypOnShape[ edgesEnd ].GetTotalThickness() * ( 1+theThickToIntersection ));
-      int nbLEdges = iEnd - iBeg;
-      int iStep    = Max( 1, nbLEdges / nbTestPnt );
-      for ( ; iBeg < iEnd; iBeg += iStep )
+        1. / ( eos->_hyp.GetTotalThickness() * ( 1+theThickToIntersection ));
+      size_t iStep = Max( 1, eos->_edges.size() / nbTestPnt );
+      for ( size_t i = 0; i < eos->_edges.size(); i += iStep )
       {
-        gp_XY uv = helper.GetNodeUV( F, data._edges[ iBeg ]->_nodes[0] );
+        gp_XY uv = helper.GetNodeUV( F, eos->_edges[ i ]->_nodes[0] );
         surfProp.SetParameters( uv.X(), uv.Y() );
         if ( !surfProp.IsCurvatureDefined() )
           continue;
@@ -2371,15 +2431,15 @@ void _ViscousBuilder::limitStepSizeByCurvature( _SolidData& data )
 
     // Fill _ConvexFace::_simplexTestEdges. These _LayerEdge's are used to detect
     // prism distortion.
-    map< TGeomID, int >::iterator id2end = convFace._subIdToEdgeEnd.find( faceID );
-    if ( id2end != convFace._subIdToEdgeEnd.end() )
+    map< TGeomID, _EdgesOnShape* >::iterator id2eos = convFace._subIdToEOS.find( faceID );
+    if ( id2eos != convFace._subIdToEOS.end() && !id2eos->second->_edges.empty() )
     {
       // there are _LayerEdge's on the FACE it-self;
       // select _LayerEdge's near EDGEs
-      data.GetEdgesOnShape( id2end->second, iBeg, iEnd );
-      for ( ; iBeg < iEnd; ++iBeg )
+      _EdgesOnShape& eos = * id2eos->second;
+      for ( size_t i = 0; i < eos._edges.size(); ++i )
       {
-        _LayerEdge* ledge = data._edges[ iBeg ];
+        _LayerEdge* ledge = eos._edges[ i ];
         for ( size_t j = 0; j < ledge->_simplices.size(); ++j )
           if ( ledge->_simplices[j]._nNext->GetPosition()->GetDim() < 2 )
           {
@@ -2398,15 +2458,15 @@ void _ViscousBuilder::limitStepSizeByCurvature( _SolidData& data )
       set< const SMDS_MeshNode* > usedNodes;
 
       // look for _LayerEdge's with null _sWOL
-      map< TGeomID, int >::iterator id2end = convFace._subIdToEdgeEnd.begin();
-      for ( ; id2end != convFace._subIdToEdgeEnd.end(); ++id2end )
+      id2eos = convFace._subIdToEOS.begin();
+      for ( ; id2eos != convFace._subIdToEOS.end(); ++id2eos )
       {
-        data.GetEdgesOnShape( id2end->second, iBeg, iEnd );
-        if ( iBeg >= iEnd || !data._edges[ iBeg ]->_sWOL.IsNull() )
+        _EdgesOnShape& eos = * id2eos->second;
+        if ( !eos._sWOL.IsNull() )
           continue;
-        for ( ; iBeg < iEnd; ++iBeg )
+        for ( size_t i = 0; i < eos._edges.size(); ++i )
         {
-          _LayerEdge* ledge = data._edges[ iBeg ];
+          _LayerEdge* ledge = eos._edges[ i ];
           const SMDS_MeshNode* srcNode = ledge->_nodes[0];
           if ( !usedNodes.insert( srcNode ).second ) continue;
 
@@ -2425,12 +2485,11 @@ void _ViscousBuilder::limitStepSizeByCurvature( _SolidData& data )
 
 //================================================================================
 /*!
- * \brief Separate shapes (and _LayerEdge's on them) to smooth from the rest ones
+ * \brief Detect shapes (and _LayerEdge's on them) to smooth
  */
 //================================================================================
 
-bool _ViscousBuilder::sortEdges( _SolidData&                    data,
-                                 vector< vector<_LayerEdge*> >& edgesByGeom)
+bool _ViscousBuilder::findShapesToSmooth( _SolidData& data )
 {
   // define allowed thickness
   computeGeomSize( data ); // compute data._geomSize
@@ -2448,203 +2507,286 @@ bool _ViscousBuilder::sortEdges( _SolidData&                    data,
   // Find shapes needing smoothing; such a shape has _LayerEdge._normal on it's
   // boundry inclined to the shape at a sharp angle
 
-  list< TGeomID > shapesToSmooth;
+  //list< TGeomID > shapesToSmooth;
   TopTools_MapOfShape edgesOfSmooFaces;
 
   SMESH_MesherHelper helper( *_mesh );
   bool ok = true;
 
-  for ( int isEdge = 0; isEdge < 2; ++isEdge ) // loop on [ FACEs, EDGEs ]
+  vector< _EdgesOnShape >& edgesByGeom = data._edgesOnShape;
+  data._nbShapesToSmooth = 0;
+
+  for ( size_t iS = 0; iS < edgesByGeom.size(); ++iS ) // check FACEs
   {
-    const int dim = isEdge ? 1 : 2;
+    _EdgesOnShape& eos = edgesByGeom[iS];
+    eos._toSmooth = false;
+    if ( eos._edges.empty() || eos.ShapeType() != TopAbs_FACE )
+      continue;
 
-    for ( size_t iS = 0; iS < edgesByGeom.size(); ++iS )
+    TopExp_Explorer eExp( edgesByGeom[iS]._shape, TopAbs_EDGE );
+    for ( ; eExp.More() && !eos._toSmooth; eExp.Next() )
     {
-      vector<_LayerEdge*>& eS = edgesByGeom[iS];
-      if ( eS.empty() ) continue;
-      if ( eS[0]->_nodes[0]->GetPosition()->GetDim() != dim ) continue;
-
-      const TopoDS_Shape& S = getMeshDS()->IndexToShape( iS );
-      bool needSmooth = false;
-      switch ( S.ShapeType() )
+      TGeomID iE = getMeshDS()->ShapeToIndex( eExp.Current() );
+      vector<_LayerEdge*>& eE = edgesByGeom[ iE ]._edges;
+      if ( eE.empty() ) continue;
+      // TopLoc_Location loc;
+      // Handle(Geom_Surface) surface = BRep_Tool::Surface( TopoDS::Face( S ), loc );
+      // bool isPlane = GeomLib_IsPlanarSurface( surface ).IsPlanar();
+      //if ( eE[0]->_sWOL.IsNull() )
       {
-      case TopAbs_EDGE: {
-
-        const TopoDS_Edge& E = TopoDS::Edge( S );
-        if ( SMESH_Algo::isDegenerated( E ) || !edgesOfSmooFaces.Contains( E ))
-          break;
-
-        TopoDS_Face F;
-        if ( !eS[0]->_sWOL.IsNull() && eS[0]->_sWOL.ShapeType() == TopAbs_FACE )
-          F = TopoDS::Face( eS[0]->_sWOL );
-
-        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;
-          gp_Vec  eDir = getEdgeDir( TopoDS::Edge( S ), TopoDS::Vertex( vIt.Value() ));
-          double angle = eDir.Angle( eV[0]->_normal );
-          double cosin = Cos( angle );
-          double cosinAbs = Abs( cosin );
-          if ( cosinAbs > theMinSmoothCosin )
+        double faceSize;
+        for ( size_t i = 0; i < eE.size() && !eos._toSmooth; ++i )
+          if ( eE[i]->_cosin > theMinSmoothCosin )
           {
-            // always smooth analytic EDGEs
-            needSmooth = ! data.CurveForSmooth( E, 0, eS.size(), F, helper, &eS ).IsNull();
-
-            // compare tgtThick with the length of an end segment
-            SMDS_ElemIteratorPtr eIt = eV[0]->_nodes[0]->GetInverseElementIterator(SMDSAbs_Edge);
-            while ( eIt->more() && !needSmooth )
+            SMDS_ElemIteratorPtr fIt = eE[i]->_nodes[0]->GetInverseElementIterator(SMDSAbs_Face);
+            while ( fIt->more() && !eos._toSmooth )
             {
-              const SMDS_MeshElement* endSeg = eIt->next();
-              if ( endSeg->getshapeId() == iS )
-              {
-                double segLen =
-                  SMESH_TNodeXYZ( endSeg->GetNode(0) ).Distance( endSeg->GetNode(1 ));
-                needSmooth = needSmoothing( cosinAbs, tgtThick, segLen );
-              }
+              const SMDS_MeshElement* face = fIt->next();
+              if ( getDistFromEdge( face, eE[i]->_nodes[0], faceSize ))
+                eos._toSmooth = needSmoothing( eE[i]->_cosin, tgtThick, faceSize );
             }
           }
-        }
-        break;
       }
-      case TopAbs_FACE: {
+      // 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 ( size_t i = 0; i < eE.size() && !eos._toSmooth; ++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(  );
+      //     double cosin = cos( angle );
+      //     eos._toSmooth = ( cosin > theMinSmoothCosin );
+      //   }
+      // }
+    }
+    if ( eos._toSmooth )
+    {
+      for ( eExp.ReInit(); eExp.More(); eExp.Next() )
+        edgesOfSmooFaces.Add( eExp.Current() );
 
-        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;
-          // TopLoc_Location loc;
-          // Handle(Geom_Surface) surface = BRep_Tool::Surface( TopoDS::Face( S ), loc );
-          // bool isPlane = GeomLib_IsPlanarSurface( surface ).IsPlanar();
-          //if ( eE[0]->_sWOL.IsNull() )
-          {
-            double faceSize;
-            for ( size_t i = 0; i < eE.size() && !needSmooth; ++i )
-              if ( eE[i]->_cosin > theMinSmoothCosin )
-              {
-                SMDS_ElemIteratorPtr fIt = eE[i]->_nodes[0]->GetInverseElementIterator(SMDSAbs_Face);
-                while ( fIt->more() && !needSmooth )
-                {
-                  const SMDS_MeshElement* face = fIt->next();
-                  if ( getDistFromEdge( face, eE[i]->_nodes[0], faceSize ))
-                    needSmooth = needSmoothing( eE[i]->_cosin, tgtThick, faceSize );
-                }
-              }
-          }
-          // 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 ( size_t 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(  );
-          //     double cosin = cos( angle );
-          //     needSmooth = ( cosin > theMinSmoothCosin );
-          //   }
-          // }
-        }
-        if ( needSmooth )
-          for ( TopExp_Explorer eExp( S, TopAbs_EDGE ); eExp.More(); eExp.Next() )
-            edgesOfSmooFaces.Add( eExp.Current() );
+      data.PrepareEdgesToSmoothOnFace( &edgesByGeom[iS], /*substituteSrcNodes=*/false );
+    }
+    data._nbShapesToSmooth += eos._toSmooth;
 
-        break;
-      }
-      case TopAbs_VERTEX:
-        continue;
-      default:;
-      }
+  }  // check FACEs
+
+  for ( size_t iS = 0; iS < edgesByGeom.size(); ++iS ) // check EDGEs
+  {
+    _EdgesOnShape& eos = edgesByGeom[iS];
+    if ( eos._edges.empty() || eos.ShapeType() != TopAbs_EDGE ) continue;
+    if ( !eos._hyp.ToSmooth() ) continue;
+
+    const TopoDS_Edge& E = TopoDS::Edge( edgesByGeom[iS]._shape );
+    if ( SMESH_Algo::isDegenerated( E ) || !edgesOfSmooFaces.Contains( E ))
+      continue;
 
-      if ( needSmooth )
+    for ( TopoDS_Iterator vIt( E ); vIt.More() && !eos._toSmooth; vIt.Next() )
+    {
+      TGeomID iV = getMeshDS()->ShapeToIndex( vIt.Value() );
+      vector<_LayerEdge*>& eV = edgesByGeom[ iV ]._edges;
+      if ( eV.empty() ) continue;
+      gp_Vec  eDir = getEdgeDir( E, TopoDS::Vertex( vIt.Value() ));
+      double angle = eDir.Angle( eV[0]->_normal );
+      double cosin = Cos( angle );
+      double cosinAbs = Abs( cosin );
+      if ( cosinAbs > theMinSmoothCosin )
       {
-        if ( S.ShapeType() == TopAbs_EDGE ) shapesToSmooth.push_front( iS );
-        else                                shapesToSmooth.push_back ( iS );
+        // always smooth analytic EDGEs
+        eos._toSmooth = ! data.CurveForSmooth( E, eos, helper ).IsNull();
 
-        // preparation for smoothing
-        if ( S.ShapeType() == TopAbs_FACE )
+        // compare tgtThick with the length of an end segment
+        SMDS_ElemIteratorPtr eIt = eV[0]->_nodes[0]->GetInverseElementIterator(SMDSAbs_Edge);
+        while ( eIt->more() && !eos._toSmooth )
         {
-          data.PrepareEdgesToSmoothOnFace( & eS[0],
-                                           & eS[0] + eS.size(),
-                                           TopoDS::Face( S ),
-                                           /*substituteSrcNodes=*/false);
+          const SMDS_MeshElement* endSeg = eIt->next();
+          if ( endSeg->getshapeId() == iS )
+          {
+            double segLen =
+              SMESH_TNodeXYZ( endSeg->GetNode(0) ).Distance( endSeg->GetNode(1 ));
+            eos._toSmooth = needSmoothing( cosinAbs, tgtThick, segLen );
+          }
         }
       }
+    }
+    data._nbShapesToSmooth += eos._toSmooth;
 
-    } // loop on edgesByGeom
-  } //  // loop on [ FACEs, EDGEs ]
-
-  data._edges.reserve( data._n2eMap.size() );
-  data._endEdgeOnShape.clear();
-
-  // first we put _LayerEdge's on shapes to smooth
-  data._nbShapesToSmooth = 0;
-  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._endEdgeOnShape.push_back( data._edges.size() );
-    data._nbShapesToSmooth++;
-    eVec.clear();
-  }
+  } // check EDGEs
 
-  // then the rest _LayerEdge's
+  // Reset _cosin if no smooth is allowed by the user
   for ( size_t iS = 0; iS < edgesByGeom.size(); ++iS )
   {
-    vector<_LayerEdge*>& eVec = edgesByGeom[iS];
-    if ( eVec.empty() ) continue;
-    data._edges.insert( data._edges.end(), eVec.begin(), eVec.end() );
-    data._endEdgeOnShape.push_back( data._edges.size() );
-    //eVec.clear();
+    _EdgesOnShape& eos = edgesByGeom[iS];
+    if ( eos._edges.empty() ) continue;
+
+    if ( !eos._hyp.ToSmooth() )
+      for ( size_t i = 0; i < eos._edges.size(); ++i )
+        eos._edges[i]->SetCosin( 0 );
   }
 
-  // compute average StdMeshers_ViscousLayers parameters for each shape
 
-  data._hypOnShape.clear();
+  // int nbShapes = 0;
+  // for ( size_t iS = 0; iS < edgesByGeom.size(); ++iS )
+  // {
+  //   nbShapes += ( edgesByGeom[iS]._edges.size() > 0 );
+  // }
+  // data._edgesOnShape.reserve( nbShapes );
+
+  // // first we put _LayerEdge's on shapes to smooth (EGDEs go first)
+  // vector< _LayerEdge* > edges;
+  // list< TGeomID >::iterator gIt = shapesToSmooth.begin();
+  // for ( ; gIt != shapesToSmooth.end(); ++gIt )
+  // {
+  //   _EdgesOnShape& eos = edgesByGeom[ *gIt ];
+  //   if ( eos._edges.empty() ) continue;
+  //   eos._edges.swap( edges ); // avoid copying array
+  //   eos._toSmooth = true;
+  //   data._edgesOnShape.push_back( eos );
+  //   data._edgesOnShape.back()._edges.swap( edges );
+  // }
+
+  // // then the rest _LayerEdge's
+  // for ( size_t iS = 0; iS < edgesByGeom.size(); ++iS )
+  // {
+  //   _EdgesOnShape& eos = edgesByGeom[ *gIt ];
+  //   if ( eos._edges.empty() ) continue;
+  //   eos._edges.swap( edges ); // avoid copying array
+  //   eos._toSmooth = false;
+  //   data._edgesOnShape.push_back( eos );
+  //   data._edgesOnShape.back()._edges.swap( edges );
+  // }
+
+  return ok;
+}
+
+//================================================================================
+/*!
+ * \brief initialize data of _EdgesOnShape
+ */
+//================================================================================
+
+void _ViscousBuilder::setShapeData( _EdgesOnShape& eos,
+                                    SMESH_subMesh* sm,
+                                    _SolidData&    data )
+{
+  if ( !eos._shape.IsNull() ||
+       sm->GetSubShape().ShapeType() == TopAbs_WIRE )
+    return;
+
+  SMESH_MesherHelper helper( *_mesh );
+
+  eos._subMesh = sm;
+  eos._shapeID = sm->GetId();
+  eos._shape   = sm->GetSubShape();
+  if ( eos.ShapeType() == TopAbs_FACE )
+    eos._shape.Orientation( helper.GetSubShapeOri( data._solid, eos._shape ));
+  eos._toSmooth = false;
+
+  // set _SWOL
+  map< TGeomID, TopoDS_Shape >::const_iterator s2s =
+    data._shrinkShape2Shape.find( eos._shapeID );
+  if ( s2s != data._shrinkShape2Shape.end() )
+    eos._sWOL = s2s->second;
+
+  // set _hyp
   if ( data._hyps.size() == 1 )
   {
-    data._hypOnShape.resize( data._endEdgeOnShape.size(), AverageHyp( data._hyps.back() ));
+    eos._hyp = data._hyps.back();
   }
   else
   {
-    data._hypOnShape.resize( data._endEdgeOnShape.size() );
+    // compute average StdMeshers_ViscousLayers parameters
     map< TGeomID, const StdMeshers_ViscousLayers* >::iterator f2hyp;
-    for ( size_t i = 0; i < data._endEdgeOnShape.size(); ++i )
+    if ( eos.ShapeType() == TopAbs_FACE )
+    {
+      if (( f2hyp = data._face2hyp.find( eos._shapeID )) != data._face2hyp.end() )
+        eos._hyp = f2hyp->second;
+    }
+    else
     {
-      int       iEnd = data._endEdgeOnShape[i];
-      _LayerEdge* LE = data._edges[ iEnd-1 ];
-      TGeomID iShape = LE->_nodes[0]->getshapeId();
-      const TopoDS_Shape& S = getMeshDS()->IndexToShape( iShape );
-      if ( S.ShapeType() == TopAbs_FACE )
+      PShapeIteratorPtr fIt = helper.GetAncestors( eos._shape, *_mesh, TopAbs_FACE );
+      while ( const TopoDS_Shape* face = fIt->next() )
       {
-        if (( f2hyp = data._face2hyp.find( iShape )) != data._face2hyp.end() )
-        {
-          data._hypOnShape[ i ].Add( f2hyp->second );
-        }
+        TGeomID faceID = getMeshDS()->ShapeToIndex( *face );
+        if (( f2hyp = data._face2hyp.find( faceID )) != data._face2hyp.end() )
+          eos._hyp.Add( f2hyp->second );
       }
-      else
+    }
+  }
+
+  // set _faceNormals
+  if ( ! eos._hyp.UseSurfaceNormal() )
+  {
+    if ( eos.ShapeType() == TopAbs_FACE ) // get normals to elements on a FACE
+    {
+      SMESHDS_SubMesh* smDS = sm->GetSubMeshDS();
+      eos._faceNormals.resize( smDS->NbElements() );
+
+      SMDS_ElemIteratorPtr eIt = smDS->GetElements();
+      for ( int iF = 0; eIt->more(); ++iF )
       {
-        PShapeIteratorPtr fIt = SMESH_MesherHelper::GetAncestors( S, *_mesh, TopAbs_FACE );
-        while ( const TopoDS_Shape* face = fIt->next() )
-        {
-          TGeomID faceID = getMeshDS()->ShapeToIndex( *face );
-          if (( f2hyp = data._face2hyp.find( faceID )) != data._face2hyp.end() )
-          {
-            data._hypOnShape[ i ].Add( f2hyp->second );
-          }
-        }
+        const SMDS_MeshElement* face = eIt->next();
+        if ( !SMESH_MeshAlgos::FaceNormal( face, eos._faceNormals[iF], /*normalized=*/true ))
+          eos._faceNormals[iF].SetCoord( 0,0,0 );
+      }
+
+      if ( !helper.IsReversedSubMesh( TopoDS::Face( eos._shape )))
+        for ( size_t iF = 0; iF < eos._faceNormals.size(); ++iF )
+          eos._faceNormals[iF].Reverse();
+    }
+    else // find EOS of adjacent FACEs
+    {
+      PShapeIteratorPtr fIt = helper.GetAncestors( eos._shape, *_mesh, TopAbs_FACE );
+      while ( const TopoDS_Shape* face = fIt->next() )
+      {
+        TGeomID faceID = getMeshDS()->ShapeToIndex( *face );
+        eos._faceEOS.push_back( & data._edgesOnShape[ faceID ]);
+        if ( eos._faceEOS.back()->_shape.IsNull() )
+          // avoid using uninitialised _shapeID in GetNormal()
+          eos._faceEOS.back()->_shapeID = faceID;
       }
     }
   }
+}
+
+//================================================================================
+/*!
+ * \brief Returns normal of a face
+ */
+//================================================================================
+
+bool _EdgesOnShape::GetNormal( const SMDS_MeshElement* face, gp_Vec& norm )
+{
+  bool ok = false;
+  const _EdgesOnShape* eos = 0;
+
+  if ( face->getshapeId() == _shapeID )
+  {
+    eos = this;
+  }
+  else
+  {
+    for ( size_t iF = 0; iF < _faceEOS.size() && !eos; ++iF )
+      if ( face->getshapeId() == _faceEOS[ iF ]->_shapeID )
+        eos = _faceEOS[ iF ];
+  }
 
+  if (( eos ) &&
+      ( ok = ( face->getIdInShape() < eos->_faceNormals.size() )))
+  {
+    norm = eos->_faceNormals[ face->getIdInShape() ];
+  }
+  else if ( !eos )
+  {
+    debugMsg( "_EdgesOnShape::Normal() failed for face "<<face->GetID()
+              << " on _shape #" << _shapeID );
+  }
   return ok;
 }
 
+
 //================================================================================
 /*!
  * \brief Set data of _LayerEdge needed for smoothing
@@ -2653,14 +2795,12 @@ bool _ViscousBuilder::sortEdges( _SolidData&                    data,
 //================================================================================
 
 bool _ViscousBuilder::setEdgeData(_LayerEdge&         edge,
+                                  _EdgesOnShape&      eos,
                                   const set<TGeomID>& subIds,
                                   SMESH_MesherHelper& helper,
                                   _SolidData&         data)
 {
-  SMESH_MeshEditor editor(_mesh);
-
   const SMDS_MeshNode* node = edge._nodes[0]; // source node
-  const SMDS_TypeOfPosition posType = node->GetPosition()->GetTypeOfPosition();
 
   edge._len       = 0;
   edge._2neibors  = 0;
@@ -2679,18 +2819,23 @@ bool _ViscousBuilder::setEdgeData(_LayerEdge&         edge,
   gp_Vec geomNorm;
   bool normOK = true;
 
+  const bool onShrinkShape = !eos._sWOL.IsNull();
+  const bool useGeometry   = (( eos._hyp.UseSurfaceNormal() ) ||
+                              ( eos.ShapeType() != TopAbs_FACE && !onShrinkShape ));
+
   // get geom FACEs the node lies on
+  //if ( useGeometry )
   {
     set<TGeomID> faceIds;
-    if  ( posType == SMDS_TOP_FACE )
+    if  ( eos.ShapeType() == TopAbs_FACE )
     {
-      faceIds.insert( node->getshapeId() );
+      faceIds.insert( eos._shapeID );
     }
     else
     {
       SMDS_ElemIteratorPtr fIt = node->GetInverseElementIterator(SMDSAbs_Face);
       while ( fIt->more() )
-        faceIds.insert( editor.FindShape(fIt->next()));
+        faceIds.insert( fIt->next()->getshapeId() );
     }
     set<TGeomID>::iterator id = faceIds.begin();
     for ( ; id != faceIds.end(); ++id )
@@ -2704,111 +2849,133 @@ bool _ViscousBuilder::setEdgeData(_LayerEdge&         edge,
     }
   }
 
-  const TGeomID shapeInd = node->getshapeId();
-  map< TGeomID, TopoDS_Shape >::const_iterator s2s = data._shrinkShape2Shape.find( shapeInd );
-  const bool onShrinkShape ( s2s != data._shrinkShape2Shape.end() );
-
   // find _normal
-  if ( onShrinkShape ) // one of faces the node is on has no layers
-  {
-    TopoDS_Shape 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
+  if ( useGeometry )
   {
-    int nbOkNorms = 0;
-    for ( int iF = 0; iF < totalNbFaces; ++iF )
+    if ( onShrinkShape ) // one of faces the node is on has no layers
     {
-      F = TopoDS::Face( face2Norm[ iF ].first );
-      geomNorm = getFaceNormal( node, F, helper, normOK );
-      if ( !normOK ) continue;
-      nbOkNorms++;
-
-      if ( helper.GetSubShapeOri( data._solid, F ) != TopAbs_REVERSED )
-        geomNorm.Reverse();
-      face2Norm[ iF ].second = geomNorm.XYZ();
-      edge._normal += geomNorm.XYZ();
+      if ( eos.SWOLType() == TopAbs_EDGE )
+      {
+        // inflate from VERTEX along EDGE
+        edge._normal = getEdgeDir( TopoDS::Edge( eos._sWOL ), TopoDS::Vertex( eos._shape ));
+      }
+      else if ( eos.ShapeType() == TopAbs_VERTEX )
+      {
+        // inflate from VERTEX along FACE
+        edge._normal = getFaceDir( TopoDS::Face( eos._sWOL ), TopoDS::Vertex( eos._shape ),
+                                   node, helper, normOK, &edge._cosin);
+      }
+      else
+      {
+        // inflate from EDGE along FACE
+        edge._normal = getFaceDir( TopoDS::Face( eos._sWOL ), TopoDS::Edge( eos._shape ),
+                                   node, helper, normOK);
+      }
     }
-    if ( nbOkNorms == 0 )
-      return error(SMESH_Comment("Can't get normal to node ") << node->GetID(), data._index);
 
-    if ( edge._normal.Modulus() < 1e-3 && nbOkNorms > 1 )
+    // layers are on all faces of SOLID the node is on
+    else
     {
-      // opposite normals, re-get normals at shifted positions (IPAL 52426)
-      edge._normal.SetCoord( 0,0,0 );
+      int nbOkNorms = 0;
       for ( int iF = 0; iF < totalNbFaces; ++iF )
       {
-        const TopoDS_Face& F = face2Norm[iF].first;
-        geomNorm = getFaceNormal( node, F, helper, normOK, /*shiftInside=*/true );
+        F = TopoDS::Face( face2Norm[ iF ].first );
+        geomNorm = getFaceNormal( node, F, helper, normOK );
+        if ( !normOK ) continue;
+        nbOkNorms++;
+
         if ( helper.GetSubShapeOri( data._solid, F ) != TopAbs_REVERSED )
           geomNorm.Reverse();
-        if ( normOK )
-          face2Norm[ iF ].second = geomNorm.XYZ();
-        edge._normal += face2Norm[ iF ].second;
+        face2Norm[ iF ].second = geomNorm.XYZ();
+        edge._normal += geomNorm.XYZ();
       }
-    }
+      if ( nbOkNorms == 0 )
+        return error(SMESH_Comment("Can't get normal to node ") << node->GetID(), data._index);
 
-    if ( totalNbFaces < 3 )
-    {
-      //edge._normal /= totalNbFaces;
+      if ( edge._normal.Modulus() < 1e-3 && nbOkNorms > 1 )
+      {
+        // opposite normals, re-get normals at shifted positions (IPAL 52426)
+        edge._normal.SetCoord( 0,0,0 );
+        for ( int iF = 0; iF < totalNbFaces; ++iF )
+        {
+          const TopoDS_Face& F = face2Norm[iF].first;
+          geomNorm = getFaceNormal( node, F, helper, normOK, /*shiftInside=*/true );
+          if ( helper.GetSubShapeOri( data._solid, F ) != TopAbs_REVERSED )
+            geomNorm.Reverse();
+          if ( normOK )
+            face2Norm[ iF ].second = geomNorm.XYZ();
+          edge._normal += face2Norm[ iF ].second;
+        }
+      }
+
+      if ( totalNbFaces < 3 )
+      {
+        //edge._normal /= totalNbFaces;
+      }
+      else
+      {
+        edge._normal = getWeigthedNormal( node, face2Norm, totalNbFaces );
+      }
     }
-    else
+  }
+  else // !useGeometry - get _normal using surrounding mesh faces
+  {
+    set<TGeomID> faceIds;
+
+    SMDS_ElemIteratorPtr fIt = node->GetInverseElementIterator(SMDSAbs_Face);
+    while ( fIt->more() )
     {
-      edge._normal = getWeigthedNormal( node, face2Norm, totalNbFaces );
+      const SMDS_MeshElement* face = fIt->next();
+      if ( eos.GetNormal( face, geomNorm ))
+      {
+        if ( onShrinkShape && !faceIds.insert( face->getshapeId() ).second )
+          continue; // use only one mesh face on FACE
+        edge._normal += geomNorm.XYZ();
+        totalNbFaces++;
+      }
     }
   }
 
-  // set _cosin
-  switch ( posType )
+  // compute _cosin
+  //if ( eos._hyp.UseSurfaceNormal() )
   {
-  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 );
-    if ( totalNbFaces > 2 || helper.IsSeamShape( node->getshapeId() ))
-      for ( int iF = totalNbFaces-2; iF >=0; --iF )
-      {
-        F = face2Norm[ iF ].first;
-        inFaceDir = getFaceDir( F, V, node, helper, normOK );
-        if ( normOK ) {
-          double angle = inFaceDir.Angle( edge._normal );
-          edge._cosin = Max( edge._cosin, Cos( angle ));
-        }
+    switch ( eos.ShapeType() )
+    {
+    case TopAbs_FACE: {
+      edge._cosin = 0;
+      break;
+    }
+    case TopAbs_EDGE: {
+      TopoDS_Edge E    = TopoDS::Edge( eos._shape );
+      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 TopAbs_VERTEX: {
+      if ( eos.SWOLType() != TopAbs_FACE ) { // else _cosin is set by getFaceDir()
+        TopoDS_Vertex V  = TopoDS::Vertex( eos._shape );
+        gp_Vec inFaceDir = getFaceDir( F, V, node, helper, normOK );
+        double angle     = inFaceDir.Angle( edge._normal ); // [0,PI]
+        edge._cosin      = Cos( angle );
+        if ( totalNbFaces > 2 || helper.IsSeamShape( node->getshapeId() ))
+          for ( int iF = totalNbFaces-2; iF >=0; --iF )
+          {
+            F = face2Norm[ iF ].first;
+            inFaceDir = getFaceDir( F, V, node, helper, normOK=true );
+            if ( normOK ) {
+              double angle = inFaceDir.Angle( edge._normal );
+              edge._cosin = Max( 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);
+      //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();
@@ -2823,33 +2990,31 @@ bool _ViscousBuilder::setEdgeData(_LayerEdge&         edge,
   // --------------------
   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 )
+    if ( eos.SWOLType() == TopAbs_EDGE )
     {
-      double u = helper.GetNodeU( TopoDS::Edge( edge._sWOL ), node, 0, &normOK );
+      double u = helper.GetNodeU( TopoDS::Edge( eos._sWOL ), node, 0, &normOK );
       edge._pos.push_back( gp_XYZ( u, 0, 0 ));
       if ( edge._nodes.size() > 1 )
-        getMeshDS()->SetNodeOnEdge( tgtNode, TopoDS::Edge( edge._sWOL ), u );
+        getMeshDS()->SetNodeOnEdge( tgtNode, TopoDS::Edge( eos._sWOL ), u );
     }
     else // TopAbs_FACE
     {
-      gp_XY uv = helper.GetNodeUV( TopoDS::Face( edge._sWOL ), node, 0, &normOK );
+      gp_XY uv = helper.GetNodeUV( TopoDS::Face( eos._sWOL ), node, 0, &normOK );
       edge._pos.push_back( gp_XYZ( uv.X(), uv.Y(), 0));
       if ( edge._nodes.size() > 1 )
-        getMeshDS()->SetNodeOnFace( tgtNode, TopoDS::Face( edge._sWOL ), uv.X(), uv.Y() );
+        getMeshDS()->SetNodeOnFace( tgtNode, TopoDS::Face( eos._sWOL ), uv.X(), uv.Y() );
     }
   }
   else
   {
     edge._pos.push_back( SMESH_TNodeXYZ( node ));
 
-    if ( posType == SMDS_TOP_FACE )
+    if ( eos.ShapeType() == TopAbs_FACE )
     {
       _Simplex::GetSimplices( node, edge._simplices, data._ignoreFaceIds, &data );
     }
@@ -2857,14 +3022,14 @@ bool _ViscousBuilder::setEdgeData(_LayerEdge&         edge,
 
   // Set neighbour nodes for a _LayerEdge based on EDGE
 
-  if ( posType == SMDS_TOP_EDGE /*||
+  if ( eos.ShapeType() == TopAbs_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],
+    //                           edge._2neibors->_nodes[1], eos,
     //                           data))
     //   return false;
     // edge.SetDataByNeighbors( edge._2neibors->_nodes[0],
@@ -3074,74 +3239,87 @@ gp_XYZ _ViscousBuilder::getWeigthedNormal( const SMDS_MeshNode*             n,
   }
 
   // exclude equal normals
-  //int nbUniqNorms = nbFaces;
-  for ( int i = 0; i < nbFaces; ++i )
+  int nbUniqNorms = nbFaces;
+  for ( int i = 0; i < nbFaces; ++i ) {
     for ( int j = i+1; j < nbFaces; ++j )
       if ( fId2Normal[i].second.IsEqual( fId2Normal[j].second, 0.1 ))
       {
         fId2Normal[i].second.SetCoord( 0,0,0 );
-        //--nbUniqNorms;
+        --nbUniqNorms;
         break;
       }
-  //if ( nbUniqNorms < 3 )
-  {
-    for ( int i = 0; i < nbFaces; ++i )
-      resNorm += fId2Normal[i].second;
-    return resNorm;
   }
-
-  double angles[30];
   for ( int i = 0; i < nbFaces; ++i )
-  {
-    const TopoDS_Face& F = fId2Normal[i].first;
-
-    // look for two EDGEs shared by F and other FACEs within fId2Normal
-    TopoDS_Edge ee[2];
-    int nbE = 0;
-    PShapeIteratorPtr eIt = SMESH_MesherHelper::GetAncestors( V, *_mesh, TopAbs_EDGE );
-    while ( const TopoDS_Shape* E = eIt->next() )
-    {
-      if ( !SMESH_MesherHelper::IsSubShape( *E, F ))
-        continue;
-      bool isSharedEdge = false;
-      for ( int j = 0; j < nbFaces && !isSharedEdge; ++j )
-      {
-        if ( i == j ) continue;
-        const TopoDS_Shape& otherF = fId2Normal[j].first;
-        isSharedEdge = SMESH_MesherHelper::IsSubShape( *E, otherF );
-      }
-      if ( !isSharedEdge )
-        continue;
-      ee[ nbE ] = TopoDS::Edge( *E );
-      ee[ nbE ].Orientation( SMESH_MesherHelper::GetSubShapeOri( F, *E ));
-      if ( ++nbE == 2 )
-        break;
-    }
+    resNorm += fId2Normal[i].second;
 
-    // get an angle between the two EDGEs
-    angles[i] = 0;
-    if ( nbE < 1 ) continue;
-    if ( nbE == 1 )
-    {
-      ee[ 1 ] == ee[ 0 ];
-    }
-    else
+  // assure that resNorm is visible by every FACE (IPAL0052675)
+  if ( nbUniqNorms > 3 )
+  {
+    bool change = false;
+    for ( int nbAttempts = 0; nbAttempts < nbFaces; ++nbAttempts)
     {
-      if ( !V.IsSame( SMESH_MesherHelper::IthVertex( 0, ee[ 1 ] )))
-        std::swap( ee[0], ee[1] );
+      for ( int i = 0; i < nbFaces; ++i )
+        if ( resNorm * fId2Normal[i].second < 0.5 )
+        {
+          resNorm += fId2Normal[i].second;
+          change = true;
+        }
+      if ( !change ) break;
     }
-    angles[i] = SMESH_MesherHelper::GetAngle( ee[0], ee[1], F, TopoDS::Vertex( V ));
   }
 
-  // compute a weighted normal
-  double sumAngle = 0;
-  for ( int i = 0; i < nbFaces; ++i )
-  {
-    angles[i] = ( angles[i] > 2*M_PI )  ?  0  :  M_PI - angles[i];
-    sumAngle += angles[i];
-  }
-  for ( int i = 0; i < nbFaces; ++i )
-    resNorm += angles[i] / sumAngle * fId2Normal[i].second;
+  // double angles[30];
+  // for ( int i = 0; i < nbFaces; ++i )
+  // {
+  //   const TopoDS_Face& F = fId2Normal[i].first;
+
+  //   // look for two EDGEs shared by F and other FACEs within fId2Normal
+  //   TopoDS_Edge ee[2];
+  //   int nbE = 0;
+  //   PShapeIteratorPtr eIt = SMESH_MesherHelper::GetAncestors( V, *_mesh, TopAbs_EDGE );
+  //   while ( const TopoDS_Shape* E = eIt->next() )
+  //   {
+  //     if ( !SMESH_MesherHelper::IsSubShape( *E, F ))
+  //       continue;
+  //     bool isSharedEdge = false;
+  //     for ( int j = 0; j < nbFaces && !isSharedEdge; ++j )
+  //     {
+  //       if ( i == j ) continue;
+  //       const TopoDS_Shape& otherF = fId2Normal[j].first;
+  //       isSharedEdge = SMESH_MesherHelper::IsSubShape( *E, otherF );
+  //     }
+  //     if ( !isSharedEdge )
+  //       continue;
+  //     ee[ nbE ] = TopoDS::Edge( *E );
+  //     ee[ nbE ].Orientation( SMESH_MesherHelper::GetSubShapeOri( F, *E ));
+  //     if ( ++nbE == 2 )
+  //       break;
+  //   }
+
+  //   // get an angle between the two EDGEs
+  //   angles[i] = 0;
+  //   if ( nbE < 1 ) continue;
+  //   if ( nbE == 1 )
+  //   {
+  //     ee[ 1 ] == ee[ 0 ];
+  //   }
+  //   else
+  //   {
+  //     if ( !V.IsSame( SMESH_MesherHelper::IthVertex( 0, ee[ 1 ] )))
+  //       std::swap( ee[0], ee[1] );
+  //   }
+  //   angles[i] = SMESH_MesherHelper::GetAngle( ee[0], ee[1], F, TopoDS::Vertex( V ));
+  // }
+
+  // // compute a weighted normal
+  // double sumAngle = 0;
+  // for ( int i = 0; i < nbFaces; ++i )
+  // {
+  //   angles[i] = ( angles[i] > 2*M_PI )  ?  0  :  M_PI - angles[i];
+  //   sumAngle += angles[i];
+  // }
+  // for ( int i = 0; i < nbFaces; ++i )
+  //   resNorm += angles[i] / sumAngle * fId2Normal[i].second;
 
   return resNorm;
 }
@@ -3155,14 +3333,15 @@ gp_XYZ _ViscousBuilder::getWeigthedNormal( const SMDS_MeshNode*             n,
 bool _ViscousBuilder::findNeiborsOnEdge(const _LayerEdge*     edge,
                                         const SMDS_MeshNode*& n1,
                                         const SMDS_MeshNode*& n2,
+                                        _EdgesOnShape&        eos,
                                         _SolidData&           data)
 {
   const SMDS_MeshNode* node = edge->_nodes[0];
-  const int        shapeInd = node->getshapeId();
+  const int        shapeInd = eos._shapeID;
   SMESHDS_SubMesh*   edgeSM = 0;
-  if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_EDGE )
+  if ( eos.ShapeType() == TopAbs_EDGE )
   {
-    edgeSM = getMeshDS()->MeshElements( shapeInd );
+    edgeSM = eos._subMesh->GetSubMeshDS();
     if ( !edgeSM || edgeSM->NbElements() == 0 )
       return error(SMESH_Comment("Not meshed EDGE ") << shapeInd, data._index);
   }
@@ -3180,8 +3359,8 @@ bool _ViscousBuilder::findNeiborsOnEdge(const _LayerEdge*     edge,
     }
     else
     {
-      TopoDS_Shape s = SMESH_MesherHelper::GetSubShapeByNode(nNeibor, getMeshDS() );
-      if ( !SMESH_MesherHelper::IsSubShape( s, edge->_sWOL )) continue;
+      TopoDS_Shape s = SMESH_MesherHelper::GetSubShapeByNode( nNeibor, getMeshDS() );
+      if ( !SMESH_MesherHelper::IsSubShape( s, eos._sWOL )) continue;
     }
     ( iN++ ? n2 : n1 ) = nNeibor;
   }
@@ -3198,9 +3377,10 @@ bool _ViscousBuilder::findNeiborsOnEdge(const _LayerEdge*     edge,
 
 void _LayerEdge::SetDataByNeighbors( const SMDS_MeshNode* n1,
                                      const SMDS_MeshNode* n2,
+                                     const _EdgesOnShape& eos,
                                      SMESH_MesherHelper&  helper)
 {
-  if ( _nodes[0]->GetPosition()->GetTypeOfPosition() != SMDS_TOP_EDGE )
+  if ( eos.ShapeType() != TopAbs_EDGE )
     return;
 
   gp_XYZ pos = SMESH_TNodeXYZ( _nodes[0] );
@@ -3224,10 +3404,9 @@ void _LayerEdge::SetDataByNeighbors( const SMDS_MeshNode* n1,
 
   // Set _plnNorm
 
-  if ( _sWOL.IsNull() )
+  if ( eos._sWOL.IsNull() )
   {
-    TopoDS_Shape S = helper.GetSubShapeByNode( _nodes[0], helper.GetMeshDS() );
-    TopoDS_Edge  E = TopoDS::Edge( S );
+    TopoDS_Edge  E = TopoDS::Edge( eos._shape );
     // if ( SMESH_Algo::isDegenerated( E ))
     //   return;
     gp_XYZ dirE    = getEdgeDir( E, _nodes[0], helper );
@@ -3249,33 +3428,34 @@ void _LayerEdge::SetDataByNeighbors( const SMDS_MeshNode* n1,
  */
 //================================================================================
 
-gp_XYZ _LayerEdge::Copy( _LayerEdge& other, SMESH_MesherHelper& helper )
+gp_XYZ _LayerEdge::Copy( _LayerEdge&         other,
+                         _EdgesOnShape&      eos,
+                         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 );
 
   gp_XYZ lastPos( 0,0,0 );
-  if ( _sWOL.ShapeType() == TopAbs_EDGE )
+  if ( eos.SWOLType() == TopAbs_EDGE )
   {
-    double u = helper.GetNodeU( TopoDS::Edge( _sWOL ), _nodes[0] );
+    double u = helper.GetNodeU( TopoDS::Edge( eos._sWOL ), _nodes[0] );
     _pos.push_back( gp_XYZ( u, 0, 0));
 
-    u = helper.GetNodeU( TopoDS::Edge( _sWOL ), _nodes.back() );
+    u = helper.GetNodeU( TopoDS::Edge( eos._sWOL ), _nodes.back() );
     lastPos.SetX( u );
   }
   else // TopAbs_FACE
   {
-    gp_XY uv = helper.GetNodeUV( TopoDS::Face( _sWOL ), _nodes[0]);
+    gp_XY uv = helper.GetNodeUV( TopoDS::Face( eos._sWOL ), _nodes[0]);
     _pos.push_back( gp_XYZ( uv.X(), uv.Y(), 0));
 
-    uv = helper.GetNodeUV( TopoDS::Face( _sWOL ), _nodes.back() );
+    uv = helper.GetNodeUV( TopoDS::Face( eos._sWOL ), _nodes.back() );
     lastPos.SetX( uv.X() );
     lastPos.SetY( uv.Y() );
   }
@@ -3364,12 +3544,13 @@ void _ViscousBuilder::makeGroupOfLE()
 #ifdef _DEBUG_
   for ( size_t i = 0 ; i < _sdVec.size(); ++i )
   {
-    if ( _sdVec[i]._edges.empty() ) continue;
+    if ( _sdVec[i]._n2eMap.empty() ) continue;
 
     dumpFunction( SMESH_Comment("make_LayerEdge_") << i );
-    for ( size_t j = 0 ; j < _sdVec[i]._edges.size(); ++j )
+    TNode2Edge::iterator n2e;
+    for ( n2e = _sdVec[i]._n2eMap.begin(); n2e != _sdVec[i]._n2eMap.end(); ++n2e )
     {
-      _LayerEdge* le = _sdVec[i]._edges[j];
+      _LayerEdge* le = n2e->second;
       for ( size_t iN = 1; iN < le->_nodes.size(); ++iN )
         dumpCmd(SMESH_Comment("mesh.AddEdge([ ") <<le->_nodes[iN-1]->GetID()
                 << ", " << le->_nodes[iN]->GetID() <<"])");
@@ -3377,12 +3558,12 @@ void _ViscousBuilder::makeGroupOfLE()
     dumpFunctionEnd();
 
     dumpFunction( SMESH_Comment("makeNormals") << i );
-    for ( size_t j = 0 ; j < _sdVec[i]._edges.size(); ++j )
+    for ( n2e = _sdVec[i]._n2eMap.begin(); n2e != _sdVec[i]._n2eMap.end(); ++n2e )
     {
-      _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()
+      _LayerEdge* edge = n2e->second;
+      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();
@@ -3429,14 +3610,17 @@ void _ViscousBuilder::computeGeomSize( _SolidData& data )
     ( SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(),
                                            data._proxyMesh->GetFaces( data._solid )) );
 
-  TNode2Edge::iterator n2e = data._n2eMap.begin(), n2eEnd = data._n2eMap.end();
-  for ( ; n2e != n2eEnd; ++n2e )
+  for ( size_t iS = 0; iS < data._edgesOnShape.size(); ++iS )
   {
-    _LayerEdge* edge = n2e->second;
-    if ( edge->IsOnEdge() ) continue;
-    edge->FindIntersection( *searcher, intersecDist, data._epsilon );
-    if ( data._geomSize > intersecDist && intersecDist > 0 )
-      data._geomSize = intersecDist;
+    _EdgesOnShape& eos = data._edgesOnShape[ iS ];
+    if ( eos._edges.empty() || eos.ShapeType() == TopAbs_EDGE )
+      continue;
+    for ( size_t i = 0; i < eos._edges.size(); ++i )
+    {
+      eos._edges[i]->FindIntersection( *searcher, intersecDist, data._epsilon, eos );
+      if ( data._geomSize > intersecDist && intersecDist > 0 )
+        data._geomSize = intersecDist;
+    }
   }
 }
 
@@ -3468,7 +3652,6 @@ bool _ViscousBuilder::inflate(_SolidData& data)
 
   double avgThick = 0, curThick = 0, distToIntersection = Precision::Infinite();
   int nbSteps = 0, nbRepeats = 0;
-  int iBeg, iEnd, iS;
   while ( avgThick < 0.99 )
   {
     // new target length
@@ -3481,12 +3664,15 @@ bool _ViscousBuilder::inflate(_SolidData& data)
 
     // Elongate _LayerEdge's
     dumpFunction(SMESH_Comment("inflate")<<data._index<<"_step"<<nbSteps); // debug
-    for ( iBeg = 0, iS = 0; iS < data._endEdgeOnShape.size(); ++iS )
+    for ( size_t iS = 0; iS < data._edgesOnShape.size(); ++iS )
     {
-      const double shapeCurThick = Min( curThick, data._hypOnShape[ iS ].GetTotalThickness() );
-      for ( iEnd = data._endEdgeOnShape[ iS ]; iBeg < iEnd; ++iBeg )
+      _EdgesOnShape& eos = data._edgesOnShape[iS];
+      if ( eos._edges.empty() ) continue;
+
+      const double shapeCurThick = Min( curThick, eos._hyp.GetTotalThickness() );
+      for ( size_t i = 0; i < eos._edges.size(); ++i )
       {
-        data._edges[iBeg]->SetNewLength( shapeCurThick, helper );
+        eos._edges[i]->SetNewLength( shapeCurThick, eos, helper );
       }
     }
     dumpFunctionEnd();
@@ -3504,9 +3690,11 @@ bool _ViscousBuilder::inflate(_SolidData& data)
         return error("Smoothing failed", data._index);
 #endif
         dumpFunction(SMESH_Comment("invalidate")<<data._index<<"_step"<<nbSteps); // debug
-        for ( size_t i = 0; i < data._edges.size(); ++i )
+        for ( size_t iS = 0; iS < data._edgesOnShape.size(); ++iS )
         {
-          data._edges[i]->InvalidateStep( nbSteps+1 );
+          _EdgesOnShape& eos = data._edgesOnShape[iS];
+          for ( size_t i = 0; i < eos._edges.size(); ++i )
+            eos._edges[i]->InvalidateStep( nbSteps+1, eos );
         }
         dumpFunctionEnd();
       }
@@ -3516,15 +3704,18 @@ bool _ViscousBuilder::inflate(_SolidData& data)
 
     // Evaluate achieved thickness
     avgThick = 0;
-    for ( iBeg = 0, iS = 0; iS < data._endEdgeOnShape.size(); ++iS )
+    for ( size_t iS = 0; iS < data._edgesOnShape.size(); ++iS )
     {
-      const double shapeTgtThick = data._hypOnShape[ iS ].GetTotalThickness();
-      for ( iEnd = data._endEdgeOnShape[ iS ]; iBeg < iEnd; ++iBeg )
+      _EdgesOnShape& eos = data._edgesOnShape[iS];
+      if ( eos._edges.empty() ) continue;
+
+      const double shapeTgtThick = eos._hyp.GetTotalThickness();
+      for ( size_t i = 0; i < eos._edges.size(); ++i )
       {
-        avgThick += Min( 1., data._edges[iBeg]->_len / shapeTgtThick );
+        avgThick += Min( 1., eos._edges[i]->_len / shapeTgtThick );
       }
     }
-    avgThick /= data._edges.size();
+    avgThick /= data._n2eMap.size();
     debugMsg( "-- Thickness " << curThick << " ("<< avgThick*100 << "%) reached" );
 
     if ( distToIntersection < tgtThick * avgThick * safeFactor && avgThick < 0.9 )
@@ -3559,14 +3750,13 @@ bool _ViscousBuilder::inflate(_SolidData& data)
 
   // Restore position of src nodes moved by infaltion on _noShrinkShapes
   dumpFunction(SMESH_Comment("restoNoShrink_So")<<data._index); // debug
-  for ( iEnd = iS = 0; iS < data._endEdgeOnShape.size(); ++iS )
+  for ( size_t iS = 0; iS < data._edgesOnShape.size(); ++iS )
   {
-    iBeg = iEnd;
-    iEnd = data._endEdgeOnShape[ iS ];
-    if ( data._edges[ iBeg ]->_nodes.size() == 1 )
-      for ( ; iBeg < iEnd; ++iBeg )
+    _EdgesOnShape& eos = data._edgesOnShape[iS];
+    if ( !eos._edges.empty() && eos._edges[0]->_nodes.size() == 1 )
+      for ( size_t i = 0; i < eos._edges.size(); ++i )
       {
-        restoreNoShrink( *data._edges[ iBeg ] );
+        restoreNoShrink( *eos._edges[ i ] );
       }
   }
   dumpFunctionEnd();
@@ -3594,136 +3784,153 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data,
   Handle(Geom_Surface) surface;
   TopoDS_Face F;
 
-  int iBeg, iEnd = 0;
-  for ( int iS = 0; iS < data._nbShapesToSmooth; ++iS )
+  for ( int isFace = 0; isFace < 2; ++isFace ) // smooth on [ EDGEs, FACEs ]
   {
-    iBeg = iEnd;
-    iEnd = data._endEdgeOnShape[ iS ];
+    const TopAbs_ShapeEnum shapeType = isFace ? TopAbs_FACE : TopAbs_EDGE;
 
-    // need to smooth this shape?
-    bool toSmooth = ( data._hyps.front() == data._hyps.back() );
-    for ( int i = iBeg; i < iEnd && !toSmooth; ++i )
-      toSmooth = ( data._edges[ iBeg ]->NbSteps() >= nbSteps+1 );
-    if ( !toSmooth )
-    {
-      if ( iS+1 == data._nbShapesToSmooth )
-        data._nbShapesToSmooth--;
-      continue; // target length reached some steps before
-    }
-
-    // prepare data
-    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
+    for ( int iS = 0; iS < data._edgesOnShape.size(); ++iS )
     {
-      F.Nullify(); surface.Nullify();
-    }
-    const TGeomID sInd = data._edges[ iBeg ]->_nodes[0]->getshapeId();
+      _EdgesOnShape& eos = data._edgesOnShape[ iS ];
+      if ( !eos._toSmooth ||
+           eos.ShapeType() != shapeType ||
+           eos._edges.empty() )
+        continue;
 
-    // perform smoothing
+      // already smoothed?
+      bool toSmooth = ( eos._edges[ 0 ]->NbSteps() >= nbSteps+1 );
+      if ( !toSmooth ) continue;
 
-    if ( data._edges[ iBeg ]->IsOnEdge() )
-    { 
-      dumpFunction(SMESH_Comment("smooth")<<data._index << "_Ed"<<sInd <<"_InfStep"<<nbSteps);
+      if ( !eos._hyp.ToSmooth() )
+      {
+        // smooth disabled by the user; check validy only
+        if ( !isFace ) continue;
+        double vol;
+        for ( size_t i = 0; i < eos._edges.size(); ++i )
+        {
+          _LayerEdge* edge = eos._edges[i];
+          const gp_XYZ& curPos (  );
+          for ( size_t iF = 0; iF < edge->_simplices.size(); ++iF )
+            if ( !edge->_simplices[iF].IsForward( edge->_nodes[0],
+                                                 &edge->_pos.back(), vol ))
+              return false;
+        }
+        continue; // goto to the next EDGE or FACE
+      }
 
-      // try a simple solution on an analytic EDGE
-      if ( !smoothAnalyticEdge( data, iBeg, iEnd, surface, F, helper ))
+      // prepare data
+      if ( eos.SWOLType() == TopAbs_FACE )
       {
-        // 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);
+        if ( !F.IsSame( eos._sWOL )) {
+          F = TopoDS::Face( eos._sWOL );
+          helper.SetSubShape( F );
+          surface = BRep_Tool::Surface( F );
         }
-        while ( moved && step++ < 5 );
       }
-      dumpFunctionEnd();
-    }
-    else
-    {
-      // smooth on FACE's
+      else
+      {
+        F.Nullify(); surface.Nullify();
+      }
+      const TGeomID sInd = eos._shapeID;
 
-      const bool isConcaveFace = data._concaveFaces.count( sInd );
+      // perform smoothing
 
-      int step = 0, stepLimit = 5, badNb = 0;
-      while (( ++step <= stepLimit ) || improved )
+      if ( eos.ShapeType() == TopAbs_EDGE )
       {
-        dumpFunction(SMESH_Comment("smooth")<<data._index<<"_Fa"<<sInd
-                     <<"_InfStep"<<nbSteps<<"_"<<step); // debug
-        int oldBadNb = badNb;
-        badSmooEdges.clear();
+        dumpFunction(SMESH_Comment("smooth")<<data._index << "_Ed"<<sInd <<"_InfStep"<<nbSteps);
 
-        if ( step % 2 ) {
-          for ( int i = iBeg; i < iEnd; ++i ) // iterate forward
-            if ( data._edges[i]->Smooth( step, isConcaveFace, false ))
-              badSmooEdges.push_back( data._edges[i] );
-        }
-        else {
-          for ( int i = iEnd-1; i >= iBeg; --i ) // iterate backward
-            if ( data._edges[i]->Smooth( step, isConcaveFace, false ))
-              badSmooEdges.push_back( data._edges[i] );
-        }
-        badNb = badSmooEdges.size();
-        improved = ( badNb < oldBadNb );
-
-        if ( !badSmooEdges.empty() && step >= stepLimit / 2 )
+        // try a simple solution on an analytic EDGE
+        if ( !smoothAnalyticEdge( data, eos, surface, F, helper ))
         {
-          // look for the best smooth of _LayerEdge's neighboring badSmooEdges
-          vector<_Simplex> simplices;
-          for ( size_t i = 0; i < badSmooEdges.size(); ++i )
-          {
-            _LayerEdge* ledge = badSmooEdges[i];
-            _Simplex::GetSimplices( ledge->_nodes[0], simplices, data._ignoreFaceIds );
-            for ( size_t iS = 0; iS < simplices.size(); ++iS )
+          // smooth on EDGE's
+          int step = 0;
+          do {
+            moved = false;
+            for ( size_t i = 0; i < eos._edges.size(); ++i )
             {
-              TNode2Edge::iterator n2e = data._n2eMap.find( simplices[iS]._nNext );
-              if ( n2e != data._n2eMap.end()) {
-                _LayerEdge* ledge2 = n2e->second;
-                if ( ledge2->_nodes[0]->getshapeId() == sInd )
-                  ledge2->Smooth( step, isConcaveFace, /*findBest=*/true );
-              }
+              moved |= eos._edges[i]->SmoothOnEdge( surface, F, helper );
             }
+            dumpCmd( SMESH_Comment("# end step ")<<step);
           }
+          while ( moved && step++ < 5 );
         }
-        // issue 22576 -- no bad faces but still there are intersections to fix
-        // if ( improved && badNb == 0 )
-        //   stepLimit = step + 3;
-
         dumpFunctionEnd();
       }
-      if ( badNb > 0 )
+      else
       {
-#ifdef __myDEBUG
-        double vol = 0;
-        for ( int i = iBeg; i < iEnd; ++i )
+        // smooth on FACE's
+
+        const bool isConcaveFace = data._concaveFaces.count( sInd );
+
+        int step = 0, stepLimit = 5, badNb = 0;
+        while (( ++step <= stepLimit ) || improved )
         {
-          _LayerEdge* edge = data._edges[i];
-          SMESH_TNodeXYZ tgtXYZ( edge->_nodes.back() );
-          for ( size_t j = 0; j < edge->_simplices.size(); ++j )
-            if ( !edge->_simplices[j].IsForward( edge->_nodes[0], &tgtXYZ, vol ))
+          dumpFunction(SMESH_Comment("smooth")<<data._index<<"_Fa"<<sInd
+                       <<"_InfStep"<<nbSteps<<"_"<<step); // debug
+          int oldBadNb = badNb;
+          badSmooEdges.clear();
+
+          if ( step % 2 ) {
+            for ( size_t i = 0; i < eos._edges.size(); ++i )  // iterate forward
+              if ( eos._edges[i]->Smooth( step, isConcaveFace, false ))
+                badSmooEdges.push_back( eos._edges[i] );
+          }
+
+          else {
+            for ( int i = eos._edges.size()-1; i >= 0; --i ) // iterate backward
+              if ( eos._edges[i]->Smooth( step, isConcaveFace, false ))
+                badSmooEdges.push_back( eos._edges[i] );
+          }
+          badNb = badSmooEdges.size();
+          improved = ( badNb < oldBadNb );
+
+          if ( !badSmooEdges.empty() && step >= stepLimit / 2 )
+          {
+            // look for the best smooth of _LayerEdge's neighboring badSmooEdges
+            vector<_Simplex> simplices;
+            for ( size_t i = 0; i < badSmooEdges.size(); ++i )
             {
-              cout << "Bad simplex ( " << edge->_nodes[0]->GetID()<< " "<< tgtXYZ._node->GetID()
-                   << " "<< edge->_simplices[j]._nPrev->GetID()
-                   << " "<< edge->_simplices[j]._nNext->GetID() << " )" << endl;
-              return false;
+              _LayerEdge* ledge = badSmooEdges[i];
+              _Simplex::GetSimplices( ledge->_nodes[0], simplices, data._ignoreFaceIds );
+              for ( size_t iS = 0; iS < simplices.size(); ++iS )
+              {
+                TNode2Edge::iterator n2e = data._n2eMap.find( simplices[iS]._nNext );
+                if ( n2e != data._n2eMap.end()) {
+                  _LayerEdge* ledge2 = n2e->second;
+                  if ( ledge2->_nodes[0]->getshapeId() == sInd )
+                    ledge2->Smooth( step, isConcaveFace, /*findBest=*/true );
+                }
+              }
             }
+          }
+          // issue 22576 -- no bad faces but still there are intersections to fix
+          // if ( improved && badNb == 0 )
+          //   stepLimit = step + 3;
+
+          dumpFunctionEnd();
         }
+        if ( badNb > 0 )
+        {
+#ifdef __myDEBUG
+          double vol = 0;
+          for ( int i = 0; i < eos._edges.size(); ++i )
+          {
+            _LayerEdge* edge = eos._edges[i];
+            SMESH_TNodeXYZ tgtXYZ( edge->_nodes.back() );
+            for ( size_t j = 0; j < edge->_simplices.size(); ++j )
+              if ( !edge->_simplices[j].IsForward( edge->_nodes[0], &tgtXYZ, vol ))
+              {
+                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
+          return false;
+        }
+      } // // smooth on FACE's
+    } // loop on shapes
+  } // smooth on [ EDGEs, FACEs ]
 
   // Check orientation of simplices of _ConvexFace::_simplexTestEdges
   map< TGeomID, _ConvexFace >::iterator id2face = data._convexFaces.begin();
@@ -3749,37 +3956,41 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data,
   double dist;
   const SMDS_MeshElement* intFace = 0;
   const SMDS_MeshElement* closestFace = 0;
-  int iLE = 0;
-  for ( size_t i = 0; i < data._edges.size(); ++i )
+  _LayerEdge* le = 0;
+  for ( int iS = 0; iS < data._edgesOnShape.size(); ++iS )
   {
-    if ( !data._edges[i]->_sWOL.IsNull() )
+    _EdgesOnShape& eos = data._edgesOnShape[ iS ];
+    if ( eos._edges.empty() || !eos._sWOL.IsNull() )
       continue;
-    if ( data._edges[i]->FindIntersection( *searcher, dist, data._epsilon, &intFace ))
-      return false;
-    if ( distToIntersection > dist )
+    for ( size_t i = 0; i < eos._edges.size(); ++i )
     {
-      // ignore intersection of a _LayerEdge based on a _ConvexFace with a face
-      // lying on this _ConvexFace
-      if ( _ConvexFace* convFace = data.GetConvexFace( intFace->getshapeId() ))
-        if ( convFace->_subIdToEdgeEnd.count ( data._edges[i]->_nodes[0]->getshapeId() ))
-          continue;
+      if ( eos._edges[i]->FindIntersection( *searcher, dist, data._epsilon, eos, &intFace ))
+        return false;
+      if ( distToIntersection > dist )
+      {
+        // ignore intersection of a _LayerEdge based on a _ConvexFace with a face
+        // lying on this _ConvexFace
+        if ( _ConvexFace* convFace = data.GetConvexFace( intFace->getshapeId() ))
+          if ( convFace->_subIdToEOS.count ( eos._shapeID ))
+            continue;
 
-      // ignore intersection of a _LayerEdge based on a FACE with an element on this FACE
-      // ( avoid limiting the thickness on the case of issue 22576)
-      if ( intFace->getshapeId() == data._edges[i]->_nodes[0]->getshapeId() )
-        continue;
+        // ignore intersection of a _LayerEdge based on a FACE with an element on this FACE
+        // ( avoid limiting the thickness on the case of issue 22576)
+        if ( intFace->getshapeId() == eos._shapeID  )
+          continue;
 
-      distToIntersection = dist;
-      iLE = i;
-      closestFace = intFace;
+        distToIntersection = dist;
+        le = eos._edges[i];
+        closestFace = intFace;
+      }
     }
   }
 #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 ("
+    cout << "Shortest distance: _LayerEdge nodes: tgt " << le->_nodes.back()->GetID()
+         << " src " << le->_nodes[0]->GetID()<< ", intersection with face ("
          << (*nIt++)->GetID()<<" "<< (*nIt++)->GetID()<<" "<< (*nIt++)->GetID()
          << ") distance = " << distToIntersection<< endl;
   }
@@ -3796,32 +4007,26 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data,
 //================================================================================
 
 Handle(Geom_Curve) _SolidData::CurveForSmooth( const TopoDS_Edge&    E,
-                                               const int             iFrom,
-                                               const int             iTo,
-                                               const TopoDS_Face&    F,
-                                               SMESH_MesherHelper&   helper,
-                                               vector<_LayerEdge* >* edges)
+                                               _EdgesOnShape&        eos,
+                                               SMESH_MesherHelper&   helper)
 {
-  TGeomID eIndex = helper.GetMeshDS()->ShapeToIndex( E );
+  const TGeomID eIndex = eos._shapeID;
 
   map< TGeomID, Handle(Geom_Curve)>::iterator i2curve = _edge2curve.find( eIndex );
 
   if ( i2curve == _edge2curve.end() )
   {
-    if ( edges )
-      _edges.swap( *edges );
-
     // sort _LayerEdge's by position on the EDGE
-    SortOnEdge( E, iFrom, iTo, helper );
+    SortOnEdge( E, eos._edges, helper );
 
-    SMESHDS_SubMesh* smDS = helper.GetMeshDS()->MeshElements( eIndex );
+    SMESHDS_SubMesh* smDS = eos._subMesh->GetSubMeshDS();
 
     TopLoc_Location loc; double f,l;
 
     Handle(Geom_Line)   line;
     Handle(Geom_Circle) circle;
     bool isLine, isCirc;
-    if ( F.IsNull() ) // 3D case
+    if ( eos._sWOL.IsNull() ) /////////////////////////////////////////// 3D case
     {
       // check if the EDGE is a line
       Handle(Geom_Curve) curve = BRep_Tool::Curve( E, loc, f, l);
@@ -3835,35 +4040,39 @@ Handle(Geom_Curve) _SolidData::CurveForSmooth( const TopoDS_Edge&    E,
 
       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();
-
-        gp_Pnt p0, p1;
-        if ( iTo-iFrom > 1 ) {
-          p0 = SMESH_TNodeXYZ( _edges[iFrom]->_nodes[0] );
-          p1 = SMESH_TNodeXYZ( _edges[iFrom+1]->_nodes[0] );
-        }
-        else {
-          p0 = curve->Value( f );
-          p1 = curve->Value( l );
-        }
-        const double lineTol = 1e-2 * p0.Distance( p1 );
-        for ( int i = 0; i < 3 && !isLine; ++i )
-          isLine = ( size.Coord( i+1 ) <= lineTol );
+        // Bnd_B3d bndBox;
+        // SMDS_NodeIteratorPtr nIt = smDS->GetNodes();
+        // while ( nIt->more() )
+        //   bndBox.Add( SMESH_TNodeXYZ( nIt->next() ));
+        // gp_XYZ size = bndBox.CornerMax() - bndBox.CornerMin();
+
+        // gp_Pnt p0, p1;
+        // if ( eos._edges.size() > 1 ) {
+        //   p0 = SMESH_TNodeXYZ( eos._edges[0]->_nodes[0] );
+        //   p1 = SMESH_TNodeXYZ( eos._edges[1]->_nodes[0] );
+        // }
+        // else {
+        //   p0 = curve->Value( f );
+        //   p1 = curve->Value( l );
+        // }
+        // const double lineTol = 1e-2 * p0.Distance( p1 );
+        // for ( int i = 0; i < 3 && !isLine; ++i )
+        //   isLine = ( size.Coord( i+1 ) <= lineTol ); ////////// <--- WRONG
+
+        isLine = SMESH_Algo::IsStraight( E );
 
         if ( isLine )
           line = new Geom_Line( gp::OX() ); // only type does matter
       }
-      if ( !isLine && !isCirc && iTo-iFrom > 2) // Check if the EDGE is close to a circle
+      if ( !isLine && !isCirc && eos._edges.size() > 2) // Check if the EDGE is close to a circle
       {
         // TODO
       }
     }
-    else // 2D case
+    else //////////////////////////////////////////////////////////////////////// 2D case
     {
+      const TopoDS_Face& F = TopoDS::Face( eos._sWOL );
+
       // 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 )))
@@ -3886,7 +4095,7 @@ Handle(Geom_Curve) _SolidData::CurveForSmooth( const TopoDS_Edge&    E,
         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
+      if ( !isLine && !isCirc && eos._edges.size() > 2) // Check if the EDGE is close to a circle
       {
         // TODO
       }
@@ -3902,9 +4111,6 @@ Handle(Geom_Curve) _SolidData::CurveForSmooth( const TopoDS_Edge&    E,
       }
     }
 
-    if ( edges )
-      _edges.swap( *edges );
-
     Handle(Geom_Curve)& res = _edge2curve[ eIndex ];
     if ( isLine )
       res = line;
@@ -3922,21 +4128,20 @@ Handle(Geom_Curve) _SolidData::CurveForSmooth( const TopoDS_Edge&    E,
  */
 //================================================================================
 
-void _SolidData::SortOnEdge( const TopoDS_Edge&  E,
-                             const int           iFrom,
-                             const int           iTo,
-                             SMESH_MesherHelper& helper)
+void _SolidData::SortOnEdge( const TopoDS_Edge&     E,
+                             vector< _LayerEdge* >& edges,
+                             SMESH_MesherHelper&    helper)
 {
   map< double, _LayerEdge* > u2edge;
-  for ( int i = iFrom; i < iTo; ++i )
-    u2edge.insert( make_pair( helper.GetNodeU( E, _edges[i]->_nodes[0] ), _edges[i] ));
+  for ( size_t i = 0; i < edges.size(); ++i )
+    u2edge.insert( make_pair( helper.GetNodeU( E, edges[i]->_nodes[0] ), edges[i] ));
 
-  ASSERT( u2edge.size() == iTo - iFrom );
+  ASSERT( u2edge.size() == edges.size() );
   map< double, _LayerEdge* >::iterator u2e = u2edge.begin();
-  for ( int i = iFrom; i < iTo; ++i, ++u2e )
-    _edges[i] = u2e->second;
+  for ( int i = 0; i < edges.size(); ++i, ++u2e )
+    edges[i] = u2e->second;
 
-  Sort2NeiborsOnEdge( iFrom, iTo );
+  Sort2NeiborsOnEdge( edges );
 }
 
 //================================================================================
@@ -3945,41 +4150,47 @@ void _SolidData::SortOnEdge( const TopoDS_Edge&  E,
  */
 //================================================================================
 
-void _SolidData::Sort2NeiborsOnEdge( const int iFrom, const int iTo)
+void _SolidData::Sort2NeiborsOnEdge( vector< _LayerEdge* >& edges )
 {
-  for ( int i = iFrom; i < iTo-1; ++i )
-    if ( _edges[i]->_2neibors->tgtNode(1) != _edges[i+1]->_nodes.back() )
-      _edges[i]->_2neibors->reverse();
-  if ( iTo - iFrom > 1 &&
-       _edges[iTo-1]->_2neibors->tgtNode(0) != _edges[iTo-2]->_nodes.back() )
-    _edges[iTo-1]->_2neibors->reverse();
+  for ( size_t i = 0; i < edges.size()-1; ++i )
+    if ( edges[i]->_2neibors->tgtNode(1) != edges[i+1]->_nodes.back() )
+      edges[i]->_2neibors->reverse();
+
+  const size_t iLast = edges.size() - 1;
+  if ( edges.size() > 1 &&
+       edges[iLast]->_2neibors->tgtNode(0) != edges[iLast-1]->_nodes.back() )
+    edges[iLast]->_2neibors->reverse();
 }
 
 //================================================================================
 /*!
- * \brief Return index corresponding to the shape in _endEdgeOnShape
+ * \brief Return _EdgesOnShape* corresponding to the shape
  */
 //================================================================================
 
-bool _SolidData::GetShapeEdges(const TGeomID shapeID,
-                               size_t &      iEdgesEnd,
-                               int*          iBeg,
-                               int*          iEnd ) const
+_EdgesOnShape* _SolidData::GetShapeEdges(const TGeomID shapeID )
 {
-  int beg = 0, end = 0;
-  for ( iEdgesEnd = 0; iEdgesEnd < _endEdgeOnShape.size(); ++iEdgesEnd )
-  {
-    end = _endEdgeOnShape[ iEdgesEnd ];
-    TGeomID sID = _edges[ beg ]->_nodes[0]->getshapeId();
-    if ( sID == shapeID )
-    {
-      if ( iBeg ) *iBeg = beg;
-      if ( iEnd ) *iEnd = end;
-      return true;
-    }
-    beg = end;
-  }
-  return false;
+  if ( shapeID < _edgesOnShape.size() &&
+       _edgesOnShape[ shapeID ]._shapeID == shapeID )
+    return & _edgesOnShape[ shapeID ];
+
+  for ( size_t i = 0; i < _edgesOnShape.size(); ++i )
+    if ( _edgesOnShape[i]._shapeID == shapeID )
+      return & _edgesOnShape[i];
+
+  return 0;
+}
+
+//================================================================================
+/*!
+ * \brief Return _EdgesOnShape* corresponding to the shape
+ */
+//================================================================================
+
+_EdgesOnShape* _SolidData::GetShapeEdges(const TopoDS_Shape& shape )
+{
+  SMESHDS_Mesh* meshDS = _proxyMesh->GetMesh()->GetMeshDS();
+  return GetShapeEdges( meshDS->ShapeToIndex( shape ));
 }
 
 //================================================================================
@@ -3988,22 +4199,19 @@ bool _SolidData::GetShapeEdges(const TGeomID shapeID,
  */
 //================================================================================
 
-void _SolidData::PrepareEdgesToSmoothOnFace( _LayerEdge**       edgeBeg,
-                                             _LayerEdge**       edgeEnd,
-                                             const TopoDS_Face& face,
-                                             bool               substituteSrcNodes )
+void _SolidData::PrepareEdgesToSmoothOnFace( _EdgesOnShape* eof, bool substituteSrcNodes )
 {
   set< TGeomID > vertices;
   SMESH_MesherHelper helper( *_proxyMesh->GetMesh() );
-  if ( isConcave( face, helper, &vertices ))
-    _concaveFaces.insert( (*edgeBeg)->_nodes[0]->getshapeId() );
+  if ( isConcave( TopoDS::Face( eof->_shape ), helper, &vertices ))
+    _concaveFaces.insert( eof->_shapeID );
 
-  for ( _LayerEdge** edge = edgeBeg; edge != edgeEnd; ++edge )
-    (*edge)->_smooFunction = 0;
+  for ( size_t i = 0; i < eof->_edges.size(); ++i )
+    eof->_edges[i]->_smooFunction = 0;
 
-  for ( ; edgeBeg != edgeEnd; ++edgeBeg )
+  for ( size_t i = 0; i < eof->_edges.size(); ++i )
   {
-    _LayerEdge* edge = *edgeBeg;
+    _LayerEdge* edge = eof->_edges[i];
     _Simplex::GetSimplices
       ( edge->_nodes[0], edge->_simplices, _ignoreFaceIds, this, /*sort=*/true );
 
@@ -4035,72 +4243,20 @@ void _SolidData::PrepareEdgesToSmoothOnFace( _LayerEdge**       edgeBeg,
  */
 //================================================================================
 
-void _SolidData::AddShapesToSmooth( const set< TGeomID >& faceIDs )
+void _SolidData::AddShapesToSmooth( const set< _EdgesOnShape* >& eosSet )
 {
-  // convert faceIDs to indices in _endEdgeOnShape
-  set< size_t > iEnds;
-  size_t end;
-  set< TGeomID >::const_iterator fId = faceIDs.begin();
-  for ( ; fId != faceIDs.end(); ++fId )
-    if ( GetShapeEdges( *fId, end ) && end >= _nbShapesToSmooth )
-      iEnds.insert( end );
-
-  set< size_t >::iterator endsIt = iEnds.begin();
-
-  // "add" by move of _nbShapesToSmooth
-  int nbFacesToAdd = iEnds.size();
-  while ( endsIt != iEnds.end() && *endsIt == _nbShapesToSmooth )
+  set< _EdgesOnShape * >::const_iterator eos = eosSet.begin();
+  for ( ; eos != eosSet.end(); ++eos )
   {
-    ++endsIt;
-    ++_nbShapesToSmooth;
-    --nbFacesToAdd;
-  }
-  if ( endsIt == iEnds.end() )
-    return;
-
-  // Move _LayerEdge's on FACEs just after _nbShapesToSmooth
+    if ( !*eos || (*eos)->_toSmooth ) continue;
 
-  vector< _LayerEdge* > nonSmoothLE, smoothLE;
-  size_t lastSmooth = *iEnds.rbegin();
-  int iBeg, iEnd;
-  for ( size_t i = _nbShapesToSmooth; i <= lastSmooth; ++i )
-  {
-    bool toSmooth = iEnds.count(i);
-    vector< _LayerEdge* > & edgesVec = toSmooth ? smoothLE : nonSmoothLE;
-    iBeg = i ? _endEdgeOnShape[ i-1 ] : 0;
-    iEnd = _endEdgeOnShape[ i ];
-    edgesVec.insert( edgesVec.end(), _edges.begin() + iBeg, _edges.begin() + iEnd );
+    (*eos)->_toSmooth = true;
 
-    // preparation for smoothing on FACE
-    if ( toSmooth && _edges[iBeg]->_nodes[0]->GetPosition()->GetDim() == 2 )
+    if ( (*eos)->ShapeType() == TopAbs_FACE )
     {
-      TopoDS_Shape S = SMESH_MesherHelper::GetSubShapeByNode( _edges[iBeg]->_nodes[0],
-                                                              _proxyMesh->GetMeshDS() );
-      if ( !S.IsNull() && S.ShapeType() == TopAbs_FACE )
-      {
-        PrepareEdgesToSmoothOnFace( &_edges[ iBeg ],
-                                    &_edges[ iEnd ],
-                                    TopoDS::Face( S ),
-                                    /*substituteSrcNodes=*/true );
-      }
+      PrepareEdgesToSmoothOnFace( *eos, /*substituteSrcNodes=*/true );
     }
   }
-
-  iBeg = _nbShapesToSmooth ? _endEdgeOnShape[ _nbShapesToSmooth-1 ] : 0;
-  std::copy( smoothLE.begin(),    smoothLE.end(),    &_edges[ iBeg ] );
-  std::copy( nonSmoothLE.begin(), nonSmoothLE.end(), &_edges[ iBeg + smoothLE.size()]);
-
-  // update _endEdgeOnShape
-  for ( size_t i = _nbShapesToSmooth; i < _endEdgeOnShape.size(); ++i )
-  {
-    TGeomID curShape = _edges[ iBeg ]->_nodes[0]->getshapeId();
-    while ( ++iBeg < _edges.size() &&
-            curShape == _edges[ iBeg ]->_nodes[0]->getshapeId() );
-
-    _endEdgeOnShape[ i ] = iBeg;
-  }
-
-  _nbShapesToSmooth += nbFacesToAdd;
 }
 
 //================================================================================
@@ -4110,26 +4266,25 @@ void _SolidData::AddShapesToSmooth( const set< TGeomID >& faceIDs )
 //================================================================================
 
 bool _ViscousBuilder::smoothAnalyticEdge( _SolidData&           data,
-                                          const int             iFrom,
-                                          const int             iTo,
+                                          _EdgesOnShape&        eos,
                                           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 );
+  const TopoDS_Edge& E = TopoDS::Edge( eos._shape );
 
-  Handle(Geom_Curve) curve = data.CurveForSmooth( E, iFrom, iTo, F, helper );
+  Handle(Geom_Curve) curve = data.CurveForSmooth( E, eos, helper );
   if ( curve.IsNull() ) return false;
 
+  const size_t iFrom = 0, iTo = eos._edges.size();
+
   // 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];
+      curLen = prevLen * eos._edges[i]->_2neibors->_wgt[0] / eos._edges[i]->_2neibors->_wgt[1];
       len[i-iFrom+1] = len[i-iFrom] + curLen;
       prevLen = curLen;
     }
@@ -4139,26 +4294,28 @@ bool _ViscousBuilder::smoothAnalyticEdge( _SolidData&           data,
   {
     if ( F.IsNull() ) // 3D
     {
-      SMESH_TNodeXYZ p0( data._edges[iFrom]->_2neibors->tgtNode(0));
-      SMESH_TNodeXYZ p1( data._edges[iTo-1]->_2neibors->tgtNode(1));
+      SMESH_TNodeXYZ p0( eos._edges[iFrom]->_2neibors->tgtNode(0));
+      SMESH_TNodeXYZ p1( eos._edges[iTo-1]->_2neibors->tgtNode(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() );
+        eos._edges[i]->_pos.back() = newPos;
+        SMDS_MeshNode* tgtNode = const_cast<SMDS_MeshNode*>( eos._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->tgtNode(0));
-      // gp_XY uv1 = helper.GetNodeUV( F, data._edges[iTo-1]->_2neibors->tgtNode(1));
-      gp_XY uv0 = data._edges[iFrom]->_2neibors->_edges[0]->LastUV( F );
-      gp_XY uv1 = data._edges[iTo-1]->_2neibors->_edges[1]->LastUV( F );
-      if ( data._edges[iFrom]->_2neibors->tgtNode(0) ==
-           data._edges[iTo-1]->_2neibors->tgtNode(1) ) // closed edge
+      // gp_XY uv0 = helper.GetNodeUV( F, eos._edges[iFrom]->_2neibors->tgtNode(0));
+      // gp_XY uv1 = helper.GetNodeUV( F, eos._edges[iTo-1]->_2neibors->tgtNode(1));
+      _LayerEdge* e0 = eos._edges[iFrom]->_2neibors->_edges[0];
+      _LayerEdge* e1 = eos._edges[iTo-1]->_2neibors->_edges[1];
+      gp_XY uv0 = e0->LastUV( F, *data.GetShapeEdges( e0 ));
+      gp_XY uv1 = e1->LastUV( F, *data.GetShapeEdges( e1 ));
+      if ( eos._edges[iFrom]->_2neibors->tgtNode(0) ==
+           eos._edges[iTo-1]->_2neibors->tgtNode(1) ) // closed edge
       {
         int iPeriodic = helper.GetPeriodicIndex();
         if ( iPeriodic == 1 || iPeriodic == 2 )
@@ -4173,10 +4330,10 @@ bool _ViscousBuilder::smoothAnalyticEdge( _SolidData&           data,
       {
         double r = len[i-iFrom] / len.back();
         gp_XY newUV = uv0 + r * rangeUV;
-        data._edges[i]->_pos.back().SetCoord( newUV.X(), newUV.Y(), 0 );
+        eos._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() );
+        SMDS_MeshNode* tgtNode = const_cast<SMDS_MeshNode*>( eos._edges[i]->_nodes.back() );
         tgtNode->setXYZ( newPos.X(), newPos.Y(), newPos.Z() );
         dumpMove( tgtNode );
 
@@ -4195,8 +4352,8 @@ bool _ViscousBuilder::smoothAnalyticEdge( _SolidData&           data,
 
     if ( F.IsNull() ) // 3D
     {
-      if ( data._edges[iFrom]->_2neibors->tgtNode(0) ==
-           data._edges[iTo-1]->_2neibors->tgtNode(1) )
+      if ( eos._edges[iFrom]->_2neibors->tgtNode(0) ==
+           eos._edges[iTo-1]->_2neibors->tgtNode(1) )
         return true; // closed EDGE - nothing to do
 
       return false; // TODO ???
@@ -4205,12 +4362,12 @@ bool _ViscousBuilder::smoothAnalyticEdge( _SolidData&           data,
     {
       const gp_XY center( center3D.X(), center3D.Y() );
 
-      gp_XY uv0 = data._edges[iFrom]->_2neibors->_edges[0]->LastUV( F );
-      gp_XY uvM = data._edges[iFrom]->LastUV( F );
-      gp_XY uv1 = data._edges[iTo-1]->_2neibors->_edges[1]->LastUV( F );
-      // gp_XY uv0 = helper.GetNodeUV( F, data._edges[iFrom]->_2neibors->tgtNode(0));
-      // gp_XY uvM = helper.GetNodeUV( F, data._edges[iFrom]->_nodes.back());
-      // gp_XY uv1 = helper.GetNodeUV( F, data._edges[iTo-1]->_2neibors->tgtNode(1));
+      _LayerEdge* e0 = eos._edges[iFrom]->_2neibors->_edges[0];
+      _LayerEdge* eM = eos._edges[iFrom];
+      _LayerEdge* e1 = eos._edges[iTo-1]->_2neibors->_edges[1];
+      gp_XY uv0 = e0->LastUV( F, *data.GetShapeEdges( e0 ) );
+      gp_XY uvM = eM->LastUV( F, *data.GetShapeEdges( eM ) );
+      gp_XY uv1 = e1->LastUV( F, *data.GetShapeEdges( e1 ) );
       gp_Vec2d vec0( center, uv0 );
       gp_Vec2d vecM( center, uvM );
       gp_Vec2d vec1( center, uv1 );
@@ -4226,10 +4383,10 @@ bool _ViscousBuilder::smoothAnalyticEdge( _SolidData&           data,
       {
         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 );
+        eos._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() );
+        SMDS_MeshNode* tgtNode = const_cast<SMDS_MeshNode*>( eos._edges[i]->_nodes.back() );
         tgtNode->setXYZ( newPos.X(), newPos.Y(), newPos.Z() );
         dumpMove( tgtNode );
 
@@ -4267,30 +4424,35 @@ bool _ViscousBuilder::updateNormals( _SolidData&         data,
     vector< const SMDS_MeshNode*> nodes(4); // of a tmp mesh face
 
     dumpFunction(SMESH_Comment("makeTmpFacesOnEdges")<<data._index);
-    for ( size_t i = 0; i < data._edges.size(); ++i )
+    for ( size_t iS = 0; iS < data._edgesOnShape.size(); ++iS )
     {
-      _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
+      _EdgesOnShape& eos = data._edgesOnShape[ iS ];
+      if ( eos.ShapeType() != TopAbs_EDGE || !eos._sWOL.IsNull() )
+        continue;
+      for ( size_t i = 0; i < eos._edges.size(); ++i )
       {
-        const SMDS_MeshNode* tgt2 = edge->_2neibors->tgtNode(j);
-        pair< set< SMESH_TLink >::iterator, bool > link_isnew =
-          extrudedLinks.insert( SMESH_TLink( tgt1, tgt2 ));
-        if ( !link_isnew.second )
+        _LayerEdge* edge = eos._edges[i];
+        const SMDS_MeshNode* tgt1 = edge->_nodes.back();
+        for ( int j = 0; j < 2; ++j ) // loop on _2NearEdges
         {
-          extrudedLinks.erase( link_isnew.first );
-          continue; // already extruded and will no more encounter
-        }
-        // a _LayerEdge containg tgt2
-        _LayerEdge* neiborEdge = edge->_2neibors->_edges[j];
+          const SMDS_MeshNode* tgt2 = edge->_2neibors->tgtNode(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
+          }
+          // a _LayerEdge containg tgt2
+          _LayerEdge* neiborEdge = edge->_2neibors->_edges[j];
 
-        _TmpMeshFaceOnEdge* f = new _TmpMeshFaceOnEdge( edge, neiborEdge, --_tmpFaceID );
-        tmpFaces.push_back( f );
+          _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()<<" ])");
+          dumpCmd(SMESH_Comment("mesh.AddFace([ ")
+                  <<f->_nn[0]->GetID()<<", "<<f->_nn[1]->GetID()<<", "
+                  <<f->_nn[2]->GetID()<<", "<<f->_nn[3]->GetID()<<" ])");
+        }
       }
     }
     dumpFunctionEnd();
@@ -4312,22 +4474,26 @@ bool _ViscousBuilder::updateNormals( _SolidData&         data,
   TLEdge2LEdgeSet edge2CloseEdge;
 
   const double eps = data._epsilon * data._epsilon;
-  for ( size_t i = 0; i < data._edges.size(); ++i )
+  for ( size_t iS = 0; iS < data._edgesOnShape.size(); ++iS )
   {
-    _LayerEdge* edge = data._edges[i];
-    if (( !edge->IsOnEdge() ) &&
-        ( edge->_sWOL.IsNull() || edge->_sWOL.ShapeType() != TopAbs_FACE ))
+    _EdgesOnShape& eos = data._edgesOnShape[ iS ];
+    if (( eos.ShapeType() != TopAbs_EDGE ) && 
+        ( eos._sWOL.IsNull() || eos.SWOLType() != TopAbs_FACE ))
       continue;
-    if ( edge->FindIntersection( *searcher, dist, eps, &face ))
+    for ( size_t i = 0; i < eos._edges.size(); ++i )
     {
-      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 );
+      _LayerEdge* edge = eos._edges[i];
+      if ( edge->FindIntersection( *searcher, dist, eps, eos, &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() && data.GetShapeEdges( f->_le1 )->_sWOL.IsNull() )
+          edge2CloseEdge[ f->_le1 ].insert( edge );
+        if ( f->_le2->IsOnEdge() && data.GetShapeEdges( f->_le2 )->_sWOL.IsNull() )
+          edge2CloseEdge[ f->_le2 ].insert( edge );
+      }
     }
   }
 
@@ -4337,7 +4503,7 @@ bool _ViscousBuilder::updateNormals( _SolidData&         data,
   {
     dumpFunction(SMESH_Comment("updateNormals")<<data._index);
 
-    set< TGeomID > shapesToSmooth;
+    set< _EdgesOnShape* > shapesToSmooth;
 
     // vector to store new _normal and _cosin for each edge in edge2CloseEdge
     vector< pair< _LayerEdge*, _LayerEdge > > edge2newEdge( edge2CloseEdge.size() );
@@ -4351,6 +4517,9 @@ bool _ViscousBuilder::updateNormals( _SolidData&         data,
 
       edge2newEdge[ iE ].first = NULL;
 
+      _EdgesOnShape* eos1 = data.GetShapeEdges( edge1 );
+      if ( !eos1 ) continue;
+
       // find EDGEs the edges reside
       // TopoDS_Edge E1, E2;
       // TopoDS_Shape S = helper.GetSubShapeByNode( edge1->_nodes[0], getMeshDS() );
@@ -4360,7 +4529,7 @@ bool _ViscousBuilder::updateNormals( _SolidData&         data,
       set< _LayerEdge*, _LayerEdgeCmp >::iterator eIt = ee.begin();
       for ( ; !edge2 && eIt != ee.end(); ++eIt )
       {
-        if ( edge1->_sWOL == (*eIt)->_sWOL )
+        if ( eos1->_sWOL == data.GetShapeEdges( *eIt  )->_sWOL )
           edge2 = *eIt;
       }
       if ( !edge2 ) continue;
@@ -4445,11 +4614,11 @@ bool _ViscousBuilder::updateNormals( _SolidData&         data,
       if ( edge1->_cosin  < theMinSmoothCosin &&
            newEdge._cosin > theMinSmoothCosin )
       {
-        if ( edge1->_sWOL.IsNull() )
+        if ( eos1->_sWOL.IsNull() )
         {
           SMDS_ElemIteratorPtr fIt = edge1->_nodes[0]->GetInverseElementIterator(SMDSAbs_Face);
           while ( fIt->more() )
-            shapesToSmooth.insert( fIt->next()->getshapeId() );
+            shapesToSmooth.insert( data.GetShapeEdges( fIt->next()->getshapeId() ));
           //limitStepSize( data, fIt->next(), edge1->_cosin ); // too late
         }
         else // edge1 inflates along a FACE
@@ -4458,12 +4627,12 @@ bool _ViscousBuilder::updateNormals( _SolidData&         data,
           PShapeIteratorPtr eIt = helper.GetAncestors( V, *_mesh, TopAbs_EDGE );
           while ( const TopoDS_Shape* E = eIt->next() )
           {
-            if ( !helper.IsSubShape( *E, /*FACE=*/edge1->_sWOL ))
+            if ( !helper.IsSubShape( *E, /*FACE=*/eos1->_sWOL ))
               continue;
             gp_Vec edgeDir = getEdgeDir( TopoDS::Edge( *E ), TopoDS::Vertex( V ));
             double   angle = edgeDir.Angle( newEdge._normal ); // [0,PI]
             if ( angle < M_PI / 2 )
-              shapesToSmooth.insert( getMeshDS()->ShapeToIndex( *E ));
+              shapesToSmooth.insert( data.GetShapeEdges( *E ));
           }
         }
       }
@@ -4478,17 +4647,19 @@ bool _ViscousBuilder::updateNormals( _SolidData&         data,
       _LayerEdge*   edge1 = edge2newEdge[ iE ].first;
       _LayerEdge& newEdge = edge2newEdge[ iE ].second;
       if ( !edge1 ) continue;
+      _EdgesOnShape* eos1 = data.GetShapeEdges( edge1 );
+      if ( !eos1 ) continue;
 
       edge1->_normal = newEdge._normal;
       edge1->SetCosin( newEdge._cosin );
-      edge1->InvalidateStep( 1 );
+      edge1->InvalidateStep( 1, *eos1 );
       edge1->_len = 0;
-      edge1->SetNewLength( data._stepSize, helper );
+      edge1->SetNewLength( data._stepSize, *eos1, helper );
       if ( edge1->IsOnEdge() )
       {
         const SMDS_MeshNode * n1 = edge1->_2neibors->srcNode(0);
         const SMDS_MeshNode * n2 = edge1->_2neibors->srcNode(1);
-        edge1->SetDataByNeighbors( n1, n2, helper );
+        edge1->SetDataByNeighbors( n1, n2, *eos1, helper );
       }
 
       // Update normals and other dependent data of not intersecting _LayerEdge's
@@ -4501,6 +4672,8 @@ bool _ViscousBuilder::updateNormals( _SolidData&         data,
         _LayerEdge* neighbor = edge1->_2neibors->_edges[j];
         if ( edge2CloseEdge.count ( neighbor ))
           continue; // j-th neighbor is also intersected
+        _EdgesOnShape* eos = data.GetShapeEdges( neighbor );
+        if ( !eos ) continue;
         _LayerEdge* prevEdge = edge1;
         const int nbSteps = 10;
         for ( int step = nbSteps; step; --step ) // step from edge1 in j-th direction
@@ -4520,11 +4693,11 @@ bool _ViscousBuilder::updateNormals( _SolidData&         data,
 
           neighbor->_normal = newNorm;
           neighbor->SetCosin( prevEdge->_cosin * r + nextEdge->_cosin * (1-r) );
-          neighbor->SetDataByNeighbors( prevEdge->_nodes[0], nextEdge->_nodes[0], helper );
+          neighbor->SetDataByNeighbors( prevEdge->_nodes[0], nextEdge->_nodes[0], *eos, helper );
 
-          neighbor->InvalidateStep( 1 );
+          neighbor->InvalidateStep( 1, *eos );
           neighbor->_len = 0;
-          neighbor->SetNewLength( data._stepSize, helper );
+          neighbor->SetNewLength( data._stepSize, *eos, helper );
 
           // goto the next neighbor
           prevEdge = neighbor;
@@ -4575,21 +4748,19 @@ bool _ViscousBuilder::updateNormalsOfConvexFaces( _SolidData&         data,
     Bnd_B3d centersBox; // bbox of centers of curvature of _LayerEdge's on VERTEXes
     Bnd_B3d nodesBox;
     gp_Pnt  center;
-    int     iBeg, iEnd;
 
-    map< TGeomID, int >::iterator id2end = convFace._subIdToEdgeEnd.begin();
-    for ( ; id2end != convFace._subIdToEdgeEnd.end(); ++id2end )
+    map< TGeomID, _EdgesOnShape* >::iterator id2eos = convFace._subIdToEOS.begin();
+    for ( ; id2eos != convFace._subIdToEOS.end(); ++id2eos )
     {
-      data.GetEdgesOnShape( id2end->second, iBeg, iEnd );
-
-      if ( meshDS->IndexToShape( id2end->first ).ShapeType() == TopAbs_VERTEX )
+      _EdgesOnShape& eos = *(id2eos->second);
+      if ( eos.ShapeType() == TopAbs_VERTEX )
       {
-        _LayerEdge* ledge = data._edges[ iBeg ];
+        _LayerEdge* ledge = eos._edges[ 0 ];
         if ( convFace.GetCenterOfCurvature( ledge, surfProp, helper, center ))
           centersBox.Add( center );
       }
-      for ( ; iBeg < iEnd; ++iBeg )
-        nodesBox.Add( SMESH_TNodeXYZ( data._edges[ iBeg ]->_nodes[0] ));
+      for ( size_t i = 0; i < eos._edges.size(); ++i )
+        nodesBox.Add( SMESH_TNodeXYZ( eos._edges[ i ]->_nodes[0] ));
     }
     if ( centersBox.IsVoid() )
     {
@@ -4611,25 +4782,24 @@ bool _ViscousBuilder::updateNormalsOfConvexFaces( _SolidData&         data,
 
       gp_XYZ avgNormal( 0,0,0 );
       nbEdges = 0;
-      id2end = convFace._subIdToEdgeEnd.begin();
-      for ( ; id2end != convFace._subIdToEdgeEnd.end(); ++id2end )
+      id2eos = convFace._subIdToEOS.begin();
+      for ( ; id2eos != convFace._subIdToEOS.end(); ++id2eos )
       {
-        data.GetEdgesOnShape( id2end->second, iBeg, iEnd );
+        _EdgesOnShape& eos = *(id2eos->second);
         // set data of _CentralCurveOnEdge
-        const TopoDS_Shape& S = meshDS->IndexToShape( id2end->first );
-        if ( S.ShapeType() == TopAbs_EDGE )
+        if ( eos.ShapeType() == TopAbs_EDGE )
         {
           _CentralCurveOnEdge& ceCurve = centerCurves[ nbEdges++ ];
-          ceCurve.SetShapes( TopoDS::Edge(S), convFace, data, helper );
-          if ( !data._edges[ iBeg ]->_sWOL.IsNull() )
+          ceCurve.SetShapes( TopoDS::Edge( eos._shape ), convFace, data, helper );
+          if ( !eos._sWOL.IsNull() )
             ceCurve._adjFace.Nullify();
           else
             ceCurve._ledges.insert( ceCurve._ledges.end(),
-                                    &data._edges[ iBeg ], &data._edges[ iEnd ]);
+                                    eos._edges.begin(), eos._edges.end());
         }
         // summarize normals
-        for ( ; iBeg < iEnd; ++iBeg )
-          avgNormal += data._edges[ iBeg ]->_normal;
+        for ( size_t i = 0; i < eos._edges.size(); ++i )
+          avgNormal += eos._edges[ i ]->_normal;
       }
       double normSize = avgNormal.SquareModulus();
       if ( normSize < 1e-200 )
@@ -4665,17 +4835,16 @@ bool _ViscousBuilder::updateNormalsOfConvexFaces( _SolidData&         data,
         avgCosin /= nbCosin;
 
       // set _LayerEdge::_normal = avgNormal
-      id2end = convFace._subIdToEdgeEnd.begin();
-      for ( ; id2end != convFace._subIdToEdgeEnd.end(); ++id2end )
+      id2eos = convFace._subIdToEOS.begin();
+      for ( ; id2eos != convFace._subIdToEOS.end(); ++id2eos )
       {
-        data.GetEdgesOnShape( id2end->second, iBeg, iEnd );
-        const TopoDS_Shape& S = meshDS->IndexToShape( id2end->first );
-        if ( S.ShapeType() != TopAbs_EDGE )
-          for ( int i = iBeg; i < iEnd; ++i )
-            data._edges[ i ]->_cosin = avgCosin;
+        _EdgesOnShape& eos = *(id2eos->second);
+        if ( eos.ShapeType() != TopAbs_EDGE )
+          for ( size_t i = 0; i < eos._edges.size(); ++i )
+            eos._edges[ i ]->_cosin = avgCosin;
 
-        for ( ; iBeg < iEnd; ++iBeg )
-          data._edges[ iBeg ]->_normal = avgNormal;
+        for ( size_t i = 0; i < eos._edges.size(); ++i )
+          eos._edges[ i ]->_normal = avgNormal;
       }
     }
     else // if ( isSpherical )
@@ -4700,17 +4869,16 @@ bool _ViscousBuilder::updateNormalsOfConvexFaces( _SolidData&         data,
 
         // get _LayerEdge's of the EDGE
         TGeomID edgeID = meshDS->ShapeToIndex( edge );
-        id2end = convFace._subIdToEdgeEnd.find( edgeID );
-        if ( id2end == convFace._subIdToEdgeEnd.end() )
+        _EdgesOnShape* eos = data.GetShapeEdges( edgeID );
+        if ( !eos || eos->_edges.empty() )
         {
           // no _LayerEdge's on EDGE, use _LayerEdge's on VERTEXes
           for ( int iV = 0; iV < 2; ++iV )
           {
             TopoDS_Vertex v = helper.IthVertex( iV, edge );
             TGeomID     vID = meshDS->ShapeToIndex( v );
-            int  end = convFace._subIdToEdgeEnd[ vID ];
-            int iBeg = end > 0 ? data._endEdgeOnShape[ end-1 ] : 0;
-            vertexLEdges[ iV ] = data._edges[ iBeg ];
+            eos = data.GetShapeEdges( vID );
+            vertexLEdges[ iV ] = eos->_edges[ 0 ];
           }
           edgeLEdge    = &vertexLEdges[0];
           edgeLEdgeEnd = edgeLEdge + 2;
@@ -4719,15 +4887,14 @@ bool _ViscousBuilder::updateNormalsOfConvexFaces( _SolidData&         data,
         }
         else
         {
-          data.GetEdgesOnShape( id2end->second, iBeg, iEnd );
-          if ( id2end->second >= data._nbShapesToSmooth )
-            data.SortOnEdge( edge, iBeg, iEnd, helper );
-          edgeLEdge    = &data._edges[ iBeg ];
-          edgeLEdgeEnd = edgeLEdge + iEnd - iBeg;
-          vertexLEdges[0] = data._edges[ iBeg   ]->_2neibors->_edges[0];
-          vertexLEdges[1] = data._edges[ iEnd-1 ]->_2neibors->_edges[1];
-
-          if ( ! data._edges[ iBeg ]->_sWOL.IsNull() )
+          if ( ! eos->_toSmooth )
+            data.SortOnEdge( edge, eos->_edges, helper );
+          edgeLEdge    = &eos->_edges[ 0 ];
+          edgeLEdgeEnd = edgeLEdge + eos->_edges.size();
+          vertexLEdges[0] = eos->_edges.front()->_2neibors->_edges[0];
+          vertexLEdges[1] = eos->_edges.back() ->_2neibors->_edges[1];
+
+          if ( ! eos->_sWOL.IsNull() )
             centerCurves[ iE ]._adjFace.Nullify();
         }
 
@@ -4829,15 +4996,15 @@ bool _ViscousBuilder::updateNormalsOfConvexFaces( _SolidData&         data,
       if ( nbCosin > 0 )
         avgCosin /= nbCosin;
       const TGeomID faceID = meshDS->ShapeToIndex( convFace._face );
-      map< TGeomID, int >::iterator id2end = convFace._subIdToEdgeEnd.find( faceID );
-      if ( id2end != convFace._subIdToEdgeEnd.end() )
+      map< TGeomID, _EdgesOnShape* >::iterator id2eos = convFace._subIdToEOS.find( faceID );
+      if ( id2eos != convFace._subIdToEOS.end() )
       {
         int iE = 0;
         gp_XYZ newNorm;
-        data.GetEdgesOnShape( id2end->second, iBeg, iEnd );
-        for ( ; iBeg < iEnd; ++iBeg )
+        _EdgesOnShape& eos = * ( id2eos->second );
+        for ( size_t i = 0; i < eos._edges.size(); ++i )
         {
-          _LayerEdge* ledge = data._edges[ iBeg ];
+          _LayerEdge* ledge = eos._edges[ i ];
           if ( !convFace.GetCenterOfCurvature( ledge, surfProp, helper, center ))
             continue;
           for ( size_t i = 0; i < centerCurves.size(); ++i, ++iE )
@@ -4863,17 +5030,17 @@ bool _ViscousBuilder::updateNormalsOfConvexFaces( _SolidData&         data,
     dumpFunction(SMESH_Comment("updateNormalsOfConvexFaces")<<data._index
                  <<"_F"<<meshDS->ShapeToIndex( convFace._face ));
 
-    id2end = convFace._subIdToEdgeEnd.begin();
-    for ( ; id2end != convFace._subIdToEdgeEnd.end(); ++id2end )
+    id2eos = convFace._subIdToEOS.begin();
+    for ( ; id2eos != convFace._subIdToEOS.end(); ++id2eos )
     {
-      data.GetEdgesOnShape( id2end->second, iBeg, iEnd );
-      for ( ; iBeg < iEnd; ++iBeg )
+      _EdgesOnShape& eos = * ( id2eos->second );
+      for ( size_t i = 0; i < eos._edges.size(); ++i )
       {
-        _LayerEdge* & ledge = data._edges[ iBeg ];
+        _LayerEdge* & ledge = eos._edges[ i ];
         double len = ledge->_len;
-        ledge->InvalidateStep( stepNb + 1, /*restoreLength=*/true );
+        ledge->InvalidateStep( stepNb + 1, eos, /*restoreLength=*/true );
         ledge->SetCosin( ledge->_cosin );
-        ledge->SetNewLength( len, helper );
+        ledge->SetNewLength( len, eos, helper );
       }
 
     } // loop on sub-shapes of convFace._face
@@ -4881,7 +5048,7 @@ bool _ViscousBuilder::updateNormalsOfConvexFaces( _SolidData&         data,
     // Find FACEs adjacent to convFace._face that got necessity to smooth
     // as a result of normals modification
 
-    set< TGeomID > adjFacesToSmooth;
+    set< _EdgesOnShape* > adjFacesToSmooth;
     for ( size_t iE = 0; iE < centerCurves.size(); ++iE )
     {
       if ( centerCurves[ iE ]._adjFace.IsNull() ||
@@ -4891,7 +5058,7 @@ bool _ViscousBuilder::updateNormalsOfConvexFaces( _SolidData&         data,
       {
         if ( centerCurves[ iE ]._ledges[ iLE ]->_cosin > theMinSmoothCosin )
         {
-          adjFacesToSmooth.insert( meshDS->ShapeToIndex( centerCurves[ iE ]._adjFace ));
+          adjFacesToSmooth.insert( data.GetShapeEdges( centerCurves[ iE ]._adjFace ));
           break;
         }
       }
@@ -5013,7 +5180,7 @@ bool _CentralCurveOnEdge::FindNewNormal( const gp_Pnt& center, gp_XYZ& newNormal
 
 void _CentralCurveOnEdge::SetShapes( const TopoDS_Edge&  edge,
                                      const _ConvexFace&  convFace,
-                                     const _SolidData&   data,
+                                     _SolidData&         data,
                                      SMESH_MesherHelper& helper)
 {
   _edge = edge;
@@ -5025,10 +5192,8 @@ void _CentralCurveOnEdge::SetShapes( const TopoDS_Edge&  edge,
       _adjFace = TopoDS::Face( *F );
       _adjFaceToSmooth = false;
       // _adjFace already in a smoothing queue ?
-      size_t end;
-      TGeomID adjFaceID = helper.GetMeshDS()->ShapeToIndex( *F );
-      if ( data.GetShapeEdges( adjFaceID, end ))
-        _adjFaceToSmooth = ( end < data._nbShapesToSmooth );
+      if ( _EdgesOnShape* eos = data.GetShapeEdges( _adjFace ))
+        _adjFaceToSmooth = eos->_toSmooth;
       break;
     }
 }
@@ -5043,11 +5208,12 @@ void _CentralCurveOnEdge::SetShapes( const TopoDS_Edge&  edge,
 bool _LayerEdge::FindIntersection( SMESH_ElementSearcher&   searcher,
                                    double &                 distance,
                                    const double&            epsilon,
+                                   _EdgesOnShape&           eos,
                                    const SMDS_MeshElement** face)
 {
   vector< const SMDS_MeshElement* > suspectFaces;
   double segLen;
-  gp_Ax1 lastSegment = LastSegment(segLen);
+  gp_Ax1 lastSegment = LastSegment( segLen, eos );
   searcher.GetElementsNearLine( lastSegment, SMDSAbs_Face, suspectFaces );
 
   bool segmentIntersected = false;
@@ -5113,7 +5279,7 @@ bool _LayerEdge::FindIntersection( SMESH_ElementSearcher&   searcher,
  */
 //================================================================================
 
-gp_Ax1 _LayerEdge::LastSegment(double& segLen) const
+gp_Ax1 _LayerEdge::LastSegment(double& segLen, _EdgesOnShape& eos) const
 {
   // find two non-coincident positions
   gp_XYZ orig = _pos.back();
@@ -5140,18 +5306,18 @@ gp_Ax1 _LayerEdge::LastSegment(double& segLen) const
   else
   {
     gp_Pnt pPrev = _pos[ iPrev ];
-    if ( !_sWOL.IsNull() )
+    if ( !eos._sWOL.IsNull() )
     {
       TopLoc_Location loc;
-      if ( _sWOL.ShapeType() == TopAbs_EDGE )
+      if ( eos.SWOLType() == TopAbs_EDGE )
       {
         double f,l;
-        Handle(Geom_Curve) curve = BRep_Tool::Curve( TopoDS::Edge( _sWOL ), loc, f,l);
+        Handle(Geom_Curve) curve = BRep_Tool::Curve( TopoDS::Edge( eos._sWOL ), loc, f,l);
         pPrev = curve->Value( pPrev.X() ).Transformed( loc );
       }
       else
       {
-        Handle(Geom_Surface) surface = BRep_Tool::Surface( TopoDS::Face(_sWOL), loc );
+        Handle(Geom_Surface) surface = BRep_Tool::Surface( TopoDS::Face( eos._sWOL ), loc );
         pPrev = surface->Value( pPrev.X(), pPrev.Y() ).Transformed( loc );
       }
       dir = SMESH_TNodeXYZ( _nodes.back() ) - pPrev.XYZ();
@@ -5172,17 +5338,17 @@ gp_Ax1 _LayerEdge::LastSegment(double& segLen) const
  */
 //================================================================================
 
-gp_XY _LayerEdge::LastUV( const TopoDS_Face& F ) const
+gp_XY _LayerEdge::LastUV( const TopoDS_Face& F, _EdgesOnShape& eos ) const
 {
-  if ( F.IsSame( _sWOL )) // F is my FACE
+  if ( F.IsSame( eos._sWOL )) // F is my FACE
     return gp_XY( _pos.back().X(), _pos.back().Y() );
 
-  if ( _sWOL.IsNull() || _sWOL.ShapeType() != TopAbs_EDGE ) // wrong call
+  if ( eos.SWOLType() != TopAbs_EDGE ) // wrong call
     return gp_XY( 1e100, 1e100 );
 
   // _sWOL is EDGE of F; _pos.back().X() is the last U on the EDGE
   double f, l, u = _pos.back().X();
-  Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface( TopoDS::Edge(_sWOL), F, f,l);
+  Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface( TopoDS::Edge(eos._sWOL), F, f,l);
   if ( !C2d.IsNull() && f <= u && u <= l )
     return C2d->Value( u ).XY();
 
@@ -5884,7 +6050,7 @@ gp_XYZ _LayerEdge::smoothNefPolygon()
  */
 //================================================================================
 
-void _LayerEdge::SetNewLength( double len, SMESH_MesherHelper& helper )
+void _LayerEdge::SetNewLength( double len, _EdgesOnShape& eos, SMESH_MesherHelper& helper )
 {
   if ( _len - len > -1e-6 )
   {
@@ -5893,19 +6059,48 @@ void _LayerEdge::SetNewLength( double len, SMESH_MesherHelper& helper )
   }
 
   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() );
+  gp_XYZ oldXYZ = SMESH_TNodeXYZ( n );
+  gp_XYZ newXYZ;
+  if ( eos._hyp.IsOffsetMethod() )
+  {
+    newXYZ = oldXYZ;
+    gp_Vec faceNorm;
+    SMDS_ElemIteratorPtr faceIt = _nodes[0]->GetInverseElementIterator( SMDSAbs_Face );
+    while ( faceIt->more() )
+    {
+      const SMDS_MeshElement* face = faceIt->next();
+      if ( !eos.GetNormal( face, faceNorm ))
+        continue;
 
-  _pos.push_back( nXYZ );
+      // translate plane of a face
+      gp_XYZ baryCenter = oldXYZ + faceNorm.XYZ() * ( len - _len );
+
+      // find point of intersection of the face plane located at baryCenter
+      // and _normal located at newXYZ
+      double d    = -( faceNorm.XYZ() * baryCenter ); // d of plane equation ax+by+cz+d=0
+      double dot  = ( faceNorm.XYZ() * _normal );
+      if ( dot < std::numeric_limits<double>::min() )
+        dot = ( len - _len ) * 1e-3;
+      double step = -( faceNorm.XYZ() * newXYZ + d ) / dot;
+      newXYZ += step * _normal;
+    }
+  }
+  else
+  {
+    newXYZ = oldXYZ + _normal * ( len - _len ) * _lenFactor;
+  }
+  n->setXYZ( newXYZ.X(), newXYZ.Y(), newXYZ.Z() );
+
+  _pos.push_back( newXYZ );
   _len = len;
-  if ( !_sWOL.IsNull() )
+
+  if ( !eos._sWOL.IsNull() )
   {
     double distXYZ[4];
-    if ( _sWOL.ShapeType() == TopAbs_EDGE )
+    if ( eos.SWOLType() == 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 );
+      helper.CheckNodeU( TopoDS::Edge( eos._sWOL ), n, u, 1e-10, /*force=*/true, distXYZ );
       _pos.back().SetCoord( u, 0, 0 );
       if ( _nodes.size() > 1 )
       {
@@ -5916,7 +6111,7 @@ void _LayerEdge::SetNewLength( double len, SMESH_MesherHelper& helper )
     else //  TopAbs_FACE
     {
       gp_XY uv( Precision::Infinite(), 0 );
-      helper.CheckNodeUV( TopoDS::Face( _sWOL ), n, uv, 1e-10, /*force=*/true, distXYZ );
+      helper.CheckNodeUV( TopoDS::Face( eos._sWOL ), n, uv, 1e-10, /*force=*/true, distXYZ );
       _pos.back().SetCoord( uv.X(), uv.Y(), 0 );
       if ( _nodes.size() > 1 )
       {
@@ -5936,7 +6131,7 @@ void _LayerEdge::SetNewLength( double len, SMESH_MesherHelper& helper )
  */
 //================================================================================
 
-void _LayerEdge::InvalidateStep( int curStep, bool restoreLength )
+void _LayerEdge::InvalidateStep( int curStep, const _EdgesOnShape& eos, bool restoreLength )
 {
   if ( _pos.size() > curStep )
   {
@@ -5946,15 +6141,15 @@ void _LayerEdge::InvalidateStep( int curStep, bool restoreLength )
     _pos.resize( curStep );
     gp_Pnt nXYZ = _pos.back();
     SMDS_MeshNode* n = const_cast< SMDS_MeshNode*>( _nodes.back() );
-    if ( !_sWOL.IsNull() )
+    if ( !eos._sWOL.IsNull() )
     {
       TopLoc_Location loc;
-      if ( _sWOL.ShapeType() == TopAbs_EDGE )
+      if ( eos.SWOLType() == 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);
+        Handle(Geom_Curve) curve = BRep_Tool::Curve( TopoDS::Edge( eos._sWOL ), loc, f,l);
         nXYZ = curve->Value( nXYZ.X() ).Transformed( loc );
       }
       else
@@ -5962,7 +6157,7 @@ void _LayerEdge::InvalidateStep( int curStep, bool restoreLength )
         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 );
+        Handle(Geom_Surface) surface = BRep_Tool::Surface( TopoDS::Face(eos._sWOL), loc );
         nXYZ = surface->Value( nXYZ.X(), nXYZ.Y() ).Transformed( loc );
       }
     }
@@ -5998,186 +6193,186 @@ bool _ViscousBuilder::refine(_SolidData& data)
 
   // Create intermediate nodes on each _LayerEdge
 
-  int iS = 0, iEnd = data._endEdgeOnShape[ iS ];
-
-  for ( size_t i = 0; i < data._edges.size(); ++i )
+  for ( size_t iS = 0; iS < data._edgesOnShape.size(); ++iS )
   {
-    _LayerEdge& edge = *data._edges[i];
+    _EdgesOnShape& eos = data._edgesOnShape[iS];
+    if ( eos._edges.empty() ) continue;
 
-    if ( edge._nodes.size() < 2 )
+    if ( eos._edges[0]->_nodes.size() < 2 )
       continue; // on _noShrinkShapes
 
-    // get parameters of layers for the edge
-    if ( i == iEnd )
-      iEnd = data._endEdgeOnShape[ ++iS ];
-    const AverageHyp& hyp = data._hypOnShape[ iS ];
+    for ( size_t i = 0; i < eos._edges.size(); ++i )
+    {
+      _LayerEdge& edge = *eos._edges[i];
 
-    // get accumulated length of segments
-    vector< double > segLen( edge._pos.size() );
-    segLen[0] = 0.0;
-    for ( size_t j = 1; j < edge._pos.size(); ++j )
-      segLen[j] = segLen[j-1] + (edge._pos[j-1] - edge._pos[j] ).Modulus();
+      // get accumulated length of segments
+      vector< double > segLen( edge._pos.size() );
+      segLen[0] = 0.0;
+      for ( size_t 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( hyp.GetNumberLayers() + 1, 0 );
-      edge._nodes[1] = 0;
-      edge._nodes.back() = tgtNode;
-    }
-    // get data of a shrink shape
-    if ( !edge._sWOL.IsNull() && edge._sWOL != prevSWOL )
-    {
-      isOnEdge = ( edge._sWOL.ShapeType() == TopAbs_EDGE );
-      if ( isOnEdge )
-      {
-        geomEdge = TopoDS::Edge( edge._sWOL );
-        curve    = BRep_Tool::Curve( geomEdge, loc, f,l);
-      }
-      else
-      {
-        geomFace = TopoDS::Face( edge._sWOL );
-        surface  = BRep_Tool::Surface( geomFace, loc );
-      }
-      prevSWOL = edge._sWOL;
-    }
-    // restore shapePos of the last node by already treated _LayerEdge of another _SolidData
-    const TGeomID baseShapeId = edge._nodes[0]->getshapeId();
-    if ( baseShapeId != prevBaseId )
-    {
-      map< TGeomID, TNode2Edge* >::iterator s2ne = data._s2neMap.find( baseShapeId );
-      n2eMap = ( s2ne == data._s2neMap.end() ) ? 0 : n2eMap = s2ne->second;
-      prevBaseId = baseShapeId;
-    }
-    _LayerEdge* edgeOnSameNode = 0;
-    if ( n2eMap && (( n2e = n2eMap->find( edge._nodes[0] )) != n2eMap->end() ))
-    {
-      edgeOnSameNode = n2e->second;
-      const gp_XYZ& otherTgtPos = edgeOnSameNode->_pos.back();
-      SMDS_PositionPtr  lastPos = tgtNode->GetPosition();
-      if ( isOnEdge )
+      // allocate memory for new nodes if it is not yet refined
+      const SMDS_MeshNode* tgtNode = edge._nodes.back();
+      if ( edge._nodes.size() == 2 )
       {
-        SMDS_EdgePosition* epos = static_cast<SMDS_EdgePosition*>( lastPos );
-        epos->SetUParameter( otherTgtPos.X() );
+        edge._nodes.resize( eos._hyp.GetNumberLayers() + 1, 0 );
+        edge._nodes[1] = 0;
+        edge._nodes.back() = tgtNode;
       }
-      else
+      // get data of a shrink shape
+      if ( !eos._sWOL.IsNull() && eos._sWOL != prevSWOL )
       {
-        SMDS_FacePosition* fpos = static_cast<SMDS_FacePosition*>( lastPos );
-        fpos->SetUParameter( otherTgtPos.X() );
-        fpos->SetVParameter( otherTgtPos.Y() );
-      }
-    }
-    // calculate height of the first layer
-    double h0;
-    const double T = segLen.back(); //data._hyp.GetTotalThickness();
-    const double f = hyp.GetStretchFactor();
-    const int    N = 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;
-    size_t iSeg = 1;
-    for ( size_t 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>
+        isOnEdge = ( eos.SWOLType() == TopAbs_EDGE );
         if ( isOnEdge )
         {
-          u = pos.X();
-          if ( !node )
-            pos = curve->Value( u ).Transformed(loc);
+          geomEdge = TopoDS::Edge( eos._sWOL );
+          curve    = BRep_Tool::Curve( geomEdge, loc, f,l);
         }
         else
         {
-          uv.SetCoord( pos.X(), pos.Y() );
-          if ( !node )
-            pos = surface->Value( pos.X(), pos.Y() ).Transformed(loc);
+          geomFace = TopoDS::Face( eos._sWOL );
+          surface  = BRep_Tool::Surface( geomFace, loc );
         }
+        prevSWOL = eos._sWOL;
+      }
+      // restore shapePos of the last node by already treated _LayerEdge of another _SolidData
+      const TGeomID baseShapeId = edge._nodes[0]->getshapeId();
+      if ( baseShapeId != prevBaseId )
+      {
+        map< TGeomID, TNode2Edge* >::iterator s2ne = data._s2neMap.find( baseShapeId );
+        n2eMap = ( s2ne == data._s2neMap.end() ) ? 0 : n2eMap = s2ne->second;
+        prevBaseId = baseShapeId;
       }
-      // create or update the node
-      if ( !node )
+      _LayerEdge* edgeOnSameNode = 0;
+      if ( n2eMap && (( n2e = n2eMap->find( edge._nodes[0] )) != n2eMap->end() ))
       {
-        node = helper.AddNode( pos.X(), pos.Y(), pos.Z());
-        if ( !edge._sWOL.IsNull() )
+        edgeOnSameNode = n2e->second;
+        const gp_XYZ& otherTgtPos = edgeOnSameNode->_pos.back();
+        SMDS_PositionPtr  lastPos = tgtNode->GetPosition();
+        if ( isOnEdge )
         {
-          if ( isOnEdge )
-            getMeshDS()->SetNodeOnEdge( node, geomEdge, u );
-          else
-            getMeshDS()->SetNodeOnFace( node, geomFace, uv.X(), uv.Y() );
+          SMDS_EdgePosition* epos = static_cast<SMDS_EdgePosition*>( lastPos );
+          epos->SetUParameter( otherTgtPos.X() );
         }
         else
         {
-          getMeshDS()->SetNodeInVolume( node, helper.GetSubShapeID() );
+          SMDS_FacePosition* fpos = static_cast<SMDS_FacePosition*>( lastPos );
+          fpos->SetUParameter( otherTgtPos.X() );
+          fpos->SetVParameter( otherTgtPos.Y() );
         }
       }
+      // calculate height of the first layer
+      double h0;
+      const double T = segLen.back(); //data._hyp.GetTotalThickness();
+      const double f = eos._hyp.GetStretchFactor();
+      const int    N = eos._hyp.GetNumberLayers();
+      const double fPowN = pow( f, N );
+      if ( fPowN - 1 <= numeric_limits<double>::min() )
+        h0 = T / N;
       else
-      {
-        if ( !edge._sWOL.IsNull() )
+        h0 = T * ( f - 1 )/( fPowN - 1 );
+
+      const double zeroLen = std::numeric_limits<double>::min();
+
+      // create intermediate nodes
+      double hSum = 0, hi = h0/f;
+      size_t iSeg = 1;
+      for ( size_t 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 ( !eos._sWOL.IsNull() )
         {
-          // make average pos from new and current parameters
+          // compute XYZ by parameters <pos>
           if ( isOnEdge )
           {
-            u = 0.5 * ( u + helper.GetNodeU( geomEdge, node ));
-            pos = curve->Value( u ).Transformed(loc);
-
-            SMDS_EdgePosition* epos = static_cast<SMDS_EdgePosition*>( node->GetPosition() );
-            epos->SetUParameter( u );
+            u = pos.X();
+            if ( !node )
+              pos = curve->Value( u ).Transformed(loc);
+          }
+          else
+          {
+            uv.SetCoord( pos.X(), pos.Y() );
+            if ( !node )
+              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 ( !eos._sWOL.IsNull() )
+          {
+            if ( isOnEdge )
+              getMeshDS()->SetNodeOnEdge( node, geomEdge, u );
+            else
+              getMeshDS()->SetNodeOnFace( node, geomFace, uv.X(), uv.Y() );
           }
           else
           {
-            uv = 0.5 * ( uv + helper.GetNodeUV( geomFace, node ));
-            pos = surface->Value( uv.X(), uv.Y()).Transformed(loc);
+            getMeshDS()->SetNodeInVolume( node, helper.GetSubShapeID() );
+          }
+        }
+        else
+        {
+          if ( !eos._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);
+
+              SMDS_EdgePosition* epos = static_cast<SMDS_EdgePosition*>( node->GetPosition() );
+              epos->SetUParameter( u );
+            }
+            else
+            {
+              uv = 0.5 * ( uv + helper.GetNodeUV( geomFace, node ));
+              pos = surface->Value( uv.X(), uv.Y()).Transformed(loc);
 
-            SMDS_FacePosition* fpos = static_cast<SMDS_FacePosition*>( node->GetPosition() );
-            fpos->SetUParameter( uv.X() );
-            fpos->SetVParameter( uv.Y() );
+              SMDS_FacePosition* fpos = static_cast<SMDS_FacePosition*>( node->GetPosition() );
+              fpos->SetUParameter( uv.X() );
+              fpos->SetVParameter( uv.Y() );
+            }
           }
+          node->setXYZ( pos.X(), pos.Y(), pos.Z() );
         }
-        node->setXYZ( pos.X(), pos.Y(), pos.Z() );
+      } // loop on edge._nodes
+
+      if ( !eos._sWOL.IsNull() ) // prepare for shrink()
+      {
+        if ( isOnEdge )
+          edge._pos.back().SetCoord( u, 0,0);
+        else
+          edge._pos.back().SetCoord( uv.X(), uv.Y() ,0);
+
+        if ( edgeOnSameNode )
+          edgeOnSameNode->_pos.back() = edge._pos.back();
       }
-    } // loop on edge._nodes
 
-    if ( !edge._sWOL.IsNull() ) // prepare for shrink()
-    {
-      if ( isOnEdge )
-        edge._pos.back().SetCoord( u, 0,0);
-      else
-        edge._pos.back().SetCoord( uv.X(), uv.Y() ,0);
+    } // loop on eos._edges to create nodes
 
-      if ( edgeOnSameNode )
-        edgeOnSameNode->_pos.back() = edge._pos.back();
-    }
 
-  } // loop on data._edges to create nodes
+    if ( !getMeshDS()->IsEmbeddedMode() )
+      // Log node movement
+      for ( size_t i = 0; i < eos._edges.size(); ++i )
+      {
+        SMESH_TNodeXYZ p ( eos._edges[i]->_nodes.back() );
+        getMeshDS()->MoveNode( p._node, p.X(), p.Y(), p.Z() );
+      }
+  }
 
-  if ( !getMeshDS()->IsEmbeddedMode() )
-    // Log node movement
-    for ( size_t i = 0; i < data._edges.size(); ++i )
-    {
-      _LayerEdge& edge = *data._edges[i];
-      SMESH_TNodeXYZ p ( edge._nodes.back() );
-      getMeshDS()->MoveNode( p._node, p.X(), p.Y(), p.Z() );
-    }
 
   // Create volumes
 
@@ -6372,6 +6567,7 @@ bool _ViscousBuilder::shrink()
 
   // EDGE's to shrink
   map< TGeomID, _Shrinker1D > e2shrMap;
+  vector< _EdgesOnShape* > subEOS;
   vector< _LayerEdge* > lEdges;
 
   // loop on FACES to srink mesh on
@@ -6419,30 +6615,26 @@ bool _ViscousBuilder::shrink()
     }
 
     // Find _LayerEdge's inflated along F
+    subEOS.clear();
     lEdges.clear();
     {
-      set< TGeomID > subIDs;
-      SMESH_subMeshIteratorPtr subIt = sm->getDependsOnIterator(/*includeSelf=*/false);
+      SMESH_subMeshIteratorPtr subIt = sm->getDependsOnIterator(/*includeSelf=*/false,
+                                                                /*complexFirst=*/true); //!!!
       while ( subIt->more() )
-        subIDs.insert( subIt->next()->GetId() );
-
-      int iBeg, iEnd = 0;
-      for ( int iS = 0; iS < data._endEdgeOnShape.size() && !subIDs.empty(); ++iS )
       {
-        iBeg = iEnd;
-        iEnd = data._endEdgeOnShape[ iS ];
-        TGeomID shapeID = data._edges[ iBeg ]->_nodes[0]->getshapeId();
-        set< TGeomID >::iterator idIt = subIDs.find( shapeID );
-        if ( idIt == subIDs.end() ||
-             data._edges[ iBeg ]->_sWOL.IsNull() ) continue;
-        subIDs.erase( idIt );
+        const TGeomID subID = subIt->next()->GetId();
+        if ( data._noShrinkShapes.count( subID ))
+          continue;
+        _EdgesOnShape* eos = data.GetShapeEdges( subID );
+        if ( !eos || eos->_sWOL.IsNull() ) continue;
 
-        if ( !data._noShrinkShapes.count( shapeID ))
-          for ( ; iBeg < iEnd; ++iBeg )
-          {
-            lEdges.push_back( data._edges[ iBeg ] );
-            prepareEdgeToShrink( *data._edges[ iBeg ], F, helper, smDS );
-          }
+        subEOS.push_back( eos );
+
+        for ( size_t i = 0; i < eos->_edges.size(); ++i )
+        {
+          lEdges.push_back( eos->_edges[ i ] );
+          prepareEdgeToShrink( *eos->_edges[ i ], *eos, helper, smDS );
+        }
       }
     }
 
@@ -6456,25 +6648,29 @@ bool _ViscousBuilder::shrink()
     // Replace source nodes by target nodes in mesh faces to shrink
     dumpFunction(SMESH_Comment("replNodesOnFace")<<f2sd->first); // debug
     const SMDS_MeshNode* nodes[20];
-    for ( size_t i = 0; i < lEdges.size(); ++i )
+    for ( size_t iS = 0; iS < subEOS.size(); ++iS )
     {
-      _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() )
+      _EdgesOnShape& eos = * subEOS[ iS ];
+      for ( size_t i = 0; i < eos._edges.size(); ++i )
       {
-        const SMDS_MeshElement* f = fIt->next();
-        if ( !smDS->Contains( f ))
-          continue;
-        SMDS_NodeIteratorPtr nIt = f->nodeIterator();
-        for ( int iN = 0; nIt->more(); ++iN )
+        _LayerEdge& edge = *eos._edges[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_MeshNode* n = nIt->next();
-          nodes[iN] = ( n == srcNode ? tgtNode : n );
+          const SMDS_MeshElement* f = fIt->next();
+          if ( !smDS->Contains( f ))
+            continue;
+          SMDS_NodeIteratorPtr nIt = f->nodeIterator();
+          for ( int iN = 0; nIt->more(); ++iN )
+          {
+            const SMDS_MeshNode* n = nIt->next();
+            nodes[iN] = ( n == srcNode ? tgtNode : n );
+          }
+          helper.GetMeshDS()->ChangeElementNodes( f, nodes, f->NbNodes() );
+          dumpChangeNodes( f );
         }
-        helper.GetMeshDS()->ChangeElementNodes( f, nodes, f->NbNodes() );
-        dumpChangeNodes( f );
       }
     }
     dumpFunctionEnd();
@@ -6504,21 +6700,25 @@ bool _ViscousBuilder::shrink()
     // Find EDGE's to shrink and set simpices to LayerEdge's
     set< _Shrinker1D* > eShri1D;
     {
-      for ( size_t i = 0; i < lEdges.size(); ++i )
+      for ( size_t iS = 0; iS < subEOS.size(); ++iS )
       {
-        _LayerEdge* edge = lEdges[i];
-        if ( edge->_sWOL.ShapeType() == TopAbs_EDGE )
+        _EdgesOnShape& eos = * subEOS[ iS ];
+        if ( eos.SWOLType() == TopAbs_EDGE )
         {
-          TGeomID edgeIndex = getMeshDS()->ShapeToIndex( edge->_sWOL );
-          _Shrinker1D& srinker = e2shrMap[ edgeIndex ];
+          SMESH_subMesh* edgeSM = _mesh->GetSubMesh( eos._sWOL );
+          _Shrinker1D& srinker  = e2shrMap[ edgeSM->GetId() ];
           eShri1D.insert( & srinker );
-          srinker.AddEdge( edge, helper );
-          VISCOUS_3D::ToClearSubWithMain( _mesh->GetSubMesh( edge->_sWOL ), data._solid );
+          srinker.AddEdge( eos._edges[0], eos, helper );
+          VISCOUS_3D::ToClearSubWithMain( edgeSM, data._solid );
           // restore params of nodes on EGDE if the EDGE has been already
-          // srinked while srinking another FACE
+          // srinked while srinking other FACE
           srinker.RestoreParams();
         }
-        _Simplex::GetSimplices( /*tgtNode=*/edge->_nodes.back(), edge->_simplices, ignoreShapes );
+        for ( size_t i = 0; i < eos._edges.size(); ++i )
+        {
+          _LayerEdge& edge = * eos._edges[i];
+          _Simplex::GetSimplices( /*tgtNode=*/edge._nodes.back(), edge._simplices, ignoreShapes );
+        }
       }
     }
 
@@ -6553,9 +6753,13 @@ bool _ViscousBuilder::shrink()
       // -----------------------------------------------
       dumpFunction(SMESH_Comment("moveBoundaryOnF")<<f2sd->first<<"_st"<<shriStep ); // debug
       shrinked = false;
-      for ( size_t i = 0; i < lEdges.size(); ++i )
+      for ( size_t iS = 0; iS < subEOS.size(); ++iS )
       {
-        shrinked |= lEdges[i]->SetNewLength2d( surface,F,helper );
+        _EdgesOnShape& eos = * subEOS[ iS ];
+        for ( size_t i = 0; i < eos._edges.size(); ++i )
+        {
+          shrinked |= eos._edges[i]->SetNewLength2d( surface, F, eos, helper );
+        }
       }
       dumpFunctionEnd();
 
@@ -6577,10 +6781,12 @@ bool _ViscousBuilder::shrink()
         int oldBadNb = badNb;
         badNb = 0;
         moved = false;
+        // '% 5' minimizes NB FUNCTIONS on viscous_layers_00/B2 case
+        _SmoothNode::SmoothType smooTy = ( smooStep % 5 ) ? smoothType : _SmoothNode::LAPLACIAN;
         for ( size_t i = 0; i < nodesToSmooth.size(); ++i )
         {
-          moved |= nodesToSmooth[i].Smooth( badNb,surface,helper,refSign,
-                                            smoothType, /*set3D=*/isConcaveFace);
+          moved |= nodesToSmooth[i].Smooth( badNb, surface, helper, refSign,
+                                            smooTy, /*set3D=*/isConcaveFace);
         }
         if ( badNb < oldBadNb )
           nbNoImpSteps = 0;
@@ -6695,17 +6901,17 @@ bool _ViscousBuilder::shrink()
 //================================================================================
 
 bool _ViscousBuilder::prepareEdgeToShrink( _LayerEdge&            edge,
-                                           const TopoDS_Face&     F,
+                                           _EdgesOnShape&         eos,
                                            SMESH_MesherHelper&    helper,
                                            const SMESHDS_SubMesh* faceSubMesh)
 {
   const SMDS_MeshNode* srcNode = edge._nodes[0];
   const SMDS_MeshNode* tgtNode = edge._nodes.back();
 
-  if ( edge._sWOL.ShapeType() == TopAbs_FACE )
+  if ( eos.SWOLType() == TopAbs_FACE )
   {
-    gp_XY srcUV( edge._pos[0].X(), edge._pos[0].Y() );//helper.GetNodeUV( F, srcNode );
-    gp_XY tgtUV = edge.LastUV( F );                   //helper.GetNodeUV( F, tgtNode );
+    gp_XY srcUV ( edge._pos[0].X(), edge._pos[0].Y() );          //helper.GetNodeUV( F, srcNode );
+    gp_XY tgtUV = edge.LastUV( TopoDS::Face( eos._sWOL ), eos ); //helper.GetNodeUV( F, tgtNode );
     gp_Vec2d uvDir( srcUV, tgtUV );
     double uvLen = uvDir.Magnitude();
     uvDir /= uvLen;
@@ -6722,7 +6928,7 @@ bool _ViscousBuilder::prepareEdgeToShrink( _LayerEdge&            edge,
   }
   else // _sWOL is TopAbs_EDGE
   {
-    const TopoDS_Edge&    E = TopoDS::Edge( edge._sWOL );
+    const TopoDS_Edge&    E = TopoDS::Edge( eos._sWOL );
     SMESHDS_SubMesh* edgeSM = getMeshDS()->MeshElements( E );
     if ( !edgeSM || edgeSM->NbElements() == 0 )
       return error(SMESH_Comment("Not meshed EDGE ") << getMeshDS()->ShapeToIndex( E ));
@@ -6968,6 +7174,7 @@ void _ViscousBuilder::fixBadFaces(const TopoDS_Face&          F,
 
 bool _LayerEdge::SetNewLength2d( Handle(Geom_Surface)& surface,
                                  const TopoDS_Face&    F,
+                                 _EdgesOnShape&        eos,
                                  SMESH_MesherHelper&   helper )
 {
   if ( _pos.empty() )
@@ -6975,7 +7182,7 @@ bool _LayerEdge::SetNewLength2d( Handle(Geom_Surface)& surface,
 
   SMDS_MeshNode* tgtNode = const_cast< SMDS_MeshNode*& >( _nodes.back() );
 
-  if ( _sWOL.ShapeType() == TopAbs_FACE )
+  if ( eos.SWOLType() == TopAbs_FACE )
   {
     gp_XY    curUV = helper.GetNodeUV( F, tgtNode );
     gp_Pnt2d tgtUV( _pos[0].X(), _pos[0].Y() );
@@ -7024,7 +7231,7 @@ bool _LayerEdge::SetNewLength2d( Handle(Geom_Surface)& surface,
   }
   else // _sWOL is TopAbs_EDGE
   {
-    const TopoDS_Edge&      E = TopoDS::Edge( _sWOL );
+    const TopoDS_Edge&      E = TopoDS::Edge( eos._sWOL );
     const SMDS_MeshNode*   n2 = _simplices[0]._nPrev;
     SMDS_EdgePosition* tgtPos = static_cast<SMDS_EdgePosition*>( tgtNode->GetPosition() );
 
@@ -7230,21 +7437,26 @@ gp_XY _SmoothNode::computeAngularPos(vector<gp_XY>& uv,
 
 _SolidData::~_SolidData()
 {
-  for ( size_t i = 0; i < _edges.size(); ++i )
+  TNode2Edge::iterator n2e = _n2eMap.begin();
+  for ( ; n2e != _n2eMap.end(); ++n2e )
   {
-    if ( _edges[i] && _edges[i]->_2neibors )
-      delete _edges[i]->_2neibors;
-    delete _edges[i];
+    _LayerEdge* & e = n2e->second;
+    if ( e && e->_2neibors )
+      delete e->_2neibors;
+    delete e;
+    e = NULL;
   }
-  _edges.clear();
+  _n2eMap.clear();
 }
 //================================================================================
 /*!
- * \brief Add a _LayerEdge inflated along the EDGE
+ * \brief Keep a _LayerEdge inflated along the EDGE
  */
 //================================================================================
 
-void _Shrinker1D::AddEdge( const _LayerEdge* e, SMESH_MesherHelper& helper )
+void _Shrinker1D::AddEdge( const _LayerEdge*   e,
+                           _EdgesOnShape&      eos,
+                           SMESH_MesherHelper& helper )
 {
   // init
   if ( _nodes.empty() )
@@ -7255,16 +7467,16 @@ void _Shrinker1D::AddEdge( const _LayerEdge* e, SMESH_MesherHelper& helper )
   // check _LayerEdge
   if ( e == _edges[0] || e == _edges[1] )
     return;
-  if ( e->_sWOL.IsNull() || e->_sWOL.ShapeType() != TopAbs_EDGE )
+  if ( eos.SWOLType() != TopAbs_EDGE )
     throw SALOME_Exception(LOCALIZED("Wrong _LayerEdge is added"));
-  if ( _edges[0] && _edges[0]->_sWOL != e->_sWOL )
+  if ( _edges[0] && !_geomEdge.IsSame( eos._sWOL ))
     throw SALOME_Exception(LOCALIZED("Wrong _LayerEdge is added"));
 
   // store _LayerEdge
-  const TopoDS_Edge& E = TopoDS::Edge( e->_sWOL );
+  _geomEdge = TopoDS::Edge( eos._sWOL );
   double f,l;
-  BRep_Tool::Range( E, f,l );
-  double u = helper.GetNodeU( E, e->_nodes[0], e->_nodes.back());
+  BRep_Tool::Range( _geomEdge, f,l );
+  double u = helper.GetNodeU( _geomEdge, e->_nodes[0], e->_nodes.back());
   _edges[ u < 0.5*(f+l) ? 0 : 1 ] = e;
 
   // Update _nodes
@@ -7274,11 +7486,11 @@ void _Shrinker1D::AddEdge( const _LayerEdge* e, SMESH_MesherHelper& helper )
 
   if ( _nodes.empty() )
   {
-    SMESHDS_SubMesh * eSubMesh = helper.GetMeshDS()->MeshElements( E );
+    SMESHDS_SubMesh * eSubMesh = helper.GetMeshDS()->MeshElements( _geomEdge );
     if ( !eSubMesh || eSubMesh->NbNodes() < 1 )
       return;
     TopLoc_Location loc;
-    Handle(Geom_Curve) C = BRep_Tool::Curve(E, loc, f,l);
+    Handle(Geom_Curve) C = BRep_Tool::Curve( _geomEdge, loc, f,l );
     GeomAdaptor_Curve aCurve(C, f,l);
     const double totLen = GCPnts_AbscissaPoint::Length(aCurve, f, l);
 
@@ -7294,7 +7506,7 @@ void _Shrinker1D::AddEdge( const _LayerEdge* e, SMESH_MesherHelper& helper )
            node == tgtNode0 || node == tgtNode1 )
         continue; // refinement nodes
       _nodes.push_back( node );
-      _initU.push_back( helper.GetNodeU( E, node ));
+      _initU.push_back( helper.GetNodeU( _geomEdge, node ));
       double len = GCPnts_AbscissaPoint::Length(aCurve, f, _initU.back());
       _normPar.push_back(  len / totLen );
     }
@@ -7328,17 +7540,16 @@ void _Shrinker1D::Compute(bool set3D, SMESH_MesherHelper& helper)
   _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);
+    Handle(Geom_Curve) C = BRep_Tool::Curve(_geomEdge, f,l);
     GeomAdaptor_Curve aCurve(C, f,l);
 
     if ( _edges[0] )
-      f = helper.GetNodeU( E, _edges[0]->_nodes.back(), _nodes[0] );
+      f = helper.GetNodeU( _geomEdge, _edges[0]->_nodes.back(), _nodes[0] );
     if ( _edges[1] )
-      l = helper.GetNodeU( E, _edges[1]->_nodes.back(), _nodes.back() );
+      l = helper.GetNodeU( _geomEdge, _edges[1]->_nodes.back(), _nodes.back() );
     double totLen = GCPnts_AbscissaPoint::Length( aCurve, f, l );
 
     for ( size_t i = 0; i < _nodes.size(); ++i )
@@ -7357,11 +7568,11 @@ void _Shrinker1D::Compute(bool set3D, SMESH_MesherHelper& helper)
   }
   else
   {
-    BRep_Tool::Range( E, f,l );
+    BRep_Tool::Range( _geomEdge, f,l );
     if ( _edges[0] )
-      f = helper.GetNodeU( E, _edges[0]->_nodes.back(), _nodes[0] );
+      f = helper.GetNodeU( _geomEdge, _edges[0]->_nodes.back(), _nodes[0] );
     if ( _edges[1] )
-      l = helper.GetNodeU( E, _edges[1]->_nodes.back(), _nodes.back() );
+      l = helper.GetNodeU( _geomEdge, _edges[1]->_nodes.back(), _nodes.back() );
     
     for ( size_t i = 0; i < _nodes.size(); ++i )
     {
@@ -7404,7 +7615,7 @@ void _Shrinker1D::SwapSrcTgtNodes( SMESHDS_Mesh* mesh )
   {
     if ( !_edges[i] ) continue;
 
-    SMESHDS_SubMesh * eSubMesh = mesh->MeshElements( _edges[i]->_sWOL );
+    SMESHDS_SubMesh * eSubMesh = mesh->MeshElements( _geomEdge );
     if ( !eSubMesh ) return;
     const SMDS_MeshNode* srcNode = _edges[i]->_nodes[0];
     const SMDS_MeshNode* tgtNode = _edges[i]->_nodes.back();
@@ -7568,19 +7779,21 @@ bool _ViscousBuilder::addBoundaryElements()
       for ( int isFirst = 0; isFirst < 2; ++isFirst )
       {
         _LayerEdge* edge = isFirst ? ledges.front() : ledges.back();
-        if ( !edge->_sWOL.IsNull() && edge->_sWOL.ShapeType() == TopAbs_EDGE )
+        _EdgesOnShape* eos = data.GetShapeEdges( edge );
+        if ( eos && eos->SWOLType() == TopAbs_EDGE )
         {
           vector< const SMDS_MeshNode*>&  nn = edge->_nodes;
           if ( nn.size() < 2 || nn[1]->GetInverseElementIterator( SMDSAbs_Edge )->more() )
             continue;
-          helper.SetSubShape( edge->_sWOL );
+          helper.SetSubShape( eos->_sWOL );
           helper.SetElementsOnShape( true );
           for ( size_t z = 1; z < nn.size(); ++z )
             helper.AddEdge( nn[z-1], nn[z] );
         }
       }
-    }
-  }
+
+    } // loop on EDGE's
+  } // loop on _SolidData's
 
   return true;
 }
index 9c26048b637c2fa135218649d179e8e0de887db9..661ab8ab1194da3918245bddf35777dc2b823cd7 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
@@ -42,29 +42,44 @@ public:
 
   // Set boundary shapes (faces in 3D, edges in 2D) either to exclude from
   // treatment or to make the Viscous Layers on
-  void SetBndShapes(const std::vector<int>& shapeIds, bool toIgnore);
+  void   SetBndShapes(const std::vector<int>& shapeIds, bool toIgnore);
   std::vector<int> GetBndShapes() const { return _shapeIds; }
-  bool IsToIgnoreShapes() const { return _isToIgnoreShapes; }
+  bool   IsToIgnoreShapes() const { return _isToIgnoreShapes; }
 
   // Set total thickness of layers of prisms
-  void SetTotalThickness(double thickness);
+  void   SetTotalThickness(double thickness);
   double GetTotalThickness() const { return _thickness; }
 
   // Set number of layers of prisms
-  void SetNumberLayers(int nb);
-  int GetNumberLayers() const { return _nbLayers; }
+  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);
+  void   SetStretchFactor(double factor);
   double GetStretchFactor() const { return _stretchFactor; }
 
+  // Method of computing node translation 
+  enum ExtrusionMethod {
+    // node is translated along normal to a surface with possible further smoothing
+    SURF_OFFSET_SMOOTH,
+    // node is translated along the average normal of surrounding faces till
+    // intersection with a neighbor face translated along its own normal 
+    // by the layers thickness
+    FACE_OFFSET,
+    // node is translated along the average normal of surrounding faces
+    // by the layers thickness
+    NODE_OFFSET
+  };
+  void   SetMethod( ExtrusionMethod how );
+  ExtrusionMethod GetMethod() const { return _method; }
+
   // 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;
 
-  // Checks compatibility of assigned StdMeshers_ViscousLayers hypotheses 
+  // Checks compatibility of assigned StdMeshers_ViscousLayers hypotheses
   static SMESH_ComputeErrorPtr
     CheckHypothesis(SMESH_Mesh&                          aMesh,
                     const TopoDS_Shape&                  aShape,
@@ -81,8 +96,6 @@ public:
     * \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);
 
@@ -102,6 +115,7 @@ public:
   int              _nbLayers;
   double           _thickness;
   double           _stretchFactor;
+  ExtrusionMethod  _method;
 };
 
 class SMESH_subMesh;
index 013e2d9d94d5f2747d825dc0d68687f8e39f5811..56613b3515179ab19d2e6753ea3bc2509b726dba 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
@@ -817,7 +817,7 @@ bool _ViscousBuilder2D::findEdgesWithLayers()
                   {
                     hasVL = false;
                     for ( hyp = allHyps.begin(); hyp != allHyps.end() && !hasVL; ++hyp )
-                      if ( viscHyp = dynamic_cast<const THypVL*>( *hyp ))
+                      if (( viscHyp = dynamic_cast<const THypVL*>( *hyp )))
                         hasVL = viscHyp->IsShapeWithLayers( neighbourID );
                   }
                   if ( !hasVL )
@@ -1438,7 +1438,7 @@ bool _ViscousBuilder2D::inflate()
       _PolyLine::TEdgeIterator eIt = isR ? L._lEdges.end()-1 : L._lEdges.begin();
       if ( eIt->_length2D == 0 ) continue;
       _Segment seg1( eIt->_uvOut, eIt->_uvIn );
-      for ( eIt += deltaIt; nbRemove < L._lEdges.size()-1; eIt += deltaIt )
+      for ( eIt += deltaIt; nbRemove < (int)L._lEdges.size()-1; eIt += deltaIt )
       {
         _Segment seg2( eIt->_uvOut, eIt->_uvIn );
         if ( !intersection.Compute( seg1, seg2 ))
@@ -1446,7 +1446,7 @@ bool _ViscousBuilder2D::inflate()
         ++nbRemove;
       }
       if ( nbRemove > 0 ) {
-        if ( nbRemove == L._lEdges.size()-1 ) // 1st and last _LayerEdge's intersect
+        if ( nbRemove == (int)L._lEdges.size()-1 ) // 1st and last _LayerEdge's intersect
         {
           --nbRemove;
           _LayerEdge& L0 = L._lEdges.front();
@@ -2131,7 +2131,7 @@ bool _ViscousBuilder2D::refine()
   // store a proxyMesh in a sub-mesh
   // make faces on each _PolyLine
   vector< double > layersHeight;
-  double prevLen2D = -1;
+  //double prevLen2D = -1;
   for ( size_t iL = 0; iL < _polyLineVec.size(); ++iL )
   {
     _PolyLine& L = _polyLineVec[ iL ];
@@ -2669,7 +2669,7 @@ _SegmentTree::box_type* _SegmentTree::buildRootBox()
 
 void _SegmentTree::buildChildrenData()
 {
-  for ( int i = 0; i < _segments.size(); ++i )
+  for ( size_t i = 0; i < _segments.size(); ++i )
     for (int j = 0; j < nbChildren(); j++)
       if ( !myChildren[j]->getBox()->IsOut( *_segments[i]._seg->_uv[0],
                                             *_segments[i]._seg->_uv[1] ))
@@ -2680,7 +2680,7 @@ void _SegmentTree::buildChildrenData()
   for (int j = 0; j < nbChildren(); j++)
   {
     _SegmentTree* child = static_cast<_SegmentTree*>( myChildren[j]);
-    child->myIsLeaf = ( child->_segments.size() <= maxNbSegInLeaf() );
+    child->myIsLeaf = ((int) child->_segments.size() <= maxNbSegInLeaf() );
   }
 }
 
@@ -2698,7 +2698,7 @@ void _SegmentTree::GetSegmentsNear( const _Segment&            seg,
 
   if ( isLeaf() )
   {
-    for ( int i = 0; i < _segments.size(); ++i )
+    for ( size_t i = 0; i < _segments.size(); ++i )
       if ( !_segments[i].IsOut( seg ))
         found.push_back( _segments[i]._seg );
   }
@@ -2724,7 +2724,7 @@ void _SegmentTree::GetSegmentsNear( const gp_Ax2d&             ray,
 
   if ( isLeaf() )
   {
-    for ( int i = 0; i < _segments.size(); ++i )
+    for ( size_t i = 0; i < _segments.size(); ++i )
       if ( !_segments[i].IsOut( ray ))
         found.push_back( _segments[i]._seg );
   }
index f9fab2b338c25cc01f2faddc143c59ab7aede241..e508f173e6b87e7b8291d00c3ef7c967970c2930 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index 229c9ac2d9929fd2a33d2679a55928dfc5cefa8b..9db3c64c0ba7b09d86e71192f9c52c9a2c769ce7 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2012-2015  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
@@ -72,7 +72,6 @@ SET(_link_LIBRARIES
 # header files / to be processed by moc
 SET(_moc_HEADERS
   StdMeshersGUI_StdHypothesisCreator.h
-  StdMeshersGUI_DistrPreview.h
   StdMeshersGUI_DistrTable.h
   StdMeshersGUI_NbSegmentsCreator.h
   StdMeshersGUI_ObjectReferenceParamWdg.h
@@ -82,8 +81,15 @@ SET(_moc_HEADERS
   StdMeshersGUI_SubShapeSelectorWdg.h
   StdMeshersGUI_CartesianParamCreator.h
   StdMeshersGUI_RadioButtonsGrpWdg.h
+  StdMeshersGUI_PropagationHelperWdg.h
 )
 
+IF(SALOME_USE_PLOT2DVIEWER)
+  LIST(APPEND _moc_HEADERS
+    StdMeshersGUI_DistrPreview.h
+    )
+ENDIF()
+
 # header files / no moc processing
 SET(_other_HEADERS
   SMESH_StdMeshersGUI.hxx
@@ -101,7 +107,6 @@ QT4_WRAP_CPP(_moc_SOURCES ${_moc_HEADERS})
 SET(_other_SOURCES
   StdMeshersGUI.cxx
   StdMeshersGUI_StdHypothesisCreator.cxx
-  StdMeshersGUI_DistrPreview.cxx
   StdMeshersGUI_DistrTable.cxx
   StdMeshersGUI_NbSegmentsCreator.cxx
   StdMeshersGUI_ObjectReferenceParamWdg.cxx
@@ -111,8 +116,15 @@ SET(_other_SOURCES
   StdMeshersGUI_SubShapeSelectorWdg.cxx
   StdMeshersGUI_CartesianParamCreator.cxx
   StdMeshersGUI_RadioButtonsGrpWdg.cxx
+  StdMeshersGUI_PropagationHelperWdg.cxx
 )
 
+IF(SALOME_USE_PLOT2DVIEWER)
+  LIST(APPEND _other_SOURCES
+    StdMeshersGUI_DistrPreview.cxx
+    )
+ENDIF()
+
 # sources / to compile
 SET(StdMeshersGUI_SOURCES ${_other_SOURCES} ${_moc_SOURCES})
 
index 0e78ac5ac5bda17efcbe230aacd74b7a5d9f321c..e565d5f5907af318861efcdb08ec8fd8fb6c848c 100755 (executable)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index c23b6fd01f13d81322585fb1526861a912e8d6a2..eaca180d309bbec2fa1cf1ac1134ffac9b56b1ab 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 0c5ad56fb6aa56a495f227cd3adb5603eab12665..762bccdecff55ae3a8b5541f5c4265e8e8c7402f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 48477ea0d9f262987f90ddd8864e1df0af5a06ee..a8e87306fa55f1b9c8691f7e512c44c1a587ff6f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 5234cf911ad42c7629c978a15bb93dbff2275c4f..0d567e4fb232d2e74af3458a136ca8d5cd6547f5 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -106,7 +106,7 @@ StdMeshersGUI_DistrPreview::StdMeshersGUI_DistrPreview( QWidget* p, StdMeshers::
   myDistr->attach( this );
   QPen distrPen = QPen( Qt::blue, 1 );
   QwtSymbol* distrSymbol = new QwtSymbol( QwtSymbol::XCross, QBrush( Qt::blue ),
-                                                 QPen( Qt::blue ), QSize( 5, 5 ) );
+                                                  QPen( Qt::blue ), QSize( 5, 5 ) );
   myDistr->setPen( distrPen );
   myDistr->setSymbol( distrSymbol );
   if( Plot2d_QwtLegendLabel* anItem = getLegendLabel( myDistr ) ) {
index 3806b3e55b4352eb1277afc26c16e22413ad3048..cf31e093283ecaaad71a5fc5eae6f776f28516fa 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 582b92b2585ab0bd1df17b282c932c538be729f7..2066cac77a02cd2bc0fb54f87bb29523844a8e9a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -445,7 +445,7 @@ deleteRow()
 {
   QList<int> selRows = selectedRows();
   for ( int r = selRows.count()-1; r >= 0; r-- )
-    removeRow( r );
+    removeRow( selRows.at(r) );
 }
 
 void
index 7cdbc84e83256150c1a288a3a476c0cce01ca3e5..dbf216a4f5b3d1bbd2f070b03f541aacabe7e467 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 4d36d494c43c8e683bf2ab5b8548b980ae275884..3b5ece91c76d2661195971d527270a09020f6b72 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index bcd19407eedeea0992f3af18fc14e67f6df0c2ab..3483edb8189a2d065a86de7091ac54a9a15ea8c8 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index 78608b81f07bc4cfb490abe5193afc781db51836..82d2e437d8726a5a743e365d02278b3e1f5ebf3c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -111,9 +111,11 @@ void StdMeshersGUI_LayerDistributionParamWdg::init()
 
   myCreateButton = new QPushButton( this );
   myCreateButton->setObjectName( "createBut" );
+  myCreateButton->setMinimumWidth(100);
 
   myEditButton   = new QPushButton( tr("EDIT"), this );
   myEditButton->setObjectName( "editBut" );
+  myEditButton->setMinimumWidth(100);
 
   myHypTypePopup = new QMenu( this );
 
@@ -130,8 +132,8 @@ void StdMeshersGUI_LayerDistributionParamWdg::init()
   }
 
   aHBox->addWidget( myCreateButton );
+  aHBox->addStretch(5);
   aHBox->addWidget( myEditButton );
-  aHBox->addStretch();
 
   connect( myCreateButton, SIGNAL(clicked()), SLOT(onCreate()));
   connect( myEditButton,   SIGNAL(clicked()), SLOT(onEdit()));
index 2a86090def3c124f362c37f286297b90340470c8..f7c8ea42b5e9b172e1b57edd6fe1eccff68774ca 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 9003083e8b3686d36343e8428357e305ffab4469..6749e0b9c753d5653eff3116fe0d1e0be5dd39e6 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 // SMESH includes
 //
 #include "StdMeshersGUI_NbSegmentsCreator.h"
+#ifndef DISABLE_PLOT2DVIEWER
+  #include "StdMeshersGUI_DistrPreview.h"
+#endif
 #include "StdMeshersGUI_DistrTable.h"
-#include "StdMeshersGUI_DistrPreview.h"
+#include "StdMeshersGUI_PropagationHelperWdg.h"
 #include "StdMeshersGUI_SubShapeSelectorWdg.h"
 
 #include <SMESHGUI.h>
@@ -63,7 +66,9 @@ StdMeshersGUI_NbSegmentsCreator::StdMeshersGUI_NbSegmentsCreator()
   myDistr( 0 ),
   myScale( 0 ),
   myTable( 0 ),
+#ifndef DISABLE_PLOT2DVIEWER
   myPreview( 0 ),
+#endif
   myExpr( 0 ),
   myConvBox( 0 ),
   myConv( 0 ),
@@ -89,9 +94,10 @@ bool StdMeshersGUI_NbSegmentsCreator::checkParams( QString& msg ) const
   readParamsFromHypo( data_old );
   readParamsFromWidgets( data_new );
   bool res = storeParamsToHypo( data_new );
-  storeParamsToHypo( data_old );
   res = myNbSeg->isValid( msg, true ) && res;
   res = myScale->isValid( msg, true ) && res;
+  if ( !res )
+    storeParamsToHypo( data_old );
   return res;
 }
 
@@ -178,12 +184,14 @@ QFrame* StdMeshersGUI_NbSegmentsCreator::buildFrame()
   
        // c)  table
   myTable = new StdMeshersGUI_DistrTableFrame( GroupC1 );
+  myTable->setMinimumHeight(220);
   myDistLayout->addWidget( myTable, 1, 0, 2, 1 );
 
+#ifndef DISABLE_PLOT2DVIEWER
        // d) preview
   myPreview = new StdMeshersGUI_DistrPreview( GroupC1, h.in() );  
-  myPreview->setMinimumHeight(220);
   myDistLayout->addWidget( myPreview, 1, 1, 2, 1 );
+#endif
   
   // 5)  conversion (radiogroup)
   myConvBox = new QGroupBox( tr( "SMESH_CONV_MODE" ), GroupC1 );
@@ -214,21 +222,30 @@ QFrame* StdMeshersGUI_NbSegmentsCreator::buildFrame()
   QString aMainEntry = getMainShapeEntry();
   if ( aGeomEntry == "" )
     aGeomEntry = h->GetObjectEntry();
-  myDirectionWidget->SetGeomShapeEntry( aGeomEntry );
-  myDirectionWidget->SetMainShapeEntry( aMainEntry );
+  myDirectionWidget->SetGeomShapeEntry( aGeomEntry, aMainEntry );
   myDirectionWidget->SetListOfIDs( h->GetReversedEdges() );
   edgeLay->addWidget( myDirectionWidget );
 
   lay->addWidget( myReversedEdgesBox );
-  lay->setStretchFactor( GroupC1, 2);
+  lay->setStretchFactor( GroupC1, 1);
   lay->setStretchFactor( myReversedEdgesBox, 1);
-  
+
+  myReversedEdgesHelper = 0;
+  if ( !aGeomEntry.isEmpty() || !aMainEntry.isEmpty() )
+  {
+    myReversedEdgesHelper = new StdMeshersGUI_PropagationHelperWdg( myDirectionWidget, fr, false );
+    lay->addWidget( myReversedEdgesHelper );
+    lay->setStretchFactor( myReversedEdgesHelper, 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( buttonClicked( int ) ), this, SLOT( onValueChanged() ) );
 
+  onValueChanged();
+
   return fr;
 }
 
@@ -366,9 +383,10 @@ bool StdMeshersGUI_NbSegmentsCreator::storeParamsToHypo( const NbSegmentsHypothe
 
     h->SetVarParameter( h_data.myNbSegVarName.toLatin1().constData(), "SetNumberOfSegments" );
     h->SetNumberOfSegments( h_data.myNbSeg );
-    int distr = h_data.myDistrType;
-    h->SetDistrType( distr );
     
+    int distr = h_data.myDistrType;
+    if ( distr == 0 )
+      h->SetDistrType( distr ); // this is actually needed at non-uniform -> uniform switch
     if( distr==1 ) {
       h->SetVarParameter( h_data.myScaleVarName.toLatin1().constData(), "SetScaleFactor" );
       h->SetScaleFactor( h_data.myScale );
@@ -431,11 +449,17 @@ void StdMeshersGUI_NbSegmentsCreator::onValueChanged()
 
   myScale->setShown( distr==1 );
   myLScale->setShown( distr==1 );
-  myReversedEdgesBox->setShown( !distr==0 );
-  myDirectionWidget->showPreview( !distr==0 );
+  myReversedEdgesBox->setShown( distr!=0 );
+  if ( myReversedEdgesHelper ) {
+    myReversedEdgesHelper->Clear();
+    myReversedEdgesHelper->setShown( distr!=0 );
+  }
+  myDirectionWidget->ShowPreview( distr!=0 );
 
   bool isFunc = distr==2 || distr==3;
+#ifndef DISABLE_PLOT2DVIEWER
   myPreview->setShown( isFunc );
+#endif
   myConvBox->setShown( isFunc );
   
   myTable->setShown( distr==2 );
@@ -443,6 +467,7 @@ void StdMeshersGUI_NbSegmentsCreator::onValueChanged()
   myLExpr->setShown( distr==3 );
   myInfo->setShown( distr==3);
 
+#ifndef DISABLE_PLOT2DVIEWER
   //change of preview
   int nbSeg = myNbSeg->value();
   if( distr==2 ) //preview for table-described function
@@ -456,6 +481,7 @@ void StdMeshersGUI_NbSegmentsCreator::onValueChanged()
 
   if( isFunc )
     myPreview->setConversion( StdMeshersGUI_DistrPreview::Conversion( myConv->checkedId() ) );
+#endif
 
   if ( (QtxComboBox*)sender() == myDistr && dlg() ) {
     QApplication::instance()->processEvents();
index 7c9cb4dc4b5333ad214ae1384d03dff886f1ed76..99c235e4ac6067782a411b9c3ccea78de9478188 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -39,13 +39,16 @@ class SalomeApp_IntSpinBox;
 class QtxComboBox;
 class SMESHGUI_SpinBox;
 class StdMeshersGUI_DistrTableFrame;
-class StdMeshersGUI_DistrPreview;
+#ifndef DISABLE_PLOT2DVIEWER
+  class StdMeshersGUI_DistrPreview;
+#endif
 class QLineEdit;
 class QButtonGroup;
 class QGroupBox;
 class QGridLayout;
 class QRadioButton;
 class StdMeshersGUI_SubShapeSelectorWdg;
+class StdMeshersGUI_PropagationHelperWdg;
 
 typedef struct
 {
@@ -85,7 +88,9 @@ private:
   QtxComboBox*     myDistr;
   SMESHGUI_SpinBox*   myScale;
   StdMeshersGUI_DistrTableFrame*  myTable;
+#ifndef DISABLE_PLOT2DVIEWER
   StdMeshersGUI_DistrPreview* myPreview;
+#endif
   QLineEdit       *myName, *myExpr;
   QGroupBox*       myConvBox;
   QButtonGroup*    myConv;
@@ -96,6 +101,7 @@ private:
   QGroupBox*       myReversedEdgesBox;
 
   StdMeshersGUI_SubShapeSelectorWdg*    myDirectionWidget;
+  StdMeshersGUI_PropagationHelperWdg*   myReversedEdgesHelper;
 };
 
 #endif // STDMESHERSGUI_NBSEGMENTSCREATOR_H
index 7960a968632c304ccc0199ce37be03b4c2009225..70abfea101ef17fd7fc419087a450a72a62d1ac3 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 //================================================================================
 
 StdMeshersGUI_ObjectReferenceParamWdg::StdMeshersGUI_ObjectReferenceParamWdg
-( SUIT_SelectionFilter* f, QWidget* parent, bool multiSelection, bool stretch )
+( SUIT_SelectionFilter* f, QWidget* parent, bool multiSelection 
+  /*, bool stretch */)
   : QWidget( parent ), myMultiSelection( multiSelection )
 {
   myFilter = f;
-  myStretchActivated = stretch;
+  // myStretchActivated = stretch;
   init();
 }
 
@@ -123,12 +124,13 @@ void StdMeshersGUI_ObjectReferenceParamWdg::init()
   myObjNameLineEdit = new QLineEdit(this);
   myObjNameLineEdit->setReadOnly(true);
   myObjNameLineEdit->setStyleSheet(myEmptyStyleSheet);
+  myObjNameLineEdit->setMinimumWidth(150);
 
   aHBox->addWidget( mySelButton );
   aHBox->addWidget( myObjNameLineEdit );
-  if (myStretchActivated){
-    aHBox->addStretch();
-  }
+  //if (myStretchActivated){
+  //  aHBox->addStretch();
+  //}
 
   connect( mySelButton, SIGNAL(clicked()), SLOT(activateSelection()));
 }
index 02f4f36e097daf2ca1370f92ad7cfcd4042041da..03706a8fe392b5c65c59cc8d2a217d65a4d9131b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -56,8 +56,8 @@ class STDMESHERSGUI_EXPORT StdMeshersGUI_ObjectReferenceParamWdg : public QWidge
 public:
   StdMeshersGUI_ObjectReferenceParamWdg( SUIT_SelectionFilter* filter, 
                                          QWidget*              parent,
-                                         bool                  multiSelection=false,
-                                         bool                  stretch=true);
+                                         bool                  multiSelection=false
+                                         /* ,bool                  stretch=true*/);
   StdMeshersGUI_ObjectReferenceParamWdg( SMESH::MeshObjectType objType,
                                          QWidget*       parent,
                                          bool           multiSelection=false);
diff --git a/src/StdMeshersGUI/StdMeshersGUI_PropagationHelperWdg.cxx b/src/StdMeshersGUI/StdMeshersGUI_PropagationHelperWdg.cxx
new file mode 100644 (file)
index 0000000..617f5cb
--- /dev/null
@@ -0,0 +1,524 @@
+// Copyright (C) 2007-2015  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, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// 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_PropagationHelperWdg.cxx
+// Created   : Thu Mar 19 18:46:24 2015
+// Author    : Edward AGAPOV (eap)
+
+#include "StdMeshersGUI_PropagationHelperWdg.h"
+
+#include "StdMeshersGUI_SubShapeSelectorWdg.h"
+#include "SMESH_PreviewActorsCollection.h"
+#include "SMESHGUI_VTKUtils.h"
+
+#include <GEOM_Actor.h>
+
+#include <LightApp_SelectionMgr.h>
+#include <SUIT_OverrideCursor.h>
+#include <SVTK_ViewWindow.h>
+#include <vtkRenderer.h>
+
+#include <QCheckBox>
+#include <QGridLayout>
+#include <QGroupBox>
+#include <QLabel>
+#include <QList>
+#include <QListWidget>
+#include <QListWidgetItem>
+#include <QPushButton>
+
+#include <BRepTools_WireExplorer.hxx>
+#include <BRep_Builder.hxx>
+#include <NCollection_DataMap.hxx>
+#include <TColStd_IndexedMapOfInteger.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Compound.hxx>
+#include <TopoDS_Iterator.hxx>
+
+#include <set>
+
+#define SPACING 6
+#define MARGIN 11
+
+//================================================================================
+/*!
+ * \brief Constructor
+ */
+//================================================================================
+
+StdMeshersGUI_PropagationHelperWdg::
+StdMeshersGUI_PropagationHelperWdg( StdMeshersGUI_SubShapeSelectorWdg* subSelectWdg,
+                                    QWidget*                           parent,
+                                    bool                               show ):
+  QWidget( parent ), mySubSelectWdg( subSelectWdg ), myActor( 0 ), myModelActor( 0 )
+{
+  QGroupBox* helperBox = new QGroupBox( tr("HELPER"), this );
+  myShowGeomChkBox     = new QCheckBox( tr("SHOW_GEOMETRY"), helperBox );
+  myChainBox           = new QGroupBox( tr("PROPAGATION_CHAINS"), helperBox );
+  myChainBox->setCheckable( true );
+  myChainBox->setChecked( false );
+  myListWidget         = new QListWidget( helperBox );
+  myListWidget->setSelectionMode( QAbstractItemView::SingleSelection );
+  myAddButton          = new QPushButton( tr("ADD"), helperBox );
+  myReverseButton      = new QPushButton( tr("REVERSE"), helperBox );
+
+  QGridLayout* chainsLayout = new QGridLayout( myChainBox );
+  chainsLayout->setMargin( MARGIN );
+  chainsLayout->setSpacing( SPACING );
+  chainsLayout->addWidget(myListWidget,    0, 0, 3, 3);
+  chainsLayout->addWidget(myAddButton,     0, 3);
+  chainsLayout->addWidget(myReverseButton, 1, 3);
+
+  QVBoxLayout* helperLayout = new QVBoxLayout( helperBox );
+  helperLayout->setMargin( MARGIN );
+  helperLayout->setSpacing( SPACING );
+  helperLayout->addWidget( myShowGeomChkBox );
+  helperLayout->addWidget( myChainBox );
+
+  QVBoxLayout* lay = new QVBoxLayout( this );
+  lay->setMargin( 0 );
+  lay->setSpacing( SPACING );
+  lay->addWidget( helperBox );
+
+  connect( myShowGeomChkBox,SIGNAL( toggled(bool)), SLOT( onShowGeometry(bool)));
+  connect( myChainBox,        SIGNAL( toggled(bool)), SLOT( updateList(bool)));
+  connect( myListWidget,    SIGNAL( itemSelectionChanged()), SLOT( onListSelectionChanged() ));
+  connect( myAddButton,     SIGNAL( clicked(bool)), SLOT( onAdd() ));
+  connect( myReverseButton, SIGNAL( clicked(bool)), SLOT( onReverse() ));
+
+  if ( show )
+    onListSelectionChanged();
+}
+
+//================================================================================
+/*!
+ * \brief Destructor
+ */
+//================================================================================
+
+StdMeshersGUI_PropagationHelperWdg::~StdMeshersGUI_PropagationHelperWdg()
+{
+  if ( myActor )
+  {
+    myActor->RemoveFromRender( myRenderer );
+    myActor->Delete();
+    myActor = 0;
+  }
+  if ( myModelActor )
+  {
+    myModelActor->RemoveFromRender( myRenderer );
+    myModelActor->Delete();
+    myModelActor = 0;
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Switch off all buttons and previews
+ */
+//================================================================================
+
+void StdMeshersGUI_PropagationHelperWdg::Clear()
+{
+  myShowGeomChkBox->setChecked( false );
+
+  myListWidget->blockSignals( true );
+  myListWidget->clear();
+  myListWidget->blockSignals( false );
+
+  myChainBox->blockSignals( true );
+  myChainBox->setChecked( false );
+  myChainBox->blockSignals( false );
+
+  if ( myActor )
+    myActor->SetVisibility( false );
+
+  if ( myModelActor )
+    myModelActor->SetVisibility( false );
+}
+
+//================================================================================
+/*!
+ * \brief SLOT called when 'Show Geometry' is checked
+ */
+//================================================================================
+
+void StdMeshersGUI_PropagationHelperWdg::onShowGeometry(bool toShow)
+{
+  if ( ! myModelActor )
+  {
+    TopoDS_Shape shape     = mySubSelectWdg->GetGeomShape();
+    TopoDS_Shape mainShape = mySubSelectWdg->GetMainShape();
+    if ( shape.IsNull() && mainShape.IsNull() ) return;
+    if ( mainShape.IsNull() ) mainShape = shape;
+
+    SUIT_OverrideCursor wc;
+
+    TopoDS_Compound aCompound;
+    BRep_Builder aBuilder;
+    aBuilder.MakeCompound( aCompound );
+    
+    TopTools_MapOfShape edgesMap;
+    TopExp_Explorer edge( mainShape, TopAbs_EDGE );
+    for ( ; edge.More(); edge.Next() )
+      if ( edgesMap.Add( edge.Current() ))
+        aBuilder.Add( aCompound, edge.Current() );
+
+    myModelActor = GEOM_Actor::New();
+    myModelActor->SetShape( aCompound, 0, 0 );
+    myModelActor->SetPickable( false );
+    myModelActor->SetIsolatedEdgeColor( 0.5, 0.5, 0.5 );
+
+    if (( myRenderer = mySubSelectWdg->GetRenderer() ))
+      myModelActor->AddToRender( myRenderer );
+  }
+
+  if ( myModelActor )
+    myModelActor->SetVisibility( toShow );
+
+  SMESH::RepaintCurrentView();
+}
+
+//================================================================================
+/*!
+ * \brief Build propagation chains. Return false if no chains found
+ */
+//================================================================================
+
+bool StdMeshersGUI_PropagationHelperWdg::buildChains()
+{
+  if ( !myChains.empty() ) return false;
+
+  if ( !mySubSelectWdg ) return false;
+
+  TopoDS_Shape shape     = mySubSelectWdg->GetGeomShape();
+  TopoDS_Shape mainShape = mySubSelectWdg->GetMainShape();
+  if ( shape.IsNull() && mainShape.IsNull() ) return false;
+
+  if ( shape.IsNull() )     shape = mainShape;
+  if ( mainShape.IsNull() ) mainShape = shape;
+
+  SUIT_OverrideCursor wc;
+
+  // aPreviewActor holds a map od all sub-shapes of mainShape
+  SMESH_PreviewActorsCollection* previewActor = mySubSelectWdg->GetActorCollection();
+  if ( !previewActor ) return false;
+  const QList<int>& egdeIDs = previewActor->GetIndices();
+
+  // Make a 'map' of WIREs of EDGE with quadrilateral WIREs only
+
+  typedef int                        TGeomID; // index in the mainShape
+  typedef std::vector< TGeomID >     TWire; // signed IDs of EDGEs, sign means orientation
+  typedef std::pair< int, TWire* >   TEdgeInWire; // index in TWire + TWire*
+  typedef std::vector< TEdgeInWire > TWiresOfEdge;// WIREs including an EDGE
+
+  std::vector< TWire > quadWires;
+  quadWires.reserve( previewActor->NbShapesOfType( TopAbs_FACE ));
+  NCollection_DataMap< TGeomID, TWiresOfEdge >
+    wiresOfEdge( previewActor->NbShapesOfType( TopAbs_EDGE ));
+
+  TopExp_Explorer wire;
+  TopTools_MapOfShape faceMap;
+  for ( TopExp_Explorer face( mainShape, TopAbs_FACE ); face.More(); face.Next() )
+  {
+    if ( !faceMap.Add( face.Current() )) continue;
+
+    wire.Init( face.Current(), TopAbs_WIRE );
+    TopoDS_Shape W = wire.Current().Oriented( TopAbs_FORWARD );
+
+    wire.Next();
+    if ( wire.More() ) continue;
+
+    // count EDGEs
+    int nbE = 0;
+    for ( TopoDS_Iterator edge( W, false, false ); edge.More() && nbE < 5; ++nbE )
+      edge.Next();
+    if ( nbE != 4 ) continue;
+
+    // fill a TWire and TWiresOfEdge
+    quadWires.push_back( TWire() );
+    TWire& wire = quadWires.back();
+    wire.reserve( 4 );
+    for ( BRepTools_WireExplorer edge( TopoDS::Wire( W )); edge.More(); edge.Next() )
+    {
+      const TopoDS_Shape& E = edge.Current();
+      int iE = previewActor->GetIndexByShape( E );
+      if ( iE < 1 )
+        continue;
+      if ( !wiresOfEdge.IsBound( iE ))
+        wiresOfEdge.Bind( iE, TWiresOfEdge() );
+      wiresOfEdge( iE ).push_back( TEdgeInWire( wire.size(), & wire ));
+
+      wire.push_back( E.Orientation() == TopAbs_REVERSED ? -iE : iE );
+    }
+  }
+  if ( quadWires.empty() )
+    return false;
+
+  // Find chains
+
+  TColStd_IndexedMapOfInteger chain, chainedEdges;
+
+  TColStd_MapOfInteger shapeEdges;
+  if ( !shape.IsSame( mainShape ))
+    for ( QList<TGeomID>::const_iterator ieIt = egdeIDs.begin(); ieIt != egdeIDs.end(); ++ieIt )
+      shapeEdges.Add( *ieIt );
+
+  // loop on all EDGEs in mainShape
+  for ( QList<TGeomID>::const_iterator ieIt = egdeIDs.begin(); ieIt != egdeIDs.end(); ++ieIt )
+  {
+    if ( chainedEdges.Contains( *ieIt ))
+      continue;
+    // start a new chain
+    chain.Clear();
+    chain.Add( *ieIt );
+    chainedEdges.Add( *ieIt );
+    for ( int iC = 1; iC <= chain.Extent(); ++iC ) // loop on EDGE's in chain
+    {
+      TGeomID iE = chain( iC ), iEAbs = Abs( iE );
+      if ( !wiresOfEdge.IsBound( iEAbs ))
+        continue;
+      const TWiresOfEdge& wires = wiresOfEdge( iEAbs );
+      for (size_t i = 0; i < wires.size(); ++i ) // loop on WIREs sharing iE
+      {
+        const TEdgeInWire& eInW = wires[i];
+        const TWire&    W = *eInW.second;
+        if ( W.size() != 4 ) continue;
+        const int    iInW = eInW.first;
+        const int iInWOpp = ( iInW + 2 ) % 4; // an opposite edge index
+        TGeomID  iEOppAbs = Abs( W[ iInWOpp ] );
+
+        int prevNbChained = chainedEdges.Extent();
+        if ( prevNbChained < chainedEdges.Add( iEOppAbs ))
+        {
+          int dir = iE / iEAbs;
+          bool isSameDir = ( W[ iInW ] * W[ iInWOpp ] < 0 );
+          if ( !isSameDir )
+            dir *= -1;
+          chain.Add( dir * iEOppAbs );
+        }
+      }
+    }
+    // store a chain
+    if ( chain.Extent() > 1 )
+    {
+      myChains.push_back( std::vector< TGeomID >() );
+      std::vector< TGeomID > & ch = myChains.back();
+      for ( int iC = 1; iC <= chain.Extent(); ++iC )
+      {
+        TGeomID iE = chain( iC );
+        if ( shapeEdges.IsEmpty() || shapeEdges.Contains( Abs( iE )))
+          ch.push_back( iE );
+      }
+      if ( ch.size() < 2 )
+        myChains.pop_back();
+    }
+  } // loop on egdeIDs
+
+  return !myChains.empty();
+}
+
+//================================================================================
+/*!
+ * \brief Fills myListWidget
+ */
+//================================================================================
+
+void StdMeshersGUI_PropagationHelperWdg::updateList(bool enable)
+{
+  buildChains();
+
+  myListWidget->clear();
+
+  if ( enable )
+  {
+    QListWidgetItem* item;
+    if ( myChains.empty() || !enable )
+    {
+      item = new QListWidgetItem(tr("NO_CHAINS"), myListWidget );
+      item->setData( Qt::UserRole, -1 );
+    }
+    else
+      for ( size_t i = 0; i < myChains.size(); ++i )
+      {
+        QString text = tr( "CHAIN_NUM_NB_EDGES" ).arg( i+1 ).arg( myChains[i].size() );
+        item = new QListWidgetItem( text, myListWidget );
+        item->setData( Qt::UserRole, (int) i );
+      }
+  }
+  else
+  {
+    onListSelectionChanged();
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Returns ids of a selected chain
+ */
+//================================================================================
+
+std::vector< int > * StdMeshersGUI_PropagationHelperWdg::getSelectedChain()
+{
+  std::vector< int > * chain = 0;
+  if ( QListWidgetItem * item = myListWidget->currentItem() )
+  {
+    size_t i = (size_t) item->data( Qt::UserRole ).toInt();
+    if ( 0 <= i && i < myChains.size() )
+      chain = & myChains[i];
+  }
+  return chain;
+}
+
+//================================================================================
+/*!
+ * \brief SLOT called when a selected chain changes
+ */
+//================================================================================
+
+void StdMeshersGUI_PropagationHelperWdg::onListSelectionChanged()
+{
+  if ( !mySubSelectWdg ) return;
+  SMESH_PreviewActorsCollection* previewActor = mySubSelectWdg->GetActorCollection();
+  if ( !previewActor ) return;
+
+  bool hasReversedEdges = false;
+  const std::vector< int > * chain = getSelectedChain();
+  if ( chain )
+  {
+    SUIT_OverrideCursor wc;
+
+    TopoDS_Compound aCompound;
+    BRep_Builder aBuilder;
+    aBuilder.MakeCompound( aCompound );
+
+    for ( size_t i = 0; i < chain->size(); ++i )
+    {
+      int iE = Abs( (*chain)[ i ]);
+      TopoDS_Shape E = previewActor->GetShapeByIndex( iE );
+      if ( !E.IsNull() && E.ShapeType() == TopAbs_EDGE )
+      {
+        E.Orientation( (*chain)[ i ] < 0 ? TopAbs_REVERSED : TopAbs_FORWARD );
+        aBuilder.Add( aCompound, E );
+        if ( (*chain)[ i ] < 0 )
+          hasReversedEdges = true;
+      }
+    }
+    if ( myActor )
+    {
+      // SetShape() to an existing actor leads to a wrong FitAll
+      myActor->RemoveFromRender( myRenderer );
+      myActor->Delete();
+    }
+    myActor = GEOM_Actor::New();
+    myActor->SetShape( aCompound, 0, true );
+    myActor->SetIsolatedEdgeColor( 1, 0, 1 );
+    myActor->SetWidth( 2 );
+    myActor->SetVectorMode( true );
+    myActor->SetPickable( false );
+
+    if (( myRenderer = mySubSelectWdg->GetRenderer() ))
+      myActor->AddToRender( myRenderer );
+
+    if ( LightApp_SelectionMgr* selMrg = SMESHGUI::selectionMgr())
+    {
+      selMrg->clearSelected();
+      mySubSelectWdg->ClearSelected(); /* call this because the above call does not
+                                          lead to currentSelectionChanged signal (bug?)*/
+    }
+  }
+  bool enableButtons = chain;
+  if ( chain )
+    enableButtons = myListWidget->currentItem()->data( Qt::UserRole+1 ).isNull();
+
+  myAddButton->setEnabled( enableButtons && hasReversedEdges );
+  myReverseButton->setEnabled( enableButtons );
+
+
+  bool toShowChain = chain;
+
+  if ( myActor )
+    myActor->SetVisibility( toShowChain );
+
+  previewActor->SetShown( !toShowChain );
+
+  if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow())
+    aViewWindow->Repaint();
+}
+
+//================================================================================
+/*!
+ * \brief SLOT called when 'Add' button is clicked
+ */
+//================================================================================
+
+void StdMeshersGUI_PropagationHelperWdg::onAdd()
+{
+  const std::vector< int > * chain = getSelectedChain();
+  if ( !chain || !mySubSelectWdg ) return;
+
+  // join current and new IDs
+
+  SMESH::long_array_var ids = mySubSelectWdg->GetListOfIDs();
+
+  std::set< int > idSet;
+  for ( int i = 0, nb = ids->length(); i < nb; ++i )
+    idSet.insert( idSet.end(), ids[i] );
+
+  for ( size_t i = 0; i < chain->size(); ++i )
+    if ( (*chain)[ i ] < 0 )
+      idSet.insert( -1 * (*chain)[ i ]);
+
+  if ( ids->length() != idSet.size() )
+  {
+    ids->length( idSet.size() );
+    std::set< int >::iterator id = idSet.begin();
+    for ( int i = 0, nb = ids->length(); i < nb; ++i, ++id )
+      ids[ i ] = *id;
+
+    mySubSelectWdg->SetListOfIDs( ids );
+  }
+  mySubSelectWdg->ClearSelected();
+
+  if ( QListWidgetItem * item = myListWidget->currentItem() )
+  {
+    //delete item;
+    item->setForeground( QBrush( QColor( 100, 100, 100 )));
+    item->setData( Qt::UserRole+1, 1 );
+  }
+  myAddButton->setEnabled( false );
+  myReverseButton->setEnabled( false );
+}
+
+//================================================================================
+/*!
+ * \brief SLOT called when 'Reverse' button is clicked
+ */
+//================================================================================
+
+void StdMeshersGUI_PropagationHelperWdg::onReverse()
+{
+  if ( std::vector< int > * chain = getSelectedChain())
+  {
+    for ( size_t i = 0; i < chain->size(); ++i )
+      (*chain)[ i ] *= -1;
+
+    onListSelectionChanged();
+  }
+}
diff --git a/src/StdMeshersGUI/StdMeshersGUI_PropagationHelperWdg.h b/src/StdMeshersGUI/StdMeshersGUI_PropagationHelperWdg.h
new file mode 100644 (file)
index 0000000..241e407
--- /dev/null
@@ -0,0 +1,81 @@
+// Copyright (C) 2007-2015  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, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// 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 STDMESHERSGUI_PropagationHelperWdg_H
+#define STDMESHERSGUI_PropagationHelperWdg_H
+
+#include "SMESH_StdMeshersGUI.hxx"
+
+#include <QWidget>
+#include <vector>
+
+class QPushButton;
+class QListWidget;
+class StdMeshersGUI_SubShapeSelectorWdg;
+class vtkRenderer;
+class GEOM_Actor;
+class QCheckBox;
+class QGroupBox;
+
+/*!
+ * \brief A widget showing a list of propagation chains of EDGEs.
+ * Selecting a chain shows its EDGEs in a viewer with all EDGEs equally oriented,
+ * 'Reverse' button reverses the EDGEs of a selected chain. 'Add' button adds
+ *  EDGEs to a list of reversed EDGEs of StdMeshersGUI_SubShapeSelectorWdg
+ */
+class STDMESHERSGUI_EXPORT StdMeshersGUI_PropagationHelperWdg : public QWidget
+{
+  Q_OBJECT
+
+ public:
+  StdMeshersGUI_PropagationHelperWdg( StdMeshersGUI_SubShapeSelectorWdg* subSelectWdg,
+                                      QWidget* parent = 0,
+                                      bool show = true);
+  ~StdMeshersGUI_PropagationHelperWdg();
+
+  void                           Clear();
+
+ private slots:
+
+  void                           onShowGeometry(bool toShow);
+  void                           onListSelectionChanged();
+  void                           onAdd(); 
+  void                           onReverse(); 
+  void                           updateList(bool enable);
+
+ private:
+
+  bool                           buildChains();
+  std::vector< int > *           getSelectedChain();
+
+  StdMeshersGUI_SubShapeSelectorWdg* mySubSelectWdg;
+  vtkRenderer*                       myRenderer;
+  GEOM_Actor*                        myActor;
+  GEOM_Actor*                        myModelActor;
+
+  QListWidget*                       myListWidget;
+  QPushButton*                       myAddButton;
+  QPushButton*                       myReverseButton;
+  QCheckBox*                         myShowGeomChkBox;
+  QGroupBox*                         myChainBox;
+
+  std::vector< std::vector<int> >    myChains;
+};
+
+#endif
index 9db22c2a9face2bf7313e4a21fd19fa1993d89b2..b1112e7864e30c16fd1923816991319a597c8de2 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
@@ -24,6 +24,7 @@
 
 #include "SMESHGUI.h"
 #include "SMESHGUI_SpinBox.h"
+#include "SMESHGUI_Utils.h"
 #include "StdMeshersGUI_SubShapeSelectorWdg.h"
 
 #include <GEOMBase.h>
@@ -194,8 +195,7 @@ void StdMeshersGUI_QuadrangleParamCreator::retrieveParams() const
   QString aMainEntry = SMESHGUI_GenericHypothesisCreator::getMainShapeEntry();
   if ( anEntry.isEmpty() )
     anEntry = h->GetObjectEntry();
-  myVertexSelWdg->SetGeomShapeEntry(anEntry);
-  myVertexSelWdg->SetMainShapeEntry(aMainEntry);
+  myVertexSelWdg->SetGeomShapeEntry(anEntry,aMainEntry);
 
   if ( !isCreation())
   {
@@ -215,7 +215,7 @@ void StdMeshersGUI_QuadrangleParamCreator::retrieveParams() const
     GEOM::ListOfGO_var     shapes;
     SMESH::nodes_array_var points;
     h->GetEnforcedNodes( shapes, points );
-    for ( int i = 0; i < shapes->length(); ++i )
+    for ( size_t i = 0; i < shapes->length(); ++i )
     {
       CORBA::String_var name  = shapes[i]->GetName();
       CORBA::String_var entry = shapes[i]->GetStudyEntry();
@@ -223,7 +223,7 @@ void StdMeshersGUI_QuadrangleParamCreator::retrieveParams() const
       item->setData( Qt::UserRole, entry.in() );
       myShapesList->addItem( item );
     }
-    for ( int i = 0; i < points->length(); ++i )
+    for ( size_t i = 0; i < points->length(); ++i )
     {
       QTreeWidgetItem* item = new QTreeWidgetItem
         ( QStringList()
@@ -407,7 +407,7 @@ void StdMeshersGUI_QuadrangleParamCreator::onSelectionChanged()
 
 void StdMeshersGUI_QuadrangleParamCreator::onTabChanged(int i)
 {
-  myVertexSelWdg->showPreview( i == TAB_VERTEX );
+  myVertexSelWdg->ShowPreview( i == TAB_VERTEX );
 }
 
 //================================================================================
index 3e87369b067a2970c05bdba7e3cc6dbdcfc08e58..b2a61011910da180427b612ad9eec395fdc8f4f6 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index 1d939f28bcde2ded62e7e5990fa89a6087c81a93..4c694d8222e5e96270a09a70df78c6270e0bbf23 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
 //
 #include "StdMeshersGUI_RadioButtonsGrpWdg.h"
 
-#include <QVBoxLayout>
+#include "SMESHGUI.h"
+
+#include <SUIT_ResourceMgr.h>
+
+#include <QGridLayout>
+#include <QLabel>
 #include <QRadioButton>
 #include <QButtonGroup>
 #include <QStringList>
@@ -44,17 +49,28 @@ StdMeshersGUI_RadioButtonsGrpWdg::StdMeshersGUI_RadioButtonsGrpWdg( const QStrin
  */
 //================================================================================
 
-void StdMeshersGUI_RadioButtonsGrpWdg::setButtonLabels( const QStringList& buttonLabels )
+void StdMeshersGUI_RadioButtonsGrpWdg::setButtonLabels( const QStringList& buttonLabels,
+                                                        const QStringList& buttonIcons )
 {
-  QVBoxLayout* layout = new QVBoxLayout( this );
+  QGridLayout* layout = new QGridLayout( this );
   layout->setSpacing(SPACING);
   layout->setMargin(MARGIN);
 
   for ( int id = 0; id < buttonLabels.size(); ++id )
   {
     QRadioButton* button = new QRadioButton( buttonLabels.at(id), this );
-    layout->addWidget( button );
+    layout->addWidget( button, id, 0 );
     myButtonGrp->addButton( button, id );
+
+    if ( id < buttonIcons.count() )
+    {
+      QPixmap pmi (SMESHGUI::resourceMgr()->loadPixmap("SMESH", buttonIcons.at(id)));
+      if ( !pmi.isNull() ) {
+        QLabel* pixLabel = new QLabel( this );
+        pixLabel->setPixmap( pmi );
+        layout->addWidget( pixLabel, id, 1 );
+      }
+    }
   }
 }
 
index a0133136b8fec292b957b4be5c55a349947fbe4f..e82a163cc8e9bc83901914e37854b74fe49182fd 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
@@ -38,7 +38,8 @@ class STDMESHERSGUI_EXPORT StdMeshersGUI_RadioButtonsGrpWdg : public QGroupBox
 public:
   StdMeshersGUI_RadioButtonsGrpWdg (const QString& title);
 
-  void setButtonLabels( const QStringList& buttonLabels );
+  void setButtonLabels( const QStringList& buttonLabels,
+                        const QStringList& buttonIcons=QStringList());
 
   void setChecked(int id);
 
index e912e113d1d337b55483d397ac80483c2b4aff4a..ea722142c8ebfff0881eb20bb03730226c3b14f9 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 #include "StdMeshersGUI_FixedPointsParamWdg.h"
 #include "StdMeshersGUI_LayerDistributionParamWdg.h"
 #include "StdMeshersGUI_ObjectReferenceParamWdg.h"
+#include "StdMeshersGUI_PropagationHelperWdg.h"
 #include "StdMeshersGUI_QuadrangleParamWdg.h"
-#include "StdMeshersGUI_SubShapeSelectorWdg.h"
 #include "StdMeshersGUI_RadioButtonsGrpWdg.h"
+#include "StdMeshersGUI_SubShapeSelectorWdg.h"
 
 #include <SALOMEDSClient_Study.hxx>
 
@@ -77,7 +78,7 @@ const double VALUE_MAX = 1.0e+15, // COORD_MAX
 //================================================================================
 
 StdMeshersGUI_StdHypothesisCreator::StdMeshersGUI_StdHypothesisCreator( const QString& type )
-: SMESHGUI_GenericHypothesisCreator( type )
+  : SMESHGUI_GenericHypothesisCreator( type ), myHelperWidget( 0 )
 {
 }
 
@@ -714,17 +715,18 @@ QString StdMeshersGUI_StdHypothesisCreator::storeParams() const
       StdMeshers::StdMeshers_ViscousLayers_var h =
         StdMeshers::StdMeshers_ViscousLayers::_narrow( hypothesis() );
 
-      h->SetVarParameter( params[0].text(), "SetTotalThickness" );
+      h->SetVarParameter  ( params[0].text(), "SetTotalThickness" );
       h->SetTotalThickness( params[0].myValue.toDouble() );
-      h->SetVarParameter( params[1].text(), "SetNumberLayers" );
+      h->SetVarParameter  ( params[1].text(), "SetNumberLayers" );
       h->SetNumberLayers  ( params[1].myValue.toInt() );
-      h->SetVarParameter( params[2].text(), "SetStretchFactor" );
+      h->SetVarParameter  ( params[2].text(), "SetStretchFactor" );
       h->SetStretchFactor ( params[2].myValue.toDouble() );
+      h->SetMethod (( StdMeshers::VLExtrusionMethod ) params[3].myValue.toInt() );
 
-      if ( StdMeshersGUI_SubShapeSelectorWdg* idsWg = 
-           widget< StdMeshersGUI_SubShapeSelectorWdg >( 4 ))
+      if ( StdMeshersGUI_SubShapeSelectorWdg* idsWg =
+           widget< StdMeshersGUI_SubShapeSelectorWdg >( 5 ))
       {
-        h->SetFaces( idsWg->GetListOfIDs(), params[3].myValue.toInt() );
+        h->SetFaces( idsWg->GetListOfIDs(), params[4].myValue.toInt() );
       }
     }
     else if( hypType()=="ViscousLayers2D" )
@@ -732,11 +734,11 @@ QString StdMeshersGUI_StdHypothesisCreator::storeParams() const
       StdMeshers::StdMeshers_ViscousLayers2D_var h =
         StdMeshers::StdMeshers_ViscousLayers2D::_narrow( hypothesis() );
 
-      h->SetVarParameter( params[0].text(), "SetTotalThickness" );
+      h->SetVarParameter  ( params[0].text(), "SetTotalThickness" );
       h->SetTotalThickness( params[0].myValue.toDouble() );
-      h->SetVarParameter( params[1].text(), "SetNumberLayers" );
+      h->SetVarParameter  ( params[1].text(), "SetNumberLayers" );
       h->SetNumberLayers  ( params[1].myValue.toInt() );
-      h->SetVarParameter( params[2].text(), "SetStretchFactor" );
+      h->SetVarParameter  ( params[2].text(), "SetStretchFactor" );
       h->SetStretchFactor ( params[2].myValue.toDouble() );
 
       if ( StdMeshersGUI_SubShapeSelectorWdg* idsWg =
@@ -882,18 +884,7 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const
     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 );
+    customWidgets()->append ( makeReverseEdgesWdg( h->GetReversedEdges(), h->GetObjectEntry() ));
   }
 
   else if( hypType()=="GeometricProgression" )
@@ -918,18 +909,7 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const
     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 );
+    customWidgets()->append ( makeReverseEdgesWdg( h->GetReversedEdges(), h->GetObjectEntry() ));
   }
 
   else if( hypType()=="FixedPoints1D" )
@@ -952,17 +932,7 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const
     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 );
+    customWidgets()->append ( makeReverseEdgesWdg( h->GetReversedEdges(), h->GetObjectEntry() ));
   }
 
 
@@ -975,7 +945,7 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const
     if(!initVariableName( hyp, item, "SetMaxElementArea" ))
       item.myValue = h->GetMaxElementArea();
     p.append( item );
-    
+
   }
   else if( hypType()=="MaxElementVolume" )
   {
@@ -994,13 +964,13 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const
 
     item.myName = tr( "SMESH_START_LENGTH_PARAM" );
 
-    if(!initVariableName( hyp, item, "SetStartLength" )) 
+    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( hyp, item, "SetEndLength" )) 
+    if(!initVariableName( hyp, item, "SetEndLength" ))
       item.myValue = h->GetLength( false );
     p.append( item );
     customWidgets()->append(0);
@@ -1008,17 +978,7 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const
     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 );
+    customWidgets()->append ( makeReverseEdgesWdg( h->GetReversedEdges(), h->GetObjectEntry() ));
   }
   else if( hypType()=="Deflection1D" )
   {
@@ -1026,7 +986,7 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const
       StdMeshers::StdMeshers_Deflection1D::_narrow( hyp );
 
     item.myName = tr( "SMESH_DEFLECTION1D_PARAM" );
-    if(!initVariableName( hyp, item, "SetDeflection" )) 
+    if(!initVariableName( hyp, item, "SetDeflection" ))
       item.myValue = h->GetDeflection();
     p.append( item );
   }
@@ -1036,17 +996,17 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const
       StdMeshers::StdMeshers_Adaptive1D::_narrow( hyp );
 
     item.myName = tr( "SMESH_MIN_SIZE" );
-    if(!initVariableName( hyp, item, "SetMinSize" )) 
+    if(!initVariableName( hyp, item, "SetMinSize" ))
       item.myValue = h->GetMinSize();
     p.append( item );
 
     item.myName = tr( "SMESH_MAX_SIZE" );
-    if(!initVariableName( hyp, item, "SetMaxSize" )) 
+    if(!initVariableName( hyp, item, "SetMaxSize" ))
       item.myValue = h->GetMaxSize();
     p.append( item );
 
     item.myName = tr( "SMESH_DEFLECTION1D_PARAM" );
-    if(!initVariableName( hyp, item, "SetDeflection" )) 
+    if(!initVariableName( hyp, item, "SetDeflection" ))
       item.myValue = h->GetDeflection();
     p.append( item );
   }
@@ -1242,6 +1202,20 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const
     p.append( item );
     customWidgets()->append (0);
 
+    item.myName = tr( "EXTRUSION_METHOD" );
+    p.append( item );
+    StdMeshersGUI_RadioButtonsGrpWdg* methodWdg = new StdMeshersGUI_RadioButtonsGrpWdg("");
+    methodWdg->setButtonLabels ( QStringList()
+                                 << tr("EXTMETH_SURF_OFFSET_SMOOTH")
+                                 << tr("EXTMETH_FACE_OFFSET")
+                                 << tr("EXTMETH_NODE_OFFSET"),
+                                 QStringList()
+                                 << tr("ICON_EXTMETH_SURF_OFFSET_SMOOTH")
+                                 << tr("ICON_EXTMETH_FACE_OFFSET")
+                                 << tr("ICON_EXTMETH_NODE_OFFSET"));
+    methodWdg->setChecked( (int) h->GetMethod() );
+    customWidgets()->append( methodWdg );
+
     QString aMainEntry = SMESHGUI_GenericHypothesisCreator::getMainShapeEntry();
     QString aSubEntry  = SMESHGUI_GenericHypothesisCreator::getShapeEntry();
     if ( !aMainEntry.isEmpty() )
@@ -1264,11 +1238,10 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const
       StdMeshersGUI_SubShapeSelectorWdg* idsWg =
         new StdMeshersGUI_SubShapeSelectorWdg(0,TopAbs_FACE);
 
-      idsWg->SetMainShapeEntry( aMainEntry );
-      idsWg->SetGeomShapeEntry( aSubEntry.isEmpty() ? aMainEntry : aSubEntry );
+      idsWg->SetGeomShapeEntry( aSubEntry, aMainEntry );
       if ( idsWg->SetListOfIDs( h->GetFaces() ))
       {
-        idsWg->showPreview( true );
+        idsWg->ShowPreview( true );
       }
       else
       {
@@ -1323,11 +1296,10 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const
       StdMeshersGUI_SubShapeSelectorWdg* idsWg =
         new StdMeshersGUI_SubShapeSelectorWdg(0,TopAbs_EDGE);
 
-      idsWg->SetMainShapeEntry( aMainEntry );
-      idsWg->SetGeomShapeEntry( aSubEntry.isEmpty() ? aMainEntry : aSubEntry );
+      idsWg->SetGeomShapeEntry( aSubEntry, aMainEntry );
       if ( idsWg->SetListOfIDs( h->GetEdges() ))
       {
-        idsWg->showPreview( true );
+        idsWg->ShowPreview( true );
       }
       else
       {
@@ -1337,46 +1309,6 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const
       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;
@@ -1417,6 +1349,7 @@ void StdMeshersGUI_StdHypothesisCreator::attuneStdWidget (QWidget* w, const int)
     {
       sb->RangeStepAndValidator( VALUE_SMALL, VALUE_MAX, 1.0, "length_precision" );
       sb->setEnabled( !widget< QCheckBox >( 1 )->isChecked() );
+      sb->setMinimumWidth( 150 );
     }
     else if( hypType()=="MaxElementArea" )
     {
@@ -1685,9 +1618,10 @@ void StdMeshersGUI_StdHypothesisCreator::valueChanged( QWidget* paramWidget)
   }
   else if ( hypType().startsWith( "ViscousLayers" ) && paramWidget->inherits("QButtonGroup"))
   {
-    if ( QLabel* label = getLabel(4) )
+    int widgetNumber = hypType() == "ViscousLayers2D" ? 3 : 4;
+    if ( QLabel* label = getLabel( widgetNumber + 1 ) )
     {
-      bool toIgnore = widget< StdMeshersGUI_RadioButtonsGrpWdg >( 3 )->checkedId();
+      bool toIgnore = widget< StdMeshersGUI_RadioButtonsGrpWdg >( widgetNumber )->checkedId();
       if ( hypType() == "ViscousLayers2D" )
         label->setText( tr( toIgnore ? "SMESH_EDGES_WO_LAYERS" : "SMESH_EDGES_WITH_LAYERS" ));
       else
@@ -1713,3 +1647,34 @@ bool StdMeshersGUI_StdHypothesisCreator::initVariableName(SMESH::SMESH_Hypothesi
 
   return theParams.isVariable;
 }
+
+//================================================================================
+/*!
+ * \brief Creates two widgets used to define reversed edges for some 1D hypotheses
+ *  \param [in] edgeIDs - ids of reversed edges to set to the widgets
+ *  \param [in] shapeEntry - entry of a sub-shape of a sub-mesh if any
+ *  \return QWidget* - new StdMeshersGUI_SubShapeSelectorWdg; 
+ *          new StdMeshersGUI_PropagationHelperWdg is stored in \a myHelperWidget field.
+ */
+//================================================================================
+
+QWidget*
+StdMeshersGUI_StdHypothesisCreator::makeReverseEdgesWdg( SMESH::long_array_var edgeIDs,
+                                                         CORBA::String_var     shapeEntry) const
+{
+  QString aGeomEntry = SMESHGUI_GenericHypothesisCreator::getShapeEntry();
+  QString aMainEntry = SMESHGUI_GenericHypothesisCreator::getMainShapeEntry();
+  if ( aGeomEntry.isEmpty() && shapeEntry.in() )
+    aGeomEntry = shapeEntry.in();
+
+  StdMeshersGUI_SubShapeSelectorWdg* wdg = new StdMeshersGUI_SubShapeSelectorWdg();
+  wdg->SetGeomShapeEntry( aGeomEntry, aMainEntry );
+  wdg->SetListOfIDs( edgeIDs );
+  wdg->ShowPreview( true );
+
+  if ( !aGeomEntry.isEmpty() || !aMainEntry.isEmpty() )
+    const_cast<StdMeshersGUI_StdHypothesisCreator*>( this )->
+      myHelperWidget = new StdMeshersGUI_PropagationHelperWdg( wdg );
+
+  return wdg;
+}
index 2f8a3859c481d1472e7d6aea278f0df76f80e50b..b9e22ae0217873b724855e2c7a4acb29ec8d6169 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -54,15 +54,20 @@ protected:
   virtual QPixmap  icon() const;
   virtual QString  type() const;
   virtual QWidget* getCustomWidget( const StdParam&, QWidget*, const int ) const;
+  virtual QWidget* getHelperWidget() const { return myHelperWidget; }
   virtual bool     getParamFromCustomWidget( StdParam& , QWidget* ) const;
 
   virtual QString  hypTypeName( const QString& ) const;
   virtual QWidget* getWidgetForParam( int paramIndex ) const;
   virtual ListOfWidgets* customWidgets() const;
   virtual void     onReject();
+  virtual void     valueChanged( QWidget* );
+
   bool             initVariableName(SMESH::SMESH_Hypothesis_var theHyp, StdParam& theParams, const char* theMethod) const;
+  QWidget*         makeReverseEdgesWdg( SMESH::long_array_var edgeIDs,
+                                        CORBA::String_var     shapeEntry) const;
+  
 
-  virtual void     valueChanged( QWidget* );
 
   template<class T>
     T* widget(int i) const {
@@ -70,6 +75,7 @@ protected:
   }
 
   ListOfWidgets    myCustomWidgets;
+  QWidget*         myHelperWidget;
 };
 
 #endif // STDMESHERSGUI_STDHYPOTHESISCREATOR_H
index 7986354934dbabdeb02b0353834f5990c5b8b989..b5d7629f7508bf51cd7be02c9f707ee955f08729 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
 #include "StdMeshersGUI_SubShapeSelectorWdg.h"
 
 // SMESH Includes
-#include "SMESH_Type.h"
-#include "SMESHGUI_MeshUtils.h"
+#include "SMESHGUI_Utils.h"
+#include "SMESHGUI_VTKUtils.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>
+#include "SMESH_PreviewActorsCollection.h"
+#include "SMESH_Type.h"
 
 // SALOME GUI includes
-#include <SALOME_ListIO.hxx>
 #include <LightApp_SelectionMgr.h>
-
-// SUIT Includes
+#include <SALOME_ListIO.hxx>
+#include <SUIT_OverrideCursor.h>
 #include <SUIT_ResourceMgr.h>
+#include <SVTK_Selector.h>
+#include <SVTK_ViewModel.h>
+#include <SVTK_ViewWindow.h>
 
 // GEOM Includes
 #include <GEOMBase.h>
 
 // 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>
 
 
 #define SPACING 6
@@ -80,8 +72,8 @@
 StdMeshersGUI_SubShapeSelectorWdg
 ::StdMeshersGUI_SubShapeSelectorWdg( QWidget * parent, TopAbs_ShapeEnum aSubShType ): 
   QWidget( parent ),
-  myPreviewActor( 0 ),
-  myMaxSize( -1 )
+  myMaxSize( -1 ),
+  myPreviewActor( 0 )
 {
   QPixmap image0( SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap( "SMESH", tr( "ICON_SELECT" ) ) );
 
@@ -91,7 +83,7 @@ StdMeshersGUI_SubShapeSelectorWdg
   
   myListWidget   = new QListWidget( this );
   myAddButton    = new QPushButton( tr( "SMESH_BUT_ADD" ),    this );
-  myRemoveButton = new QPushButton( tr( "SMESH_BUT_REMOVE" ), this );      
+  myRemoveButton = new QPushButton( tr( "SMESH_BUT_REMOVE" ), this );
   myInfoLabel    = new QLabel( this );
   myPrevButton   = new QPushButton( "<<", this );
   myNextButton   = new QPushButton( ">>", this );
@@ -142,6 +134,8 @@ StdMeshersGUI_SubShapeSelectorWdg::~StdMeshersGUI_SubShapeSelectorWdg()
     mySelectionMgr->removeFilter( myFilter );
   delete myFilter; myFilter=0;
 
+  mySelectionMgr->clearSelected();
+
   SUIT_SelectionFilter* filter;
   foreach( filter, myGeomFilters )
     delete filter;
@@ -178,7 +172,7 @@ void StdMeshersGUI_SubShapeSelectorWdg::init()
   connect( myPrevButton,   SIGNAL(clicked()), SLOT(onPrevious()));
   connect( myNextButton,   SIGNAL(clicked()), SLOT(onNext()));
   
-  connect( mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
+  connect( mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(selectionIntoArgument()));
   connect( myListWidget,   SIGNAL(itemSelectionChanged()),    this, SLOT(onListSelectionChanged()));
 
   updateState();
@@ -208,7 +202,7 @@ void StdMeshersGUI_SubShapeSelectorWdg::setFilter()
  */
 //================================================================================
 
-void StdMeshersGUI_SubShapeSelectorWdg::showPreview( bool visible)
+void StdMeshersGUI_SubShapeSelectorWdg::ShowPreview( bool visible)
 {
   if ( !myPreviewActor )
     return;
@@ -223,11 +217,24 @@ void StdMeshersGUI_SubShapeSelectorWdg::showPreview( bool visible)
   }
 }
 
+//================================================================================
+/*!
+ * \brief Clears selected IDs. This is a workaround of a bug that
+ *        SUIT_SelectionMgr::clearSelected() does not emit currentSelectionChanged
+ */
+//================================================================================
+
+void StdMeshersGUI_SubShapeSelectorWdg::ClearSelected()
+{
+  mySelectedIDs.clear();
+  selectionIntoArgument();
+}
+
 //=================================================================================
-// function : SelectionIntoArgument()
+// function : selectionIntoArgument()
 // purpose  : Called when selection as changed or other case
 //=================================================================================
-void StdMeshersGUI_SubShapeSelectorWdg::SelectionIntoArgument()
+void StdMeshersGUI_SubShapeSelectorWdg::selectionIntoArgument()
 {
   if ( !myPreviewActor )
     return;
@@ -241,31 +248,36 @@ void StdMeshersGUI_SubShapeSelectorWdg::SelectionIntoArgument()
 
   if (nbSel > 0) {
     SALOME_ListIteratorOfListIO anIt (aList);
-    
-    for ( ; anIt.More(); anIt.Next()) { // Loop on selected objects
+
+    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_var 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_var aMainFatherObj = aGeomMain->GetMainShape();
-            if ( !CORBA::is_nil( aMainFatherObj ) )
-              aMainFatherEntry = aMainFatherObj->GetStudyEntry();
-          }
-          aFatherEntry = aGeomFatherObj->GetStudyEntry();
-        }
-
-        if ( aFatherEntry != "" && ( aFatherEntry == myEntry || aFatherEntry == aMainFatherEntry ) )
+        // commented for IPAL52836
+        //
+        // GEOM::GEOM_Object_var 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.c_str() );
+        //   if ( !CORBA::is_nil( aGeomMain ) && aGeomMain->GetType() == 37 ) {  // Main Shape is a Group
+        //     GEOM::GEOM_Object_var aMainFatherObj = aGeomMain->GetMainShape();
+        //     if ( !CORBA::is_nil( aMainFatherObj ) )
+        //       aMainFatherEntry = aMainFatherObj->GetStudyEntry();
+        //   }
+        //   aFatherEntry = aGeomFatherObj->GetStudyEntry();
+        // }
+
+        // if (( ! aFatherEntry.isEmpty() ) &&
+        //     ( aFatherEntry == myEntry.c_str() || aFatherEntry == aMainFatherEntry ) )
         {
+          TopoDS_Shape shape;
           if ( aGeomObj->GetType() == 37 /*GEOM_GROUP*/ ) { // Selected Group that belongs the main object
-            GEOMBase::GetShape(aGeomObj, shape); 
+            GEOMBase::GetShape(aGeomObj, shape);
             if ( !shape.IsNull() ) {
               TopExp_Explorer exp( shape, mySubShType );
               for ( ; exp.More(); exp.Next() ) {
@@ -276,7 +288,9 @@ void StdMeshersGUI_SubShapeSelectorWdg::SelectionIntoArgument()
                 }
               }
             }
-          } else if ( aGeomObj->GetType() == 28 /*GEOM_SUBSHAPE*/  ) {
+          } else if ( aGeomObj->GetType() == 28 /*GEOM_SUBSHAPE*/ ||
+                      myEntry == IO->getEntry() )
+          {
             GEOMBase::GetShape(aGeomObj, shape); 
             if ( !shape.IsNull() && shape.ShapeType() == mySubShType ) {
               int index = myPreviewActor->GetIndexByShape( shape );
@@ -340,7 +354,9 @@ void StdMeshersGUI_SubShapeSelectorWdg::onAdd()
   }
   onListSelectionChanged();
   myListWidget->blockSignals( false );
-  myAddButton->setEnabled( myMaxSize == -1 || myListOfIDs.size() < myMaxSize );
+
+  mySelectedIDs.clear();
+  myAddButton->setEnabled( false );
 }
          
 //=================================================================================
@@ -367,7 +383,7 @@ void StdMeshersGUI_SubShapeSelectorWdg::onRemove()
   onListSelectionChanged();
   myListWidget->blockSignals( false );
   
-  myAddButton->setEnabled( true );
+  myAddButton->setEnabled( !mySelectedIDs.isEmpty() );
 }
 
 void StdMeshersGUI_SubShapeSelectorWdg::onPrevious()
@@ -401,7 +417,7 @@ void StdMeshersGUI_SubShapeSelectorWdg::onListSelectionChanged()
   if ( !myPreviewActor )
     return;
 
-  mySelectionMgr->clearSelected();
+  //mySelectionMgr->clearSelected();
   TColStd_MapOfInteger aIndexes;
   QList<QListWidgetItem*> selItems = myListWidget->selectedItems();
   QListWidgetItem* anItem;
@@ -410,18 +426,34 @@ void StdMeshersGUI_SubShapeSelectorWdg::onListSelectionChanged()
 
   // update remove button
   myRemoveButton->setEnabled( selItems.size() > 0 );
+
+  emit selectionChanged();
 }
 
 //=================================================================================
 // function : setGeomShape
 // purpose  : Called to set geometry whose sub-shapes are selected
 //================================================================================
-void StdMeshersGUI_SubShapeSelectorWdg::SetGeomShapeEntry( const QString& theEntry )
+void StdMeshersGUI_SubShapeSelectorWdg::SetGeomShapeEntry( const QString& theEntry,
+                                                           const QString& theMainShapeEntry )
 {
-  if ( theEntry != "") {
+  if ( !theEntry.isEmpty() || theMainShapeEntry.isEmpty() )
+  {
     myParamValue = theEntry;
-    myEntry = theEntry;
-    myGeomShape = GetTopoDSByEntry( theEntry );
+    myEntry      = theEntry.toStdString();
+    myMainEntry  = theMainShapeEntry.toStdString();
+
+    if ( myMainEntry.empty() ) myMainEntry = myEntry;
+    if ( myEntry.empty() )     myEntry     = myMainEntry;
+    if ( myMainEntry.length() > myEntry.length() &&
+         theMainShapeEntry.startsWith( theEntry ))
+      std::swap( myMainEntry, myEntry );
+
+    myGeomShape = GetTopoDSByEntry( myEntry.c_str() );
+    if ( myEntry == myMainEntry )
+      myMainShape = myGeomShape;
+    else
+      myMainShape = GetTopoDSByEntry( myMainEntry.c_str() );
     updateState();
     myIsNotCorrected = true;
   }
@@ -444,9 +476,10 @@ void StdMeshersGUI_SubShapeSelectorWdg::updateState()
   myAddButton->setEnabled( mySelectedIDs.size() > 0 );
   
   if (state) {
+    SUIT_OverrideCursor wc;
     myPreviewActor = new SMESH_PreviewActorsCollection();
     myPreviewActor->SetSelector( mySelector );
-    myPreviewActor->Init( myGeomShape, mySubShType, myEntry );
+    myPreviewActor->Init( myGeomShape, myMainShape, mySubShType, myEntry.c_str() );
     myPreviewActor->SetShown( false );
     myIsShown = false;
     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) {
@@ -499,16 +532,11 @@ 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);
-    }
-  }
+  for (int i = 0; i < size; i++)
+    anArray[i] = myListOfIDs.at(i);
+
   return anArray;
 }
 
@@ -524,109 +552,36 @@ bool StdMeshersGUI_SubShapeSelectorWdg::SetListOfIDs( SMESH::long_array_var theI
   for ( int i = 0; i < size; i++ )
     mySelectedIDs.append( theIds[ i ] );
 
-  bool isOk;
-  mySelectedIDs = GetCorrectedListOfIDs( false, &isOk );
+  myListWidget->blockSignals( true );
+  myListWidget->clear();
+  myListWidget->blockSignals( false );
+
+  bool isOk = true;
+  if ( myPreviewActor )
+  {
+    for ( int i = 0; i < size && isOk; i++ )
+      isOk = myPreviewActor->IsValidIndex( theIds[ i ] );
+  }
+  else if ( !myMainShape.IsNull() )
+  {
+    TopTools_IndexedMapOfShape aMainMap;
+    TopExp::MapShapes(myMainShape, aMainMap);
+    for ( int i = 0; i < size && isOk; i++ )
+      isOk = ( theIds[ i ] > 0 && theIds[ i ] <= aMainMap.Extent() );
+  }
+  // mySelectedIDs = GetCorrectedListOfIDs( false, &isOk );
   onAdd();
   return isOk;
 }
 
-//=================================================================================
-// 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,
-                                                          bool* isOK )
-{
-  if (( myMainShape.IsNull() || myGeomShape.IsNull() ) &&  fromSubshapeToMainshape )
-    return myListOfIDs;
-  else if (( myMainShape.IsNull() /*||*/&& myGeomShape.IsNull() ) &&  !fromSubshapeToMainshape )
-    return mySelectedIDs;
-
-  if ( !fromSubshapeToMainshape ) // called from SetListOfIDs
-  {
-    if ( myMainShape.IsNull() )
-      std::swap( myMainShape, myGeomShape );
-  }
-
-  QList<int> aList;
-  TopTools_IndexedMapOfShape aGeomMap, aMainMap;
-  TopExp::MapShapes(myMainShape, aMainMap);
-  if ( !myGeomShape.IsNull() )
-    TopExp::MapShapes(myGeomShape, aGeomMap);
-
-  bool ok = true;
-  if ( fromSubshapeToMainshape ) // convert indexes from sub-shape to mainshape
-  {
-    int size = myListOfIDs.size();
-    for (int i = 0; i < size; i++) {
-      int index = myListOfIDs.at(i);
-      if ( aGeomMap.Extent() < index )
-      {
-        ok = false;
-      }
-      else
-      {
-        TopoDS_Shape aSubShape = aGeomMap.FindKey( index );
-        if ( mySubShType != aSubShape.ShapeType() )
-          ok = false;
-        if ( !aMainMap.Contains( aSubShape ))
-          ok = false;
-        else
-          index = aMainMap.FindIndex( aSubShape );
-      }
-      aList.append( index );
-    }
-    myIsNotCorrected = false;
-  }
-  else // convert indexes from main shape to sub-shape, or just check indices
-  {
-    int size = mySelectedIDs.size();
-    for (int i = 0; i < size; i++) {
-      int index = mySelectedIDs.at(i);
-      if ( aMainMap.Extent() < index )
-      {
-        ok = false;
-      }
-      else
-      {
-        TopoDS_Shape aSubShape = aMainMap.FindKey( index );
-        if ( mySubShType != aSubShape.ShapeType() )
-          ok = false;
-        if ( !aGeomMap.Contains( aSubShape ) && !aGeomMap.IsEmpty() )
-          ok = false;
-        else
-          index = aGeomMap.FindIndex( aSubShape );
-      }
-      aList.append( index );
-    }
-  }
-  if ( isOK ) *isOK = ok;
-
-  return aList;
+  if ( myMainEntry.empty() ) myMainEntry = "";
+  return myMainEntry.c_str();
 }
 
 void StdMeshersGUI_SubShapeSelectorWdg::updateButtons()
index 7793817be8419c5a208e519dcf66c7eaac8dfb1d..1b40658d95d11c4340fefa14924962f7f0bae927 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
@@ -24,7 +24,7 @@
 #define STDMESHERSGUI_SUBSHAPESELECTORWDG_H
 
 // SMESH includes
-#include <SMESHGUI.h>
+#include "SMESHGUI.h"
 #include "SMESH_StdMeshersGUI.hxx"
 #include "SMESH_SMESHGUI.hxx"
 
 #include <QStringList>
 #include <TopoDS_Shape.hxx>
 
-#include <SMESHGUI_VTKUtils.h>
+#include <string>
 
 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;
@@ -60,29 +57,36 @@ public:
   SMESH::long_array_var          GetListOfIDs();
   bool                           SetListOfIDs( SMESH::long_array_var );
 
-  void                           SetGeomShapeEntry( const QString& theEntry );
-  const char*                    GetGeomShapeEntry() { return myEntry.toLatin1().data();}
+  void                           SetGeomShapeEntry( const QString& theEntry,
+                                                    const QString& theMainShapeEntry);
+  //QString                        GetGeomShapeEntry() { return myEntry; }
 
-  void                           SetMainShapeEntry( const QString& theEntry );
+  // void                           SetMainShapeEntry( const QString& theEntry );
   const char*                    GetMainShapeEntry();
 
   TopoDS_Shape                   GetGeomShape() { return myGeomShape; }
   TopoDS_Shape                   GetMainShape() { return myMainShape; }
 
-  QList<int>                     GetCorrectedListOfIDs( bool fromSubshapeToMainshape,
-                                                        bool* isOK=0);
+  // QList<int>                     GetCorrectedListOfIDs( bool fromSubshapeToMainshape,
+  //                                                       bool* isOK=0);
 
   static GEOM::GEOM_Object_var   GetGeomObjectByEntry( const QString& );
   static TopoDS_Shape            GetTopoDSByEntry( const QString& );
 
   QString                        GetValue() const { return myParamValue; }
 
-  void                           showPreview ( bool );
+  void                           ShowPreview( bool );
 
   int                            GetListSize() { return myListOfIDs.size(); }
 
-  void SetMaxSize(int aMaxSize) { myMaxSize = aMaxSize; }
-  //void SetSubShType(TopAbs_ShapeEnum aSubShType) { mySubShType = aSubShType; }
+  void                           SetMaxSize(int aMaxSize) { myMaxSize = aMaxSize; }
+
+  vtkRenderer*                   GetRenderer() { return myRenderer; }
+  SMESH_PreviewActorsCollection* GetActorCollection() { return myPreviewActor; }
+  void                           ClearSelected();
+
+signals:
+  void                           selectionChanged();
 
 private:
   void                           updateState();
@@ -94,7 +98,7 @@ private slots:
   void                           onRemove(); 
   void                           onPrevious(); 
   void                           onNext(); 
-  void                           SelectionIntoArgument();
+  void                           selectionIntoArgument();
   void                           onListSelectionChanged();
 
 private:
@@ -107,8 +111,8 @@ private:
   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;
+  std::string                    myEntry;
+  std::string                    myMainEntry;
   vtkRenderer*                   myRenderer;
   
   QListWidget*                   myListWidget;
index 537118cf5d75d3a393595ca145fa0a47897d8b15..0f56903ef2b147f423333fdf675f5f97c8c54168 100644 (file)
             <source>ICON_SMESH_TREE_ALGO_MEFISTO_2D</source>
             <translation>mesh_tree_algo_mefisto.png</translation>
         </message>
+        <message>
+            <source>ICON_SMESH_TREE_ALGO_PolygonPerFace_2D</source>
+            <translation>mesh_tree_algo_polygon.png</translation>
+        </message>
         <message>
             <source>ICON_SMESH_TREE_ALGO_Projection_1D</source>
             <translation>mesh_tree_algo_regular.png</translation>
             <source>ICON_SMESH_TREE_ALGO_RadialQuadrangle_1D2D</source>
             <translation>mesh_tree_algo_radial_quadrangle_1D2D.png</translation>
         </message>
+       <message>
+            <source>ICON_SMESH_TREE_ALGO_QuadFromMedialAxis_1D2D</source>
+            <translation>mesh_tree_algo_quad.png</translation>
+        </message>
        <message>
             <source>ICON_SMESH_TREE_ALGO_Prism_3D</source>
             <translation>mesh_tree_algo_prism.png</translation>
             <translation>mesh_quadrangle_reduced.png</translation>
         </message>
     </context>
+    <context>
+    <name>StdMeshersGUI_StdHypothesisCreator</name>
+        <message>
+            <source>ICON_EXTMETH_SURF_OFFSET_SMOOTH</source>
+            <translation>mesh_extmeth_surf_offset_smooth.png</translation>
+        </message>
+        <message>
+            <source>ICON_EXTMETH_NODE_OFFSET</source>
+            <translation>mesh_extmeth_node_offset.png</translation>
+        </message>
+        <message>
+            <source>ICON_EXTMETH_FACE_OFFSET</source>
+            <translation>mesh_extmeth_face_offset.png</translation>
+        </message>
+    </context>
 </TS>
index 5e38ea864680f4124b287528f9e406bd4b5972e3..5b6fe40c30f13be00185adebc70f77b5b4926ca5 100644 (file)
@@ -13,7 +13,7 @@
     </message>
     <message>
         <source>TO_IGNORE_EDGES</source>
-        <translation>Edges without layers (inlets and oulets)</translation>
+        <translation>Edges without layers (inlets and outlets)</translation>
     </message>
     <message>
         <source>TO_IGNORE_FACES_OR_NOT</source>
@@ -25,7 +25,7 @@
     </message>
     <message>
         <source>TO_IGNORE_FACES</source>
-        <translation>Faces without layers (inlets and oulets)</translation>
+        <translation>Faces without layers (inlets and outlets)</translation>
     </message>
     <message>
         <source>BAD_FACES_WARNING</source>
@@ -43,6 +43,22 @@ mesh/sub-mesh.
 Consider creating another hypothesis instead of using
 this one for this mesh/sub-mesh.</translation>
     </message>
+    <message>
+        <source>EXTMETH_SURF_OFFSET_SMOOTH</source>
+        <translation>Surface offset + smooth</translation>
+    </message>
+    <message>
+        <source>EXTRUSION_METHOD</source>
+        <translation>Extrusion method</translation>
+    </message>
+    <message>
+        <source>EXTMETH_NODE_OFFSET</source>
+        <translation>Node offset</translation>
+    </message>
+    <message>
+        <source>EXTMETH_FACE_OFFSET</source>
+        <translation>Face offset</translation>
+    </message>
 </context>
 <context>
     <name>@default</name>
@@ -233,7 +249,7 @@ this one for this mesh/sub-mesh.</translation>
     <message>
         <source>SMESH_FACES_WO_LAYERS</source>
         <translation>Faces without layers
-(inlets and oulets)</translation>
+(inlets and outlets)</translation>
     </message>
     <message>
         <source>SMESH_EDGES_WO_LAYERS</source>
@@ -306,11 +322,11 @@ this one for this mesh/sub-mesh.</translation>
     </message>
     <message>
         <source>SMESH_NUMBER_OF_LAYERS_HYPOTHESIS</source>
-        <translation>Radial Prism Parameter</translation>
+        <translation>Radial Discretization</translation>
     </message>
     <message>
         <source>SMESH_NUMBER_OF_LAYERS_2D_HYPOTHESIS</source>
-        <translation>Radial Quadrangle Parameter</translation>
+        <translation>Radial Discretization</translation>
     </message>
     <message>
         <source>SMESH_NUMBER_OF_LAYERS_TITLE</source>
@@ -526,10 +542,6 @@ this one for this mesh/sub-mesh.</translation>
         <source>ENF_NODES</source>
         <translation>Enforced nodes</translation>
     </message>
-    <message>
-        <source></source>
-        <translation></translation>
-    </message>
 </context>
 <context>
     <name>StdMeshersGUI_LayerDistributionParamWdg</name>
@@ -612,4 +624,35 @@ this one for this mesh/sub-mesh.</translation>
         <translation>Step</translation>
     </message>
 </context>
+<context>
+    <name>StdMeshersGUI_PropagationHelperWdg</name>
+    <message>
+        <source>HELPER</source>
+        <translation>Helper</translation>
+    </message>
+    <message>
+        <source>SHOW_GEOMETRY</source>
+        <translation>Show whole geometry</translation>
+    </message>
+    <message>
+        <source>PROPAGATION_CHAINS</source>
+        <translation>Propagation chains</translation>
+    </message>
+    <message>
+        <source>ADD</source>
+        <translation>Add</translation>
+    </message>
+    <message>
+        <source>REVERSE</source>
+        <translation>Reverse</translation>
+    </message>
+    <message>
+        <source>NO_CHAINS</source>
+        <translation>(no chains)</translation>
+    </message>
+    <message>
+        <source>CHAIN_NUM_NB_EDGES</source>
+        <translation>Chain %1 (%2 edges)</translation>
+    </message>
+</context>
 </TS>
index ef19f469fe10b7de6d2778d0e37de149acceb31e..9b0522b23ae7cef6b68ba7f61a2d2dbb87dc6642 100755 (executable)
@@ -2,55 +2,80 @@
 <!DOCTYPE TS>
 <TS version="2.0" language="fr_FR">
 <context>
-    <name>@default</name>
+    <name>StdMeshersGUI_StdHypothesisCreator</name>
     <message>
-        <source>SMESH_COMMON_RATIO</source>
-        <translation>Taux de croissance</translation>
+        <source>TO_IGNORE_EDGES</source>
+        <translation>Arêtes sans couches limites (entrées / sorties)</translation>
     </message>
     <message>
-        <source>SMESH_GEOMETRIC_1D_TITLE</source>
-        <translation>Construction de l&apos;hypothèse</translation>
+        <source>NOT_TO_IGNORE_EDGES</source>
+        <translation>Arêtes avec couche limite (parois)</translation>
     </message>
     <message>
-        <source>SMESH_GEOMETRIC_1D_HYPOTHESIS</source>
-        <translation>Progression géométrique</translation>
+        <source>TO_IGNORE_EDGES_OR_NOT</source>
+        <translation>Les arêtes sélectionnées sont</translation>
     </message>
     <message>
-        <source>SMESH_EDGES_WITH_LAYERS</source>
-        <translation>Arêtes avec couche limite</translation>
+        <source>TO_IGNORE_FACES_OR_NOT</source>
+        <translation>Les face sélectionnées sont</translation>
     </message>
     <message>
-        <source>SMESH_FACES_WITH_LAYERS</source>
+        <source>NOT_TO_IGNORE_FACES</source>
         <translation>Faces avec couche limite (parois)</translation>
     </message>
     <message>
-        <source>SMESH_ADAPTIVE1D_TITLE</source>
-        <translation>Construction de l&apos;hypothèse</translation>
+        <source>TO_IGNORE_FACES</source>
+        <translation>Faces sans couche limite (entrées / sorties)</translation>
     </message>
     <message>
-        <source>SMESH_MAX_SIZE</source>
-        <translation>Taille max</translation>
+        <source>BAD_FACES_WARNING</source>
+        <translation>
+Les faces sélectionnées ne sont pas des sous-géométries de la pièce à mailler (ou de la pièce du sous-maillage). Veuillez plutôt créer une autre hypothèse à la place de celle-ci pour ce maillage/sous-maillage.</translation>
     </message>
     <message>
-        <source>SMESH_MIN_SIZE</source>
-        <translation>Taille min</translation>
+        <source>BAD_EDGES_WARNING</source>
+        <translation>
+Les arêtes sélectionnées ne sont pas des sous-géométries de la pièce à mailler (ou de la pièce du sous-maillage). Veuillez plutôt créer une autre hypothèse à la place de celle-ci pour ce maillage/sous-maillage.</translation>
     </message>
     <message>
-        <source>SMESH_ADAPTIVE1D_HYPOTHESIS</source>
-        <translation>Adaptation géométrique</translation>
+        <source>EXTMETH_SURF_OFFSET_SMOOTH</source>
+        <translation>Décalage de la surface + lissage</translation>
+    </message>
+    <message>
+        <source>EXTRUSION_METHOD</source>
+        <translation>Méthode d'extrusion</translation>
+    </message>
+    <message>
+        <source>EXTMETH_NODE_OFFSET</source>
+        <translation>Décalage des Nœuds</translation>
+    </message>
+    <message>
+        <source>EXTMETH_FACE_OFFSET</source>
+        <translation>Décalage de la face</translation>
     </message>
+</context>
+<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>
+        <source>SMESH_ARITHMETIC_1D_TITLE</source>
+        <translation>Construction de l&apos;hypothèse</translation>
     </message>
     <message>
-        <source>SMESH_ARITHMETIC_1D_TITLE</source>
+        <source>SMESH_GEOMETRIC_1D_HYPOTHESIS</source>
+        <translation>Progression géométrique</translation>
+    </message>
+    <message>
+        <source>SMESH_GEOMETRIC_1D_TITLE</source>
         <translation>Construction de l&apos;hypothèse</translation>
     </message>
+    <message>
+        <source>SMESH_COMMON_RATIO</source>
+        <translation>Taux de croissance</translation>
+    </message>
     <message>
         <source>SMESH_AUTOMATIC_LENGTH_HYPOTHESIS</source>
         <translation>Longueur automatique</translation>
         <source>SMESH_CUT_NEG_MODE</source>
         <translation>Section négative</translation>
     </message>
+    <message>
+        <source>SMESH_ADAPTIVE1D_HYPOTHESIS</source>
+        <translation>Adaptation géométrique</translation>
+    </message>
+    <message>
+        <source>SMESH_MIN_SIZE</source>
+        <translation>Taille min</translation>
+    </message>
+    <message>
+        <source>SMESH_MAX_SIZE</source>
+        <translation>Taille max</translation>
+    </message>
+    <message>
+        <source>SMESH_ADAPTIVE1D_TITLE</source>
+        <translation>Construction de l&apos;hypothèse</translation>
+    </message>
     <message>
         <source>SMESH_DEFLECTION1D_HYPOTHESIS</source>
         <translation>Déflection 1D</translation>
         <translation>Arêtes sans couche limite
 (entrées et sorties)</translation>
     </message>
+    <message>
+        <source>SMESH_EDGES_WITH_LAYERS</source>
+        <translation>Arêtes avec couche limite (parois)</translation>
+    </message>
+    <message>
+        <source>SMESH_FACES_WITH_LAYERS</source>
+        <translation>Faces avec couche limite (parois)</translation>
+    </message>
     <message>
         <source>SMESH_MAX_LENGTH_TITLE</source>
         <translation>Construction de l&apos;hypothèse</translation>
         <translation>Réduction</translation>
     </message>
 </context>
+<context>
+    <name>StdMeshersGUI_QuadrangleParamCreator</name>
+    <message>
+        <source>POINTS</source>
+        <translation>Coordonnées</translation>
+    </message>
+    <message>
+        <source>SHAPES</source>
+        <translation>Points</translation>
+    </message>
+    <message>
+        <source>TRANSITION</source>
+        <translation>Transition</translation>
+    </message>
+    <message>
+        <source>ENF_NODES</source>
+        <translation>Nœuds imposés</translation>
+    </message>
+</context>
 <context>
     <name>StdMeshersGUI_LayerDistributionParamWdg</name>
     <message>
 </context>
 <context>
     <name>StdMeshersGUI_CartesianParamCreator</name>
-    <message>
-        <source>ADD_EDGES</source>
-        <translation>Ajouter des arêtes</translation>
-    </message>
     <message>
         <source>THRESHOLD</source>
         <translation>Seuil</translation>
     </message>
+    <message>
+        <source>ADD_EDGES</source>
+        <translation>Ajouter des arêtes</translation>
+    </message>
     <message>
         <source>AXIS_X</source>
         <translation>Axe X</translation>
     </message>
 </context>
 <context>
-    <name>StdMeshersGUI_StdHypothesisCreator</name>
+    <name>StdMeshersGUI_PropagationHelperWdg</name>
     <message>
-        <source>TO_IGNORE_EDGES</source>
-        <translation>Arêtes sans couches limites (entrées / sorties)</translation>
+        <source>HELPER</source>
+        <translation>Assistant</translation>
     </message>
     <message>
-        <source>NOT_TO_IGNORE_EDGES</source>
-        <translation>Arêtes avec couche limite (parois)</translation>
+        <source>SHOW_GEOMETRY</source>
+        <translation>Affiche toute la géométrie</translation>
     </message>
     <message>
-        <source>TO_IGNORE_EDGES_OR_NOT</source>
-        <translation>Les arêtes sélectionnées sont</translation>
+        <source>PROPAGATION_CHAINS</source>
+        <translation>Chaînes de propagation</translation>
     </message>
     <message>
-        <source>TO_IGNORE_FACES_OR_NOT</source>
-        <translation>Les face sélectionnées sont</translation>
+        <source>ADD</source>
+        <translation>Ajoute</translation>
     </message>
     <message>
-        <source>NOT_TO_IGNORE_FACES</source>
-        <translation>Faces avec couche limite (parois)</translation>
+        <source>REVERSE</source>
+        <translation>Inverse</translation>
     </message>
     <message>
-        <source>TO_IGNORE_FACES</source>
-        <translation>Faces sans couche limite (entrées / sorties)</translation>
+        <source>NO_CHAINS</source>
+        <translation>(aucune chaîne)</translation>
+    </message>
+    <message>
+        <source>CHAIN_NUM_NB_EDGES</source>
+        <translation>Chaîne %1 (%2 arêtes)</translation>
     </message>
 </context>
 </TS>
index 8a90c5e1f61268b7b0f6cedac65e72de2716db34..3e07638091be8cfcc6dec9cb623f27bc81b6db68 100644 (file)
       <source>TO_IGNORE_FACES</source>
       <translation>レイヤ(入出口)を伴わない面</translation>
     </message>
+    <message>
+      <source>BAD_FACES_WARNING</source>
+      <translation>明示された面はメッシュ/サブメッシュ形状のサブ形状ではありません。このメッシュ/サブメッシュのためにこれを使用する代わりにもう一つのhypothesisを作成していることが考えられます。</translation>
+    </message>
+    <message>
+      <source>BAD_EDGES_WARNING</source>
+      <translation>明示されたエッジはメッシュ/サブメッシュ形状のサブ形状ではありません。このメッシュ/サブメッシュのためにこれを使用する代わりにもう一つのhypothesisを作成していることが考えられます。</translation>
+    </message>
+    <message>
+      <source>EXTMETH_SURF_OFFSET_SMOOTH</source>
+      <translation>表面オフセットと平滑化</translation>
+    </message>
+    <message>
+      <source>EXTRUSION_METHOD</source>
+      <translation>押出方法</translation>
+    </message>
+    <message>
+      <source>EXTMETH_NODE_OFFSET</source>
+      <translation>節点オフセット</translation>
+    </message>
+    <message>
+      <source>EXTMETH_FACE_OFFSET</source>
+      <translation>面オフセット</translation>
+    </message>
   </context>
   <context>
     <name>@default</name>
       <source>ENF_NODES</source>
       <translation>強化された節点</translation>
     </message>
-    <message>
-      <source/>
-      <translation type="unfinished"/>
-    </message>
   </context>
   <context>
     <name>StdMeshersGUI_LayerDistributionParamWdg</name>
       <translation>ステップ</translation>
     </message>
   </context>
+  <context>
+    <name>StdMeshersGUI_PropagationHelperWdg</name>
+    <message>
+      <source>HELPER</source>
+      <translation>ヘルパ</translation>
+    </message>
+    <message>
+      <source>SHOW_GEOMETRY</source>
+      <translation>ジオメトリ全体の表示</translation>
+    </message>
+    <message>
+      <source>PROPAGATION_CHAINS</source>
+      <translation>伝播チェーン</translation>
+    </message>
+    <message>
+      <source>ADD</source>
+      <translation>追加</translation>
+    </message>
+    <message>
+      <source>REVERSE</source>
+      <translation>反転</translation>
+    </message>
+    <message>
+      <source>NO_CHAINS</source>
+      <translation>(no chains)</translation>
+    </message>
+    <message>
+      <source>CHAIN_NUM_NB_EDGES</source>
+      <translation>Chain %1 (%2 edges)</translation>
+    </message>
+  </context>
 </TS>
index e53bf5fa482e77b4ff495e52dc5ec91828fb9e72..57b2d058a1862d2769e634af47bf0c08443a1c55 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2012-2015  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
@@ -119,6 +119,7 @@ SET(StdMeshersEngine_HEADERS
   StdMeshers_ViscousLayers2D_i.hxx
   StdMeshers_CartesianParameters3D_i.hxx
   StdMeshers_Cartesian_3D_i.hxx
+  StdMeshers_PolygonPerFace_2D_i.hxx
 )
 IF(SALOME_SMESH_ENABLE_MEFISTO)
   SET(StdMeshersEngine_HEADERS ${StdMeshersEngine_HEADERS} StdMeshers_MEFISTO_2D_i.hxx)
@@ -173,6 +174,7 @@ SET(StdMeshersEngine_SOURCES
   StdMeshers_CartesianParameters3D_i.cxx
   StdMeshers_Cartesian_3D_i.cxx
   StdMeshers_Adaptive1D_i.cxx 
+  StdMeshers_PolygonPerFace_2D_i.cxx
 )
 
 IF(SALOME_SMESH_ENABLE_MEFISTO)
index f1aed23dc0fad43ee408f9416427fb455cf19874..472538f9bccc273ed968c2e1bd1ec0bd70ecda08 100755 (executable)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index c6d82b9c11e41d0fe96fc171f40bc2de96dc1637..42caa4857b87d9f11480a1b16f8f286ef1ab064b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 7dd59e708a64d918715fccc168730fe179b0be3b..ffe72c475c7a3436d6a2b938afa1a93c4d959573 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 9fe0a6e71efcb2a04fd2267118ce5bd481eb9200..96f16c5e4552df12eed8f3b70d5a857bd01caf05 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -225,7 +225,7 @@ SMESH::long_array* StdMeshers_Arithmetic1D_i::GetReversedEdges()
   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++)
+  for ( CORBA::ULong i = 0; i < ids.size(); i++)
     anArray [ i ] = ids [ i ];
 
   return anArray._retn();
index 53d6538d874f028c1521dcb91386febfacd75d8d..8aa8a30f36062d13e484c7cb4b61f2b66daef3f0 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 1b77d6e861809b3347f0cd156b7318496afa43d1..606c738194c1bfcceede4e6745c8ff8f590ba7a8 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index cccf0075a9786844cc3466bc69cc2bc72d41d802..a34dc777f203f2fde9b4de28333f3717bd4a7bd2 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index cd90066a0da17cdd200bc5439d411158f477d592..9ca0a8ee8e58b6975e7fb2b0522aef0d6d91d10b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 7246ac1f383dabbd3b50fae052f2a7b286054468..74cae16bc9db5301539bc0f022aeb1dff6d6d8e7 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index b17bdf2d57f63e58879dc60dd0e92e53e7c097ca..c5f0658efc28d03eee08c1f3707563cffbcaf27e 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index c6b1bbb3417ee7b656b30316c6e84a184c59ce9c..c72b0464c3ad3d112510f765dd633e9fac479a93 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index acc773b9a3cb7d08b68861e11e1ff37aba62eb2b..28a8a72d03cc7dc8eb86131395319dd764b635eb 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 61473104677e8d8d25e1439f4c03e00fd12ade33..dd8a5eac2d3ccffb9293c2af613a33a5166ae02c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 1668a857ed03c6b7f97e93131c43a0fea8d57638..e41abbc263cc4c2dbd3f7fbf7e2ff39dfa154bee 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 60186cfcd57bdfa593e3972b07c7b2f54fb229c3..55b72c8b7ffa2a624bc606b2c1cee37a9ffef524 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 12bd81879635fd9056dc1ea821e928ee61a75227..580331db541a383bca7ac287cadb3867fd097bcc 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
@@ -137,7 +137,7 @@ SMESH::double_array* StdMeshers_FixedPoints1D_i::GetPoints()
   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++)
+  for ( CORBA::ULong i = 0; i < params.size(); i++)
     anArray [ i ] = params [ i ];
 
   return anArray._retn();
@@ -158,7 +158,7 @@ SMESH::long_array* StdMeshers_FixedPoints1D_i::GetNbSegments()
   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++)
+  for ( CORBA::ULong i = 0; i < nbsegs.size(); i++)
     anArray [ i ] = nbsegs [ i ];
 
   return anArray._retn();
@@ -252,7 +252,7 @@ SMESH::long_array* StdMeshers_FixedPoints1D_i::GetReversedEdges()
   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++)
+  for ( CORBA::ULong i = 0; i < ids.size(); i++)
     anArray [ i ] = ids [ i ];
 
   return anArray._retn();
index 803414187677b71c678a8fe695ad4e52a0c56ac0..ca1856ba61237ed1f17181cc045543153ab8c2e8 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index 6bf870191d079330778a192d34bf14f3483fc74a..c6ad3c90221e70a506115dbb2ff67f200e4504b9 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index fb980724d9edc1b59a1080f9c98502c84161659a..f7c668148acaa102a306174837fc0039d3c78f8c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 9b1f7e22b22ae85b7952a9fcd24baf6d11fd97cc..93bf3e7a6390ac41fca60e6da71e1b090f24bc40 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 999eb94d2d4cf188db372d4762d5fcf0253fc642..21b52566531cc360dcbf753ff6cbf2c5ba805458 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index cea7bc36febe07c87b7db6474cb1a0a104c1956b..9b6f41db1ce214ddab195e6f6572cdf43a50ad5c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -91,7 +91,7 @@ void StdMeshers_ImportSource1D_i::SetSourceEdges(const SMESH::ListOfGroups& grou
     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 )
+    for ( CORBA::ULong 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 )
@@ -109,7 +109,7 @@ void StdMeshers_ImportSource1D_i::SetSourceEdges(const SMESH::ListOfGroups& grou
 
     _groupEntries = new SMESH::string_array;
     _groupEntries->length( entries.size ());
-    for ( int i = 0; i < entries.size(); ++i )
+    for ( size_t i = 0; i < entries.size(); ++i )
       _groupEntries[i] = entries[i].c_str();
   }
   catch ( SALOME_Exception& S_ex )
@@ -173,7 +173,7 @@ char* StdMeshers_ImportSource1D_i::SaveTo()
   os << " " << _groupEntries->length();
 
   SALOMEDS::Study_var study = SMESH_Gen_i::GetSMESHGen()->GetCurrentStudy();
-  for ( int i = 0; i < _groupEntries->length(); ++i )
+  for ( size_t i = 0; i < _groupEntries->length(); ++i )
   {
     // entry
     os << " " << _groupEntries[i];
@@ -208,7 +208,7 @@ void StdMeshers_ImportSource1D_i::LoadFrom( const char* theStream )
   _groupEntries = new SMESH::string_array;
   _groupEntries->length( nbGroups );
   std::string id, entry;
-  for ( int i = 0; i < _groupEntries->length(); ++i )
+  for ( size_t i = 0; i < _groupEntries->length(); ++i )
   {
     if ( is >> entry )
       _groupEntries[i] = entry.c_str();
index b48d9e28b3e40e9308a94e51c743662c4a157fae..f3a6656bf9e34a8e00cee341ea53ee004310fe35 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 545d98d018ef82f1b9b3e5f76e7683c564f2c0dc..051ae469ce548e78c58267067c2ccca0e1953774 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -90,7 +90,7 @@ void StdMeshers_ImportSource2D_i::SetSourceFaces(const SMESH::ListOfGroups& grou
     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 )
+    for ( CORBA::ULong 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 )
@@ -109,7 +109,7 @@ void StdMeshers_ImportSource2D_i::SetSourceFaces(const SMESH::ListOfGroups& grou
 
     _groupEntries = new SMESH::string_array;
     _groupEntries->length( entries.size ());
-    for ( int i = 0; i < entries.size(); ++i )
+    for ( size_t i = 0; i < entries.size(); ++i )
       _groupEntries[i] = entries[i].c_str();
   }
   catch ( SALOME_Exception& S_ex )
@@ -173,7 +173,7 @@ char* StdMeshers_ImportSource2D_i::SaveTo()
   os << " " << _groupEntries->length();
 
   SALOMEDS::Study_var study = SMESH_Gen_i::GetSMESHGen()->GetCurrentStudy();
-  for ( int i = 0; i < _groupEntries->length(); ++i )
+  for ( CORBA::ULong i = 0; i < _groupEntries->length(); ++i )
   {
     // entry
     os << " " << _groupEntries[i];
@@ -210,7 +210,7 @@ void StdMeshers_ImportSource2D_i::LoadFrom( const char* theStream )
   _groupEntries = new SMESH::string_array;
   _groupEntries->length( nbGroups );
   std::string id, entry;
-  for ( int i = 0; i < _groupEntries->length(); ++i )
+  for ( CORBA::ULong i = 0; i < _groupEntries->length(); ++i )
   {
     if ( is >> entry )
       _groupEntries[i] = entry.c_str();
index 53570f5157b1ef5c32389f939c48cd34b5596419..58307aa2e58bdaaf7769fe2b04ec5dbc4d2d3f69 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index c15ed6f3cff8373578ac17a73aadac71b895b1a0..bd183949d1a7cb997022526457ad76508041b0ea 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index 662871cb783007b2951d9ba15a0a01b1bc763d44..d9ea7683badc898b65b230a5f043509de9839016 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index e7b1a1f5750781e0a90c75fda29c3bb38f3bee70..d0db0e8d2240e50c037693d32e6a125ccabf516e 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 5dd4e1e30750ad0593fd2b377695d470c39f6336..e830ccbb6d6c2c925b66baefd4be4157c34557d7 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index c710649e21ee74ebf3ac459c8eb7cc5eb438fa04..48530d600486d43f3fa7d10cbf62a39efc17e463 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
@@ -38,8 +38,8 @@ 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 )
+:SMESH_Hypothesis_i( thePOA ),
StdMeshers_LayerDistribution_i(thePOA,theStudyId,theGenImpl)
 {
   MESSAGE( "StdMeshers_LayerDistribution2D_i::StdMeshers_LayerDistribution2D_i" );
   myBaseImpl = new ::StdMeshers_LayerDistribution2D(theGenImpl->GetANewId(),
index abb456f47c0c8f7d74a2326fc9c9ddcf71873752..d087924f2630aa9203277814e855e3084fead65d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index 8128acd56d693cc42fb7fc6ec7e0fa60ca01a1eb..a979f4715e68549cf13766d81662de55f73e0d4a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index a54acd92c53493126f07c8dc493a3b70c65de578..24ac579982d4d52fef0e5cd12df50ac63ec6ac9d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 9802d36d8d421d26cb0bb6cd1051a59c1a4bb7ec..da92224e8e506801532c24ad20c2a1d02c2c7039 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -105,6 +105,16 @@ CORBA::Long StdMeshers_LengthFromEdges_i::GetMode()
   return this->GetImpl()->GetMode();
 }
 
+//================================================================================
+/*!
+ * \brief Return false as in SALOME the mode is not used
+ */
+//================================================================================
+
+CORBA::Boolean StdMeshers_LengthFromEdges_i::HasParameters()
+{
+  return false;
+}
 
 //=============================================================================
 /*!
index 7fe1ddf099d5a9c2929704e3192d82987d6502cf..6e121afc7f45e61a4598056ffe379252f8785630 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -59,6 +59,9 @@ public:
   // Get mode
   CORBA::Long GetMode();
 
+  // Return false as in SALOME the mode is not used
+  CORBA::Boolean HasParameters();
+
   // Get implementation
   ::StdMeshers_LengthFromEdges* GetImpl();
   
index f9d209d5e733b1fe33a24d61811f9ccf7635c4d0..909ff59b999958ecd0b79f6c3679ab6f861bb0f4 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 4b9ce31234979d610f0a7c297aa846b4bc6e69be..92e3eb9bf9096311abb451b1c94fe03865ddc0b0 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index df1f7d0259cbbdd7e741946503a0a439d5a60b35..3a2645fd627283677d33114ab11607e75feb5b3a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index a7542cdc769c68e6969a35d482b185de5434127d..b8ff575330e53dca76b53a35cae470df391d3d1d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 43c9f853f6699d128064586ddb8bfeae84f944b2..19bd15993b26087eb01dd83cf94d1267ae4e66b8 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index e3482d1238ae7603e11e28c92d9d4bd529d14ad4..005219bf9ac42f0e52b2ec0ac9fb6eda8603d67b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index dfd637651ae42a2d45cc787420160c9c2ef8bc59..80f0a6d14d4558eef5f3cb2433384c52445ea75e 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 0a7c75ae44e4134cc7bf9b44191350f4166c9894..6920ccec6f774f50a77fa4d8e5a0dbb1d84bf786 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 258c8ac19651dd7b788bd371749a0658bd89cde6..83a1be4deeac31a72dfbc9f37deb4ec00b101530 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index 8ab02cb683db5067b0335d9c78baf018e0ca4ced..0eb8fc4819a0d3a8f2c41a0dcc2900a0d079e9ce 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index c2a1931b690ca85d61bbd66605570e97d40f52ac..70db544127fffff8a4ac99e0a5c9f47d1dd43ae9 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index be2df28ab5537af21b130134037e42c20c4ebd04..603745381ffee7d54a880113c0416efed067cce4 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 220ac6506923e3031b927f8401375827e26201d7..2863962972ed17d49ba2d86b11d41fc6b18db2e5 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
@@ -38,8 +38,8 @@ 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 )
+ :SMESH_Hypothesis_i( thePOA ),
+  StdMeshers_NumberOfLayers_i(thePOA,theStudyId,theGenImpl)
 {
   MESSAGE("StdMeshers_NumberOfLayers2D_i::StdMeshers_NumberOfLayers2D_i");
   myBaseImpl = new ::StdMeshers_NumberOfLayers2D(theGenImpl->GetANewId(),
index af4e58063bba6d82a1c4a67054c4cda0ea1954a8..1730afb5b722ea10d0aedd4b2bff313c07ea5ae7 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index c0c9ffcb8bcdc8cbb95788a3133169b89ed19154..be790539f8130c6f0004c7c29d1e584f643aa96d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index d177572d2a9143b85108d66a064f018502bcd6ff..447e4f204fd109b73a2e82ffee23274ba2d649f8 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index a59fd13183d842c9c5e2f05906752f162b31e144..47bbbcd79f3639a939240313aeadb94f2d4f3df2 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -88,7 +88,7 @@ SMESH::double_array* StdMeshers_NumberOfSegments_i::BuildDistributionExpr( const
     SMESH::double_array_var aRes = new SMESH::double_array();
     const std::vector<double>& res = this->GetImpl()->BuildDistributionExpr( func, nbSeg, conv );
     aRes->length( res.size() );
-    for (int i = 0; i < res.size(); i++)
+    for (size_t i = 0; i < res.size(); i++)
       aRes[i] = res[i];
     return aRes._retn();
   }
@@ -98,23 +98,24 @@ 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 )
+SMESH::double_array*
+StdMeshers_NumberOfSegments_i::BuildDistributionTab( const SMESH::double_array& func,
+                                                     CORBA::Long                nbSeg,
+                                                     CORBA::Long                conv )
   throw ( SALOME::SALOME_Exception )
 {
   ASSERT( myBaseImpl );
 
   std::vector<double> tbl( func.length() );
-  for (int i = 0; i < func.length(); i++)
+  for ( size_t i = 0; i < tbl.size(); i++ )
     tbl[i] = func[i];
 
   try
   {
-    SMESH::double_array_var aRes = new SMESH::double_array();
+    SMESH::double_array_var   aRes = new SMESH::double_array();
     const std::vector<double>& res = this->GetImpl()->BuildDistributionTab( tbl, nbSeg, conv );
     aRes->length( res.size() );
-    for (int i = 0; i < res.size(); i++)
+    for (size_t i = 0; i < res.size(); i++)
       aRes[i] = res[i];
     return aRes._retn();
   }
@@ -251,7 +252,7 @@ SMESH::long_array* StdMeshers_NumberOfSegments_i::GetReversedEdges()
   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++)
+  for ( size_t i = 0; i < ids.size(); i++)
     anArray [ i ] = ids [ i ];
 
   return anArray._retn();
@@ -267,10 +268,13 @@ void StdMeshers_NumberOfSegments_i::SetDistrType(CORBA::Long typ)
 {
   ASSERT( myBaseImpl );
   try {
+    CORBA::Long oldType = (CORBA::Long) this->GetImpl()->GetDistrType();
+
     this->GetImpl()->SetDistrType( (::StdMeshers_NumberOfSegments::DistrType) typ );
 
     // Update Python script
-    SMESH::TPythonDump() << _this() << ".SetDistrType( " << typ << " )";
+    if ( oldType != typ )
+      SMESH::TPythonDump() << _this() << ".SetDistrType( " << typ << " )";
   }
   catch ( SALOME_Exception& S_ex ) {
     THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
@@ -345,7 +349,7 @@ void StdMeshers_NumberOfSegments_i::SetTableFunction(const SMESH::double_array&
 {
   ASSERT( myBaseImpl );
   std::vector<double> tbl( table.length() );
-  for (int i = 0; i < table.length(); i++)
+  for ( CORBA::ULong i = 0; i < table.length(); i++)
     tbl[i] = table[i];
   try {
     this->GetImpl()->SetTableFunction( tbl );
@@ -372,12 +376,11 @@ SMESH::double_array* StdMeshers_NumberOfSegments_i::GetTableFunction()
     tbl = &this->GetImpl()->GetTableFunction();
   }
   catch ( SALOME_Exception& S_ex ) {
-    THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
-                                  SALOME::BAD_PARAM );
+    THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM );
   }
   SMESH::double_array_var aRes = new SMESH::double_array();
   aRes->length(tbl->size());
-  for (int i = 0; i < tbl->size(); i++)
+  for ( size_t i = 0; i < tbl->size(); i++ )
     aRes[i] = (*tbl)[i];
   return aRes._retn();
 }
index e81711b2f72dbe7cd0659a04b8ec0bc22a495c72..70f38f3c5a4ecef31f8257c73671165d1f79fa20 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 4afaa0a8b99033b7e1177a7dec5ebb341a26f0dd..99256855bd8fcfcd5cad26c8b9ef4957449fef0d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index b79fba02fcf0a3565aa438bb6737687387c24925..ed0ce004c1b7849a666cb3ba819981d1a161e53d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
diff --git a/src/StdMeshers_I/StdMeshers_PolygonPerFace_2D_i.cxx b/src/StdMeshers_I/StdMeshers_PolygonPerFace_2D_i.cxx
new file mode 100644 (file)
index 0000000..d41e343
--- /dev/null
@@ -0,0 +1,61 @@
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&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, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// 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_PolygonPerFace_2D_i.cxx
+//  Module : SMESH
+//
+
+#include "StdMeshers_PolygonPerFace_2D_i.hxx"
+
+#include "SMESH_Gen.hxx"
+#include "StdMeshers_PolygonPerFace_2D.hxx"
+
+//=============================================================================
+/*!
+ *  Constructor
+ */
+//=============================================================================
+
+StdMeshers_PolygonPerFace_2D_i::StdMeshers_PolygonPerFace_2D_i( PortableServer::POA_ptr thePOA,
+                                                                int                     theStudyId,
+                                                                ::SMESH_Gen*            theGenImpl )
+  : SALOME::GenericObj_i( thePOA ),
+    SMESH_Hypothesis_i( thePOA ),
+    SMESH_Algo_i( thePOA ),
+    SMESH_2D_Algo_i( thePOA )
+{
+  //MESSAGE( "StdMeshers_PolygonPerFace_2D_i::StdMeshers_PolygonPerFace_2D_i" );
+  myBaseImpl = new ::StdMeshers_PolygonPerFace_2D( theGenImpl->GetANewId(),
+                                                   theStudyId,
+                                                   theGenImpl );
+}
+
+//=============================================================================
+/*!
+ *  Destructor
+ */
+//=============================================================================
+
+StdMeshers_PolygonPerFace_2D_i::~StdMeshers_PolygonPerFace_2D_i()
+{
+  //MESSAGE( "StdMeshers_PolygonPerFace_2D_i::~StdMeshers_PolygonPerFace_2D_i" );
+}
diff --git a/src/StdMeshers_I/StdMeshers_PolygonPerFace_2D_i.hxx b/src/StdMeshers_I/StdMeshers_PolygonPerFace_2D_i.hxx
new file mode 100644 (file)
index 0000000..3718010
--- /dev/null
@@ -0,0 +1,54 @@
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&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, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// 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_PolygonPerFace_2D_i.hxx
+//  Module : SMESH
+//
+#ifndef _SMESH_PolygonPerFace_2D_I_HXX_
+#define _SMESH_PolygonPerFace_2D_I_HXX_
+
+#include "SMESH_StdMeshers_I.hxx"
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "SMESH_2D_Algo_i.hxx"
+
+class SMESH_Gen;
+
+// ======================================================
+// Polygon Per Face 2d algorithm
+// ======================================================
+class STDMESHERS_I_EXPORT StdMeshers_PolygonPerFace_2D_i:
+  public virtual POA_StdMeshers::StdMeshers_PolygonPerFace_2D,
+  public virtual SMESH_2D_Algo_i
+{
+ public:
+  // Constructor
+  StdMeshers_PolygonPerFace_2D_i( PortableServer::POA_ptr thePOA,
+                                  int                     theStudyId,
+                                  ::SMESH_Gen*            theGenImpl );
+  // Destructor
+  virtual ~StdMeshers_PolygonPerFace_2D_i();
+};
+
+#endif
index 450e32586e16d78fec4e5c8ab6098ba4ebe33670..eda0ecc14a68ce7b2c033f7fc28ffc8cfe153071 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index dc01ef2e7c4542adb2c1beb3505e54054ed0fda9..43cc6dd085cd162111467a12b5e8938be88cba3e 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 9ee397fae3d297cc6bc9bc8f43e18d9d7fc4b37c..fba792cd4ed1f48f064a93d4ffc10982181f2bc5 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 9b4fa33684550d1e20b7a673828b2b9c4500a0d9..4023302c236d259b0a494cd7f90d08653ea6248a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 28f63e480934a20d00066aa6db77a5e369f0c19b..5f1275088f243fbe09249887da5987e0a5b89fb8 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 2aea213ba587768d9b2f4120d4540d9f92846e50..18dfcbf2a8c6c9340cea9d8e831b91a9d43123dc 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 05414ee40d5e75eab2dbc71bde07c2519fa84a37..88f7343d6b037fc19a6b3d5e455a119a63fd2ccf 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index e28f881e73663772c2b0f9c959ff459d18f5d62c..09e76af7fafa34b79c64d70b6e7699f559620750 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 771b4e828d955e9a636e5046ceee8e5764f76527..dfe12adfd917ecb6713f0f008b32eeae078105d0 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -66,6 +66,17 @@ StdMeshers_Projection_3D_i::~StdMeshers_Projection_3D_i()
   return ( ::StdMeshers_Projection_3D* )myBaseImpl;
 }
 
+//================================================================================
+/*!
+ * \brief Return true if the algorithm is applicable to a shape
+ */
+//================================================================================
+
+CORBA::Boolean StdMeshers_Projection_3D_i::IsApplicable(const TopoDS_Shape &S,
+                                                        CORBA::Boolean toCheckAll)
+{
+  return ::StdMeshers_Projection_3D::IsApplicable( S, toCheckAll );
+}
 
 //=============================================================================
 /*!
index c1d3517e0a1994170bf409779842b1c8eb3a27c1..f2b65aab200a1bf62ccf382d78f3d407feb58567 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -37,6 +37,7 @@
 #include "StdMeshers_Projection_3D.hxx"
 
 class SMESH_Gen;
+class TopoDS_Shape;
 
 // ======================================================
 // Projection 3D algorithm
@@ -57,6 +58,9 @@ public:
 
   // Get implementation
   ::StdMeshers_Projection_3D* GetImpl();
+
+  // Return true if the algorithm is applicable to a shape
+  static CORBA::Boolean IsApplicable(const TopoDS_Shape &S, CORBA::Boolean toCheckAll);
 };
 
 // ======================================================
index f49333a5e2cd26f6ea03cc0abd474125a33bf3d5..2684d38013e082dc2da30606ed91f17c42697548 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index c7d8ba4815d375e2a60881411f997456441cd564..e61723edab0378c55db8828a2644bd86d4a00bf8 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index a76be4f4fb8af40712036a2d1fd751922db608c6..e31e6035ac8331853746983f176ce9d424c0393d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index 6a3d00400dbdf73932813eec0660a2540d153515..b10081c966807579be01a49d2d4337c1d5afee4a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index e1b44fe318d1d74e5927b541b953a15580e0c025..6ea97fa273d6c0cdc12456b55bb31272be62c223 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 474246550772101bf4aa912a3baee05b57ce3cb1..c842251c0441ba8fb63a1e856e3fac7e80390813 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 3ca07c9e8f677b2f77d196b12bf52a813aa79bdd..c9a1ef050ca198bae48d31ed92a058f0163d4430 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&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,6 +32,8 @@
 #include "Utils_CorbaException.hxx"
 #include "utilities.h"
 
+#include "StdMeshers_QuadFromMedialAxis_1D2D.hxx"
+
 using namespace std;
 
 //=============================================================================
@@ -98,3 +100,51 @@ CORBA::Boolean StdMeshers_Quadrangle_2D_i::IsApplicable( const TopoDS_Shape &S,
   return ::StdMeshers_Quadrangle_2D::IsApplicable( S, toCheckAll );
 }
 
+//=============================================================================
+/*!
+ *  StdMeshers_QuadFromMedialAxis_1D2D_i::StdMeshers_QuadFromMedialAxis_1D2D_i
+ *
+ *  Constructor
+ */
+//=============================================================================
+
+StdMeshers_QuadFromMedialAxis_1D2D_i::
+StdMeshers_QuadFromMedialAxis_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_QuadFromMedialAxis_1D2D_i::StdMeshers_QuadFromMedialAxis_1D2D_i" );
+  myBaseImpl = new ::StdMeshers_QuadFromMedialAxis_1D2D( theGenImpl->GetANewId(),
+                                                         theStudyId,
+                                                         theGenImpl );
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_QuadFromMedialAxis_1D2D_i::~StdMeshers_QuadFromMedialAxis_1D2D_i
+ *
+ *  Destructor
+ *
+ */
+//=============================================================================
+
+StdMeshers_QuadFromMedialAxis_1D2D_i::~StdMeshers_QuadFromMedialAxis_1D2D_i()
+{
+  MESSAGE( "StdMeshers_QuadFromMedialAxis_1D2D_i::~StdMeshers_QuadFromMedialAxis_1D2D_i" );
+}
+
+//================================================================================
+/*!
+ * \brief Return true if the algorithm is applicable to a shape
+ */
+//================================================================================
+
+CORBA::Boolean StdMeshers_QuadFromMedialAxis_1D2D_i::IsApplicable( const TopoDS_Shape &S,
+                                                                   CORBA::Boolean toCheckAll )
+{
+  return ::StdMeshers_QuadFromMedialAxis_1D2D::IsApplicable( S, toCheckAll );
+}
index 194817527ce8a6eaf946de31da138ec57c30b662..c8c2cf1157f6983e01c7d7554f6678c147d8cab3 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -62,4 +62,24 @@ class STDMESHERS_I_EXPORT StdMeshers_Quadrangle_2D_i:
   static CORBA::Boolean IsApplicable(const TopoDS_Shape &S, CORBA::Boolean toCheckAll);
 };
 
+// ======================================================
+// Quadrangle (Medial Axis Projection) 2d algorithm
+// ======================================================
+class STDMESHERS_I_EXPORT StdMeshers_QuadFromMedialAxis_1D2D_i:
+  public virtual POA_StdMeshers::StdMeshers_QuadFromMedialAxis_1D2D,
+  public virtual SMESH_2D_Algo_i
+{
+ public:
+  // Constructor
+  StdMeshers_QuadFromMedialAxis_1D2D_i( PortableServer::POA_ptr thePOA,
+                                        int                     theStudyId,
+                                        ::SMESH_Gen*            theGenImpl );
+
+  // Destructor
+  virtual ~StdMeshers_QuadFromMedialAxis_1D2D_i();
+
+  // Return true if the algorithm is applicable to a shape
+  static CORBA::Boolean IsApplicable(const TopoDS_Shape &S, CORBA::Boolean toCheckAll);
+};
+
 #endif
index b7309f46f960c69260e4ca09ddf13cc34d319851..08f24804a48220b991c42990d315473fb992ca10 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index bfa27b206f0cede10f116f414915f7bcd8347e3b..2349f9d7b47107eae3e3a31ad1f95f44b6f8eb94 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 2e085910f888c0d19ade2ef06b99a376fc3918b5..a848ebbd6399cdbab76df1c6c21332de317e5216 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index 6b5ad31158e599ab74a125055bbffbf17713fb98..2befae9ba17a8b3fd8a4cf22e041ab5006977ce5 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index 151551f2e2b01491dfe35254c339312cb3e2ee5e..82de1af259f496df95c1b5795998f8272ca2da8a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index c1ddc6bec147fb327d88bfb9e2f2eee5768a98fd..5f32a0c64ec699bd391648c6faded1721ae911f5 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index b09207f24e9e8f09f34a4d0c311a6195018f109d..13e86c06a6a3527919727de9941621f3e396aaf8 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -123,7 +123,7 @@ SMESH::long_array* StdMeshers_Reversible1D_i::GetReversedEdges()
   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++)
+  for ( CORBA::ULong i = 0; i < ids.size(); i++)
     anArray [ i ] = ids [ i ];
 
   return anArray._retn();
index f03c5d854dc54b39c772c6889b4fb9a1121eb1a6..7d511d48c404c12b4687b6082022633553b161d2 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 346842f63b508cc00d5cc832d20be7dfdf1f5329..1e8a70bff7e9968d85b41d0305f85ebecf7186cd 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 9a5c5030a6550a103890c456985903490251bba8..e43e89e008c68c33cbd7ac0a37344a4a0e3714f9 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index a294ee46413da9359386b467241a7774f356999f..219a44848ab07e25b630426b51befe228664ef2e 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 1729a48bc583aa97eb79beee3b71c2816e61fcb7..2db64754fdb124602ca614ecf88be1415bea21c9 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 7e8b3ac4cb4e51b54fb437bb235cf07be2350462..b73eab39b0efb9b31b8d7ca752fab36770fc1fd6 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -223,7 +223,7 @@ SMESH::long_array* StdMeshers_StartEndLength_i::GetReversedEdges()
   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++)
+  for ( CORBA::ULong i = 0; i < ids.size(); i++)
     anArray [ i ] = ids [ i ];
 
   return anArray._retn();
index 79a9dbf55405fa49f12d6780221f3ad748858313..083953fe593aa78e2502b45282a4e0a2ec51653d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 8790c981012341353f4239faa0d297503570d95d..fce8851137b03082b2701e93ee088b04e6a5b46b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index 01f182067b30cd20954123e7d5efb754fdec1a3c..107b5e40cee0756bfb5bd8b10a210a831095ef51 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
index c8fae2d92dacee1fcf9fa7e0cc30895bb5d000df..58f21163ab66c064b3ddbe0ea57e6dfd17294712 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index f521d3431c60226a3abc3b3907b9d1d74210ea6f..94518e707a856d2a0a83494cc4829fd4f025cd8d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
index 6a1f41daa8aac95da73942a36a69c6c17d07b4c1..a5a33fe2866a3f7bf11b0198105c8f0ff3f130e6 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -230,6 +230,33 @@ throw ( SALOME::SALOME_Exception )
   return GetImpl()->GetStretchFactor();
 }
 
+//================================================================================
+/*!
+ * \brief Set Method of computing translation of a node
+ */
+//================================================================================
+
+void StdMeshers_ViscousLayers_i::SetMethod( ::StdMeshers::VLExtrusionMethod how )
+{
+  GetImpl()->SetMethod( ::StdMeshers_ViscousLayers::ExtrusionMethod( how ));
+  const char* methNames[3] = { "SURF_OFFSET_SMOOTH",
+                               "FACE_OFFSET",
+                               "NODE_OFFSET" };
+  if ( how >= 0 && how < 3 )
+    SMESH::TPythonDump() << _this() << ".SetMethod( StdMeshers." << methNames[ how ]<< " )";
+}
+
+//================================================================================
+/*!
+ * \brief Return Method of computing translation of a node
+ */
+//================================================================================
+
+::StdMeshers::VLExtrusionMethod StdMeshers_ViscousLayers_i::GetMethod()
+{
+  return (::StdMeshers::VLExtrusionMethod) GetImpl()->GetMethod();
+}
+
 //=============================================================================
 /*!
  *  Get implementation
index e2e5b4b9da3181b8663c8f45fc822827c8833d27..1b95fd1753cdd3320f396044d03f797c72ed41de 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -65,6 +65,9 @@ class STDMESHERS_I_EXPORT StdMeshers_ViscousLayers_i:
   void SetStretchFactor(::CORBA::Double factor) throw ( SALOME::SALOME_Exception );
   ::CORBA::Double GetStretchFactor();
 
+  void SetMethod( ::StdMeshers::VLExtrusionMethod how );
+  ::StdMeshers::VLExtrusionMethod GetMethod();
+
   // Get implementation
   ::StdMeshers_ViscousLayers* GetImpl();
 
index bdfcb2fc8d3256e92a57b05d1857dea02e2ef36c..2346e1cf80ceb9deca68fdcd033149e045d2e30e 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 
 #include "utilities.h"
 
-#include "StdMeshers_LocalLength_i.hxx"
-#include "StdMeshers_AutomaticLength_i.hxx"
-#include "StdMeshers_StartEndLength_i.hxx"
+#include "StdMeshers_Adaptive1D_i.hxx"
 #include "StdMeshers_Arithmetic1D_i.hxx"
-#include "StdMeshers_Geometric1D_i.hxx"
-#include "StdMeshers_FixedPoints1D_i.hxx"
-#include "StdMeshers_NumberOfSegments_i.hxx"
+#include "StdMeshers_AutomaticLength_i.hxx"
+#include "StdMeshers_CartesianParameters3D_i.hxx"
+#include "StdMeshers_Cartesian_3D_i.hxx"
+#include "StdMeshers_CompositeSegment_1D_i.hxx"
 #include "StdMeshers_Deflection1D_i.hxx"
-#include "StdMeshers_Adaptive1D_i.hxx"
-#include "StdMeshers_Propagation_i.hxx"
+#include "StdMeshers_FixedPoints1D_i.hxx"
+#include "StdMeshers_Geometric1D_i.hxx"
+#include "StdMeshers_Hexa_3D_i.hxx"
+#include "StdMeshers_ImportSource1D_i.hxx"
+#include "StdMeshers_ImportSource2D_i.hxx"
+#include "StdMeshers_Import_1D2D_i.hxx"
+#include "StdMeshers_Import_1D_i.hxx"
+#include "StdMeshers_LayerDistribution2D_i.hxx"
+#include "StdMeshers_LayerDistribution_i.hxx"
 #include "StdMeshers_LengthFromEdges_i.hxx"
-#include "StdMeshers_QuadranglePreference_i.hxx"
-//#include "StdMeshers_TrianglePreference_i.hxx"
-#include "StdMeshers_QuadraticMesh_i.hxx"
+#include "StdMeshers_LocalLength_i.hxx"
 #include "StdMeshers_MaxElementArea_i.hxx"
 #include "StdMeshers_MaxElementVolume_i.hxx"
+#include "StdMeshers_MaxLength_i.hxx"
 #include "StdMeshers_NotConformAllowed_i.hxx"
-#include "StdMeshers_ProjectionSource3D_i.hxx"
-#include "StdMeshers_ProjectionSource2D_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_NumberOfLayers_i.hxx"
+#include "StdMeshers_NumberOfSegments_i.hxx"
+#include "StdMeshers_PolygonPerFace_2D_i.hxx"
+#include "StdMeshers_Prism_3D_i.hxx"
+#include "StdMeshers_ProjectionSource1D_i.hxx"
+#include "StdMeshers_ProjectionSource2D_i.hxx"
+#include "StdMeshers_ProjectionSource3D_i.hxx"
+#include "StdMeshers_Projection_1D_2D_3D_i.hxx"
+#include "StdMeshers_Propagation_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"
-#ifdef ENABLE_MEFISTO
- #include "StdMeshers_MEFISTO_2D_i.hxx"
-#endif
+#include "StdMeshers_QuadranglePreference_i.hxx"
 #include "StdMeshers_Quadrangle_2D_i.hxx"
-#include "StdMeshers_Hexa_3D_i.hxx"
-#include "StdMeshers_Projection_1D_2D_3D_i.hxx"
-#include "StdMeshers_Prism_3D_i.hxx"
+#include "StdMeshers_QuadraticMesh_i.hxx"
+#include "StdMeshers_RadialQuadrangle_1D2D_i.hxx"
+#include "StdMeshers_Regular_1D_i.hxx"
 #include "StdMeshers_SegmentAroundVertex_0D_i.hxx"
-#include "StdMeshers_CompositeSegment_1D_i.hxx"
+#include "StdMeshers_SegmentLengthAroundVertex_i.hxx"
+#include "StdMeshers_StartEndLength_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_ViscousLayers2D_i.hxx"
-#include "StdMeshers_CartesianParameters3D_i.hxx"
+#include "StdMeshers_ViscousLayers_i.hxx"
+#ifdef ENABLE_MEFISTO
+ #include "StdMeshers_MEFISTO_2D_i.hxx"
+#endif
 
 namespace SMESH {
   class ApplicableToAny
   {
   public:
-    static CORBA::Boolean IsApplicable( const TopoDS_Shape &S, CORBA::Boolean toCheckAll ) {
+    static CORBA::Boolean IsApplicable( const TopoDS_Shape &S, CORBA::Boolean toCheckAll )
+    {
       return true;
     }
   };
 };
-template <class T, class TIsApplicable = SMESH::ApplicableToAny> class StdHypothesisCreator_i:public HypothesisCreator_i<T>
+template <class T, class TIsApplicable = SMESH::ApplicableToAny>
+class StdHypothesisCreator_i : public HypothesisCreator_i< T >
 {
 public:
   // as we have 'module StdMeshers' in SMESH_BasicHypothesis.idl
   virtual std::string GetModuleName() { return "StdMeshers"; }
-  virtual CORBA::Boolean IsApplicable( const TopoDS_Shape & S, CORBA::Boolean toCheckAll ) {
+  virtual CORBA::Boolean IsApplicable( const TopoDS_Shape & S, CORBA::Boolean toCheckAll )
+  {
     return TIsApplicable::IsApplicable( S, toCheckAll );
   }
 };
@@ -216,6 +218,8 @@ STDMESHERS_I_EXPORT
 #endif
     else if (strcmp(aHypName, "Quadrangle_2D") == 0)
       aCreator = new StdHypothesisCreator_i<StdMeshers_Quadrangle_2D_i, StdMeshers_Quadrangle_2D_i>;
+    else if (strcmp(aHypName, "QuadFromMedialAxis_1D2D") == 0)
+      aCreator = new StdHypothesisCreator_i<StdMeshers_QuadFromMedialAxis_1D2D_i, StdMeshers_QuadFromMedialAxis_1D2D_i>;
     else if (strcmp(aHypName, "Hexa_3D") == 0)
       aCreator = new StdHypothesisCreator_i<StdMeshers_Hexa_3D_i, StdMeshers_Hexa_3D_i>;
     else if (strcmp(aHypName, "Projection_1D") == 0)
@@ -225,7 +229,7 @@ STDMESHERS_I_EXPORT
     else if (strcmp(aHypName, "Projection_2D") == 0)
       aCreator = new StdHypothesisCreator_i<StdMeshers_Projection_2D_i>;
     else if (strcmp(aHypName, "Projection_3D") == 0)
-      aCreator = new StdHypothesisCreator_i<StdMeshers_Projection_3D_i, StdMeshers_Hexa_3D_i>;
+      aCreator = new StdHypothesisCreator_i<StdMeshers_Projection_3D_i, StdMeshers_Projection_3D_i>;
     else if (strcmp(aHypName, "Prism_3D") == 0)
       aCreator = new StdHypothesisCreator_i<StdMeshers_Prism_3D_i, StdMeshers_Prism_3D_i>;
     else if (strcmp(aHypName, "RadialPrism_3D") == 0)
@@ -246,6 +250,8 @@ STDMESHERS_I_EXPORT
       aCreator = new StdHypothesisCreator_i<StdMeshers_Import_1D2D_i>;
     else if (strcmp(aHypName, "Cartesian_3D") == 0)
       aCreator = new StdHypothesisCreator_i<StdMeshers_Cartesian_3D_i>;
+    else if (strcmp(aHypName, "PolygonPerFace_2D") == 0)
+      aCreator = new StdHypothesisCreator_i<StdMeshers_PolygonPerFace_2D_i>;
     else ;
 
     return aCreator;
index bf0346e8fee7bc592240f892bc8550b65dbcd9fe..b7bc5d7e06cb953037bc768093aec7d78d532ebc 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  EDF R&D
+# Copyright (C) 2012-2015  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
index f631a56c5606b54a598919498517ed21931d58e9..f0900c8110afc1187107be7fe6ceda9e8babd03c 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  EDF R&D
+# Copyright (C) 2013-2015  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
index 9eb63906467229a0710ea5b1d30da77fdc2a7036..3b2b88e525330272ab1e1ffad3ed05a9fd78c67b 100644 (file)
@@ -1,5 +1,5 @@
 # -*- coding: utf-8 -*-
-# Copyright (C) 2007-2014  EDF R&D
+# Copyright (C) 2013-2015  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
@@ -67,7 +67,7 @@ class MGCleanerMonPlugDialog(Ui_MGCleanerPlugDialog,QWidget):
     self.PB_MeshFile.setIcon(icon)
     self.PB_MeshFile.setToolTip("source mesh from a file in disk")
     
-    #Ces parametres ne sont pas remis à rien par le clean
+    #Ces parametres ne sont pas remis ?? rien par le clean
     self.paramsFile= os.path.abspath(os.path.join(os.environ["HOME"],".MGCleaner.dat"))
     self.LE_ParamsFile.setText(self.paramsFile)
     self.LE_MeshFile.setText("")
index b139a0d4c0db6e96c9ce5df36544ad86977f5317..df10768327db93fd1d44bbd9b1984e2e80b6b791 100644 (file)
@@ -1,5 +1,5 @@
 # -*- coding: utf-8 -*-
-# Copyright (C) 2007-2014  EDF R&D
+# Copyright (C) 2013-2015  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
@@ -51,23 +51,6 @@ class MGCleanerMonViewText(Ui_ViewExe, QDialog):
         # Je n arrive pas a utiliser le setEnvironment du QProcess
         # fonctionne hors Salome mais pas dans Salome ???
         cmds=''
-        try :
-          LICENCE_FILE=os.environ["DISTENE_LICENCE_FILE_FOR_MGCLEANER"]
-        except:
-          LICENCE_FILE=''
-        try :
-          PATH=os.environ["DISTENE_PATH_FOR_MGCLEANER"]
-        except:
-          PATH=''
-        if LICENCE_FILE != '': 
-          cmds+='source '+LICENCE_FILE+'\n'
-        else:
-          cmds+="# $DISTENE_LICENCE_FILE_FOR_MGCLEANER NOT SET\n"
-        if PATH != '': 
-          cmds+='export PATH='+PATH+':$PATH\n'
-        else:
-          cmds+="# $DISTENE_PATH_FOR_MGCLEANER NOT SET\n"
-        #cmds+='env\n'
         cmds+='rm -f '+self.parent().fichierOut+'\n'
         cmds+=txt+'\n'
         cmds+='echo END_OF_MGCleaner\n'
index 18893f886a03a61dee16c7de7fe3e80f2c568b36..6043b7b0a6c3534c9e8da297e30145f1e1142db2 100644 (file)
@@ -1,5 +1,5 @@
 # -*- coding: utf-8 -*-
-# Copyright (C) 2006-2014  EDF R&D
+# Copyright (C) 2013-2015  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
index faeb39e6dbae33e496d456fcdaa981430d5f3a3d..ec27c9ff42e9120622744e11115c33b739a0c4c7 100755 (executable)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  EDF R&D
+# Copyright (C) 2013-2015  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
index 5d8876c8b06b2460ab73d6279b16d61ed6e9d29a..b52763b9eae93c5a62370dc97eb481dc4fce42c1 100644 (file)
@@ -36,7 +36,7 @@ master_doc = 'index'
 
 # General substitutions.
 project = 'MGCleaner Plug-in'
-copyright = '2013-2014, CEA'
+copyright = '2013-2015, EDF R&D'
 
 # The default replacements for |version| and |release|, also used in various
 # other places throughout the built documents.
index 4cf6c7293d5b8d904476abc250658026e9b4da7c..e652b59eb1b5705d7183eef6341d74d0a5989d84 100644 (file)
@@ -1,23 +1,21 @@
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
-
-# Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-
+# Copyright (C) 2014-2015  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, or (at your option) any later version.
-
+#
 # This library is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # Lesser General Public License for more details.
-
+#
 # You should have received a copy of the GNU Lesser General Public
 # License along with this library; if not, write to the Free Software
 # 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(MACMESH_INSTALL_PY ${SALOME_SMESH_INSTALL_PLUGINS}/MacMesh)
 SET(MACMESH_INSTALL_DOC ${SALOME_INSTALL_DOC}/gui/SMESH/MacMesh)
index 713e27f4a0faa287913ca46d70305b739a54faaf..389f6ab2910cf1b46b548b84269e7d6ffb8c4d3b 100755 (executable)
@@ -1,23 +1,21 @@
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
-
-# Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-
+# Copyright (C) 2014-2015  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, or (at your option) any later version.
-
+#
 # This library is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # Lesser General Public License for more details.
-
+#
 # You should have received a copy of the GNU Lesser General Public
 # License along with this library; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
+#
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
 
 ##################################################################
 # Header for salome initialization ###############################
index 9bfd71a66754dec401ccd5988fe43effe3fe7e81..49de79cf2c04c555e87822b9f0a413e06d02d641 100644 (file)
@@ -1,23 +1,21 @@
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
-
-# Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-
+# Copyright (C) 2014-2015  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, or (at your option) any later version.
-
+#
 # This library is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # Lesser General Public License for more details.
-
+#
 # You should have received a copy of the GNU Lesser General Public
 # License along with this library; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
+#
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
 
 def Message (code) :
        import sys
index 2a7c9d59c937c00b64b7f545d9b89c0a02df8218..32c29a37935f99ed3f423392af14314d45ef8d7b 100644 (file)
@@ -1,24 +1,21 @@
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
-
-# Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-
+# Copyright (C) 2014-2015  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, or (at your option) any later version.
-
+#
 # This library is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # Lesser General Public License for more details.
-
+#
 # You should have received a copy of the GNU Lesser General Public
 # License along with this library; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
+#
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-
+#
 
 
 
index 773fc41b74bcb9c5713eea99c39f5825c9509409..2a2b45ca22f485402ac262e0072ebc8d0f105149 100644 (file)
@@ -1,24 +1,21 @@
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
-
-# Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-
+# Copyright (C) 2014-2015  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, or (at your option) any later version.
-
+#
 # This library is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # Lesser General Public License for more details.
-
+#
 # You should have received a copy of the GNU Lesser General Public
 # License along with this library; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
+#
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-
+#
 
 
 # INTRODUCTION HERE
index 88cdc83b05746548d3b326cc1f14eaba10398314..685177414d8971931f0436acf7c3bc186b906800 100644 (file)
@@ -1,25 +1,21 @@
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
-
-# Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-
+# Copyright (C) 2014-2015  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, or (at your option) any later version.
-
+#
 # This library is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # Lesser General Public License for more details.
-
+#
 # You should have received a copy of the GNU Lesser General Public
 # License along with this library; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
+#
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-
-
+#
 
 
 # INTRODUCTION HERE
index a0816f497d31fff189bd38b0dee209283aedda8b..d0816ea4f8acfc7517435d08d04775892bc298d6 100644 (file)
@@ -1,23 +1,21 @@
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
-
-# Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-
+# Copyright (C) 2014-2015  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, or (at your option) any later version.
-
+#
 # This library is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # Lesser General Public License for more details.
-
+#
 # You should have received a copy of the GNU Lesser General Public
 # License along with this library; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
+#
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
 
 
 
index 3a4cd4f49341a24453dd49635e2ee9f9b3559965..86bcc549bd39e3f0c4a647b5d9a12a9db3988d76 100644 (file)
@@ -1,24 +1,21 @@
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
-
-# Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-
+# Copyright (C) 2014-2015  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, or (at your option) any later version.
-
+#
 # This library is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # Lesser General Public License for more details.
-
+#
 # You should have received a copy of the GNU Lesser General Public
 # License along with this library; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
+#
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-
+#
 
 
 
index e2e2c42196cedab228eccb1302b7d141ea38b923..bee18b3770a6327df84ce7bf02f5a05727098a10 100644 (file)
@@ -1,25 +1,21 @@
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
-
-# Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-
+# Copyright (C) 2014-2015  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, or (at your option) any later version.
-
+#
 # This library is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # Lesser General Public License for more details.
-
+#
 # You should have received a copy of the GNU Lesser General Public
 # License along with this library; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
+#
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-
-
+#
 
 
 
index 2e3dce3087e91e95176bc2701fea3df15c48f84a..45ae806ab1010da9edd9af98c068c9e3bf3dd10c 100644 (file)
@@ -1,23 +1,21 @@
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
-
-# Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-
+# Copyright (C) 2014-2015  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, or (at your option) any later version.
-
+#
 # This library is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # Lesser General Public License for more details.
-
+#
 # You should have received a copy of the GNU Lesser General Public
 # License along with this library; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
+#
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
 
 
 
index 4b78724cc13d2dd5a2ae2bf78ada49be3fb88b9a..87dcb6aa6911582d4697b454ab6b46f067bcecff 100644 (file)
@@ -1,23 +1,21 @@
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
-
-# Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-
+# Copyright (C) 2014-2015  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, or (at your option) any later version.
-
+#
 # This library is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # Lesser General Public License for more details.
-
+#
 # You should have received a copy of the GNU Lesser General Public
 # License along with this library; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
+#
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
 
 
 
index f634488992ac8433a4fa98edca11e1cc6ea3e243..c57d49b1c68deab1f1011b9404f9bb18f4f6d025 100644 (file)
@@ -1,24 +1,21 @@
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
-
-# Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-
+# Copyright (C) 2014-2015  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, or (at your option) any later version.
-
+#
 # This library is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # Lesser General Public License for more details.
-
+#
 # You should have received a copy of the GNU Lesser General Public
 # License along with this library; if not, write to the Free Software
 # 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 SMESH
index dd6293029aee01897082bc31886fd1d61bb49800..307b35944fd775a1ea3925b22c0e2f3df4a5f354 100644 (file)
@@ -1,23 +1,21 @@
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
-
-# Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-
+# Copyright (C) 2014-2015  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, or (at your option) any later version.
-
+#
 # This library is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # Lesser General Public License for more details.
-
+#
 # You should have received a copy of the GNU Lesser General Public
 # License along with this library; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
+#
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
 
 
 
index 5aed1ff41d16a3c47adadfe78d51dfd50fd29f63..4ad8c1c6997092422755952a2f456662a2bb82be 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2006-2014  EDF R&D
+// Copyright (C) 2006-2015  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
index 9eb6b11a7d6ddc091590fae27b5e9d927857dda5..139b61f30c4765b22cd2068f0690ba1870662fe9 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  EDF R&D
+# Copyright (C) 2012-2015  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
index 8c5f88e67778919a9037e68f1d6d540cfb045317..c488af0f4a598040db5f6947c2334cae51368690 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2006-2014  EDF R&D
+// Copyright (C) 2006-2015  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
index ceb4bc118632f9a1849a71dd099e66ea2742673b..f98216e4b4cb63e4d20ec2118be8b7c02777c429 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2006-2014  EDF R&D
+// Copyright (C) 2006-2015  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
index 9b43f468ad55b4711fe11ca9de1d6170f4ea1107..bd4abba83160905433bd1b1c558c0055d7eca116 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2006-2014  EDF R&D
+// Copyright (C) 2006-2015  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
index be2d926a1021226d6cc37ce5c40a9d0a793eb446..dbce2c056685ef6ae9c9471653f979269a998bc8 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2006-2014  EDF R&D
+// Copyright (C) 2006-2015  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
index 02572a17aae01007323da6b524c77731690276ae..7043ef6bfa315172bf8e2b07c9a3d6598d4a6893 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2006-2014  EDF R&D
+// Copyright (C) 2006-2015  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
index 58e36a4f78450c95f8c601ad7e884ccfdc977ad8..36ec1eb27f737d7c2706a13aa137a5cb3212bfd2 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2006-2014  EDF R&D
+// Copyright (C) 2006-2015  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
index e702abbe7a4009a2e5a25a725da200b7ea62ad89..e148e75ef7944a3cc707f0cdac900bf368471f18 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2006-2014  EDF R&D
+// Copyright (C) 2006-2015  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
index 7fb1fc1ef67871c5b307e70cc64dff3ad893c439..3b96e550559fc4f66aacffdcaf4d66cfbbbf5a3e 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2006-2014  EDF R&D
+// Copyright (C) 2006-2015  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
index ca589a035ad41bd7f2b9bf2af2809cbf716d3d97..18754fdc2b0126044e5a7f38426c778e8618ce95 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2006-2014  EDF R&D
+// Copyright (C) 2006-2015  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
index 6997cf42b5e1bf7d3d6d9aeaea75a69ec2b0c4f9..ce33f1251aa3ab769f0d18e829435a6e9d632d32 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2006-2014  EDF R&D
+// Copyright (C) 2006-2015  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
index 38ec6cb7a0118b0d1ab1cb3dd8684487d063c5b5..1a3c7617a31061e7846a49b94060909e7b771e4f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2006-2014  EDF R&D
+// Copyright (C) 2006-2015  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
index 778728b6fed4012c2f9db2551e699a3b62c1572c..7ec32314ef19d873ab44fee1b6455340882dfc6f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2006-2014  EDF R&D
+// Copyright (C) 2006-2015  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
index 7670a2606cc5061f6aff7b192280fedbde774a31..8394845f0c69654824d2540be5123147aab3be43 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2006-2014  EDF R&D
+// Copyright (C) 2006-2015  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
index 63658e5a8409fe5cad1d9b7280b2c3fe44cd5b4e..ba98c0643071e87ada1f3251ae9147abb563d887 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2006-2014  EDF R&D
+// Copyright (C) 2006-2015  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
 #ifndef __MESHCUT_UTILS_HXX__
 #define __MESHCUT_UTILS_HXX__
 
-extern "C"
-  {
 #include <med.h>
-  }
 
 #include <string>
 #include <vector>
index 997f72e2887dd0f0bbfc59c6a0c09eee2f274ef1..f140d77b567698a8ac786233bcc452dccd42b03d 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2006-2014  EDF R&D
+# Copyright (C) 2006-2015  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
index 213ff534901bee121e3b4ce8f151abf26a2be1a3..e4f65616e6bcf0a4e2f55a8eedda462acde9bc37 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  EDF R&D
+# Copyright (C) 2012-2015  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
index 07e6537b0f38c1e91d03488236284e42a4eef761..bf82ad1e0dfb465f9f0c3200b8ced1836b8e6310 100644 (file)
@@ -1,10 +1,10 @@
 # -*- coding: utf-8 -*-
-# Copyright (C) 2007-201  EDF R&D
+# Copyright (C) 2007-2015  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.
+# version 2.1 of the License, or (at your option) any later version.
 #
 # This library is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
index 33941eae40f55e1689bfbfad0830228b0b5a0847..afc3503fa7ca995448f3c64544e3e38ab06e0c83 100755 (executable)
@@ -24,6 +24,7 @@ if __name__ == "__main__":
          exit()
 
       maBase=Base(options.database)
+      maBase.create()
       maBase.initialise()
       maBase.importFromCSV(folder,options.partiel,options.force)
       maBase.close()
index e92fb50ba887406df208ddc657ad36639b649b33..8707711d63b1f3ddbd514c499edf05f7947747ed 100644 (file)
@@ -4,8 +4,8 @@ from tableDeBase import TableDeBase
 class TablePerfs (TableDeBase):
       def __init__(self):
           TableDeBase.__init__(self,"Perfs")
-          self.setField(('Maillage','Version','NbSecCpu','Memoire'))
-          self.setTypeField(('int','int','int','int'),('idMaillage','idVersion','Machine'))
+          self.setField(('Maillage','Version','Machine','NbSecCpu','Memoire'))
+          self.setTypeField(('int','int','str','int','int'),('idMaillage','idVersion','Machine'))
 
       def createSqlTable(self):
           query=QtSql.QSqlQuery()
index 6626f9d608ebe32045724f21bba2ec334b247de2..8334ae67d7b880d37dd3b10808a921cdf3625f8b 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  EDF R&D
+# Copyright (C) 2012-2015  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
index a4d1bc698ec938f579dc808ba017c713484d6826..f815d828ff6ca5c7c8790d66dcc7f7f130f6f14e 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  EDF R&D
+# Copyright (C) 2012-2015  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
index 7cb14af7ca75e951f343852e160e56fadae6718a..b83a5f44c169e2d6dec17f0957a39a4d5a9dd7f3 100644 (file)
@@ -1,5 +1,5 @@
 # -*- coding: utf-8 -*-
-# Copyright (C) 2007-2014  EDF R&D
+# Copyright (C) 2007-2015  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
index 32566e3050007b521827130912e07bc99e6a0d81..b002db7002bbcfaa694c09597c7492502e652570 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  EDF R&D
+# Copyright (C) 2012-2015  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
index 0dfa0613df74be3abe5aa5067ec7d19891934850..34354e972430aaba11ece887b7d8c16232f3d46b 100755 (executable)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  EDF R&D
+# Copyright (C) 2012-2015  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
index eb5c48184ce4cf790e79d7b3fec864618f7a58eb..28501f67ba9c9f05104ddb6142ae5fff48e2c9e6 100644 (file)
@@ -36,7 +36,7 @@ master_doc = 'index'
 
 # General substitutions.
 project = 'Verima Plug-in'
-copyright = '2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE'
+copyright = '2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE'
 
 # The default replacements for |version| and |release|, also used in various
 # other places throughout the built documents.
index 026e2d8edc037542ed31782cf38a6822c588ca29..2ce0fcdbf37ffc9c29b111d2a5cffd43df427810 100644 (file)
@@ -36,7 +36,7 @@ master_doc = 'index'
 
 # General substitutions.
 project = 'Verima Plug-in'
-copyright = '2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE'
+copyright = '2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE'
 
 # The default replacements for |version| and |release|, also used in various
 # other places throughout the built documents.
index 2cadddafd01ea7fac8b937c158250ed33e9c555b..e36500df16e3c727c3caef1ffbf651f2f591aa4c 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2011-2014  EDF R&D
+# Copyright (C) 2011-2015  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
index 8ba06340ea15c580085f13bd33a21e1fa19bcf82..c8e1557329188ec561355321d743cead5a6b5994 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  EDF R&D
+# Copyright (C) 2012-2015  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
index b6ea681fb4a0696c74769cada70bbe7890ce4c21..52c7ab155de87023e5fd9875602a41467348c910 100644 (file)
@@ -1,10 +1,10 @@
 # -*- coding: utf-8 -*-
-# Copyright (C) 2007-201  EDF R&D
+# Copyright (C) 2007-2015  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.
+# version 2.1 of the License, or (at your option) any later version.
 #
 # This library is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
index f733ea97cf81769a9338126c11f81d0cfa287349..9a31df28635068b4a72ef59bb152c9facfc73626 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  EDF R&D
+# Copyright (C) 2012-2015  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
index 2f96268b20b307b6ad5669ce4b14fb294306f2ae..b83a5f44c169e2d6dec17f0957a39a4d5a9dd7f3 100644 (file)
@@ -1,10 +1,10 @@
 # -*- coding: utf-8 -*-
-# Copyright (C) 2007-201  EDF R&D
+# Copyright (C) 2007-2015  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.
+# version 2.1 of the License, or (at your option) any later version.
 #
 # This library is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
index 88f6aa847fff89ea7a88e5eb990ab344b756df2d..baa1b6f60caada1ac035442697b2470503c092aa 100644 (file)
@@ -1,10 +1,10 @@
 # -*- coding: utf-8 -*-
-# Copyright (C) 2007-201  EDF R&D
+# Copyright (C) 2007-2015  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.
+# version 2.1 of the License, or (at your option) any later version.
 #
 # This library is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
index aaa6bd1826a667c408391bf3db982f3860f99170..3228f4d596aab3765ad408c52c62e99535979b57 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  EDF R&D
+# Copyright (C) 2012-2015  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
index b62b187130283577506a939b966d9d36a1a4540f..ed5258b054512c0687d5baa460899186668ee384 100755 (executable)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  EDF R&D
+# Copyright (C) 2012-2015  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
index a49c3ab61d42d3fcdc93987ec308dd58af9b0775..79e8badf90fee8f3e282b38d76b27aae62fc9cef 100644 (file)
@@ -36,7 +36,7 @@ master_doc = 'index'
 
 # General substitutions.
 project = 'MeshGems-SurfOpt Plug-in'
-copyright = '2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE'
+copyright = '2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE'
 
 # The default replacements for |version| and |release|, also used in various
 # other places throughout the built documents.
index d3061e688fac58f2e5f94f8e2473a31576086d36..7b518b574eb005380da43b7721f1d18fd62cf804 100644 (file)
@@ -1,5 +1,5 @@
 # -*- coding: utf-8 -*-
-# Copyright (C) 2007-2014  EDF R&D
+# Copyright (C) 2007-2015  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
@@ -49,23 +49,6 @@ class MonViewText(Ui_ViewExe, QDialog):
         # Je n arrive pas a utiliser le setEnvironment du QProcess
         # fonctionne hors Salome mais pas dans Salome ???
         cmds=''
-        try :
-          LICENCE_FILE=os.environ["DISTENE_LICENCE_FILE_FOR_YAMS"]
-        except:
-          LICENCE_FILE=''
-        try :
-          PATH=os.environ["DISTENE_PATH_FOR_YAMS"]
-        except:
-          PATH=''
-        if LICENCE_FILE != '': 
-          cmds+='source '+LICENCE_FILE+'\n'
-        else:
-          cmds+="# $DISTENE_LICENCE_FILE_FOR_YAMS NOT SET\n"
-        if PATH != '': 
-          cmds+='export PATH='+PATH+':$PATH\n'
-        else:
-          cmds+="# $DISTENE_PATH_FOR_YAMS NOT SET\n"
-        #cmds+='env\n'
         cmds+='rm -f '+self.parent().fichierOut+'\n'
         cmds+=txt+'\n'
         cmds+='echo END_OF_Yams\n'
index 3fa65e55796181fb633a6000b9104cce16c1403d..9a4a658412c452d7fb1b3430eb8045ba9a3777a1 100644 (file)
@@ -1,5 +1,5 @@
 # -*- coding: utf-8 -*-
-# Copyright (C) 2007-2014  EDF R&D
+# Copyright (C) 2007-2015  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
index 94a4cd9fe2b5d0d8ef0a31e328b0f7d8b58a989c..d8a6950674912fc3ba639a94fd9348f7ae127ae7 100644 (file)
@@ -1,5 +1,5 @@
 # -*- coding: utf-8 -*-
-# Copyright (C) 2006-2014  EDF R&D
+# Copyright (C) 2006-2015  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
index b27ae7a3467f6c130a8a41c834008055064d7f01..4bd67dcebb2f6f327193071968e2b7b00e14a9ce 100644 (file)
@@ -1,9 +1,9 @@
-# Copyright (C) 2012-2013  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2012-2015  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.
+# version 2.1 of the License, or (at your option) any later version.
 #
 # This library is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
index 0fe36c7f1c88f54eae9032157648107ab19a888f..9570c2a9dc8633dc76a89241143b0c4753fca7b4 100755 (executable)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  EDF R&D
+# Copyright (C) 2012-2015  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
index e4739e2bdc8352900242ef3eaed34f2ec079d2af..8b3c9aa0b69c0086f76fc6028fa623e5c50f556a 100644 (file)
@@ -36,7 +36,7 @@ master_doc = 'index'
 
 # General substitutions.
 project = 'ZCracks Plug-in'
-copyright = '2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE'
+copyright = '2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE'
 
 # The default replacements for |version| and |release|, also used in various
 # other places throughout the built documents.
index 85ced69cfd809c3643796881a3d154fd9b7e4409..e97c6ddd32884d34272cb04a77904d105d1e4bcb 100644 (file)
@@ -1,10 +1,10 @@
 # -*- coding: utf-8 -*-
-# Copyright (C) 2006-2013  EDF R&D
+# Copyright (C) 2006-2015  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.
+# version 2.1 of the License, or (at your option) any later version.
 #
 # This library is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
index 4dab87093ed4908144d0715f0cd0a8b0486fad28..ccebbba99e05b92e775a2cb6a516557336e9daf0 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  EDF R&D
+# Copyright (C) 2012-2015  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
index 0f6f09f9853fad2f5379652ee69848c02d05fd07..a2d4b2a7fb53e92c608b60eaa133e73383233a1b 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  EDF R&D
+# Copyright (C) 2012-2015  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
index d7d2d9e5c508faa8307fc2398da51f660cf60bb1..abe18806b38d1dbc999c9942835bed8ef6d5ef67 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  EDF R&D
+# Copyright (C) 2012-2015  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
index 068ca40b7a40b22aaf24adce51d8a769418ab55f..8113cd077eecff59ca66b848cbc0149ccb48c1bf 100644 (file)
@@ -27,9 +27,10 @@ def triedreBase():
     OY = geompy.MakeVectorDXDYDZ(0, 1, 0)
     OZ = geompy.MakeVectorDXDYDZ(0, 0, 1)
   
-    geomPublish(initLog.debug,  O, 'O' )
-    geomPublish(initLog.debug,  OX, 'OX' )
-    geomPublish(initLog.debug,  OY, 'OY' )
-    geomPublish(initLog.debug,  OZ, 'OZ' )
+    if not geompy.myStudy.FindObjectByName( 'OX', geompy.ComponentDataType() ):
+      geomPublish(initLog.debug,  O, 'O' )
+      geomPublish(initLog.debug,  OX, 'OX' )
+      geomPublish(initLog.debug,  OY, 'OY' )
+      geomPublish(initLog.debug,  OZ, 'OZ' )
 
   return O, OX, OY, OZ
index ab8e80b1538ec34b5744f9e0885441c295a2546d..f8187ef727d57a3938cac46a7da023035784195f 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  EDF R&D
+# Copyright (C) 2012-2015  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
index 4e4453f2553bbd004d4e1a2b7403d360f6ddaed8..d6144f20a8a1929dacbb2f5aeb01571c2a857dbf 100644 (file)
@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 
-# Copyright (C) 2006-2013  EDF R&D
+# Copyright (C) 2006-2015  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
index 958211354af0da9e6ade7c3fc6c9c8bed254aff7..af9a2996db306b2d407f8208cd0c59f1076791a6 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  EDF R&D
+# Copyright (C) 2012-2015  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
index 55b2d8c19181da8b1f02d7b1cf131ffbdf597826..49abe7d81cc406bdd40fbb81a6cf3302ff0b3219 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  EDF R&D
+# Copyright (C) 2012-2015  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
index e9c34837ed58e3c52fddbb8526fc44d86eecde39..45a8a39b367ec0b89c4358deaafc025503069488 100755 (executable)
@@ -1,4 +1,4 @@
-# Copyright (C) 2007-2014  EDF R&D
+# Copyright (C) 2007-2015  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
@@ -24,6 +24,6 @@ ADD_CUSTOM_TARGET(usr_padder_docs ${DOXYGEN_EXECUTABLE})
 ADD_DEPENDENCIES(usr_padder_docs html_docs)
 
 INSTALL(CODE "EXECUTE_PROCESS(COMMAND \"${CMAKE_COMMAND}\" --build ${PROJECT_BINARY_DIR} --target usr_padder_docs)")
-INSTALL(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/SMESH DESTINATION ${SALOME_INSTALL_DOC}/gui) 
+INSTALL(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/padder DESTINATION ${SALOME_INSTALL_DOC}/gui/SMESH)
 
 SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES SMESH)
index 6180b0aecaede64e6d950e958dbf7d2bea0dfabb..e3ce86ea3add27f17f83c5794928f390ab17feae 100755 (executable)
@@ -1,4 +1,4 @@
-# Copyright (C) 2007-2014  EDF R&D
+# Copyright (C) 2007-2015  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
@@ -21,7 +21,7 @@
 # Project related configuration options
 #---------------------------------------------------------------------------
 PROJECT_NAME      = "SALOME Mesh User's Guide"
-OUTPUT_DIRECTORY  = SMESH
+OUTPUT_DIRECTORY  = padder
 CREATE_SUBDIRS   = NO
 OUTPUT_LANGUAGE   = English
 TAB_SIZE          = 5
index 3f08166051469a0bb3fb0d0ca9c05593d093e3ba..7d273bf84b9fb28cb47891e048b15227356eddb0 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  EDF R&D
+# Copyright (C) 2012-2015  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
index a5af8ea1902b2eb70d6326027748e8299bb35df0..cd9bdc7e9bcfa6618b4d64de877090333bda628c 100755 (executable)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  EDF R&D
+# Copyright (C) 2012-2015  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
index d4dfcada7304beb55b87ee3f7937996f8b358886..bf00c089327a2a7bc1e16890010ac02cf1fe17bd 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2011-2014  EDF R&D
+// Copyright (C) 2011-2015  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
index d59708bcb2834cc40309e01f6be76155040fd01f..0f84e09baa1ef1acd56493b27f99acae40e4916a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2011-2014  EDF R&D
+// Copyright (C) 2011-2015  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
index aac67087bf1835dcf764d7633a73f386cdc2d4ba..174bbc0689836e0875b26eda896153254deeee9b 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  EDF R&D
+# Copyright (C) 2012-2015  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
index 2e6587594c0de63f3866239241d5813de7b94c81..379e593d5a892dc2976b8eee896afaf9b292ff28 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2011-2014  EDF R&D
+// Copyright (C) 2011-2015  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
@@ -140,7 +140,12 @@ static std::string DATAFILE("data.txt");
 static std::string SCRIPTFILE("padder.sh");
 static std::string SEPARATOR(" ");
 
+#ifdef WIN32
+static std::string USER(getenv("USERNAME"));
+#else
 static std::string USER(getenv("USER"));
+#endif
+
 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);
@@ -410,7 +415,7 @@ CORBA::Long MeshJobManager_i::initialize(const MESHJOB::MeshJobParameterList & m
   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->maximum_duration = CORBA::string_dup("01:00");
   jobParameters->queue = CORBA::string_dup("");
 
   // Setting resource and additionnal properties (if needed)
@@ -685,6 +690,7 @@ char* MeshJobManager_i::getLastErrorMessage() {
 //
 extern "C"
 {
+  MESHJOBMANAGERENGINE_EXPORT
   PortableServer::ObjectId * MeshJobManagerEngine_factory( CORBA::ORB_ptr orb,
                                                            PortableServer::POA_ptr poa,
                                                            PortableServer::ObjectId * contId,
index d590565c6ae5af670d0f4e30989f1c9effd508e9..d3f408abeae623f389a487d16c7f02cfbe36070e 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2011-2014  EDF R&D
+// Copyright (C) 2011-2015  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
index 467e69d63740e943fa86ac789bb1a6eae7b7360a..985913a0881c73e981922615e09a09e10b1d523f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2011-2014  EDF R&D
+// Copyright (C) 2011-2015  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
index 10c2053ae073cfd89f23aacc38d7e4935183430a..c9d70348f94f2a55dc6ac04fe09663ed744506b1 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2011-2014  EDF R&D
+// Copyright (C) 2011-2015  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
index 6bedcb1f29ffd9cc76290629c7753639f9dea069..f5fa18d5d34d939dd1fbc929159f48503c4760b5 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2011-2014  EDF R&D
+// Copyright (C) 2011-2015  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
index 7d8d8e7b42b441e3e4d1a46e8bc2ff9d29f40ee8..fcba895446336e8b761643797339082c80d08332 100755 (executable)
@@ -1,4 +1,4 @@
-# Copyright (C) 2007-2014  EDF R&D
+# Copyright (C) 2007-2015  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
index 657e4e4a7fef9ead325ff7e970022e93eb72f6c2..42ba9d28f9b818ac8de8e97339cd4dba155ad82d 100755 (executable)
@@ -1,5 +1,5 @@
 #!/usr/bin/env python
-# Copyright (C) 2011-2014  EDF R&D
+# Copyright (C) 2011-2015  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
index 0c73c5f1ef1202d0c44f736b7da052488b387af8..c30e45ef32a62452d36d2c4773dd0f38eabefafa 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  EDF R&D
+# Copyright (C) 2012-2015  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
index 57d022fd1f8a2f66a647c84a4cbe7ea68650a180..775c9f10e1ecc657f93c38b6680feaa8965cafca 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2011-2014  EDF R&D
+# Copyright (C) 2011-2015  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
index 02e5188f7207ea17dabbbac38e7b9968b93c5ff6..25c851282e888bd390018577510772d30db28322 100644 (file)
@@ -1,5 +1,5 @@
 # -*- coding: iso-8859-1 -*-
-# Copyright (C) 2011-2014  EDF R&D
+# Copyright (C) 2011-2015  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
index 3a1c02a51eb36bf36b478601a2441a1152c5bfd6..5730c4830f13cef8195e465c32725cace175f7c9 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  EDF R&D
+# Copyright (C) 2012-2015  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
index 27164b3adff4e3b51a3fe9cc8d1365deb94741c0..b2f154f3f9c358e44196e603d30befb1f073c545 100644 (file)
@@ -1,4 +1,4 @@
-#  Copyright (C) 2011-2014 EDF R&D
+#  Copyright (C) 2011-2015 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
index 2a16876838424ec6b9b1f8947aca523b9a46dc5a..7ffe653598524bac7b68e949cdcb514078445b1a 100644 (file)
@@ -1,5 +1,5 @@
 # -*- coding: iso-8859-1 -*-
-# Copyright (C) 2011-2014  EDF R&D
+# Copyright (C) 2011-2015  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
index d51d5c7ba989f91768041833989521876442c45b..73d629c51bcd29697c576a372e4b55571e006cf9 100644 (file)
@@ -1,5 +1,5 @@
 # -*- coding: iso-8859-1 -*-
-# Copyright (C) 2011-2014  EDF R&D
+# Copyright (C) 2011-2015  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
index e2aa0f84edf322bbe9eb3f69edd70009a26be494..180dfe3cc2a27f661b55e5e92802184546e0a68e 100644 (file)
@@ -1,5 +1,5 @@
 # -*- coding: iso-8859-1 -*-
-# Copyright (C) 2011-2014  EDF R&D
+# Copyright (C) 2011-2015  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
@@ -50,7 +50,7 @@ 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.
+# whether we want a local execution or a remote one.
 resource_name = "localhost"
 from salome.smesh.spadder.configreader import ConfigReader
 
index d84588d3ce2587b9cae3d15fc0696a2fbb9af0ec..d0d4d2498803e55b6a1627574cc8451aef6117f8 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  EDF R&D
+# Copyright (C) 2012-2015  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
index 0b533f6bd1edfcfb376d983fd1bccc8e7e087a20..d6b2538c6318e2ddfcf899835a2bf523bbbc303a 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2011-2014  EDF R&D
+# Copyright (C) 2011-2015  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
index 3902ab4fb882a4dc2d1b0a2ef9adfe03afaf57fe..3c699cddb312e9071c845c15934455f2534eb8d7 100644 (file)
@@ -1,5 +1,5 @@
 # -*- coding: iso-8859-1 -*-
-# Copyright (C) 2011-2014  EDF R&D
+# Copyright (C) 2011-2015  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
index 44c84025e85f2fede92eab74c0de19041f247ddf..6a91bcf5c0c582f78cc41dc012caef4e776a3c8c 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2014  EDF R&D
+# Copyright (C) 2012-2015  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
index 0d8e495bac746389cd398a023ea799878649158a..dcfba264c22bbc5584b5cce221f4ee9acf222a50 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2011-2014  CEA/DEN, EDF R&D
+# Copyright (C) 2011-201 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
@@ -16,3 +16,4 @@
 #
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
index e4130283b23d72c3360ed827fc1983791dc46324..fac18bace625af40c204c46d032d6619d471f565 100644 (file)
@@ -1,5 +1,5 @@
 #!/bin/bash
-# Copyright (C) 2010-2014  EDF R&D
+# Copyright (C) 2010-2015  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
index 5402747c3fda03e815add780f2c077439fc1d22d..3d86f4e6ed931986f0716fba39830952fbfdc3a6 100644 (file)
@@ -1,5 +1,5 @@
 # -*- coding: iso-8859-1 -*-
-# Copyright (C) 2011-2014  EDF R&D
+# Copyright (C) 2011-2015  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
index 132577d0acae083fec8940be7cd8257d745cb22e..8d6ff398595b4fee5c0144ae6244359691aa212b 100644 (file)
@@ -1,5 +1,5 @@
 # -*- coding: iso-8859-1 -*-
-# Copyright (C) 2011-2014  EDF R&D
+# Copyright (C) 2011-2015  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
index b043ec69271194e080f689e505396f9da4347f41..e8798921d31b735624022f8f90952cd638dbde1a 100644 (file)
@@ -1,5 +1,5 @@
 # -*- coding: iso-8859-1 -*-
-# Copyright (C) 2011-2014  EDF R&D
+# Copyright (C) 2011-2015  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