Salome HOME
Merge from PHASE_25_BR 14/11/2010
authorvsr <vsr@opencascade.com>
Mon, 15 Nov 2010 06:52:35 +0000 (06:52 +0000)
committervsr <vsr@opencascade.com>
Mon, 15 Nov 2010 06:52:35 +0000 (06:52 +0000)
170 files changed:
doc/salome/gui/SMESH/images/a-clipping2.png
doc/salome/gui/SMESH/images/advanced_mesh_infos.png
doc/salome/gui/SMESH/images/bnd_box.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/bnd_box_preview.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/elem_info.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/eleminfo1.png
doc/salome/gui/SMESH/images/eleminfo2.png
doc/salome/gui/SMESH/images/formula5.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/hexotic_parameters.png
doc/salome/gui/SMESH/images/hyp_source_edges.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/hyp_source_faces.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/image42.png [new file with mode: 0755]
doc/salome/gui/SMESH/images/image43.png [new file with mode: 0755]
doc/salome/gui/SMESH/images/image49.png
doc/salome/gui/SMESH/images/image79.jpg
doc/salome/gui/SMESH/images/image99.gif
doc/salome/gui/SMESH/images/max_element_length_2d.png [new file with mode: 0755]
doc/salome/gui/SMESH/images/max_element_length_3d.png [new file with mode: 0755]
doc/salome/gui/SMESH/images/min_distance.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/min_distance_preview.png [new file with mode: 0644]
doc/salome/gui/SMESH/input/about_quality_controls.doc
doc/salome/gui/SMESH/input/area.doc
doc/salome/gui/SMESH/input/aspect_ratio.doc
doc/salome/gui/SMESH/input/aspect_ratio_3d.doc
doc/salome/gui/SMESH/input/basic_meshing_algos.doc
doc/salome/gui/SMESH/input/clipping.doc
doc/salome/gui/SMESH/input/index.doc
doc/salome/gui/SMESH/input/length_2d.doc
doc/salome/gui/SMESH/input/max_element_length_2d.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/max_element_length_3d.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/measurements.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/mesh_infos.doc
doc/salome/gui/SMESH/input/minimum_angle.doc
doc/salome/gui/SMESH/input/modifying_meshes.doc
doc/salome/gui/SMESH/input/selection_filter_library.doc
doc/salome/gui/SMESH/input/skew.doc
doc/salome/gui/SMESH/input/smeshpy_interface.doc
doc/salome/gui/SMESH/input/taper.doc
doc/salome/gui/SMESH/input/tui_defining_hypotheses.doc
doc/salome/gui/SMESH/input/tui_filters.doc
doc/salome/gui/SMESH/input/tui_grouping_elements.doc
doc/salome/gui/SMESH/input/tui_measurements.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/tui_quality_controls.doc
doc/salome/gui/SMESH/input/use_existing_algos.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/volume.doc
doc/salome/gui/SMESH/input/warping.doc
idl/Makefile.am
idl/SMESH_BasicHypothesis.idl
idl/SMESH_Filter.idl
idl/SMESH_Gen.idl
idl/SMESH_Group.idl
idl/SMESH_Measurements.idl [new file with mode: 0644]
idl/SMESH_Mesh.idl
resources/Makefile.am
resources/SalomeApp.xml
resources/StdMeshers.xml
resources/advanced_mesh_info.png
resources/mesh_bounding_box.png [new file with mode: 0755]
resources/mesh_elem_info.png [new file with mode: 0644]
resources/mesh_max_element_length_2d.png [new file with mode: 0755]
resources/mesh_max_element_length_3d.png [new file with mode: 0755]
resources/mesh_min_dist.png [new file with mode: 0755]
src/Controls/SMESHControls.cxx
src/Controls/SMESH_Controls.cxx
src/Controls/SMESH_ControlsDef.hxx
src/OBJECT/Makefile.am
src/OBJECT/SMESH_Actor.cxx
src/OBJECT/SMESH_Actor.h
src/OBJECT/SMESH_ActorDef.h
src/OBJECT/SMESH_DeviceActor.cxx
src/OBJECT/SMESH_DeviceActor.h
src/OBJECT/SMESH_PreviewActorsCollection.cxx
src/OBJECT/SMESH_ScalarBarActor.cxx [new file with mode: 0644]
src/OBJECT/SMESH_ScalarBarActor.h [new file with mode: 0644]
src/SMDS/SMDS_MeshElement.hxx
src/SMESH/SMESH_Algo.hxx
src/SMESH/SMESH_Group.cxx
src/SMESH/SMESH_Group.hxx
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_MesherHelper.cxx
src/SMESH/SMESH_MesherHelper.hxx
src/SMESH/SMESH_subMesh.cxx
src/SMESHDS/SMESHDS_Group.cxx
src/SMESHDS/SMESHDS_Group.hxx
src/SMESHDS/SMESHDS_GroupBase.hxx
src/SMESHDS/SMESHDS_GroupOnGeom.cxx
src/SMESHDS/SMESHDS_GroupOnGeom.hxx
src/SMESHDS/SMESHDS_Mesh.cxx
src/SMESHDS/SMESHDS_Mesh.hxx
src/SMESHFiltersSelection/SMESH_Type.h
src/SMESHFiltersSelection/SMESH_TypeFilter.cxx
src/SMESHGUI/Makefile.am
src/SMESHGUI/SMESHGUI.cxx
src/SMESHGUI/SMESHGUI.h
src/SMESHGUI/SMESHGUI_ClippingDlg.cxx
src/SMESHGUI/SMESHGUI_ClippingDlg.h
src/SMESHGUI/SMESHGUI_FilterDlg.cxx
src/SMESHGUI/SMESHGUI_Measurements.cxx [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_Measurements.h [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_MeshInfo.cxx [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_MeshInfo.h [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_MeshOp.cxx
src/SMESHGUI/SMESHGUI_MeshUtils.cxx
src/SMESHGUI/SMESHGUI_MeshUtils.h
src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.cxx
src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.h
src/SMESHGUI/SMESHGUI_Selection.cxx
src/SMESHGUI/SMESHGUI_Selection.h
src/SMESHGUI/SMESHGUI_Utils.cxx
src/SMESHGUI/SMESHGUI_Utils.h
src/SMESHGUI/SMESHGUI_VTKUtils.cxx
src/SMESHGUI/SMESHGUI_VTKUtils.h
src/SMESHGUI/SMESH_images.ts
src/SMESHGUI/SMESH_msg_en.ts
src/SMESH_I/Makefile.am
src/SMESH_I/SMESH_2smeshpy.cxx
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_Hypothesis_i.cxx
src/SMESH_I/SMESH_Hypothesis_i.hxx
src/SMESH_I/SMESH_Measurements_i.cxx [new file with mode: 0644]
src/SMESH_I/SMESH_Measurements_i.hxx [new file with mode: 0644]
src/SMESH_I/SMESH_MeshEditor_i.cxx
src/SMESH_I/SMESH_Mesh_i.cxx
src/SMESH_I/SMESH_Mesh_i.hxx
src/SMESH_I/SMESH_PythonDump.hxx
src/SMESH_I/SMESH_subMesh_i.cxx
src/SMESH_I/SMESH_subMesh_i.hxx
src/SMESH_SWIG/SMESH_BelongToGeom.py
src/SMESH_SWIG/SMESH_GroupLyingOnGeom.py
src/SMESH_SWIG/SMESH_controls.py
src/SMESH_SWIG/smeshDC.py
src/StdMeshers/Makefile.am
src/StdMeshers/StdMeshers_CompositeSegment_1D.hxx
src/StdMeshers/StdMeshers_ImportSource.cxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_ImportSource.hxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_Import_1D.cxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_Import_1D.hxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_Import_1D2D.cxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_Import_1D2D.hxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_QuadToTriaAdaptor.cxx
src/StdMeshers/StdMeshers_QuadToTriaAdaptor.hxx
src/StdMeshersGUI/StdMeshersGUI_ObjectReferenceParamWdg.cxx
src/StdMeshersGUI/StdMeshersGUI_ObjectReferenceParamWdg.h
src/StdMeshersGUI/StdMeshersGUI_StdHypothesisCreator.cxx
src/StdMeshersGUI/StdMeshers_images.ts
src/StdMeshersGUI/StdMeshers_msg_en.ts
src/StdMeshers_I/Makefile.am
src/StdMeshers_I/StdMeshers_Deflection1D_i.cxx
src/StdMeshers_I/StdMeshers_ImportSource1D_i.cxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_ImportSource1D_i.hxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_ImportSource2D_i.cxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_ImportSource2D_i.hxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_Import_1D2D_i.cxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_Import_1D2D_i.hxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_Import_1D_i.cxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_Import_1D_i.hxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_ProjectionSource1D_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_i.cxx

index bfac4cea53acd9b713925ea20e3e34e0edf45f19..9d1249c68694fb6d24d18e92d9246522b8648574 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/a-clipping2.png and b/doc/salome/gui/SMESH/images/a-clipping2.png differ
index 2dc9f8f4822514c9b38701078985a9972186f256..d8bdbc6e52fa7c2a23eddf535f0d022572be8856 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/advanced_mesh_infos.png and b/doc/salome/gui/SMESH/images/advanced_mesh_infos.png differ
diff --git a/doc/salome/gui/SMESH/images/bnd_box.png b/doc/salome/gui/SMESH/images/bnd_box.png
new file mode 100644 (file)
index 0000000..6761a76
Binary files /dev/null and b/doc/salome/gui/SMESH/images/bnd_box.png differ
diff --git a/doc/salome/gui/SMESH/images/bnd_box_preview.png b/doc/salome/gui/SMESH/images/bnd_box_preview.png
new file mode 100644 (file)
index 0000000..902101c
Binary files /dev/null and b/doc/salome/gui/SMESH/images/bnd_box_preview.png differ
diff --git a/doc/salome/gui/SMESH/images/elem_info.png b/doc/salome/gui/SMESH/images/elem_info.png
new file mode 100644 (file)
index 0000000..9937d6d
Binary files /dev/null and b/doc/salome/gui/SMESH/images/elem_info.png differ
index a93a622f1d44046971ac167d2f52e5ff7cfefed3..4d12b54b1279934a85b3277a9e47b437f4b2e313 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/eleminfo1.png and b/doc/salome/gui/SMESH/images/eleminfo1.png differ
index c417b6d25f37a6a14349ba792d770376fee7f1b0..26cfae3651dabdc316df9acb76f1f47c05314fe8 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/eleminfo2.png and b/doc/salome/gui/SMESH/images/eleminfo2.png differ
diff --git a/doc/salome/gui/SMESH/images/formula5.png b/doc/salome/gui/SMESH/images/formula5.png
new file mode 100644 (file)
index 0000000..823ba06
Binary files /dev/null and b/doc/salome/gui/SMESH/images/formula5.png differ
index c06ff3bb2ecb0a5ee2f3ed61570aa8a481d7d9de..5f4bb3df5e8f7ada557f671ecb1a37fa7f0eae30 100644 (file)
Binary files a/doc/salome/gui/SMESH/images/hexotic_parameters.png and b/doc/salome/gui/SMESH/images/hexotic_parameters.png differ
diff --git a/doc/salome/gui/SMESH/images/hyp_source_edges.png b/doc/salome/gui/SMESH/images/hyp_source_edges.png
new file mode 100644 (file)
index 0000000..2305e17
Binary files /dev/null and b/doc/salome/gui/SMESH/images/hyp_source_edges.png differ
diff --git a/doc/salome/gui/SMESH/images/hyp_source_faces.png b/doc/salome/gui/SMESH/images/hyp_source_faces.png
new file mode 100644 (file)
index 0000000..fe9e6c6
Binary files /dev/null and b/doc/salome/gui/SMESH/images/hyp_source_faces.png differ
diff --git a/doc/salome/gui/SMESH/images/image42.png b/doc/salome/gui/SMESH/images/image42.png
new file mode 100755 (executable)
index 0000000..d0120fa
Binary files /dev/null and b/doc/salome/gui/SMESH/images/image42.png differ
diff --git a/doc/salome/gui/SMESH/images/image43.png b/doc/salome/gui/SMESH/images/image43.png
new file mode 100755 (executable)
index 0000000..7b6b895
Binary files /dev/null and b/doc/salome/gui/SMESH/images/image43.png differ
index 74926d24450a3e5b4ca4e9466d88538874a38df9..6e5b3176bc67ae89e0b55398dff8f90a58084dae 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/image49.png and b/doc/salome/gui/SMESH/images/image49.png differ
index 6d164167fb70656b96bdf17c574eb4ed3765009c..0efc736950fdfe0da08551e01812327ecde6a5f0 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/image79.jpg and b/doc/salome/gui/SMESH/images/image79.jpg differ
index 4959ed82548939a522238bb5b9c57adb0d1dfb6d..2672e99f3241466518910e294744154285d7cc9b 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/image99.gif and b/doc/salome/gui/SMESH/images/image99.gif differ
diff --git a/doc/salome/gui/SMESH/images/max_element_length_2d.png b/doc/salome/gui/SMESH/images/max_element_length_2d.png
new file mode 100755 (executable)
index 0000000..d19c80e
Binary files /dev/null and b/doc/salome/gui/SMESH/images/max_element_length_2d.png differ
diff --git a/doc/salome/gui/SMESH/images/max_element_length_3d.png b/doc/salome/gui/SMESH/images/max_element_length_3d.png
new file mode 100755 (executable)
index 0000000..356e5e2
Binary files /dev/null and b/doc/salome/gui/SMESH/images/max_element_length_3d.png differ
diff --git a/doc/salome/gui/SMESH/images/min_distance.png b/doc/salome/gui/SMESH/images/min_distance.png
new file mode 100644 (file)
index 0000000..765522e
Binary files /dev/null and b/doc/salome/gui/SMESH/images/min_distance.png differ
diff --git a/doc/salome/gui/SMESH/images/min_distance_preview.png b/doc/salome/gui/SMESH/images/min_distance_preview.png
new file mode 100644 (file)
index 0000000..c5373d9
Binary files /dev/null and b/doc/salome/gui/SMESH/images/min_distance_preview.png differ
index 0d7ab61b0b05f5bbd7c39214228b1cf3e488c61c..8f78c38c5340d8ff4b4ed58fe057ca9bf3c8753a 100644 (file)
@@ -13,24 +13,25 @@ the meshing elements and these calculated values is shown with the
 help of a scalar bar, which is displayed near the presentation of your
 mesh.
 
-There are 0D, 1D, 2D and 3D quality controls.
+There are four types of quality controls, corresponding to node, edge,
+face and volume entity type.
 
-0D mesh quality controls:
+Node quality controls:
 <ul>
-<li>\ref free_nodes_page "Free nodes"</li>
+<li>\subpage free_nodes_page "Free nodes"</li>
 </ul>
 
-1D mesh quality controls:
+Edge quality controls:
 <ul>
+<li>\subpage free_edges_page "Free edges"</li>
 <li>\subpage free_borders_page "Free borders"</li>
-<li>\subpage borders_at_multi_connection_page "Borders at multi-connection"</li>
 <li>\subpage length_page "Length"</li>
+<li>\subpage borders_at_multi_connection_page "Borders at multi-connection"</li>
 </ul>
 
-2D mesh quality controls:
+Face quality controls:
 <ul>
-<li>\subpage free_nodes_page "Free nodes"</li>
-<li>\subpage free_edges_page "Free edges"</li>
+<li>\subpage free_faces_page "Free faces"</li>
 <li>\subpage length_2d_page "Length 2D"</li>
 <li>\subpage borders_at_multi_connection_2d_page "Borders at multi-connection 2D"</li>
 <li>\subpage area_page "Area"</li>
@@ -39,13 +40,14 @@ There are 0D, 1D, 2D and 3D quality controls.
 <li>\subpage minimum_angle_page "Minimum angle"</li>
 <li>\subpage warping_page "Warping"</li>
 <li>\subpage skew_page "Skew"</li>
+<li>\subpage max_element_length_2d_page "Max element length 2D"</li>
 </ul>
 
-3D mesh quality controls:
+Volume quality controls:
 <ul>
 <li>\subpage aspect_ratio_3d_page "Aspect ratio 3D"</li>
 <li>\subpage volume_page "Volume"</li>
-<li>\subpage free_faces_page "Free faces"</li>
+<li>\subpage max_element_length_3d_page "Max element length 3D"</li>
 </ul>
 
 */
index bef0c0f8aed9748c0b389fa53cef6b42216296dc..f650a3fd65b1b867cd932b75fd99cdbf9560104e 100644 (file)
@@ -11,7 +11,8 @@ quadrangles).
 <ol>
 <li>Display your mesh in the viewer.</li>
 
-<li>Choose <b>Controls > Area</b> or click <em>"Area"</em> button. 
+<li>Choose <b>Controls > Face Controls > Area</b> or click
+<em>"Area"</em> button. 
 
 \image html image35.png
 <center><em>"Area" button</em></center>
index 070d377cc47da6a6a4875dedc2a509d444dc25e8..c6c3dbdee3cb3bd648e253eef153bd84c57ffd89 100644 (file)
@@ -13,10 +13,10 @@ nodes is calculated by the formula:
 
 \image html formula4.png
 
-- The <b>Aspect Ratio</b> of a \b quadrangle 2D element consisting of
- 4 nodes is the worst (i.e. the greatest) value from all triangles
- which can be built taking three nodes of the quadrangle. There are
- four triangles to consider:
+- The <b>Aspect Ratio</b> of a \b quadrangle 2D element consisting of 4
+nodes is calculated by the formula:
+
+\image html formula5.png
 
 \image html image138.gif
 
@@ -24,8 +24,8 @@ nodes is calculated by the formula:
 <ol>
 <li>Display your mesh in the viewer.</li>
 
-<li>Choose <b>Controls > Aspect Ratio</b> or click <em>"Aspect
-Ratio"</em> button in the toolbar.
+<li>Choose <b>Controls > Face Controls > Aspect Ratio</b> or click
+<em>"Aspect Ratio"</em> button in the toolbar.
 
 \image html image37.png
 <center><em>"Aspect Ratio" button</em></center>
index 751e411028fe4a3c9fe9d60ef633b7dba312c0a2..6e8b708080618c6d889f41dad1d6c0eefc1ba1f0 100644 (file)
@@ -21,8 +21,8 @@ by the formula:
 <ol>
 <li>Display your mesh in the viewer.</li>
 
-<li>Choose <b>Controls > Aspect Ratio 3D</b> or click <em>"Aspect Ratio 3D"</em> 
-button of the toolbar.
+<li>Choose <b>Controls > Volume Controls > Aspect Ratio 3D</b> or click
+<em>"Aspect Ratio 3D"</em> button of the toolbar.
 
 \image html image144.png
 <center><em>"Aspect Ratio 3D" button</em></center>
index e957a97138435df1cbae9f24346b9d057968abeb..274ab74385be74e34b0cb05252da168a7eccce53 100644 (file)
@@ -62,6 +62,7 @@ license to be used within the Mesh module.
 There is also a number of more specific algorithms:
 <ul>
 <li>\subpage projection_algos_page "for meshing by projection of another mesh"</li>
+<li>\subpage import_algos_page "for meshing by importing elements from another mesh"</li>
 <li>\subpage radial_prism_algo_page "for meshing geometrical objects with cavities"</li>
 <li>\subpage segments_around_vertex_algo_page "for defining the local size of elements around a certain node"</li>
 <li>\subpage prism_3d_algo_page "for meshing prismatic shapes"</li>
index f3b19f3742cd61033b1c20584a5f0a2482270206..df3e39495f7902a152e70f6465df1f64c3fd70c9 100644 (file)
@@ -9,11 +9,14 @@ To start, click on the \em New button.
 
 \image html a-clipping2.png
 
-Now you can define the parameters of your cross-section: \b Orientation
-(X-Y, X-Z or Y-Z); \b Distance between the opposite extremities of the
-object, if it is set to 0.5 the object is split in two halves; and
-\b Rotation (in angle degrees) <b>around X</b> (Y to Z) and <b>around Y</b> (X to
-Z). If the <b>Show preview</b> button is on, you can see the clipping plane
+Now you can define the parameters of your cross-section: list of
+<b>meshes, sub-meshes and groups</b> the cross-section will be applied to
+(<b>Select all</b> button allows to select and deselect all available
+objects at once), \b Orientation (X-Y, X-Z or Y-Z); \b Distance between the
+opposite extremities of the boundary box of selected objects, if it is set
+to 0.5 the boundary box is split in two halves; and \b Rotation (in angle
+degrees) <b>around X</b> (Y to Z) and <b>around Y</b> (X to Z).
+If the <b>Show preview</b> button is on, you can see the clipping plane
 in the <b>3D Viewer</b>.
 
 \image html image79.jpg "The plane and the cut object"
index 0975842aece16b6c0d89fc93b9c54e15414ca7e7..5301ce8de6c1ed2fcf0e6ff9985a415c62fc85d8 100644 (file)
@@ -12,12 +12,13 @@ previously created or imported by the Geometry component; </li>
 <li>\subpage viewing_meshes_overview_page "viewing created meshes" in
 the VTK viewer;</li>
 <li>\subpage grouping_elements_page "creating groups of mesh elements";</li>
-<li>applying to meshes \subpage quality_page "Quality Controls" 
-allowing to highlight important elements:
+<li>applying to meshes \subpage quality_page "Quality Controls", 
+allowing to highlight important elements;
 <li>filtering sub-sets of mesh entities (nodes elements) using
-\subpage filters_page "Filters" functionality.</li>
+\subpage filters_page "Filters" functionality;</li>
 <li>\subpage modifying_meshes_page "modifying meshes" with a vast
-array of dedicated operations.</li> 
+array of dedicated operations;</li> 
+<li>different \subpage measurements_page "measurements" of the mesh objects;
 <li>easily setting parameters via the variables predefined in
 \subpage using_notebook_mesh_page "Salome notebook".</li>
 </ul>
index def8afa9585b81a93e9edd949e47991acaed5292..4ed5b69e6a408857ce3e01af34ae6adb0c99f644 100644 (file)
@@ -10,8 +10,8 @@ of your mesh.
 <ol>
 <li>Display your mesh in the viewer. </li>
 
-<li>Choose <b>Controls > Length 2D</b> or click <em>"Length 2D"</em>
-button in the toolbar. 
+<li>Choose <b>Controls > Face Controls > Length 2D</b> or click
+<em>"Length 2D"</em> button in the toolbar. 
 
 \image html image34.png
 <center><em>"Length 2D" button</em></center>
diff --git a/doc/salome/gui/SMESH/input/max_element_length_2d.doc b/doc/salome/gui/SMESH/input/max_element_length_2d.doc
new file mode 100644 (file)
index 0000000..0c062f8
--- /dev/null
@@ -0,0 +1,29 @@
+/*!
+
+\page max_element_length_2d_page Max Element Length 2D
+
+\n This quality control criterion consists of calculation of length of
+the edges and diagonals combining the meshing elements (triangles and quadrangles)
+of your mesh.
+
+<em>To apply the Max Element Length 2D quality criterion to your mesh:</em>
+<ol>
+<li>Display your mesh in the viewer. </li>
+
+<li>Choose <b>Controls > Face Controls > Max Element Length 2D</b> or click
+<em>"Max Element Length 2D"</em> button in the toolbar. 
+
+\image html image42.png
+<center><em>"Max Element 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:
+
+\image html max_element_length_2d.png
+</li>
+</ol>
+
+<br><b>See Also</b> a sample TUI Script of a 
+\ref tui_max_element_length_2d "Max Element Length 2D quality control" operation.  
+
+*/
\ No newline at end of file
diff --git a/doc/salome/gui/SMESH/input/max_element_length_3d.doc b/doc/salome/gui/SMESH/input/max_element_length_3d.doc
new file mode 100644 (file)
index 0000000..287c3f2
--- /dev/null
@@ -0,0 +1,30 @@
+/*!
+
+\page max_element_length_3d_page Max Element Length 3D
+
+\n This quality control criterion consists of calculation of length of
+the edges and diagonals combining the 3D meshing elements
+(tetrahedrons, pyramids, pentahendrons, hexahedrons and polyhedrons)
+of your mesh.
+
+<em>To apply the Max Element Length 3D quality criterion to your mesh:</em>
+<ol>
+<li>Display your mesh in the viewer. </li>
+
+<li>Choose <b>Controls > Volume Controls > Max Element Length 3D</b> or click
+<em>"Max Element Length 3D"</em> button in the toolbar. 
+
+\image html image43.png
+<center><em>"Max Element Length 3D" button</em></center>
+
+Your mesh will be displayed in the viewer with its elements colored according to the
+applied mesh quality control criterion:
+
+\image html max_element_length_3d.png
+</li>
+</ol>
+
+<br><b>See Also</b> a sample TUI Script of a 
+\ref tui_max_element_length_3d "Max Element Length 3D quality control" operation.  
+
+*/
\ No newline at end of file
diff --git a/doc/salome/gui/SMESH/input/measurements.doc b/doc/salome/gui/SMESH/input/measurements.doc
new file mode 100644 (file)
index 0000000..27894a4
--- /dev/null
@@ -0,0 +1,71 @@
+/*!
+
+\page measurements_page Measurements
+
+Mesh module provides possibility to perform different measurements
+of the selected mesh data.
+
+All the measurement operations are available via \b Measurements
+top-level menu. An access to the measurements operations is
+implemented via single dialog box, where each operation is represented
+as a separate tab page.
+
+\section min_distance_anchor Minimum Distance
+
+This operation allows measuring a distance between two objects.
+Currently only node-to-node and node-to-origin operations are
+available, but this operation will be extended in future to support
+other mesh objects - elements, meshes, sub-meshes and groups.
+
+To start <b>Minimum Distance</b> operation, select <b>Minimum Distance</b>
+item from \b Measurements menu.
+
+\image html min_distance.png
+
+In the dialog box choose the first target and second target mode by
+switching the corresponding radio buttons, then select the objects
+between which the distance is to be calculated (or enter directly IDs
+in case of nodes/elements) and press \em Compute button.
+
+The following types of targets are supported:
+- \em Node: single mesh node;
+- \em Element: single mesh element (not available in this version);
+- \em Object: mesh, sub-mesh or group object (not available in this
+version);
+- \em Origin: origin of the global co-ordinate system.
+
+The result will
+be shown in the bottom area of the dialog box. In addition, the simple
+preview will be shown in the 3D viewer.
+
+\image html min_distance_preview.png
+
+\section bounding_box_anchor Bounding Box
+
+This operation allows to calculate the bounding box of the selected
+object(s).
+
+To start <b>Bounding Box</b> operation, select <b>Bounding Box</b>
+item from \b Measurements menu.
+
+\image html bnd_box.png
+
+In the dialog box choose desired type of the object by switching the
+corresponding radio button, select the desired object(s) and press
+\em Compute button.
+
+The following types of input are available:
+- \em Objects: select one or more mesh, sub-mesh, group objects;
+- \em Nodes: select set of mesh nodes;
+- \em Elements: select set of mesh elements.
+
+The result of calculation will be shown in the bottom area of the
+dialog box. In addition, the simple preview will be shown in the 3D
+viewer.
+
+\image html bnd_box_preview.png
+
+<b>See Also</b> a sample TUI Script of a 
+\ref tui_measurements_page "Measurement operations".
+
+*/
index 7b855c42cf4371aae8974978d475bfbbf741c566..919f6768e56dd75a62660042446fb4889e89d694 100644 (file)
@@ -1,62 +1,67 @@
 /*!
 
-\page mesh_infos_page Mesh infos
+\page mesh_infos_page Mesh Information
 
-\n There are three information boxes: <b>Standard Mesh
-Infos</b>, <b>Advanced Mesh Infos</b> and <b> Mesh Element Info</b>.
+The user can obtain an information about the selected mesh object
+(mesh, sub-mesh or group) using <b>Mesh Information</b> dialog box.
 
-<br>
-\anchor standard_mesh_infos_anchor
-<h2>Standard Mesh Infos</h2>
-
-The <b>Standard Mesh Infos</b> box gives only the information on the
-number of elements of maximum dimension and the number of nodes in the
-mesh. However, from this Info you can learn about groups selected on
-this mesh.
-\n To view the <b>Standard Mesh Infos</b>, select your mesh or submesh
-in the <b>Object Browser</b> and select <b>Standard Mesh Infos</b>
-from the \b Mesh menu or click <em>"Standard Mesh Infos"</em> button
-in the toolbar. 
-
-\image html image49.png
-<center><em>"Standard Mesh Infos" button</em></center>
-
-The following information will be displayed:
-
-\image html a-standmeshinfo.png
+The <b>Mesh Information</b> dialog box provides two tab pages:
+- <b>Base Info</b> - to show base information about selected mesh
+object
+- <b>Element Info</b> - to show detail information about selected mesh
+node or element.
 
-<br>
 \anchor advanced_mesh_infos_anchor
-<h2>Advanced Mesh Infos</h2>
+<h2>Base Info</h2>
 
-The <b>Advanced Mesh Infos</b> box gives more information about the mesh,
-including the total number of faces and volumes and their geometrical
-types.
-\n To view the <b>Advanced Mesh Infos</b>, select your mesh or submesh
-in the <b>Object Browser</b> and select <b>Advanced Mesh Infos</b>
-from the \b Mesh menu or click <em>"Advanced Mesh Infos"</em> button
-in the toolbar.
+The <b>Base Info</b> tab page of the dialog box provides general
+information on the selected object - mesh, sub-mesh or mesh group:
+name, type, total number of nodes and elements separately for each
+type: 0D elements, edges, faces and volumes.
+
+To view the <b>Mesh Information</b>, select your mesh, sub-mesh or
+group in the <b>Object Browser</b> and invoke <b>Mesh Information</b>
+item from the \b Mesh menu or click <em>"Mesh Information"</em> button
+in the toolbar. 
 
-\image html image50.gif
-<center><em>"Advanced Mesh Infos" button</em></center>
+\image html image49.png
+<center><em>"Mesh Information" button</em></center>
 
 The following information will be displayed:
 
 \image html advanced_mesh_infos.png
+<center><em>"Base Info" page</em></center>
 
-<br>
 \anchor mesh_element_info_anchor
-<h2>Mesh Element Info</h2> 
+<h2>Mesh Element Information</h2> 
 
-The <b>Mesh Element Info</b> dialog box gives basic information about the type, coordinates and connectivity of the selected mesh node or element.
-\n It is possible to input the Element ID or to select the Element in
-the Viewer.
+The <b>Element Info</b> tab page of the dialog box gives basic
+information about the type, coordinates and connectivity of the
+selected mesh node or element.
 
-\image html eleminfo1.png
+To view the <b>Mesh Element Information</b>, select your mesh, sub-mesh or
+group in the <b>Object Browser</b> and invoke <b>Mesh Element Information</b>
+item from the \b Mesh menu or click <em>"Mesh Element Information"</em> button
+in the toolbar. 
+
+\image html elem_info.png
+<center><em>"Mesh Element Information" button</em></center>
 
+The following information will be displayed:
+
+\image html eleminfo1.png
+<center><em>"Element Info" page, node</em></center>
+<br>
 \image html eleminfo2.png 
+<center><em>"Element Info" page, element</em></center>
+
+The use can either input the ID of a node or element he wants to
+analyze directly in the dialog box or select the node or element in
+the 3D viewer.
 
-In case you get Mesh Infos via a TUI script the information is displayed in Python Console.
-<b>See the</b> \ref tui_viewing_mesh_infos "TUI Example", 
+In case you get <b>Mesh Information</b> via a TUI script, the information is
+displayed in the Python Console. 
+<b>See the</b> \ref tui_viewing_mesh_infos "TUI Example".
 
-*/
\ No newline at end of file
+*/
+       
index af631b0ec14ce67dd61b2fd36b73e04b9354f134..4236d65627f02a43ba4dc9212643ecf227e1d9ae 100644 (file)
@@ -10,7 +10,8 @@ element (triangle or quadrangle).
 <ol>
 <li>Display your mesh in the viewer.</li>
 
-<li>Choose <b>Controls > Minimum angle</b> or click <em>"Minimum Angle"</em> button.
+<li>Choose <b>Controls > Face Controls > Minimum angle</b> or click
+<em>"Minimum Angle"</em> button.
 
 \image html image38.png
 <center><em>"Minimum Angle" button</em></center>
index 45e746da4dd86923dffa259f06fbb92362d2663f..ddddfad5026b07eae121d770b3938281883952b1 100644 (file)
@@ -48,7 +48,6 @@ of the selected node or edge.</li>
 <li>\subpage convert_to_from_quadratic_mesh_page "Convert regular mesh to quadratic", 
 or vice versa.</li>
 <li>\subpage make_2dmesh_from_3d_page "Generate boundary elements".</li>
-
 </ul>
 
 \note It is possible to use the variables defined in the SALOME \b NoteBook
index c01dc0a54f6cf1848ee0be5bee16b0ce1a44c0f3..00af8c7ebf837e1131bee745798f5efc6c908055 100644 (file)
@@ -162,6 +162,11 @@ by ID in <b>Threshold Value</b> field, if the angle between the
 normal to the neighboring face and the normal to the selected face is less then the
 angular tolerance (defined in degrees). Selection continues among all neighbor faces of already 
 selected ones.<br>
+</li><li>
+<b>Max Element Length 2D</b> selects triangles and quadrangles combining of the edges and
+diagonals with a value of length, which is more, less or equal
+(within a given <b>Tolerance</b>) to the predefined <b>Threshold Value</b>. See also a
+\ref max_element_length_2d_page "Max Element Length 2D quality control".
 </li>
 </ul>
 
@@ -175,6 +180,11 @@ Additional criteria to select mesh <b>Volumes</b> are the following:
 \ref volume_page "Volume quality control"), which is more, less or equal (within a given
 <b>Tolerance</b>) to the predefined <b>Threshold Value</b>.
 </li><li>
+<b>Max Element Length 3D</b> selects 3D mesh elements combining of the edges and
+diagonals with a value of length, which is more, less or equal
+(within a given <b>Tolerance</b>) to the predefined <b>Threshold Value</b>. See also a
+\ref max_element_length_3d_page "Max Element Length 3D quality control".
+</li><li>
 <b>Bad oriented volume</b> selects mesh volumes, which are incorrectly oriented from
 the point of view of MED convention.
 </li>
index 5235b4dddeb00c88b2bb7a9562d3e317f84c244e..036c70d83aaf7e9a655c1f646e0c97286e16cd28 100644 (file)
@@ -14,7 +14,8 @@ criterion can be applied to elements composed of 4 and 3 nodes
 <ol>
 <li>Display your mesh in the viewer.</li>
 
-<li>Choose <b>Controls > Skew</b> or click <em>"Skew"</em> button of the toolbar.
+<li>Choose <b>Controls > Face Controls > Skew</b> or click
+<em>"Skew"</em> button of the toolbar.
 
 \image html image40.png
 <center><em>"Skew" button </em></center>
index 5e1fe6ebd007410b4497f82ff7075765c1852499..8b63ddfa335a9d9fbc3b388552e6f64b47134f19 100644 (file)
@@ -138,5 +138,6 @@ the following links:
 - \subpage tui_modifying_meshes_page
 - \subpage tui_transforming_meshes_page
 - \subpage tui_notebook_smesh_page
+- \subpage tui_measurements_page
 
 */
index d2c4dd2b4358cd407db279825c5bcfcb15f63c8b..86472eabe82c537b2f40a3a9c72245ea1060e1c8 100644 (file)
@@ -13,8 +13,8 @@ for elements consisting of 4 nodes.
 <ol>
 <li>Display your mesh in the viewer.</li>
 
-<li>Choose <b>Controls > Taper</b> or click <em>"Taper"</em> button in
-the toolbar.
+<li>Choose <b>Controls > Face Controls > Taper</b> or click
+<em>"Taper"</em> button in the toolbar.
 
 \image html image36.png
 <center><em>"Taper" button</em></center>
index 9932991f8c219134ddf32225d99142b1774efc41..1581e7c2fbb4f495a4d0719af05e136de7ec1cf5 100644 (file)
@@ -551,9 +551,8 @@ mesh.Compute()
 \anchor tui_quadrangle_parameters
 <h2>Quadrangle Parameters example 1 (meshing a face with 3 edges) </h2>
 \code
-import geompy
-import smesh
-import StdMeshers
+from smesh import *
+SetCurrentStudy(salome.myStudy)
 
 # Get 1/4 part from the disk face.
 Box_1 = geompy.MakeBoxDXDYDZ(100, 100, 100)
@@ -566,16 +565,15 @@ geompy.addToStudy( Common_1, "Common_1" )
 # Set the Geometry for meshing
 Mesh_1 = smesh.Mesh(Common_1)
 
-# Create Quadrangle parameters and define the Base Vertex.
-Quadrangle_Parameters_1 = smesh.CreateHypothesis('QuadrangleParams')
-Quadrangle_Parameters_1.SetTriaVertex( 8 )
 
 # Define 1D hypothesis and compute the mesh
 Regular_1D = Mesh_1.Segment()
 Nb_Segments_1 = Regular_1D.NumberOfSegments(10)
 Nb_Segments_1.SetDistrType( 0 )
-status = Mesh_1.AddHypothesis(Quadrangle_Parameters_1)
-Quadrangle_2D = Mesh_1.Quadrangle()
+
+# Create Quadrangle parameters and define the Base Vertex.
+Quadrangle_2D = Mesh_1.Quadrangle().TriangleVertex( 8 )
+
 Mesh_1.Compute()
 \endcode
 
@@ -628,6 +626,52 @@ Quadrangle_Parameters_1.SetQuadType( StdMeshers.QUAD_REDUCED )
 isDone = Mesh_1.Compute()
 \endcode
 
+\anchor tui_import
+<h2>"Use Existing Elements" example </h2>
+\code
+
+from smesh import *
+SetCurrentStudy(salome.myStudy)
+
+# Make a patritioned box
+
+box = geompy.MakeBoxDXDYDZ(100,100,100)
+
+N = geompy.MakeVectorDXDYDZ( 1,0,0 )
+O = geompy.MakeVertex( 50,0,0 )
+plane = geompy.MakePlane( O, N, 200 ) # plane YOZ
+
+shape2boxes = geompy.MakeHalfPartition( box, plane )
+boxes = geompy.SubShapeAllSorted(shape2boxes, geompy.ShapeType["SOLID"])
+
+geompy.addToStudy( boxes[0], "boxes[0]")
+geompy.addToStudy( boxes[1], "boxes[1]")
+midFace0 = geompy.SubShapeAllSorted(boxes[0], geompy.ShapeType["FACE"])[5]
+geompy.addToStudyInFather( boxes[0], midFace0, "middle Face")
+midFace1 = geompy.SubShapeAllSorted(boxes[1], geompy.ShapeType["FACE"])[0]
+geompy.addToStudyInFather( boxes[1], midFace1, "middle Face")
+
+# Mesh one of boxes with quadrangles. It is a source mesh
+
+srcMesh = Mesh(boxes[0], "source mesh") # box coloser to CS origin
+nSeg1 = srcMesh.Segment().NumberOfSegments(4)
+srcMesh.Quadrangle()
+srcMesh.Compute()
+srcFaceGroup = srcMesh.GroupOnGeom( midFace0, "src faces", FACE )
+
+# Import faces from midFace0 to the target mesh
+
+tgtMesh = Mesh(boxes[1], "target mesh")
+importAlgo = tgtMesh.UseExisting2DElements(midFace1)
+import2hyp = importAlgo.SourceFaces( [srcFaceGroup] )
+tgtMesh.Segment().NumberOfSegments(3)
+tgtMesh.Quadrangle()
+tgtMesh.Compute()
+
+# Import the whole source mesh with groups
+import2hyp.SetCopySourceMesh(True,True)
+tgtMesh.Compute()
+\endcode
 
 \n Other meshing algorithms:
 
index 0a4fccd3bd2195e167f28d0c85d99234fbed0653..a736158086d12fc9c523ea6e2fcfd44542cf60aa 100755 (executable)
@@ -337,6 +337,46 @@ print "Number of faces with maximum edge length > 14:", len(ids)
 
 \sa \ref tui_length_2d
 
+\section filter_max_element_length_2d Max Element Length 2D
+
+Filter 2D mesh elements (faces) corresponding to the maximum length
+value of its edges and diagonals:
+- element type should be \a smesh.FACE
+- functor type should be \a smesh.FT_MaxElementLength2D
+- threshold is floating point value (edge/diagonal length)
+
+\code
+# create mesh
+from SMESH_mechanic import *
+# get all faces that have elements with length > 10
+filter = smesh.GetFilter(smesh.FACE, smesh.FT_MaxElementLength2D, smesh.FT_MoreThan, 10)
+ids = mesh.GetIdsFromFilter(filter)
+print "Number of faces with maximum element length > 10:", len(ids)
+\endcode
+
+\sa \ref tui_max_element_length_2d
+
+\section filter_max_element_length_3d Max Element Length 3D
+
+Filter 3D mesh elements (volumes) corresponding to the maximum length
+value of its edges and diagonals:
+- element type should be \a smesh.VOLUME
+- functor type should be \a smesh.FT_MaxElementLength3D
+- threshold is floating point value (edge/diagonal length)
+
+\code
+# create mesh with volumes
+from SMESH_mechanic import *
+mesh.Tetrahedron( algo=smesh.NETGEN )
+mesh.Compute()
+# get all volumes that have elements with length > 10
+filter = smesh.GetFilter(smesh.VOLUME, smesh.FT_MaxElementLength3D, smesh.FT_MoreThan, 10)
+ids = mesh.GetIdsFromFilter(filter)
+print "Number of volumes with maximum element length > 10:", len(ids)
+\endcode
+
+\sa \ref tui_max_element_length_3d
+
 \section filter_belong_to_geom Belong to Geom
 
 Filter mesh entities (nodes or elements) which all nodes lie on the
index 763e939d4fa9cea7f510f213119e434d6df4d901..1aa73a4846b3502e1c76c92a7c13e842f958b7db 100644 (file)
@@ -1,4 +1,4 @@
-       /*!
+/*!
 
 \page tui_grouping_elements_page Grouping Elements
 
diff --git a/doc/salome/gui/SMESH/input/tui_measurements.doc b/doc/salome/gui/SMESH/input/tui_measurements.doc
new file mode 100644 (file)
index 0000000..aabf0b3
--- /dev/null
@@ -0,0 +1,84 @@
+/*!
+
+\page tui_measurements_page Measurements
+
+\section tui_min_distance Minimum Distance
+
+\code
+
+import smesh
+from SMESH_mechanic import mesh as mesh1
+from SMESH_test1 import mesh as mesh2
+
+mesh1.Compute()
+mesh2.Compute()
+
+# compute min distance from mesh1 to the origin (not available yet)
+smesh.MinDistance(mesh1)
+
+# compute min distance from node 10 of mesh1 to the origin
+smesh.MinDistance(mesh1, id1=10)
+# ... or
+mesh1.MinDistance(10)
+
+# compute min distance between nodes 10 and 20 of mesh1
+smesh.MinDistance(mesh1, id1=10, id2=20)
+# ... or
+mesh1.MinDistance(10, 20)
+
+# compute min distance from element 100 of mesh1 to the origin (not available yet)
+smesh.MinDistance(mesh1, id1=100, isElem1=True)
+# ... or
+mesh1.MinDistance(100, isElem1=True)
+
+# compute min distance between elements 100 and 200 of mesh1 (not available yet)
+smesh.MinDistance(mesh1, id1=100, id2=200, isElem1=True, isElem2=True)
+# ... or
+mesh1.MinDistance(100, 200, True, True)
+
+# compute min distance from element 100 to node 20 of mesh1 (not available yet)
+smesh.MinDistance(mesh1, id1=100, id2=20, isElem1=True)
+# ... or
+mesh1.MinDistance(100, 20, True)
+
+# compute min distance from mesh1 to mesh2 (not available yet)
+smesh.MinDistance(mesh1, mesh2)
+
+# compute min distance from node 10 of mesh1 to node 20 of mesh2
+smesh.MinDistance(mesh1, mesh2, 10, 20)
+
+# compute min distance from node 10 of mesh1 to element 200 of mesh2 (not available yet)
+smesh.MinDistance(mesh1, mesh2, 10, 200, isElem2=True)
+
+# etc...
+
+\endcode
+
+\section tui_bounding_box Bounding Box
+
+\code
+
+import smesh
+from SMESH_mechanic import mesh as mesh1
+from SMESH_test1 import mesh as mesh2
+
+mesh1.Compute()
+mesh2.Compute()
+
+# compute bounding box for mesh1
+mesh1.BoundingBox()
+
+# compute bounding box for list of nodes of mesh1
+mesh1.BoundingBox([363, 364, 370, 371, 372, 373, 379, 380, 381])
+
+# compute bounding box for list of elements of mesh1
+mesh1.BoundingBox([363, 364, 370, 371, 372, 373, 379, 380, 381], isElem=True)
+
+# compute common bounding box of mesh1 and mesh2
+smesh.BoundingBox([mesh1, mesh2])
+
+# etc...
+
+\endcode
+
+*/
index 740c42247f584e2a7928a0402708b077550d845b..acbf89198437b748b58b487c12d7ec581d96b8bc 100644 (file)
@@ -603,6 +603,39 @@ aGroup.Add(anIds)
 salome.sg.updateObjBrowser(1)
 \endcode
 
+\section tui_max_element_length_2d Max Element Length 2D
+
+\code
+import SMESH_mechanic
+
+smesh  = SMESH_mechanic.smesh
+mesh   = SMESH_mechanic.mesh
+salome = SMESH_mechanic.salome
+
+# Criterion : MAX ELEMENT LENGTH 2D > 10
+mel_2d_margin = 10
+
+aFilter = smesh.GetFilter(smesh.FACE, smesh.FT_MaxElementLength2D, smesh.FT_MoreThan, mel_2d_margin)
+
+anIds = mesh.GetIdsFromFilter(aFilter) 
+
+# print the result
+print "Criterion: Max Element Length 2D Ratio > ", mel_2d_margin, " Nb = ", len(anIds)
+j = 1
+for i in range(len(anIds)):
+  if j > 20: j = 1; print ""
+  print anIds[i],
+  j = j + 1
+  pass
+print ""
+
+# create a group
+aGroup = mesh.CreateEmptyGroup(smesh.FACE, "Max Element Length 2D > " + `mel_2d_margin`)
+aGroup.Add(anIds)
+
+salome.sg.updateObjBrowser(1)
+\endcode
+
 \section tui_aspect_ratio_3d Aspect Ratio 3D
 
 \code
@@ -672,4 +705,37 @@ aGroup.Add(anIds)
 salome.sg.updateObjBrowser(1) 
 \endcode
 
+\section tui_max_element_length_3d Max Element Length 3D
+
+\code
+import SMESH_mechanic_tetra
+
+smesh  = SMESH_mechanic_tetra.smesh
+mesh   = SMESH_mechanic_tetra.mesh
+salome = SMESH_mechanic_tetra.salome
+
+# Criterion : MAX ELEMENT LENGTH 3D > 10
+mel_3d_margin = 10
+
+aFilter = smesh.GetFilter(smesh.FACE, smesh.FT_MaxElementLength3D, smesh.FT_MoreThan, mel_3d_margin)
+
+anIds = mesh.GetIdsFromFilter(aFilter) 
+
+# print the result
+print "Criterion: Max Element Length 3D Ratio > ", mel_3d_margin, " Nb = ", len(anIds)
+j = 1
+for i in range(len(anIds)):
+  if j > 20: j = 1; print ""
+  print anIds[i],
+  j = j + 1
+  pass
+print ""
+
+# create a group
+aGroup = mesh.CreateEmptyGroup(smesh.FACE, "Max Element Length 3D > " + `mel_3d_margin`)
+aGroup.Add(anIds)
+
+salome.sg.updateObjBrowser(1)
+\endcode
+
 */
diff --git a/doc/salome/gui/SMESH/input/use_existing_algos.doc b/doc/salome/gui/SMESH/input/use_existing_algos.doc
new file mode 100644 (file)
index 0000000..b2273a4
--- /dev/null
@@ -0,0 +1,58 @@
+/*!
+
+\page import_algos_page Use Existing Elements Algorithms
+
+\n Use Existing Elements algorithms allow to define the mesh of a geometrical
+object by the importing suitably located mesh elements from another
+mesh. The mesh elements to import from the other mesh are to be contained in
+groups. If several groups are used to mesh one geometry, validity of
+nodal connectivity of result mesh must be assured by connectivity of
+the source mesh; no geometrical checks are performed to merge
+different nodes at same locations.
+<br> The source elements must totally cover the meshed geometry.
+The source elements lying partially over the geometry will not be used.
+<br>
+These algorithms can be used to mesh a very complex geometry part by
+part, by storing meshes of parts in files and then fusing them
+together using these algorithms.
+<br>
+
+<b>Use Existing 1D Elements</b> algorithm allows to define the mesh of
+a geometrical edge (or group of edges)
+by the importing of mesh edges of another mesh contained in a group (or groups).
+\n To apply this algorithm select the edge to be meshed (indicated in
+the field \b Geometry of <b>Create mesh</b> dialog box),
+<b>Use existing 1D elements</b> in the list of 1D algorithms and click the
+<em>"Add Hypothesis"</em> button.
+The following dialog box will appear:
+
+\image html hyp_source_edges.png
+
+In this menu you can define the \b Name of the algorithm, the
+<b>Groups of Edges</b> to import elements from, <b> To copy mesh</b>
+the selected <b>Groups of Edges</b> belong to as a whole and <b>To
+copy groups</b> along with the whole mesh.
+<br>
+
+<b>Use Existing 2D Elements</b> algorithm allows to define the mesh of
+a geometrical face (or group of faces)
+by the importing of mesh faces of another mesh contained in a group (or groups).
+\n To apply this algorithm select the edge to be meshed (indicated in
+the field \b Geometry of <b>Create mesh</b> dialog box),
+<b>Use existing 2D elements</b> in the list of 2D algorithms and click the
+<em>"Add Hypothesis"</em> button.
+The following dialog box will appear:
+
+\image html hyp_source_faces.png
+
+In this menu you can define the \b Name of the algorithm, the
+<b>Groups of Faces</b> to import elements from, <b> To copy mesh</b>
+the selected <b>Groups of Fcaes</b> belong to as a whole and <b>To
+copy groups</b> along with the whole mesh.
+<br>
+
+<br><b>See Also</b> a sample TUI Script of a 
+\ref tui_import "Use Existing Elements Algorithms".
+
+*/
+
index ba99c193ebc3b9bd3528f7f73894ef1c2149e551..4d74fcbf02efd33341a2dce73e33b22aa8685902 100644 (file)
@@ -9,8 +9,8 @@
 <ol>
 <li>Display your mesh in the viewer.</li>
 
-<li>Choose <b>Controls > Volume</b> or click <em>"Volume"</em> button
-in the toolbar.
+<li>Choose <b>Controls > Volume Controls > Volume</b> or click
+<em>"Volume"</em> button in the toolbar.
 
 \image html image145.png
 <center><em>"Volume" button</em></center>
index 83bfaa3ac638c4d11b7cd188669af966a62d8b5d..86ba0c9055e1bf0ed2426c77b468ae740a5602ca 100644 (file)
@@ -24,8 +24,8 @@ projection height ?h? to the half edge length ?l?.
 <ol>
 <li>Display your mesh in the viewer.</li>
 
-<li>Choose <b>Controls > Warping Angle</b> or click <em>"Warping angle"</em>
-button of the toolbar.
+<li>Choose <b>Controls > Face Controls > Warping Angle</b> or click
+<em>"Warping angle"</em> button of the toolbar.
 
 \image html image39.png
 <center><em>"Warping angle" button</em></center>
index 5a88808b30e51f8c05385801643e8174ae7f700e..491c38667fe62ed1838fff01371b6ddf84729c18 100644 (file)
@@ -32,7 +32,8 @@ BASEIDL_FILES = \
        SMESH_Filter.idl \
        SMESH_Group.idl \
        SMESH_Pattern.idl \
-       SMESH_MeshEditor.idl
+       SMESH_MeshEditor.idl \
+       SMESH_Measurements.idl
 
 # This variable defines the files to be installed
 dist_salomeidl_DATA = $(BASEIDL_FILES)
@@ -49,7 +50,8 @@ nodist_libSalomeIDLSMESH_la_SOURCES = \
        SMESH_FilterSK.cc \
        SMESH_GroupSK.cc \
        SMESH_PatternSK.cc \
-       SMESH_MeshEditorSK.cc
+       SMESH_MeshEditorSK.cc \
+       SMESH_MeasurementsSK.cc
 
 # header files must be exported: other modules have to use this library
 nodist_salomeinclude_HEADERS = $(BASEIDL_FILES:%.idl=%.hh)
index a5ecbcabf2e15f0af7eab40ff9cb6389964a6b55..88b0ab7512f3b2a81a814b1bb04e795d33c57f4d 100644 (file)
@@ -796,6 +796,48 @@ module StdMeshers
     QuadType GetQuadType();
   };
 
+  /*!
+   * interface of "Source edges" hypothesis.
+   * This hypothesis specifies groups of edges of other mesh to be imported
+   * in this mesh
+   */
+  interface StdMeshers_ImportSource1D : SMESH::SMESH_Hypothesis
+  {
+    /*!
+     * Set edges to import from other mesh
+     */
+    void SetSourceEdges(in SMESH::ListOfGroups groups);
+    SMESH::string_array GetSourceEdges();
+
+    /*!
+     * Set to import the whole other mesh or not, and if yes, to
+     * copy groups of not. By default the mesh is not copied.
+     */
+    void SetCopySourceMesh(in boolean toCopyMesh, in boolean toCopyGroups);
+    void GetCopySourceMesh(out boolean toCopyMesh,out boolean toCopyGroups);
+  };
+
+  /*!
+   * interface of "Source faces" hypothesis.
+   * This hypothesis specifies groups of faces of other mesh to be imported
+   * in this mesh
+   */
+  interface StdMeshers_ImportSource2D : SMESH::SMESH_Hypothesis
+  {
+    /*!
+     * Set faces to import from other mesh
+     */
+    void SetSourceFaces(in SMESH::ListOfGroups groups);
+    SMESH::string_array GetSourceFaces();
+
+    /*!
+     * Set to import the whole other mesh or not, and if yes, to
+     * copy groups of not. By default the mesh is not copied.
+     */
+    void SetCopySourceMesh(in boolean toCopyMesh,in boolean toCopyGroups);
+    void GetCopySourceMesh(out boolean toCopyMesh,out boolean toCopyGroups);
+  };
+
   /*!
    * StdMeshers_SegmentAroundVertex_0D: interface of "SegmentAroundVertex" algorithm
    */
@@ -896,6 +938,19 @@ module StdMeshers
   {
   };
 
+  /*!
+   * StdMeshers_Import_1D2D: interface of "Use existing 2D elements" algorithm
+   */
+  interface StdMeshers_Import_1D2D : SMESH::SMESH_2D_Algo
+  {
+  };
+  /*!
+   * StdMeshers_Import_1D: interface of "Use existing 1D elements" algorithm
+   */
+  interface StdMeshers_Import_1D : SMESH::SMESH_1D_Algo
+  {
+  };
+
 };
 
 #endif
index 3b478fec0d74235fcdd4ae63c15dca70ac0bf809..e12607bcda9252aa7d35ca337d9c961ee18c30fd 100644 (file)
@@ -47,6 +47,8 @@ module SMESH
     FT_Skew,         
     FT_Area,          
     FT_Volume3D,          
+    FT_MaxElementLength2D,
+    FT_MaxElementLength3D,
     FT_FreeBorders,
     FT_FreeEdges,
     FT_FreeNodes,
@@ -75,6 +77,17 @@ module SMESH
     FT_Undefined
   };
 
+  /*!
+  * Parameters of a reclangle of histogram
+  */
+  struct HistogramRectangle
+  {
+    long nbEvents;
+    double min;
+    double max;
+  };
+  typedef sequence<HistogramRectangle> Histogram;
+
   /*!
   * Base interface for all functors ( i.e. numerical functors and predicates )
   */
@@ -94,6 +107,8 @@ module SMESH
   {
     double GetValue( in long theElementId );
 
+    Histogram GetHistogram( in short nbIntervals );
+
     /*!
     * Set precision for calculation. It is a position after point which is
     * used to functor value after calculation.
@@ -109,6 +124,8 @@ module SMESH
   interface Skew            : NumericalFunctor{};
   interface Area            : NumericalFunctor{};
   interface Volume3D        : NumericalFunctor{};
+  interface MaxElementLength2D : NumericalFunctor{};
+  interface MaxElementLength3D : NumericalFunctor{};
   interface Length          : NumericalFunctor{};
   interface Length2D        : NumericalFunctor
   {
@@ -461,6 +478,8 @@ module SMESH
     Skew              CreateSkew();
     Area              CreateArea();
     Volume3D          CreateVolume3D();
+    MaxElementLength2D CreateMaxElementLength2D();
+    MaxElementLength3D CreateMaxElementLength3D();
     Length            CreateLength();
     Length2D          CreateLength2D();
     MultiConnection   CreateMultiConnection();
index 14527a9b3b9244878734696a72c970429cf9416a..3c375e625747bd9d665c0abe2bf7efa621776939 100644 (file)
@@ -42,6 +42,7 @@ module SMESH
 
   interface FilterManager;
   interface SMESH_Pattern;
+  interface Measurements;
 
   /*!
    * Tags definition
@@ -119,6 +120,8 @@ module SMESH
 
     SMESH_Pattern GetPattern();
 
+    Measurements  CreateMeasurements();
+
     /*!
       Set the current mode
      */
@@ -244,7 +247,6 @@ module SMESH
      */
     long_array  Evaluate(in SMESH_Mesh        theMesh, 
                         in GEOM::GEOM_Object theSubObject)
-      //inout long_array     theNbElems)
       raises ( SALOME::SALOME_Exception );
 
     /*!
index b41e57df3663217386020cec73a0a9d761ed7ffa..adf63dd8365f823e3f90ea9e14c42dafe814b445 100644 (file)
@@ -82,11 +82,6 @@ module SMESH
      */
     long_array GetListOfID();
 
-    /*!
-     * Returns the mesh object this group belongs to
-     */
-    SMESH_Mesh GetMesh();
-
     /*!
      * Sets group color
      */
diff --git a/idl/SMESH_Measurements.idl b/idl/SMESH_Measurements.idl
new file mode 100644 (file)
index 0000000..6a177f5
--- /dev/null
@@ -0,0 +1,61 @@
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+//  File   : SMESH_Measurements.idl
+//  Author : Pavel Telkov, OCC
+//
+#ifndef _SMESH_MEASUREMENTS_IDL_
+#define _SMESH_MEASUREMENTS_IDL_
+
+#include "SALOME_GenericObj.idl"
+#include "SMESH_Mesh.idl"
+
+module SMESH
+{
+
+  /*
+   * Measure component
+   */
+  struct Measure {
+    double minX, minY, minZ;
+    double maxX, maxY, maxZ;
+    long node1, node2;
+    long elem1, elem2;
+    double value;
+  };
+
+  interface Measurements: SALOME::GenericObj
+  {
+    /*!
+     * minimal distance between two entities
+     */
+    Measure MinDistance(in SMESH_IDSource source1,
+                        in SMESH_IDSource source2);
+
+    /*!
+     * common bounding box of entities
+     */
+    Measure BoundingBox(in ListOfIDSources sources);
+  };
+};    
+
+#endif
index cc97d1e14bed63a706a0877f4122723b4ff2183b..8165d5c00c5e37cb10984eb3fc6d69f339a118e9 100644 (file)
@@ -248,6 +248,8 @@ module SMESH
                              long_array  elementConnectivities;
                              types_array elementTypes; };
 
+  interface SMESH_Mesh;
+
   interface SMESH_IDSource
   {
     /*!
@@ -265,6 +267,11 @@ module SMESH
      * Returns types of elements it contains
      */
     array_of_ElementType GetTypes();
+
+    /*!
+     * Returns the mesh
+     */
+    SMESH_Mesh GetMesh();
   };
 
   interface SMESH_Group;
index 9541a21336cbae3616e2787e71cf53f90e3a541d..cc7d5a885fc87001d1c98d041ff6923219fa7d12 100644 (file)
@@ -49,6 +49,7 @@ dist_salomeres_DATA = \
        mesh_info.png \
        advanced_mesh_info.png \
        standard_mesh_info.png \
+       mesh_elem_info.png \
        mesh_whatis.png \
        mesh_init.png \
        mesh_length.png \
@@ -57,6 +58,8 @@ dist_salomeres_DATA = \
        mesh_free_edges.png \
        mesh_free_edges_2d.png \
        mesh_free_nodes.png \
+       mesh_max_element_length_2d.png \
+       mesh_max_element_length_3d.png \
        mesh_multi_edges.png \
        mesh_multi_edges_2d.png \
        mesh_line_n.png \
@@ -180,7 +183,9 @@ dist_salomeres_DATA = \
         scale_along_axes.png \
        split_into_tetra.png \
        mesh_duplicate_nodes.png \
-       mesh_duplicate_nodes_with_elem.png
+       mesh_duplicate_nodes_with_elem.png \
+       mesh_bounding_box.png \
+       mesh_min_dist.png
 
 # VSR: little trick to avoid putting if SMESHCatalog.xml to the distribution archive
 nodist_salomeres_SCRIPTS = SMESHCatalog.xml
index b7993a340edf69ebd05615a84c3dd73a8a9d4d97..ea6daa0bfc4d0bbdfde8951d46e084b30a3666b8 100644 (file)
     <parameter name="scalar_bar_vertical_width"    value="0.08" />
     <parameter name="scalar_bar_vertical_x"        value="0.01" />
     <parameter name="scalar_bar_vertical_y"        value="0.1" />
+    <parameter name="distribution_visibility"      value="false" />
+    <parameter name="distribution_coloring_type"   value="0" />
+    <parameter name="distribution_color"           value="255, 255, 255" />
     <parameter name="DisplayMode"                  value="true" />
     <parameter name="auto_update"                  value="true" />
     <parameter name="update_limit"                 value="500000" />
     <parameter name="display_mode"                 value="1"    />
     <parameter name="auto_groups"                  value="false"/>
     <parameter name="show_result_notification"     value="2"/>
+    <parameter name="mesh_elem_info"               value="1"/>
     <parameter name="segmentation"                 value="10"/>
     <parameter name="nb_segments_per_edge"         value="15"/>
     <parameter name="quadratic_mode"               value="0"/>
index 557cd9613f73d9731e27473808dfff9031e7e183..41c83c997d219654952a24f665582a8fa104c929 100644 (file)
     <hypothesis type="MaxElementVolume"
                 label-id="Max. Element Volume"
                 icon-id="mesh_hypo_volume.png"
-               need-geom="false"
                 dim="3"/>
 
     <hypothesis type="ProjectionSource3D"
                 icon-id="mesh_hypo_length.png"
                 dim="1"/>
 
+    <hypothesis type="ImportSource2D"
+                label-id="Source Faces"
+                icon-id="mesh_hypo_area.png"
+                dim="2"/>
+
+    <hypothesis type="ImportSource1D"
+                label-id="Source Edges"
+                icon-id="mesh_hypo_length.png"
+                dim="1"/>
+
     <hypothesis type="NumberOfLayers"
                 label-id="Number of Layers"
                 icon-id="mesh_hypo_length.png"
                input="QUAD,TRIA"
                dim="3"/>
 
+    <algorithm type="Import_1D"
+               label-id="Use existing 1D elements"
+               icon-id="mesh_algo_regular.png"
+               hypos="ImportSource1D"
+               output="EDGE"
+               dim="1"/>
+
+    <algorithm type="Import_1D2D"
+               label-id="Use existing 2D elements"
+               icon-id="mesh_algo_quad.png"
+               hypos="ImportSource2D"
+               output="QUAD,TRIA"
+               support-submeshes="false"
+               dim="2"/>
+
     <algorithm type="Prism_3D"
                label-id="3D extrusion"
                icon-id="mesh_algo_hexa.png"
index 44ce337d960d7c1474218cf22ffb4cc0a269e543..6e5b3176bc67ae89e0b55398dff8f90a58084dae 100644 (file)
Binary files a/resources/advanced_mesh_info.png and b/resources/advanced_mesh_info.png differ
diff --git a/resources/mesh_bounding_box.png b/resources/mesh_bounding_box.png
new file mode 100755 (executable)
index 0000000..f01bae8
Binary files /dev/null and b/resources/mesh_bounding_box.png differ
diff --git a/resources/mesh_elem_info.png b/resources/mesh_elem_info.png
new file mode 100644 (file)
index 0000000..9937d6d
Binary files /dev/null and b/resources/mesh_elem_info.png differ
diff --git a/resources/mesh_max_element_length_2d.png b/resources/mesh_max_element_length_2d.png
new file mode 100755 (executable)
index 0000000..d0120fa
Binary files /dev/null and b/resources/mesh_max_element_length_2d.png differ
diff --git a/resources/mesh_max_element_length_3d.png b/resources/mesh_max_element_length_3d.png
new file mode 100755 (executable)
index 0000000..7b6b895
Binary files /dev/null and b/resources/mesh_max_element_length_3d.png differ
diff --git a/resources/mesh_min_dist.png b/resources/mesh_min_dist.png
new file mode 100755 (executable)
index 0000000..6713caf
Binary files /dev/null and b/resources/mesh_min_dist.png differ
index a2ad1e688b99431c243efa3ab607e2a831ccae09..d42072f1b61030fc14f7b25e756aa5f4014d9b54 100644 (file)
@@ -31,6 +31,8 @@ int main(int argc, char** argv)
   new Taper();
   new Skew();
   new Area();
+  new MaxElementLength2D();
+  new MaxElementLength3D();
   new Length();
   //  new Length2D();
   new MultiConnection();
index a8cf8c41925edf48730610cde8d1cc1f3c315ac3..5238b982f3c55ee99f83bf4048d2096b2f866e3c 100644 (file)
@@ -304,6 +304,63 @@ double NumericalFunctor::GetValue( long theId )
   return 0.;
 }
 
+//================================================================================
+/*!
+ * \brief Return histogram of functor values
+ *  \param nbIntervals - number of intervals
+ *  \param nbEvents - number of mesh elements having values within i-th interval
+ *  \param funValues - boundaries of intervals
+ */
+//================================================================================
+
+void NumericalFunctor::GetHistogram(int                  nbIntervals,
+                                    std::vector<int>&    nbEvents,
+                                    std::vector<double>& funValues)
+{
+  if ( nbIntervals < 1 ||
+       !myMesh ||
+       !myMesh->GetMeshInfo().NbElements( GetType() ))
+    return;
+  nbEvents.resize( nbIntervals, 0 );
+  funValues.resize( nbIntervals+1 );
+
+  // get all values sorted
+  std::multiset< double > values;
+  SMDS_ElemIteratorPtr elemIt = myMesh->elementsIterator(GetType());
+  while ( elemIt->more() )
+    values.insert( GetValue( elemIt->next()->GetID() ));
+
+  // case nbIntervals == 1
+  funValues[0] = *values.begin();
+  funValues[nbIntervals] = *values.rbegin();
+  if ( nbIntervals == 1 )
+  {
+    nbEvents[0] = values.size();
+    return;
+  }
+  // case of 1 value
+  if (funValues.front() == funValues.back())
+  {
+    nbEvents.resize( 1 );
+    nbEvents[0] = values.size();
+    funValues[1] = funValues.back();
+    funValues.resize( 2 );
+  }
+  // generic case
+  std::multiset< double >::iterator min = values.begin(), max;
+  for ( int i = 0; i < nbIntervals; ++i )
+  {
+    double r = (i+1) / double( nbIntervals );
+    funValues[i+1] = funValues.front() * (1-r) + funValues.back() * r;
+    if ( min != values.end() && *min <= funValues[i+1] )
+    {
+      max = values.upper_bound( funValues[i+1] ); // greater than funValues[i+1], or end()
+      nbEvents[i] = std::distance( min, max );
+      min = max;
+    }
+  }
+}
+
 //=======================================================================
 //function : GetValue
 //purpose  : 
@@ -340,6 +397,246 @@ SMDSAbs_ElementType Volume::GetType() const
 }
 
 
+/*
+  Class       : MaxElementLength2D
+  Description : Functor calculating maximum length of 2D element
+*/
+
+double MaxElementLength2D::GetValue( long theElementId )
+{
+  TSequenceOfXYZ P;
+  if( GetPoints( theElementId, P ) ) {
+    double aVal = 0;
+    const SMDS_MeshElement* aElem = myMesh->FindElement( theElementId );
+    SMDSAbs_ElementType aType = aElem->GetType();
+    int len = P.size();
+    switch( aType ) {
+    case SMDSAbs_Face:
+      if( len == 3 ) { // triangles
+        double L1 = getDistance(P( 1 ),P( 2 ));
+        double L2 = getDistance(P( 2 ),P( 3 ));
+        double L3 = getDistance(P( 3 ),P( 1 ));
+        aVal = Max(L1,Max(L2,L3));
+        break;
+      }
+      else if( len == 4 ) { // quadrangles
+        double L1 = getDistance(P( 1 ),P( 2 ));
+        double L2 = getDistance(P( 2 ),P( 3 ));
+        double L3 = getDistance(P( 3 ),P( 4 ));
+        double L4 = getDistance(P( 4 ),P( 1 ));
+        double D1 = getDistance(P( 1 ),P( 3 ));
+        double D2 = getDistance(P( 2 ),P( 4 ));
+        aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(D1,D2));
+        break;
+      }
+      else if( len == 6 ) { // quadratic triangles
+        double L1 = getDistance(P( 1 ),P( 2 )) + getDistance(P( 2 ),P( 3 ));
+        double L2 = getDistance(P( 3 ),P( 4 )) + getDistance(P( 4 ),P( 5 ));
+        double L3 = getDistance(P( 5 ),P( 6 )) + getDistance(P( 6 ),P( 1 ));
+        aVal = Max(L1,Max(L2,L3));
+        break;
+      }
+      else if( len == 8 ) { // quadratic quadrangles
+        double L1 = getDistance(P( 1 ),P( 2 )) + getDistance(P( 2 ),P( 3 ));
+        double L2 = getDistance(P( 3 ),P( 4 )) + getDistance(P( 4 ),P( 5 ));
+        double L3 = getDistance(P( 5 ),P( 6 )) + getDistance(P( 6 ),P( 7 ));
+        double L4 = getDistance(P( 7 ),P( 8 )) + getDistance(P( 8 ),P( 1 ));
+        double D1 = getDistance(P( 1 ),P( 5 ));
+        double D2 = getDistance(P( 3 ),P( 7 ));
+        aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(D1,D2));
+        break;
+      }
+    }
+
+    if( myPrecision >= 0 )
+    {
+      double prec = pow( 10., (double)myPrecision );
+      aVal = floor( aVal * prec + 0.5 ) / prec;
+    }
+    return aVal;
+  }
+  return 0.;
+}
+
+double MaxElementLength2D::GetBadRate( double Value, int /*nbNodes*/ ) const
+{
+  return Value;
+}
+
+SMDSAbs_ElementType MaxElementLength2D::GetType() const
+{
+  return SMDSAbs_Face;
+}
+
+/*
+  Class       : MaxElementLength3D
+  Description : Functor calculating maximum length of 3D element
+*/
+
+double MaxElementLength3D::GetValue( long theElementId )
+{
+  TSequenceOfXYZ P;
+  if( GetPoints( theElementId, P ) ) {
+    double aVal = 0;
+    const SMDS_MeshElement* aElem = myMesh->FindElement( theElementId );
+    SMDSAbs_ElementType aType = aElem->GetType();
+    int len = P.size();
+    switch( aType ) {
+    case SMDSAbs_Volume:
+      if( len == 4 ) { // tetras
+        double L1 = getDistance(P( 1 ),P( 2 ));
+        double L2 = getDistance(P( 2 ),P( 3 ));
+        double L3 = getDistance(P( 3 ),P( 1 ));
+        double L4 = getDistance(P( 1 ),P( 4 ));
+        double L5 = getDistance(P( 2 ),P( 4 ));
+        double L6 = getDistance(P( 3 ),P( 4 ));
+        aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
+        break;
+      }
+      else if( len == 5 ) { // pyramids
+        double L1 = getDistance(P( 1 ),P( 2 ));
+        double L2 = getDistance(P( 2 ),P( 3 ));
+        double L3 = getDistance(P( 3 ),P( 4 ));
+        double L4 = getDistance(P( 4 ),P( 1 ));
+        double L5 = getDistance(P( 1 ),P( 5 ));
+        double L6 = getDistance(P( 2 ),P( 5 ));
+        double L7 = getDistance(P( 3 ),P( 5 ));
+        double L8 = getDistance(P( 4 ),P( 5 ));
+        aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
+        aVal = Max(aVal,Max(L7,L8));
+        break;
+      }
+      else if( len == 6 ) { // pentas
+        double L1 = getDistance(P( 1 ),P( 2 ));
+        double L2 = getDistance(P( 2 ),P( 3 ));
+        double L3 = getDistance(P( 3 ),P( 1 ));
+        double L4 = getDistance(P( 4 ),P( 5 ));
+        double L5 = getDistance(P( 5 ),P( 6 ));
+        double L6 = getDistance(P( 6 ),P( 4 ));
+        double L7 = getDistance(P( 1 ),P( 4 ));
+        double L8 = getDistance(P( 2 ),P( 5 ));
+        double L9 = getDistance(P( 3 ),P( 6 ));
+        aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
+        aVal = Max(aVal,Max(Max(L7,L8),L9));
+        break;
+      }
+      else if( len == 8 ) { // hexas
+        double L1 = getDistance(P( 1 ),P( 2 ));
+        double L2 = getDistance(P( 2 ),P( 3 ));
+        double L3 = getDistance(P( 3 ),P( 4 ));
+        double L4 = getDistance(P( 4 ),P( 1 ));
+        double L5 = getDistance(P( 5 ),P( 6 ));
+        double L6 = getDistance(P( 6 ),P( 7 ));
+        double L7 = getDistance(P( 7 ),P( 8 ));
+        double L8 = getDistance(P( 8 ),P( 5 ));
+        double L9 = getDistance(P( 1 ),P( 5 ));
+        double L10= getDistance(P( 2 ),P( 6 ));
+        double L11= getDistance(P( 3 ),P( 7 ));
+        double L12= getDistance(P( 4 ),P( 8 ));
+        double D1 = getDistance(P( 1 ),P( 7 ));
+        double D2 = getDistance(P( 2 ),P( 8 ));
+        double D3 = getDistance(P( 3 ),P( 5 ));
+        double D4 = getDistance(P( 4 ),P( 6 ));
+        aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
+        aVal = Max(aVal,Max(Max(L7,L8),Max(L9,L10)));
+        aVal = Max(aVal,Max(L11,L12));
+        aVal = Max(aVal,Max(Max(D1,D2),Max(D3,D4)));
+        break;
+      }
+      else if( len == 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 ) { // quadratic hexas
+        double L1 = getDistance(P( 1 ),P( 9 )) + getDistance(P( 9 ),P( 2 ));
+        double L2 = getDistance(P( 2 ),P( 10 )) + getDistance(P( 10 ),P( 3 ));
+        double L3 = getDistance(P( 3 ),P( 11 )) + getDistance(P( 11 ),P( 4 ));
+        double L4 = getDistance(P( 4 ),P( 12 )) + getDistance(P( 12 ),P( 1 ));
+        double L5 = getDistance(P( 5 ),P( 13 )) + getDistance(P( 13 ),P( 6 ));
+        double L6 = getDistance(P( 6 ),P( 14 )) + getDistance(P( 14 ),P( 7 ));
+        double L7 = getDistance(P( 7 ),P( 15 )) + getDistance(P( 15 ),P( 8 ));
+        double L8 = getDistance(P( 8 ),P( 16 )) + getDistance(P( 16 ),P( 5 ));
+        double L9 = getDistance(P( 1 ),P( 17 )) + getDistance(P( 17 ),P( 5 ));
+        double L10= getDistance(P( 2 ),P( 18 )) + getDistance(P( 18 ),P( 6 ));
+        double L11= getDistance(P( 3 ),P( 19 )) + getDistance(P( 19 ),P( 7 ));
+        double L12= getDistance(P( 4 ),P( 20 )) + getDistance(P( 20 ),P( 8 ));
+        double D1 = getDistance(P( 1 ),P( 7 ));
+        double D2 = getDistance(P( 2 ),P( 8 ));
+        double D3 = getDistance(P( 3 ),P( 5 ));
+        double D4 = getDistance(P( 4 ),P( 6 ));
+        aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
+        aVal = Max(aVal,Max(Max(L7,L8),Max(L9,L10)));
+        aVal = Max(aVal,Max(L11,L12));
+        aVal = Max(aVal,Max(Max(D1,D2),Max(D3,D4)));
+        break;
+      }
+      else if( len > 1 && aElem->IsPoly() ) { // polys
+        // get the maximum distance between all pairs of nodes
+        for( int i = 1; i <= len; i++ ) {
+          for( int j = 1; j <= len; j++ ) {
+            if( j > i ) { // optimization of the loop
+              double D = getDistance( P(i), P(j) );
+              aVal = Max( aVal, D );
+            }
+          }
+        }
+      }
+    }
+
+    if( myPrecision >= 0 )
+    {
+      double prec = pow( 10., (double)myPrecision );
+      aVal = floor( aVal * prec + 0.5 ) / prec;
+    }
+    return aVal;
+  }
+  return 0.;
+}
+
+double MaxElementLength3D::GetBadRate( double Value, int /*nbNodes*/ ) const
+{
+  return Value;
+}
+
+SMDSAbs_ElementType MaxElementLength3D::GetType() const
+{
+  return SMDSAbs_Volume;
+}
+
+
 /*
   Class       : MinimumAngle
   Description : Functor for calculation of minimum angle
@@ -435,47 +732,94 @@ double AspectRatio::GetValue( const TSequenceOfXYZ& P )
     return alfa * maxLen * half_perimeter / anArea;
   }
   else if( nbNodes == 4 ) { // quadrangle
-    // return aspect ratio of the worst triange which can be built
+    // Compute lengths of the sides
+    std::vector< double > aLen (4);
+    aLen[0] = getDistance( P(1), P(2) );
+    aLen[1] = getDistance( P(2), P(3) );
+    aLen[2] = getDistance( P(3), P(4) );
+    aLen[3] = getDistance( P(4), P(1) );
+    // Compute lengths of the diagonals
+    std::vector< double > aDia (2);
+    aDia[0] = getDistance( P(1), P(3) );
+    aDia[1] = getDistance( P(2), P(4) );
+    // Compute areas of all triangles which can be built
     // taking three nodes of the quadrangle
-    TSequenceOfXYZ triaPnts(3);
-    // triangle on nodes 1 3 2
-    triaPnts(1) = P(1);
-    triaPnts(2) = P(3);
-    triaPnts(3) = P(2);
-    double ar = GetValue( triaPnts );
-    // triangle on nodes 1 3 4
-    triaPnts(3) = P(4);
-    ar = Max ( ar, GetValue( triaPnts ));
-    // triangle on nodes 1 2 4
-    triaPnts(2) = P(2);
-    ar = Max ( ar, GetValue( triaPnts ));
-    // triangle on nodes 3 2 4
-    triaPnts(1) = P(3);
-    ar = Max ( ar, GetValue( triaPnts ));
-
-    return ar;
-  }
-  else { // nbNodes==8 - quadratic quadrangle
-    // return aspect ratio of the worst triange which can be built
+    std::vector< double > anArea (4);
+    anArea[0] = getArea( P(1), P(2), P(3) );
+    anArea[1] = getArea( P(1), P(2), P(4) );
+    anArea[2] = getArea( P(1), P(3), P(4) );
+    anArea[3] = getArea( P(2), P(3), P(4) );
+    // Q = alpha * L * C1 / C2, where
+    //
+    // alpha = sqrt( 1/32 )
+    // L = max( L1, L2, L3, L4, D1, D2 )
+    // C1 = sqrt( ( L1^2 + L1^2 + L1^2 + L1^2 ) / 4 )
+    // C2 = min( S1, S2, S3, S4 )
+    // Li - lengths of the edges
+    // Di - lengths of the diagonals
+    // Si - areas of the triangles
+    const double alpha = sqrt( 1 / 32. );
+    double L = Max( aLen[ 0 ],
+                 Max( aLen[ 1 ],
+                   Max( aLen[ 2 ],
+                     Max( aLen[ 3 ],
+                       Max( aDia[ 0 ], aDia[ 1 ] ) ) ) ) );
+    double C1 = sqrt( ( aLen[0] * aLen[0] +
+                        aLen[1] * aLen[1] +
+                        aLen[2] * aLen[2] +
+                        aLen[3] * aLen[3] ) / 4. );
+    double C2 = Min( anArea[ 0 ],
+                  Min( anArea[ 1 ],
+                    Min( anArea[ 2 ], anArea[ 3 ] ) ) );
+    if ( C2 <= Precision::Confusion() )
+      return 0.;
+    return alpha * L * C1 / C2;
+  }
+  else if( nbNodes == 8 ){ // nbNodes==8 - quadratic quadrangle
+    // Compute lengths of the sides
+    std::vector< double > aLen (4);
+    aLen[0] = getDistance( P(1), P(3) );
+    aLen[1] = getDistance( P(3), P(5) );
+    aLen[2] = getDistance( P(5), P(7) );
+    aLen[3] = getDistance( P(7), P(1) );
+    // Compute lengths of the diagonals
+    std::vector< double > aDia (2);
+    aDia[0] = getDistance( P(1), P(5) );
+    aDia[1] = getDistance( P(3), P(7) );
+    // Compute areas of all triangles which can be built
     // taking three nodes of the quadrangle
-    TSequenceOfXYZ triaPnts(3);
-    // triangle on nodes 1 3 2
-    triaPnts(1) = P(1);
-    triaPnts(2) = P(5);
-    triaPnts(3) = P(3);
-    double ar = GetValue( triaPnts );
-    // triangle on nodes 1 3 4
-    triaPnts(3) = P(7);
-    ar = Max ( ar, GetValue( triaPnts ));
-    // triangle on nodes 1 2 4
-    triaPnts(2) = P(3);
-    ar = Max ( ar, GetValue( triaPnts ));
-    // triangle on nodes 3 2 4
-    triaPnts(1) = P(5);
-    ar = Max ( ar, GetValue( triaPnts ));
-
-    return ar;
+    std::vector< double > anArea (4);
+    anArea[0] = getArea( P(1), P(3), P(5) );
+    anArea[1] = getArea( P(1), P(3), P(7) );
+    anArea[2] = getArea( P(1), P(5), P(7) );
+    anArea[3] = getArea( P(3), P(5), P(7) );
+    // Q = alpha * L * C1 / C2, where
+    //
+    // alpha = sqrt( 1/32 )
+    // L = max( L1, L2, L3, L4, D1, D2 )
+    // C1 = sqrt( ( L1^2 + L1^2 + L1^2 + L1^2 ) / 4 )
+    // C2 = min( S1, S2, S3, S4 )
+    // Li - lengths of the edges
+    // Di - lengths of the diagonals
+    // Si - areas of the triangles
+    const double alpha = sqrt( 1 / 32. );
+    double L = Max( aLen[ 0 ],
+                 Max( aLen[ 1 ],
+                   Max( aLen[ 2 ],
+                     Max( aLen[ 3 ],
+                       Max( aDia[ 0 ], aDia[ 1 ] ) ) ) ) );
+    double C1 = sqrt( ( aLen[0] * aLen[0] +
+                        aLen[1] * aLen[1] +
+                        aLen[2] * aLen[2] +
+                        aLen[3] * aLen[3] ) / 4. );
+    double C2 = Min( anArea[ 0 ],
+                  Min( anArea[ 1 ],
+                    Min( anArea[ 2 ], anArea[ 3 ] ) ) );
+    if ( C2 <= Precision::Confusion() )
+      return 0.;
+    return alpha * L * C1 / C2;
   }
+  return 0;
 }
 
 double AspectRatio::GetBadRate( double Value, int /*nbNodes*/ ) const
@@ -991,16 +1335,20 @@ SMDSAbs_ElementType Skew::GetType() const
 */
 double Area::GetValue( const TSequenceOfXYZ& P )
 {
-  gp_Vec aVec1( P(2) - P(1) );
-  gp_Vec aVec2( P(3) - P(1) );
-  gp_Vec SumVec = aVec1 ^ aVec2;
-  for (int i=4; i<=P.size(); i++) {
-    gp_Vec aVec1( P(i-1) - P(1) );
-    gp_Vec aVec2( P(i) - P(1) );
-    gp_Vec tmp = aVec1 ^ aVec2;
-    SumVec.Add(tmp);
+  double val = 0.0;
+  if ( P.size() > 2 ) {
+    gp_Vec aVec1( P(2) - P(1) );
+    gp_Vec aVec2( P(3) - P(1) );
+    gp_Vec SumVec = aVec1 ^ aVec2;
+    for (int i=4; i<=P.size(); i++) {
+      gp_Vec aVec1( P(i-1) - P(1) );
+      gp_Vec aVec2( P(i) - P(1) );
+      gp_Vec tmp = aVec1 ^ aVec2;
+      SumVec.Add(tmp);
+    }
+    val = SumVec.Magnitude() * 0.5;
   }
-  return SumVec.Magnitude() * 0.5;
+  return val;
 }
 
 double Area::GetBadRate( double Value, int /*nbNodes*/ ) const
@@ -1117,7 +1465,7 @@ double Length2D::GetValue( long theElementId)
       else if (len == 5){ // piramids
         double L1 = getDistance(P( 1 ),P( 2 ));
         double L2 = getDistance(P( 2 ),P( 3 ));
-        double L3 = getDistance(P( 3 ),P( 1 ));
+        double 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 ));
@@ -1177,7 +1525,7 @@ double Length2D::GetValue( long theElementId)
       else if (len == 13){ // quadratic piramids
         double L1 = getDistance(P( 1 ),P( 6 )) + getDistance(P( 6 ),P( 2 ));
         double L2 = getDistance(P( 2 ),P( 7 )) + getDistance(P( 7 ),P( 3 ));
-        double L3 = getDistance(P( 3 ),P( 8 )) + getDistance(P( 8 ),P( 1 ));
+        double 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 ));
index 1fde3f281b60130be26003a0369dc5db1e4a4af8..915bd9f4bf1126485f452b2c1d839fec2453fe9e 100644 (file)
@@ -127,6 +127,9 @@ namespace SMESH{
       virtual void SetMesh( const SMDS_Mesh* theMesh );
       virtual double GetValue( long theElementId );
       virtual double GetValue(const TSequenceOfXYZ& thePoints) { return -1.0;};
+      void GetHistogram(int                  nbIntervals,
+                        std::vector<int>&    nbEvents,
+                        std::vector<double>& funValues);
       virtual SMDSAbs_ElementType GetType() const = 0;
       virtual double GetBadRate( double Value, int nbNodes ) const = 0;
       long  GetPrecision() const;
@@ -156,6 +159,30 @@ namespace SMESH{
     };
   
   
+    /*
+      Class       : MaxElementLength2D
+      Description : Functor calculating maximum length of 2D element
+    */
+    class SMESHCONTROLS_EXPORT MaxElementLength2D: public virtual NumericalFunctor{
+    public:
+      virtual double GetValue( long theElementId );
+      virtual double GetBadRate( double Value, int nbNodes ) const;
+      virtual SMDSAbs_ElementType GetType() const;
+    };
+  
+  
+    /*
+      Class       : MaxElementLength3D
+      Description : Functor calculating maximum length of 3D element
+    */
+    class SMESHCONTROLS_EXPORT MaxElementLength3D: public virtual NumericalFunctor{
+    public:
+      virtual double GetValue( long theElementId );
+      virtual double GetBadRate( double Value, int nbNodes ) const;
+      virtual SMDSAbs_ElementType GetType() const;
+    };
+  
+  
     /*
       Class       : SMESH_MinimumAngle
       Description : Functor for calculation of minimum angle
index 0e8cdabd9115f3c421ee9537684f974bdfd865e3..219350562eb68a338e600df0604beb9d7c1eeb91 100644 (file)
@@ -34,7 +34,9 @@ salomeinclude_HEADERS = \
        SMESH_DeviceActor.h \
        SMESH_PreviewActorsCollection.h \
        SMESH_ExtractGeometry.h \
-       SMESH_FaceOrientationFilter.h
+       SMESH_FaceOrientationFilter.h \
+       SMESH_ScalarBarActor.h
+
 
 # Libraries targets
 
@@ -46,7 +48,8 @@ dist_libSMESHObject_la_SOURCES = \
        SMESH_PreviewActorsCollection.cxx \
        SMESH_ExtractGeometry.cxx \
        SMESH_ActorUtils.cxx \
-       SMESH_FaceOrientationFilter.cxx
+       SMESH_FaceOrientationFilter.cxx \
+       SMESH_ScalarBarActor.cxx
 
 libSMESHObject_la_CPPFLAGS = \
         $(QT_INCLUDES) \
index 8f5c5bae6f32958c48438efb6cc66731cccd0d8a..4afc7f4ca903bc6cd7b1f92f0c6dab13de7efe29 100644 (file)
@@ -30,6 +30,7 @@
 #include "SMESH_DeviceActor.h"
 #include "SMESH_ObjectDef.h"
 #include "SMESH_ControlsDef.hxx"
+#include "SMESH_ScalarBarActor.h"
 #include "VTKViewer_CellCenters.h"
 #include "VTKViewer_ExtractUnstructuredGrid.h"
 #include "VTKViewer_FramedTextActor.h"
@@ -64,7 +65,6 @@
 #include <vtkLabeledDataMapper.h>
 #include <vtkSelectVisiblePoints.h>
 
-#include <vtkScalarBarActor.h>
 #include <vtkLookupTable.h>
 
 #include <vtkMath.h>
@@ -371,7 +371,7 @@ SMESH_ActorDef::SMESH_ActorDef()
   //Controls - Aspect Ratio: incorrect colors of the best and worst values
   myLookupTable->SetHueRange(0.667,0.0);
 
-  myScalarBarActor = vtkScalarBarActor::New();
+  myScalarBarActor = SMESH_ScalarBarActor::New();
   myScalarBarActor->SetVisibility(false);
   myScalarBarActor->SetLookupTable(myLookupTable);
 
@@ -500,6 +500,9 @@ SMESH_ActorDef::~SMESH_ActorDef()
 {
   if(MYDEBUG) MESSAGE("~SMESH_ActorDef - "<<this);
 
+  // caught by SMESHGUI::ProcessEvents() static method
+  this->InvokeEvent( SMESH::DeleteActorEvent, NULL );
+
   myScalarBarActor->Delete();
   myLookupTable->Delete();
 
@@ -721,51 +724,50 @@ SetControlMode(eControl theMode,
   bool anIsScalarVisible = theMode > eNone;
 
   if(anIsScalarVisible){
-    SMESH::Controls::FunctorPtr aFunctor;
     switch(theMode){
     case eLength:
     {
       SMESH::Controls::Length* aControl = new SMESH::Controls::Length();
       aControl->SetPrecision( myControlsPrecision );
-      aFunctor.reset( aControl );
+      myFunctor.reset( aControl );
       myControlActor = my1DActor;
       break;
     }
     case eLength2D:
     {
-      aFunctor.reset(new SMESH::Controls::Length2D());
+      myFunctor.reset(new SMESH::Controls::Length2D());
       myControlActor = my2DActor;
       break;
     }
     case eFreeBorders:
-      aFunctor.reset(new SMESH::Controls::FreeBorders());
+      myFunctor.reset(new SMESH::Controls::FreeBorders());
       myControlActor = my1DActor;
       break;
     case eFreeEdges:
-      aFunctor.reset(new SMESH::Controls::FreeEdges());
+      myFunctor.reset(new SMESH::Controls::FreeEdges());
       myControlActor = my2DActor;
       break;
     case eFreeNodes:
-      aFunctor.reset(new SMESH::Controls::FreeNodes());
+      myFunctor.reset(new SMESH::Controls::FreeNodes());
       myControlActor = myNodeActor;
       break;
     case eFreeFaces:
-      aFunctor.reset(new SMESH::Controls::FreeFaces());
+      myFunctor.reset(new SMESH::Controls::FreeFaces());
       myControlActor = my2DActor;
       break;
     case eMultiConnection:
-      aFunctor.reset(new SMESH::Controls::MultiConnection());
+      myFunctor.reset(new SMESH::Controls::MultiConnection());
       myControlActor = my1DActor;
       break;
     case eMultiConnection2D:
-      aFunctor.reset(new SMESH::Controls::MultiConnection2D());
+      myFunctor.reset(new SMESH::Controls::MultiConnection2D());
       myControlActor = my2DActor;
       break;
     case eArea:
     {
       SMESH::Controls::Area* aControl = new SMESH::Controls::Area();
       aControl->SetPrecision( myControlsPrecision );
-      aFunctor.reset( aControl );
+      myFunctor.reset( aControl );
       myControlActor = my2DActor;
       break;
     }
@@ -773,7 +775,7 @@ SetControlMode(eControl theMode,
     {
       SMESH::Controls::Taper* aControl = new SMESH::Controls::Taper();
       aControl->SetPrecision( myControlsPrecision );
-      aFunctor.reset( aControl );
+      myFunctor.reset( aControl );
       myControlActor = my2DActor;
       break;
     }
@@ -781,7 +783,7 @@ SetControlMode(eControl theMode,
     {
       SMESH::Controls::AspectRatio* aControl = new SMESH::Controls::AspectRatio();
       aControl->SetPrecision( myControlsPrecision );
-      aFunctor.reset( aControl );
+      myFunctor.reset( aControl );
       myControlActor = my2DActor;
       break;
     }
@@ -789,7 +791,7 @@ SetControlMode(eControl theMode,
     {
       SMESH::Controls::AspectRatio3D* aControl = new SMESH::Controls::AspectRatio3D();
       aControl->SetPrecision( myControlsPrecision );
-      aFunctor.reset( aControl );
+      myFunctor.reset( aControl );
       myControlActor = my3DActor;
       break;
     }
@@ -797,7 +799,23 @@ SetControlMode(eControl theMode,
     {
       SMESH::Controls::Volume* aControl = new SMESH::Controls::Volume();
       aControl->SetPrecision( myControlsPrecision );
-      aFunctor.reset( aControl );
+      myFunctor.reset( aControl );
+      myControlActor = my3DActor;
+      break;
+    }
+    case eMaxElementLength2D:
+    {
+      SMESH::Controls::MaxElementLength2D* aControl = new SMESH::Controls::MaxElementLength2D();
+      aControl->SetPrecision( myControlsPrecision );
+      myFunctor.reset( aControl );
+      myControlActor = my2DActor;
+      break;
+    }
+    case eMaxElementLength3D:
+    {
+      SMESH::Controls::MaxElementLength3D* aControl = new SMESH::Controls::MaxElementLength3D();
+      aControl->SetPrecision( myControlsPrecision );
+      myFunctor.reset( aControl );
       myControlActor = my3DActor;
       break;
     }
@@ -805,7 +823,7 @@ SetControlMode(eControl theMode,
     {
       SMESH::Controls::MinimumAngle* aControl = new SMESH::Controls::MinimumAngle();
       aControl->SetPrecision( myControlsPrecision );
-      aFunctor.reset( aControl );
+      myFunctor.reset( aControl );
       myControlActor = my2DActor;
       break;
     }
@@ -813,7 +831,7 @@ SetControlMode(eControl theMode,
     {
       SMESH::Controls::Warping* aControl = new SMESH::Controls::Warping();
       aControl->SetPrecision( myControlsPrecision );
-      aFunctor.reset( aControl );
+      myFunctor.reset( aControl );
       myControlActor = my2DActor;
       break;
     }
@@ -821,7 +839,7 @@ SetControlMode(eControl theMode,
     {
       SMESH::Controls::Skew* aControl = new SMESH::Controls::Skew();
       aControl->SetPrecision( myControlsPrecision );
-      aFunctor.reset( aControl );
+      myFunctor.reset( aControl );
       myControlActor = my2DActor;
       break;
     }
@@ -835,21 +853,21 @@ SetControlMode(eControl theMode,
       myControlMode = theMode;
       switch(myControlMode){
       case eFreeNodes:
-        myNodeExtActor->SetExtControlMode(aFunctor);
+        myNodeExtActor->SetExtControlMode(myFunctor);
         break;
       case eFreeEdges:
       case eFreeBorders:
-        my1DExtActor->SetExtControlMode(aFunctor);
+        my1DExtActor->SetExtControlMode(myFunctor);
         break;
       case eFreeFaces:
-        my2DExtActor->SetExtControlMode(aFunctor);
+        my2DExtActor->SetExtControlMode(myFunctor);
         break;
       case eLength2D:
       case eMultiConnection2D:
-        my1DExtActor->SetExtControlMode(aFunctor,myScalarBarActor,myLookupTable);
+        my1DExtActor->SetExtControlMode(myFunctor,myScalarBarActor,myLookupTable);
         break;
       default:
-        myControlActor->SetControlMode(aFunctor,myScalarBarActor,myLookupTable);
+        myControlActor->SetControlMode(myFunctor,myScalarBarActor,myLookupTable);
       }
     }
 
@@ -872,8 +890,11 @@ SetControlMode(eControl theMode,
         SetEntityMode(eVolumes);
     }
 
-  }else if(theCheckEntityMode){
-    myEntityMode = eAllEntity;
+  }
+  else {
+    if(theCheckEntityMode)
+      myEntityMode = eAllEntity;
+    myFunctor.reset();
   }
 
   SetRepresentation(GetRepresentation());
@@ -1805,92 +1826,6 @@ GetClippingPlane(vtkIdType theID)
   return myCippingPlaneCont[theID].Get();
 }
 
-
-static void ComputeBoundsParam(vtkDataSet* theDataSet,
-                               vtkFloatingPointType theDirection[3], vtkFloatingPointType theMinPnt[3],
-                               vtkFloatingPointType& theMaxBoundPrj, vtkFloatingPointType& theMinBoundPrj)
-{
-  vtkFloatingPointType aBounds[6];
-  theDataSet->GetBounds(aBounds);
-
-  //Enlarge bounds in order to avoid conflicts of precision
-  for(int i = 0; i < 6; i += 2){
-    static double EPS = 1.0E-3;
-    vtkFloatingPointType aDelta = (aBounds[i+1] - aBounds[i])*EPS;
-    aBounds[i] -= aDelta;
-    aBounds[i+1] += aDelta;
-  }
-
-  vtkFloatingPointType aBoundPoints[8][3] = { {aBounds[0],aBounds[2],aBounds[4]},
-                               {aBounds[1],aBounds[2],aBounds[4]},
-                               {aBounds[0],aBounds[3],aBounds[4]},
-                               {aBounds[1],aBounds[3],aBounds[4]},
-                               {aBounds[0],aBounds[2],aBounds[5]},
-                               {aBounds[1],aBounds[2],aBounds[5]}, 
-                               {aBounds[0],aBounds[3],aBounds[5]}, 
-                               {aBounds[1],aBounds[3],aBounds[5]}};
-
-  int aMaxId = 0, aMinId = aMaxId;
-  theMaxBoundPrj = vtkMath::Dot(theDirection,aBoundPoints[aMaxId]);
-  theMinBoundPrj = theMaxBoundPrj;
-  for(int i = 1; i < 8; i++){
-    vtkFloatingPointType aTmp = vtkMath::Dot(theDirection,aBoundPoints[i]);
-    if(theMaxBoundPrj < aTmp){
-      theMaxBoundPrj = aTmp;
-      aMaxId = i;
-    }
-    if(theMinBoundPrj > aTmp){
-      theMinBoundPrj = aTmp;
-      aMinId = i;
-    }
-  }
-  vtkFloatingPointType *aMinPnt = aBoundPoints[aMaxId];
-  theMinPnt[0] = aMinPnt[0];
-  theMinPnt[1] = aMinPnt[1];
-  theMinPnt[2] = aMinPnt[2];
-}
-
-
-static void DistanceToPosition(vtkDataSet* theDataSet,
-                               vtkFloatingPointType theDirection[3], vtkFloatingPointType theDist, vtkFloatingPointType thePos[3])
-{
-  vtkFloatingPointType aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];
-  ComputeBoundsParam(theDataSet,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj);
-  vtkFloatingPointType aLength = (aMaxBoundPrj-aMinBoundPrj)*theDist;
-  thePos[0] = aMinPnt[0]-theDirection[0]*aLength;
-  thePos[1] = aMinPnt[1]-theDirection[1]*aLength;
-  thePos[2] = aMinPnt[2]-theDirection[2]*aLength;
-}
-
-
-static void PositionToDistance(vtkDataSet* theDataSet, 
-                               vtkFloatingPointType theDirection[3], vtkFloatingPointType thePos[3], vtkFloatingPointType& theDist)
-{
-  vtkFloatingPointType aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];
-  ComputeBoundsParam(theDataSet,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj);
-  vtkFloatingPointType aPrj = vtkMath::Dot(theDirection,thePos);
-  theDist = (aPrj-aMinBoundPrj)/(aMaxBoundPrj-aMinBoundPrj);
-}
-
-
-void SMESH_ActorDef::SetPlaneParam(vtkFloatingPointType theDir[3], vtkFloatingPointType theDist, vtkPlane* thePlane)
-{
-  thePlane->SetNormal(theDir);
-  vtkFloatingPointType anOrigin[3];
-  ::DistanceToPosition(GetUnstructuredGrid(),theDir,theDist,anOrigin);
-  thePlane->SetOrigin(anOrigin);
-}
-
-
-void SMESH_ActorDef::GetPlaneParam(vtkFloatingPointType theDir[3], vtkFloatingPointType& theDist, vtkPlane* thePlane)
-{
-  thePlane->GetNormal(theDir);
-
-  vtkFloatingPointType anOrigin[3];
-  thePlane->GetOrigin(anOrigin);
-  ::PositionToDistance(GetUnstructuredGrid(),theDir,anOrigin,theDist);
-}
-
 void SMESH_ActorDef::UpdateScalarBar()
 {
   SUIT_ResourceMgr* mgr = SUIT_Session::session()->resourceMgr();
@@ -2004,6 +1939,21 @@ void SMESH_ActorDef::UpdateScalarBar()
   if( mgr->hasValue( "SMESH", "scalar_bar_num_colors" ) )
     anIntVal = mgr->integerValue( "SMESH", "scalar_bar_num_colors", anIntVal );
   myScalarBarActor->SetMaximumNumberOfColors( anIntVal == 0 ? 64 : anIntVal );
+
+  bool distributionVisibility = mgr->booleanValue("SMESH","distribution_visibility");
+  myScalarBarActor->SetDistributionVisibility(distributionVisibility);
+
+  int coloringType = mgr->integerValue("SMESH", "distribution_coloring_type", 0);
+  myScalarBarActor->SetDistributionColoringType(coloringType);
+  
+  QColor distributionColor = mgr->colorValue("SMESH", "distribution_color",
+                                            QColor(255, 255, 255));
+  double rgb[3];
+  rgb[0]= distributionColor.red()/255.;
+  rgb[1]= distributionColor.green()/255.;
+  rgb[2]= distributionColor.blue()/255.;
+  myScalarBarActor->SetDistributionColor(rgb);
+
   
 }
 
index bb4e2fb68a2e7a58d89d41688cc76ce65e97fdbe..24a57a00ab582cd6b502dea7184ea1351151c5b6 100644 (file)
 #include <SALOME_Actor.h>
 #include "SMESH_Object.h"
 
+#include <vtkCommand.h>
+
 class vtkUnstructuredGrid;
 
-class vtkScalarBarActor;
+class SMESH_ScalarBarActor;
 
 class vtkPlane;
 class vtkImplicitBoolean;
 
+namespace SMESH
+{
+  const vtkIdType DeleteActorEvent = vtkCommand::UserEvent + 100;
+}
+
 class SMESHOBJECT_EXPORT SMESH_Actor: public SALOME_Actor
 {
   static SMESH_Actor* New() { return NULL;}
@@ -115,14 +122,13 @@ class SMESHOBJECT_EXPORT SMESH_Actor: public SALOME_Actor
 
   enum eControl{eNone, eLength, eLength2D, eFreeBorders, eFreeEdges, eFreeNodes,
                 eFreeFaces, eMultiConnection, eArea, eTaper, eAspectRatio,
-                eMinimumAngle, eWarping, eSkew, eAspectRatio3D, eMultiConnection2D, eVolume3D};
+                eMinimumAngle, eWarping, eSkew, eAspectRatio3D, eMultiConnection2D, eVolume3D,
+                eMaxElementLength2D, eMaxElementLength3D};
   virtual void SetControlMode(eControl theMode) = 0;
   virtual eControl GetControlMode() = 0;
+  virtual SMESH::Controls::FunctorPtr GetFunctor() = 0;
 
-  virtual vtkScalarBarActor* GetScalarBarActor() = 0;
-
-  virtual void SetPlaneParam(vtkFloatingPointType theDir[3], vtkFloatingPointType theDist, vtkPlane* thePlane) = 0;
-  virtual void GetPlaneParam(vtkFloatingPointType theDir[3], vtkFloatingPointType& theDist, vtkPlane* thePlane) = 0;
+  virtual SMESH_ScalarBarActor* GetScalarBarActor() = 0;
 
   virtual void RemoveAllClippingPlanes() = 0; 
   virtual vtkIdType GetNumberOfClippingPlanes() = 0; 
index 0a740163b166774ee8e0687c24fbf4059fcdee16..09b2232f0bd660194c09227b804e8c0ab9b58371 100644 (file)
@@ -59,24 +59,20 @@ class vtkPolyDataMapper;
 class vtkUnstructuredGrid;
 class vtkMergeFilter;
 class vtkPolyData;
-
 class vtkMapper;
 class vtkActor2D;
 class vtkMaskPoints;
 class vtkLabeledDataMapper;
 class vtkSelectVisiblePoints;
-
-class vtkScalarBarActor;
 class vtkLookupTable;
-
 class vtkPlane;
 class vtkImplicitBoolean;
-
 class vtkTimeStamp;
 
 class VTKViewer_CellCenters;
 
 class SMESH_DeviceActor;
+class SMESH_ScalarBarActor;
 
 
 class SMESH_ActorDef : public SMESH_Actor
@@ -185,11 +181,9 @@ class SMESH_ActorDef : public SMESH_Actor
 
   virtual void SetControlMode(eControl theMode);
   virtual eControl GetControlMode(){ return myControlMode;}
+  virtual SMESH::Controls::FunctorPtr GetFunctor() { return myFunctor; }
 
-  virtual vtkScalarBarActor* GetScalarBarActor(){ return myScalarBarActor;}
-
-  virtual void SetPlaneParam(vtkFloatingPointType theDir[3], vtkFloatingPointType theDist, vtkPlane* thePlane);
-  virtual void GetPlaneParam(vtkFloatingPointType theDir[3], vtkFloatingPointType& theDist, vtkPlane* thePlane);
+  virtual SMESH_ScalarBarActor* GetScalarBarActor(){ return myScalarBarActor;}
 
   virtual void RemoveAllClippingPlanes();
   virtual vtkIdType GetNumberOfClippingPlanes();
@@ -218,7 +212,7 @@ class SMESH_ActorDef : public SMESH_Actor
   TVisualObjPtr myVisualObj;
   vtkTimeStamp* myTimeStamp;
 
-  vtkScalarBarActor* myScalarBarActor;
+  SMESH_ScalarBarActor* myScalarBarActor;
   vtkLookupTable* myLookupTable;
 
   vtkProperty* mySurfaceProp;
@@ -235,6 +229,7 @@ class SMESH_ActorDef : public SMESH_Actor
   SMESH_DeviceActor* myHighlitableActor;
 
   eControl myControlMode;
+  SMESH::Controls::FunctorPtr myFunctor;
   vtkProperty* my2DExtProp;
   SMESH_DeviceActor* my2DActor;
   SMESH_DeviceActor* my2DExtActor;
index 4be8cadec51d855ad2af99e58b2fdf3d1a0c9b83..600a4987cfb05e19059e9309cc6d9443c45c7dca 100644 (file)
@@ -26,6 +26,7 @@
 //  Module : SMESH
 //
 #include "SMESH_DeviceActor.h"
+#include "SMESH_ScalarBarActor.h"
 #include "SMESH_ExtractGeometry.h"
 #include "SMESH_ControlsDef.hxx"
 #include "SMESH_ActorUtils.h"
@@ -48,7 +49,6 @@
 #include <vtkPolyDataMapper.h>
 #include <vtkUnstructuredGrid.h>
 
-#include <vtkScalarBarActor.h>
 #include <vtkLookupTable.h>
 #include <vtkDoubleArray.h>
 #include <vtkCellData.h>
@@ -282,7 +282,7 @@ SMESH_DeviceActor
 void
 SMESH_DeviceActor
 ::SetControlMode(SMESH::Controls::FunctorPtr theFunctor,
-                 vtkScalarBarActor* theScalarBarActor,
+                 SMESH_ScalarBarActor* theScalarBarActor,
                  vtkLookupTable* theLookupTable)
 {
   bool anIsInitialized = theFunctor;
@@ -310,6 +310,12 @@ SMESH_DeviceActor
         double aValue = aNumericalFunctor->GetValue(anObjId);
         aScalars->SetValue(i,aValue);
       }
+      int nbIntervals = theScalarBarActor->GetMaximumNumberOfColors();
+      std::vector<int> nbEvents;
+      std::vector<double> funValues;
+      aNumericalFunctor->GetHistogram(nbIntervals, nbEvents, funValues);
+      theScalarBarActor->SetDistribution(nbEvents);
+
     }else if(Predicate* aPredicate = dynamic_cast<Predicate*>(theFunctor.get())){
       for(vtkIdType i = 0; i < aNbCells; i++){
         vtkIdType anId = myExtractUnstructuredGrid->GetInputId(i);
@@ -336,7 +342,7 @@ SMESH_DeviceActor
 void
 SMESH_DeviceActor
 ::SetExtControlMode(SMESH::Controls::FunctorPtr theFunctor,
-                    vtkScalarBarActor* theScalarBarActor,
+                    SMESH_ScalarBarActor* theScalarBarActor,
                     vtkLookupTable* theLookupTable)
 {
   bool anIsInitialized = theFunctor;
@@ -469,6 +475,16 @@ SMESH_DeviceActor
       myMergeFilter->SetScalars(aDataSet);
       aDataSet->Delete();
     }
+    
+    //Set Distribution 
+    if(NumericalFunctor* aNumericalFunctor = dynamic_cast<NumericalFunctor*>(theFunctor.get())){
+      int nbIntervals = theScalarBarActor->GetMaximumNumberOfColors();
+      std::vector<int> nbEvents;
+      std::vector<double> funValues;
+      aNumericalFunctor->GetHistogram(nbIntervals, nbEvents, funValues);
+      theScalarBarActor->SetDistribution(nbEvents);
+    }
+    
   }
   GetMapper()->SetScalarVisibility(anIsInitialized);
   theScalarBarActor->SetVisibility(anIsInitialized);
index 7c506bd38379926e22ca45c70b738b0292a7d8bd..1e598fa84d0b80184b2d46ced91718431e68ff40 100644 (file)
@@ -42,7 +42,6 @@ class vtkProperty;
 class vtkMergeFilter;
 class vtkShrinkFilter;
 class vtkUnstructuredGrid;
-class vtkScalarBarActor;
 class vtkLookupTable;
 class vtkImplicitBoolean;
 class vtkPassThroughFilter;
@@ -54,6 +53,7 @@ class VTKViewer_PolyDataMapper;
 
 class SMESH_ExtractGeometry;
 class SMESH_FaceOrientationFilter;
+class SMESH_ScalarBarActor;
 
 
 class SMESHOBJECT_EXPORT SMESH_DeviceActor: public vtkLODActor{
@@ -120,10 +120,10 @@ class SMESHOBJECT_EXPORT SMESH_DeviceActor: public vtkLODActor{
   vtkUnstructuredGrid* GetUnstructuredGrid();
 
   void SetControlMode(SMESH::Controls::FunctorPtr theFunctor,
-                      vtkScalarBarActor* theScalarBarActor,
+                      SMESH_ScalarBarActor* theScalarBarActor,
                       vtkLookupTable* theLookupTable);
   void SetExtControlMode(SMESH::Controls::FunctorPtr theFunctor,
-                         vtkScalarBarActor* theScalarBarActor,
+                         SMESH_ScalarBarActor* theScalarBarActor,
                          vtkLookupTable* theLookupTable);
   void SetExtControlMode(SMESH::Controls::FunctorPtr theFunctor);
 
index d014af78c98ea1a60af3f7a07fad518daa79470f..059edd9270b3aa35a096a6ce30388fe5f6e96ea5 100644 (file)
@@ -35,7 +35,6 @@
 
 // VTK includes
 #include <vtkUnstructuredGrid.h>
-#include <vtkScalarBarActor.h>
 #include <vtkPlane.h>
 #include <vtkRenderer.h>
 #include <vtkProperty.h>
diff --git a/src/OBJECT/SMESH_ScalarBarActor.cxx b/src/OBJECT/SMESH_ScalarBarActor.cxx
new file mode 100644 (file)
index 0000000..3f76226
--- /dev/null
@@ -0,0 +1,923 @@
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//  File   : SMESH_ScalarBarActor.cxx
+//  Author : Roman NIKOLAEV
+//  Module : SMESH
+//
+
+#include "SMESH_ScalarBarActor.h"
+
+#include <vtkCellArray.h>
+#include <vtkCellData.h>
+#include <vtkObjectFactory.h>
+#include <vtkPolyData.h>
+#include <vtkPolyDataMapper2D.h>
+#include <vtkScalarsToColors.h>
+#include <vtkTextMapper.h>
+#include <vtkTextProperty.h>
+#include <vtkViewport.h>
+#include <vtkWindow.h>
+#include <vtkLookupTable.h>
+#include <vtkProperty2D.h>
+
+#define SHRINK_COEF 0.08;
+
+vtkStandardNewMacro(SMESH_ScalarBarActor);
+
+vtkCxxSetObjectMacro(SMESH_ScalarBarActor,LookupTable,vtkScalarsToColors);
+vtkCxxSetObjectMacro(SMESH_ScalarBarActor,LabelTextProperty,vtkTextProperty);
+vtkCxxSetObjectMacro(SMESH_ScalarBarActor,TitleTextProperty,vtkTextProperty);
+
+//----------------------------------------------------------------------------
+// Instantiate object with 64 maximum colors; 5 labels; %%-#6.3g label
+// format, no title, and vertical orientation. The initial scalar bar
+// size is (0.05 x 0.8) of the viewport size.
+SMESH_ScalarBarActor::SMESH_ScalarBarActor() {
+  this->LookupTable = NULL;
+  this->Position2Coordinate->SetValue(0.17, 0.8);
+  
+  this->PositionCoordinate->SetCoordinateSystemToNormalizedViewport();
+  this->PositionCoordinate->SetValue(0.82,0.1);
+  
+  this->MaximumNumberOfColors = 64;
+  this->NumberOfLabels = 5;
+  this->NumberOfLabelsBuilt = 0;
+  this->Orientation = VTK_ORIENT_VERTICAL;
+  this->Title = NULL;
+
+  this->LabelTextProperty = vtkTextProperty::New();
+  this->LabelTextProperty->SetFontSize(12);
+  this->LabelTextProperty->SetBold(1);
+  this->LabelTextProperty->SetItalic(1);
+  this->LabelTextProperty->SetShadow(1);
+  this->LabelTextProperty->SetFontFamilyToArial();
+
+  this->TitleTextProperty = vtkTextProperty::New();
+  this->TitleTextProperty->ShallowCopy(this->LabelTextProperty);
+
+  this->LabelFormat = new char[8]; 
+  sprintf(this->LabelFormat,"%s","%-#6.3g");
+
+  this->TitleMapper = vtkTextMapper::New();
+  this->TitleActor = vtkActor2D::New();
+  this->TitleActor->SetMapper(this->TitleMapper);
+  this->TitleActor->GetPositionCoordinate()->
+    SetReferenceCoordinate(this->PositionCoordinate);
+  
+  this->TextMappers = NULL;
+  this->TextActors = NULL;
+
+  this->ScalarBar = vtkPolyData::New();
+  this->ScalarBarMapper = vtkPolyDataMapper2D::New();
+  this->ScalarBarMapper->SetInput(this->ScalarBar);
+  this->ScalarBarActor = vtkActor2D::New();
+  this->ScalarBarActor->SetMapper(this->ScalarBarMapper);
+  this->ScalarBarActor->GetPositionCoordinate()->
+    SetReferenceCoordinate(this->PositionCoordinate);
+  this->LastOrigin[0] = 0;
+  this->LastOrigin[1] = 0;
+  this->LastSize[0] = 0;
+  this->LastSize[1] = 0;
+
+
+  // rnv begin
+  // Customization of the vtkScalarBarActor to show distribution histogram.
+  myDistribution = vtkPolyData::New();
+  myDistributionMapper = vtkPolyDataMapper2D::New();
+  myDistributionMapper->SetInput(this->myDistribution);
+  
+  myDistributionActor = vtkActor2D::New();
+  myDistributionActor->SetMapper(this->myDistributionMapper);
+  myDistributionActor->GetPositionCoordinate()->
+    SetReferenceCoordinate(this->PositionCoordinate);
+
+  // By default distribution histogram is invisible
+  myDistributionActor->SetVisibility(0);
+
+  // By default monocolor
+  myDistributionColoringType = SMESH_MONOCOLOR_TYPE;
+  // rnv end
+}
+
+//----------------------------------------------------------------------------
+// Release any graphics resources that are being consumed by this actor.
+// The parameter window could be used to determine which graphic
+// resources to release.
+void SMESH_ScalarBarActor::ReleaseGraphicsResources(vtkWindow *win)
+{
+  this->TitleActor->ReleaseGraphicsResources(win);
+  if (this->TextMappers != NULL )
+    {
+    for (int i=0; i < this->NumberOfLabelsBuilt; i++)
+      {
+      this->TextActors[i]->ReleaseGraphicsResources(win);
+      }
+    }
+  this->ScalarBarActor->ReleaseGraphicsResources(win);
+  // rnv begin
+  // Customization of the vtkScalarBarActor to show distribution histogram.
+  myDistributionActor->ReleaseGraphicsResources(win);
+}
+
+
+/*--------------------------------------------------------------------------*/
+SMESH_ScalarBarActor::~SMESH_ScalarBarActor() {
+  if (this->LabelFormat) 
+    {
+    delete [] this->LabelFormat;
+    this->LabelFormat = NULL;
+    }
+
+  this->TitleMapper->Delete();
+  this->TitleActor->Delete();
+
+  if (this->TextMappers != NULL )
+    {
+    for (int i=0; i < this->NumberOfLabelsBuilt; i++)
+      {
+      this->TextMappers[i]->Delete();
+      this->TextActors[i]->Delete();
+      }
+    delete [] this->TextMappers;
+    delete [] this->TextActors;
+    }
+
+  this->ScalarBar->Delete();
+  this->ScalarBarMapper->Delete();
+  this->ScalarBarActor->Delete();
+
+  if (this->Title)
+    {
+    delete [] this->Title;
+    this->Title = NULL;
+    }
+  
+  this->SetLookupTable(NULL);
+  this->SetLabelTextProperty(NULL);
+  this->SetTitleTextProperty(NULL);
+  
+  // rnv begin
+  // Customization of the vtkScalarBarActor to show distribution histogram:
+  myDistribution->Delete();
+  myDistributionMapper->Delete();
+  myDistributionActor->Delete();
+  // rnv end
+}
+
+//----------------------------------------------------------------------------
+int SMESH_ScalarBarActor::RenderOverlay(vtkViewport *viewport)
+{
+  int renderedSomething = 0;
+  int i;
+  
+  // Everything is built, just have to render
+  if (this->Title != NULL)
+    {
+    renderedSomething += this->TitleActor->RenderOverlay(viewport);
+    }
+  this->ScalarBarActor->RenderOverlay(viewport);
+  this->myDistributionActor->RenderOverlay(viewport);
+  if( this->TextActors == NULL)
+    {
+     vtkWarningMacro(<<"Need a mapper to render a scalar bar");
+     return renderedSomething;
+    }
+  
+  for (i=0; i<this->NumberOfLabels; i++)
+    {
+    renderedSomething += this->TextActors[i]->RenderOverlay(viewport);
+    }
+
+  renderedSomething = (renderedSomething > 0)?(1):(0);
+
+  return renderedSomething;
+}
+
+
+//----------------------------------------------------------------------------
+int SMESH_ScalarBarActor::RenderOpaqueGeometry(vtkViewport *viewport)
+{
+  int renderedSomething = 0;
+  int i;
+  int size[2];
+  
+  if (!this->LookupTable)
+    {
+    vtkWarningMacro(<<"Need a mapper to render a scalar bar");
+    return 0;
+    }
+
+  if (!this->TitleTextProperty)
+    {
+    vtkErrorMacro(<<"Need title text property to render a scalar bar");
+    return 0;
+    }
+
+  if (!this->LabelTextProperty)
+    {
+    vtkErrorMacro(<<"Need label text property to render a scalar bar");
+    return 0;
+    }
+
+  // Check to see whether we have to rebuild everything
+  int positionsHaveChanged = 0;
+  if (viewport->GetMTime() > this->BuildTime || 
+      (viewport->GetVTKWindow() && 
+       viewport->GetVTKWindow()->GetMTime() > this->BuildTime))
+    {
+    // if the viewport has changed we may - or may not need
+    // to rebuild, it depends on if the projected coords chage
+    int *barOrigin;
+    barOrigin = this->PositionCoordinate->GetComputedViewportValue(viewport);
+    size[0] = 
+      this->Position2Coordinate->GetComputedViewportValue(viewport)[0] -
+      barOrigin[0];
+    size[1] = 
+      this->Position2Coordinate->GetComputedViewportValue(viewport)[1] -
+      barOrigin[1];
+    if (this->LastSize[0] != size[0] || 
+        this->LastSize[1] != size[1] ||
+        this->LastOrigin[0] != barOrigin[0] || 
+        this->LastOrigin[1] != barOrigin[1])
+      {
+      positionsHaveChanged = 1;
+      }
+    }
+  
+  // Check to see whether we have to rebuild everything
+  if (positionsHaveChanged ||
+      this->GetMTime() > this->BuildTime || 
+      this->LookupTable->GetMTime() > this->BuildTime ||
+      this->LabelTextProperty->GetMTime() > this->BuildTime ||
+      this->TitleTextProperty->GetMTime() > this->BuildTime)
+    {
+    vtkDebugMacro(<<"Rebuilding subobjects");
+
+    // Delete previously constructed objects
+    //
+    if (this->TextMappers != NULL )
+      {
+      for (i=0; i < this->NumberOfLabelsBuilt; i++)
+        {
+        this->TextMappers[i]->Delete();
+        this->TextActors[i]->Delete();
+        }
+      delete [] this->TextMappers;
+      delete [] this->TextActors;
+      }
+
+    // Build scalar bar object; determine its type
+    //
+    // is this a vtkLookupTable or a subclass of vtkLookupTable 
+    // with its scale set to log
+    // NOTE: it's possible we could to without the 'lut' variable
+    // later in the code, but if the vtkLookupTableSafeDownCast operation
+    // fails for some reason, this code will break in new ways. So, the 'LUT'
+    // variable is used for this operation only
+    vtkLookupTable *LUT = vtkLookupTable::SafeDownCast( this->LookupTable );
+    int isLogTable = 0;
+    if ( LUT )
+      {
+      if ( LUT->GetScale() == VTK_SCALE_LOG10 )
+        {
+        isLogTable = 1; 
+        }
+      }
+    
+    // we hard code how many steps to display
+    vtkScalarsToColors *lut = this->LookupTable;
+    int numColors = this->MaximumNumberOfColors;
+    double *range = lut->GetRange();
+
+    int numPts = 2*(numColors + 1);
+    vtkPoints *pts = vtkPoints::New();
+    pts->SetNumberOfPoints(numPts);
+    vtkCellArray *polys = vtkCellArray::New();
+    polys->Allocate(polys->EstimateSize(numColors,4));
+    vtkUnsignedCharArray *colors = vtkUnsignedCharArray::New();
+    colors->SetNumberOfComponents(3);
+    colors->SetNumberOfTuples(numColors);
+
+
+    // rnv begin
+    // Customization of the vtkScalarBarActor to show distribution histogram.
+    bool distrVisibility =  (numColors == this->myNbValues.size());
+    vtkPoints *distrPts;
+    vtkCellArray *distrPolys;
+    vtkUnsignedCharArray *distColors = 0;
+    int numDistrPts = 0, numPositiveVal=0, maxValue=0;
+    if(!distrVisibility)
+      vtkDebugMacro(<<" Distribution invisible, because numColors == this->myNbValues.size()");
+
+    if (distrVisibility && GetDistributionVisibility()) {
+      for( i=0 ;i<myNbValues.size();i++ ) {
+       if(myNbValues[i]) {
+         numPositiveVal++;
+         maxValue = std::max(maxValue,myNbValues[i]);
+       } 
+      }
+      numDistrPts = 4*(numPositiveVal);
+      distrPts = vtkPoints::New();
+      distrPolys = vtkCellArray::New();
+      distrPts->SetNumberOfPoints(numDistrPts);
+      distrPolys->Allocate(distrPolys->EstimateSize(numPositiveVal,4));
+      this->myDistribution->Initialize();
+      this->myDistribution->SetPoints(distrPts);
+      this->myDistribution->SetPolys(distrPolys);
+      distrPts->Delete();
+      distrPolys->Delete();
+      if ( myDistributionColoringType == SMESH_MULTICOLOR_TYPE ) {
+       distColors = vtkUnsignedCharArray::New();
+       distColors->SetNumberOfComponents(3);
+       distColors->SetNumberOfTuples(numPositiveVal);
+       this->myDistribution->GetCellData()->SetScalars(distColors);
+       distColors->Delete();
+      } else if( myDistributionColoringType == SMESH_MONOCOLOR_TYPE ){
+       this->myDistribution->GetCellData()->SetScalars(NULL);
+      }
+    } else {
+      myDistribution->Reset();
+    }
+    // rnv end
+
+    this->ScalarBarActor->SetProperty(this->GetProperty());
+    this->ScalarBar->Initialize();
+    this->ScalarBar->SetPoints(pts);
+    this->ScalarBar->SetPolys(polys);
+    this->ScalarBar->GetCellData()->SetScalars(colors);
+    pts->Delete(); polys->Delete(); colors->Delete();
+
+    // get the viewport size in display coordinates
+    int *barOrigin, barWidth, barHeight, distrHeight;
+    barOrigin = this->PositionCoordinate->GetComputedViewportValue(viewport);
+    size[0] = 
+      this->Position2Coordinate->GetComputedViewportValue(viewport)[0] -
+      barOrigin[0];
+    size[1] = 
+      this->Position2Coordinate->GetComputedViewportValue(viewport)[1] -
+      barOrigin[1];
+    this->LastOrigin[0] = barOrigin[0];
+    this->LastOrigin[1] = barOrigin[1];
+    this->LastSize[0] = size[0];
+    this->LastSize[1] = size[1];
+    
+    // Update all the composing objects
+    this->TitleActor->SetProperty(this->GetProperty());
+    this->TitleMapper->SetInput(this->Title);
+    if (this->TitleTextProperty->GetMTime() > this->BuildTime)
+      {
+      // Shallow copy here so that the size of the title prop is not affected
+      // by the automatic adjustment of its text mapper's size (i.e. its
+      // mapper's text property is identical except for the font size
+      // which will be modified later). This allows text actors to
+      // share the same text property, and in that case specifically allows
+      // the title and label text prop to be the same.
+      this->TitleMapper->GetTextProperty()->ShallowCopy(this->TitleTextProperty);
+      this->TitleMapper->GetTextProperty()->SetJustificationToCentered();
+      }
+    
+    // find the best size for the title font
+    int titleSize[2];
+    this->SizeTitle(titleSize, size, viewport);
+    
+    // find the best size for the ticks
+    int labelSize[2];
+    this->AllocateAndSizeLabels(labelSize, size, viewport,range);
+    this->NumberOfLabelsBuilt = this->NumberOfLabels;
+    
+    // generate points
+    double x[3]; x[2] = 0.0;
+    double delta, itemH, shrink;
+    if ( this->Orientation == VTK_ORIENT_VERTICAL ) {
+      // rnv begin
+      // Customization of the vtkScalarBarActor to show distribution histogram.
+      double delimeter=0.0;
+      if(GetDistributionVisibility() && distrVisibility) {
+       delimeter=0.01*size[0]; //1 % from horizontal size of the full presentation size.
+       barWidth = size[0] - 4 - labelSize[0];
+       distrHeight = barWidth/2;
+      } else {
+       barWidth = size[0] - 4 - labelSize[0];
+       distrHeight = 0;
+      }
+
+      barHeight = (int)(0.86*size[1]);
+      delta=(double)barHeight/numColors;
+      
+      for ( i=0; i<numPts/2; i++ ) {
+        x[0] = distrHeight+delimeter/2.0;
+        x[1] = i*delta;
+        pts->SetPoint(2*i,x);
+        x[0] = barWidth;
+        pts->SetPoint(2*i+1,x);
+      }
+
+      if(GetDistributionVisibility() && distrVisibility) {
+       // Distribution points 
+       shrink = delta*SHRINK_COEF;
+       vtkIdType distPtsId=0;
+       vtkIdType distPtsIds[4];
+       for(i=0; i<numColors; i++) {
+         if(myNbValues[i]) {
+           itemH = distrHeight*((double)myNbValues[i]/maxValue);
+           
+           if(distrHeight == itemH) 
+             itemH = itemH - delimeter/2;
+
+           x[1] = i*delta+shrink;
+
+           // first point of polygon (quadrangle)
+           x[0] = 0; 
+           distPtsIds[0] = distPtsId;
+           distrPts->SetPoint(distPtsId++,x);
+
+           // second point of polygon (quadrangle)
+           x[0] = itemH;
+           distPtsIds[1] = distPtsId;
+           distrPts->SetPoint(distPtsId++,x);
+
+           x[1] = i*delta+delta-shrink;
+
+           // third point of polygon (quadrangle)
+           x[0] = 0; 
+           distPtsIds[3] = distPtsId;
+           distrPts->SetPoint(distPtsId++,x);
+
+           // fourth point of polygon (quadrangle)
+           x[0] = itemH;
+           distPtsIds[2] = distPtsId;
+           distrPts->SetPoint(distPtsId++,x);
+
+           //Inser Quadrangle
+           distrPolys->InsertNextCell(4,distPtsIds);
+         }
+       }
+      }    
+    }
+    // rnv end
+    else {
+      barWidth = size[0];
+      
+      // rnv begin
+      // Customization of the vtkScalarBarActor to show distribution histogram.
+      double coef1, delimeter=0.0;
+      if(GetDistributionVisibility() && distrVisibility) {
+       coef1=0.62;
+       distrHeight = (int)((coef1/2)*size[1]);
+       //delimeter between distribution diagram and scalar bar 
+       delimeter=0.02*size[1];
+      }
+      else {
+       coef1=0.4;
+       barHeight = (int)(coef1*size[1]);
+       distrHeight = 0;
+      }
+      
+      barHeight = (int)(coef1*size[1]);
+      
+      delta=(double)barWidth/numColors;
+      for (i=0; i<numPts/2; i++) {
+        x[0] = i*delta;
+        x[1] = barHeight;
+        pts->SetPoint(2*i,x);                       
+        x[1] = distrHeight + delimeter;
+        pts->SetPoint(2*i+1,x);
+      }
+      
+      if(GetDistributionVisibility() && distrVisibility) {
+       // Distribution points 
+       shrink = delta*SHRINK_COEF;
+       vtkIdType distPtsId=0;
+       vtkIdType distPtsIds[4];
+       for(i=0; i<numColors; i++) {
+         if(myNbValues[i]) {
+           itemH = distrHeight*((double)myNbValues[i]/maxValue);
+           
+           // first point of polygon (quadrangle)
+           x[0] = i*delta+shrink; 
+           x[1] = 0;
+           distPtsIds[0] = distPtsId;
+           distrPts->SetPoint(distPtsId++,x);
+           
+           // second point of polygon (quadrangle)
+           x[0] = i*delta+shrink; 
+           x[1] = itemH;
+           distPtsIds[3] = distPtsId;
+           distrPts->SetPoint(distPtsId++,x);
+           
+           // third point of polygon (quadrangle)
+           x[0] = i*delta+delta-shrink; 
+           x[1] = 0;
+           distPtsIds[1] = distPtsId;
+           distrPts->SetPoint(distPtsId++,x);
+           
+           // fourth point of polygon (quadrangle)
+           x[0] = i*delta+delta-shrink; 
+           x[1] = itemH;
+           distPtsIds[2] = distPtsId;
+           distrPts->SetPoint(distPtsId++,x);
+           
+           // Add polygon into poly data
+           distrPolys->InsertNextCell(4,distPtsIds);
+         }
+       } 
+      }
+      // rnv end
+    }
+    
+    //polygons & cell colors
+    unsigned char *rgba, *rgb;
+    vtkIdType ptIds[4], dcCount=0;
+    for (i=0; i<numColors; i++)
+      {
+      ptIds[0] = 2*i;
+      ptIds[1] = ptIds[0] + 1;
+      ptIds[2] = ptIds[1] + 2;
+      ptIds[3] = ptIds[0] + 2;
+      polys->InsertNextCell(4,ptIds);
+
+      if ( isLogTable )
+        {
+        double rgbval = log10(range[0]) + 
+          i*(log10(range[1])-log10(range[0]))/(numColors -1);
+        rgba = lut->MapValue(pow(10.0,rgbval));
+        }
+      else
+        {
+        rgba = lut->MapValue(range[0] + (range[1] - range[0])*
+                             ((double)i /(numColors-1.0)));
+        }
+
+      rgb = colors->GetPointer(3*i); //write into array directly
+      rgb[0] = rgba[0];
+      rgb[1] = rgba[1];
+      rgb[2] = rgba[2];
+      
+      // rnv begin
+      // Customization of the vtkScalarBarActor to show distribution histogram.
+      if(myNbValues[i] && myDistributionColoringType == SMESH_MULTICOLOR_TYPE && GetDistributionVisibility() && distrVisibility)
+       {
+         rgb = distColors->GetPointer(3*dcCount); //write into array directly
+         rgb[0] = rgba[0];
+         rgb[1] = rgba[1];
+         rgb[2] = rgba[2];
+         dcCount++;
+       }
+      }
+
+    // Now position everything properly
+    //
+    double val;
+    if (this->Orientation == VTK_ORIENT_VERTICAL)
+      {
+      int sizeTextData[2];
+      
+      // center the title
+      this->TitleActor->SetPosition(size[0]/2, 0.9*size[1]);
+      
+      for (i=0; i < this->NumberOfLabels; i++)
+        {
+        if (this->NumberOfLabels > 1)
+          {
+          val = (double)i/(this->NumberOfLabels-1) *barHeight;
+          }
+        else 
+          {
+          val = 0.5*barHeight;
+          }
+        this->TextMappers[i]->GetSize(viewport,sizeTextData);
+        this->TextMappers[i]->GetTextProperty()->SetJustificationToLeft();
+        this->TextActors[i]->SetPosition(barWidth+3,
+                                         val - sizeTextData[1]/2);
+        }
+      }
+    else
+      {
+      this->TitleActor->SetPosition(size[0]/2, 
+                                    barHeight + labelSize[1] + 0.1*size[1]);
+      for (i=0; i < this->NumberOfLabels; i++)
+        {
+        this->TextMappers[i]->GetTextProperty()->SetJustificationToCentered();
+        if (this->NumberOfLabels > 1)
+          {
+          val = (double)i/(this->NumberOfLabels-1) * barWidth;
+          }
+        else
+          {
+          val = 0.5*barWidth;
+          }
+        this->TextActors[i]->SetPosition(val, barHeight + 0.05*size[1]);
+        }
+      }
+
+    this->BuildTime.Modified();
+    }
+
+  // Everything is built, just have to render
+  if (this->Title != NULL)
+    {
+    renderedSomething += this->TitleActor->RenderOpaqueGeometry(viewport);
+    }
+  this->ScalarBarActor->RenderOpaqueGeometry(viewport);
+  this->myDistributionActor->RenderOpaqueGeometry(viewport);
+  for (i=0; i<this->NumberOfLabels; i++)
+    {
+    renderedSomething += this->TextActors[i]->RenderOpaqueGeometry(viewport);
+    }
+
+  renderedSomething = (renderedSomething > 0)?(1):(0);
+
+  return renderedSomething;
+}
+
+//----------------------------------------------------------------------------
+void SMESH_ScalarBarActor::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os,indent);
+
+  if ( this->LookupTable )
+    {
+    os << indent << "Lookup Table:\n";
+    this->LookupTable->PrintSelf(os,indent.GetNextIndent());
+    }
+  else
+    {
+    os << indent << "Lookup Table: (none)\n";
+    }
+
+  if (this->TitleTextProperty)
+    {
+    os << indent << "Title Text Property:\n";
+    this->TitleTextProperty->PrintSelf(os,indent.GetNextIndent());
+    }
+  else
+    {
+    os << indent << "Title Text Property: (none)\n";
+    }
+
+  if (this->LabelTextProperty)
+    {
+    os << indent << "Label Text Property:\n";
+    this->LabelTextProperty->PrintSelf(os,indent.GetNextIndent());
+    }
+  else
+    {
+    os << indent << "Label Text Property: (none)\n";
+    }
+
+  os << indent << "Title: " << (this->Title ? this->Title : "(none)") << "\n";
+  os << indent << "Maximum Number Of Colors: " 
+     << this->MaximumNumberOfColors << "\n";
+  os << indent << "Number Of Labels: " << this->NumberOfLabels << "\n";
+  os << indent << "Number Of Labels Built: " << this->NumberOfLabelsBuilt << "\n";
+
+  os << indent << "Orientation: ";
+  if ( this->Orientation == VTK_ORIENT_HORIZONTAL )
+    {
+    os << "Horizontal\n";
+    }
+  else
+    {
+    os << "Vertical\n";
+    }
+
+  os << indent << "Label Format: " << this->LabelFormat << "\n";
+}
+
+//----------------------------------------------------------------------------
+void SMESH_ScalarBarActor::ShallowCopy(vtkProp *prop)
+{
+  SMESH_ScalarBarActor *a = SMESH_ScalarBarActor::SafeDownCast(prop);
+  if ( a != NULL )
+    {
+    this->SetPosition2(a->GetPosition2());
+    this->SetLookupTable(a->GetLookupTable());
+    this->SetMaximumNumberOfColors(a->GetMaximumNumberOfColors());
+    this->SetOrientation(a->GetOrientation());
+    this->SetLabelTextProperty(a->GetLabelTextProperty());
+    this->SetTitleTextProperty(a->GetTitleTextProperty());
+    this->SetLabelFormat(a->GetLabelFormat());
+    this->SetTitle(a->GetTitle());
+    this->GetPositionCoordinate()->SetCoordinateSystem(
+      a->GetPositionCoordinate()->GetCoordinateSystem());    
+    this->GetPositionCoordinate()->SetValue(
+      a->GetPositionCoordinate()->GetValue());
+    this->GetPosition2Coordinate()->SetCoordinateSystem(
+      a->GetPosition2Coordinate()->GetCoordinateSystem());    
+    this->GetPosition2Coordinate()->SetValue(
+      a->GetPosition2Coordinate()->GetValue());
+    }
+
+  // Now do superclass
+  this->vtkActor2D::ShallowCopy(prop);
+}
+
+//----------------------------------------------------------------------------
+void SMESH_ScalarBarActor::AllocateAndSizeLabels(int *labelSize, 
+                                              int *size,
+                                              vtkViewport *viewport,
+                                              double *range)
+{
+  labelSize[0] = labelSize[1] = 0;
+
+  this->TextMappers = new vtkTextMapper * [this->NumberOfLabels];
+  this->TextActors = new vtkActor2D * [this->NumberOfLabels];
+
+  char string[512];
+
+  double val;
+  int i;
+  
+  // TODO: this should be optimized, maybe by keeping a list of
+  // allocated mappers, in order to avoid creation/destruction of
+  // their underlying text properties (i.e. each time a mapper is
+  // created, text properties are created and shallow-assigned a font size
+  // which value might be "far" from the target font size).
+
+  // is this a vtkLookupTable or a subclass of vtkLookupTable 
+  // with its scale set to log
+  vtkLookupTable *LUT = vtkLookupTable::SafeDownCast( this->LookupTable );
+  int isLogTable = 0;
+  if ( LUT )
+    {
+    if ( LUT->GetScale() == VTK_SCALE_LOG10 )
+      {
+      isLogTable = 1; 
+      }
+    }
+
+  for (i=0; i < this->NumberOfLabels; i++)
+    {
+    this->TextMappers[i] = vtkTextMapper::New();
+
+    if ( isLogTable )
+      {
+      double lval;
+      if (this->NumberOfLabels > 1)
+        {
+        lval = log10(range[0]) + (double)i/(this->NumberOfLabels-1) *
+          (log10(range[1])-log10(range[0]));
+        }
+      else
+        {
+        lval = log10(range[0]) + 0.5*(log10(range[1])-log10(range[0]));
+        }
+      val = pow(10.0,lval);
+      }
+    else
+      {
+      if (this->NumberOfLabels > 1)
+        {
+        val = range[0] + 
+          (double)i/(this->NumberOfLabels-1) * (range[1]-range[0]);
+        }
+      else
+        {
+        val = range[0] + 0.5*(range[1]-range[0]);
+        }
+      }
+
+    sprintf(string, this->LabelFormat, val);
+    this->TextMappers[i]->SetInput(string);
+
+    // Shallow copy here so that the size of the label prop is not affected
+    // by the automatic adjustment of its text mapper's size (i.e. its
+    // mapper's text property is identical except for the font size
+    // which will be modified later). This allows text actors to
+    // share the same text property, and in that case specifically allows
+    // the title and label text prop to be the same.
+    this->TextMappers[i]->GetTextProperty()->ShallowCopy(
+      this->LabelTextProperty);
+
+    this->TextActors[i] = vtkActor2D::New();
+    this->TextActors[i]->SetMapper(this->TextMappers[i]);
+    this->TextActors[i]->SetProperty(this->GetProperty());
+    this->TextActors[i]->GetPositionCoordinate()->
+      SetReferenceCoordinate(this->PositionCoordinate);
+    }
+
+  if (this->NumberOfLabels)
+    {
+    int targetWidth, targetHeight;
+    // rnv begin
+    // Customization of the vtkScalarBarActor to show distribution histogram.
+    bool distrVisibility = this->MaximumNumberOfColors == this->myNbValues.size();
+    double coef;
+    if( GetDistributionVisibility() && distrVisibility )
+      if(this->Orientation == VTK_ORIENT_VERTICAL)
+       coef = 0.4;
+      else 
+       coef = 0.18;
+    else 
+      if(this->Orientation == VTK_ORIENT_VERTICAL)
+       coef = 0.6;
+      else 
+       coef=0.25;
+
+
+    if ( this->Orientation == VTK_ORIENT_VERTICAL )
+      {
+      targetWidth = (int)(coef*size[0]);
+      targetHeight = (int)(0.86*size[1]/this->NumberOfLabels);
+      }
+    else
+      {
+      targetWidth = (int)(size[0]*0.8/this->NumberOfLabels);
+      targetHeight = (int)(coef*size[1]);
+      }
+    // rnv end
+    
+    vtkTextMapper::SetMultipleConstrainedFontSize(viewport, 
+                                                  targetWidth, 
+                                                  targetHeight,
+                                                  this->TextMappers,
+                                                  this->NumberOfLabels,
+                                                  labelSize);
+    }
+}
+
+//----------------------------------------------------------------------------
+void SMESH_ScalarBarActor::SizeTitle(int *titleSize, 
+                                  int *size, 
+                                  vtkViewport *viewport)
+{
+  titleSize[0] = titleSize[1] = 0;
+
+  if (this->Title == NULL || !strlen(this->Title))
+    {
+    return;
+    }
+
+  int targetWidth, targetHeight;
+  
+  targetWidth = size[0];
+  // rnv begin
+  // Customization of the vtkScalarBarActor to show distribution histogram.
+  bool distrVisibility =  this->MaximumNumberOfColors == this->myNbValues.size();
+  double coef;
+  if( GetDistributionVisibility() && distrVisibility ) 
+    coef=0.18;
+  else 
+    coef=0.25;
+
+  if ( this->Orientation == VTK_ORIENT_VERTICAL )
+    {
+      targetHeight = (int)(0.1*size[1]);
+    }
+  else
+    {
+      targetHeight = (int)(coef*size[1]);
+    }
+
+  this->TitleMapper->SetConstrainedFontSize(
+    viewport, targetWidth, targetHeight);
+
+  this->TitleMapper->GetSize(viewport, titleSize);
+}
+
+
+/*--------------------------------------------------------------------------*/
+void SMESH_ScalarBarActor::SetDistributionVisibility(int flag) {
+  myDistributionActor->SetVisibility(flag);
+  Modified();
+}
+
+
+/*--------------------------------------------------------------------------*/
+int SMESH_ScalarBarActor::GetDistributionVisibility() {
+  return myDistributionActor->GetVisibility();
+}
+
+
+void SMESH_ScalarBarActor::SetDistribution(std::vector<int> theNbValues) {
+  myNbValues = theNbValues;
+} 
+
+
+void SMESH_ScalarBarActor::SetDistributionColor (double rgb[3]) {
+  myDistributionActor->GetProperty()->SetColor(rgb);
+  Modified();
+}
+
+void SMESH_ScalarBarActor::GetDistributionColor (double rgb[3]) {
+  myDistributionActor->GetProperty()->GetColor(rgb);
+}
diff --git a/src/OBJECT/SMESH_ScalarBarActor.h b/src/OBJECT/SMESH_ScalarBarActor.h
new file mode 100644 (file)
index 0000000..0f895cd
--- /dev/null
@@ -0,0 +1,246 @@
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+//  SMESH SCALAR BAR : 2D Actor for the visualization scalar bar with the distribution diagram
+//                     it is customized vtkScalarBarActor.
+//  File   : SMESH_ScalarBarActor.h
+//  Author : Roman NIKOLAEV
+//  Module : SMESH
+
+
+// .NAME vtkScalarBarActor - Create a scalar bar with labels 
+// .SECTION Description
+// vtkScalarBarActor creates a scalar bar with annotation text. A scalar
+// bar is a legend that indicates to the viewer the correspondence between
+// color value and data value. The legend consists of a rectangular bar 
+// made of rectangular pieces each colored a constant value. Since 
+// vtkScalarBarActor is a subclass of vtkActor2D, it is drawn in the image 
+// plane (i.e., in the renderer's viewport) on top of the 3D graphics window.
+//
+// To use vtkScalarBarActor you must associate a vtkScalarsToColors (or
+// subclass) with it. The lookup table defines the colors and the
+// range of scalar values used to map scalar data.  Typically, the
+// number of colors shown in the scalar bar is not equal to the number
+// of colors in the lookup table, in which case sampling of
+// the lookup table is performed. 
+//
+// Other optional capabilities include specifying the fraction of the
+// viewport size (both x and y directions) which will control the size
+// of the scalar bar and the number of annotation labels. The actual position
+// of the scalar bar on the screen is controlled by using the
+// vtkActor2D::SetPosition() method (by default the scalar bar is
+// centered in the viewport).  Other features include the ability to
+// orient the scalar bar horizontally of vertically and controlling
+// the format (printf style) with which to print the labels on the
+// scalar bar. Also, the vtkScalarBarActor's property is applied to
+// the scalar bar and annotation (including layer, and
+// compositing operator).
+//
+// Set the text property/attributes of the title and the labels through the 
+// vtkTextProperty objects associated to this actor.
+//
+// .SECTION Caveats
+// If a vtkLogLookupTable is specified as the lookup table to use, then the
+// labels are created using a logarithmic scale.
+//
+// .SECTION See Also
+// vtkActor2D vtkTextProperty vtkTextMapper vtkPolyDataMapper2D
+
+#ifndef SMESH_SCALAR_BAR_ACTOR_H
+#define SMESH_SCALAR_BAR_ACTOR_H
+
+#include <vtkActor2D.h>
+
+#include <SMESH_Object.h>
+
+#include <vector>
+
+class vtkPolyData;
+class vtkPolyDataMapper2D;
+class vtkScalarsToColors;
+class vtkTextMapper;
+class vtkTextProperty;
+
+#define VTK_ORIENT_HORIZONTAL 0
+#define VTK_ORIENT_VERTICAL 1
+
+#define SMESH_MONOCOLOR_TYPE 0
+#define SMESH_MULTICOLOR_TYPE 1
+
+
+class SMESHOBJECT_EXPORT SMESH_ScalarBarActor: public vtkActor2D {
+ public:
+  void PrintSelf(ostream& os, vtkIndent indent);
+
+  vtkTypeMacro(SMESH_ScalarBarActor,vtkActor2D);
+
+  // Description:
+  // Instantiate object with 64 maximum colors; 5 labels; %%-#6.3g label
+  // format, no title, and vertical orientation. The initial scalar bar
+  // size is (0.05 x 0.8) of the viewport size.
+  static SMESH_ScalarBarActor *New();
+
+  // Description:
+  // Draw the scalar bar and annotation text to the screen.
+  int RenderOpaqueGeometry(vtkViewport* viewport);
+  int RenderTranslucentGeometry(vtkViewport*) { return 0; };
+  int RenderOverlay(vtkViewport* viewport);
+
+  // Description:
+  // Release any graphics resources that are being consumed by this actor.
+  // The parameter window could be used to determine which graphic
+  // resources to release.
+  virtual void ReleaseGraphicsResources(vtkWindow *);
+
+  // Description:
+  // Set/Get the vtkLookupTable to use. The lookup table specifies the number
+  // of colors to use in the table (if not overridden), as well as the scalar
+  // range.
+  virtual void SetLookupTable(vtkScalarsToColors*);
+  vtkGetObjectMacro(LookupTable,vtkScalarsToColors);
+
+  // Description:
+  // Set/Get the maximum number of scalar bar segments to show. This may
+  // differ from the number of colors in the lookup table, in which case
+  // the colors are samples from the lookup table.
+  vtkSetClampMacro(MaximumNumberOfColors, int, 2, VTK_LARGE_INTEGER);
+  vtkGetMacro(MaximumNumberOfColors, int);
+  
+  // Description:
+  // Set/Get the number of annotation labels to show.
+  vtkSetClampMacro(NumberOfLabels, int, 0, 64);
+  vtkGetMacro(NumberOfLabels, int);
+  
+  // Description:
+  // Control the orientation of the scalar bar.
+  vtkSetClampMacro(Orientation,int,VTK_ORIENT_HORIZONTAL, VTK_ORIENT_VERTICAL);
+  vtkGetMacro(Orientation, int);
+  void SetOrientationToHorizontal()
+       {this->SetOrientation(VTK_ORIENT_HORIZONTAL);};
+  void SetOrientationToVertical() {this->SetOrientation(VTK_ORIENT_VERTICAL);};
+
+  // Description:
+  // Set/Get the title text property.
+  virtual void SetTitleTextProperty(vtkTextProperty *p);
+  vtkGetObjectMacro(TitleTextProperty,vtkTextProperty);
+  
+  // Description:
+  // Set/Get the labels text property.
+  virtual void SetLabelTextProperty(vtkTextProperty *p);
+  vtkGetObjectMacro(LabelTextProperty,vtkTextProperty);
+    
+  // Description:
+  // Set/Get the format with which to print the labels on the scalar
+  // bar.
+  vtkSetStringMacro(LabelFormat);
+  vtkGetStringMacro(LabelFormat);
+
+  // Description:
+  // Set/Get the title of the scalar bar actor,
+  vtkSetStringMacro(Title);
+  vtkGetStringMacro(Title);
+
+  // Description:
+  // Shallow copy of a scalar bar actor. Overloads the virtual vtkProp method.
+  void ShallowCopy(vtkProp *prop);
+
+  // Description:
+  // Set visibility of the distribution histogram
+  // rnv: Customization of the vtkScalarBarActor to show distribution histogram:
+  virtual void SetDistributionVisibility(int flag);
+
+  // Description:
+  // Set visibility of the distribution histogram
+  // rnv: Customization of the vtkScalarBarActor to show distribution histogram:
+  virtual int GetDistributionVisibility();
+  // Description:
+  // Set distribution
+  virtual void SetDistribution(std::vector<int> theNbValues);
+  
+  // Description: 
+  // Set distribution coloring type (SMESH_MONOCOLOR_TYPE or SMESH_MULTICOLOR_TYPE)
+  void SetDistributionColoringType(int theDistributionColoringType) {myDistributionColoringType = theDistributionColoringType;Modified();}
+
+  // Description: 
+  // Get distribution coloring type ((SMESH_MONOCOLOR_TYPE or SMESH_MULTICOLOR_TYPE))  
+  int GetDistributionColoringType() {return myDistributionColoringType;}
+
+  // Description:
+  // Set Distribution Color
+  void SetDistributionColor (double rgb[3]);
+
+  // Description:
+  // Get Distribution Color
+  void GetDistributionColor (double rgb[3]);
+  
+
+
+ protected:
+  SMESH_ScalarBarActor();
+  ~SMESH_ScalarBarActor();
+  
+  vtkScalarsToColors *LookupTable;
+  vtkTextProperty *TitleTextProperty;
+  vtkTextProperty *LabelTextProperty;
+  
+  int   MaximumNumberOfColors;
+  int   NumberOfLabels;
+  int   NumberOfLabelsBuilt;
+  int   Orientation;
+  char  *Title;
+  char  *LabelFormat;
+
+  vtkTextMapper **TextMappers;
+  virtual void AllocateAndSizeLabels(int *labelSize, int *size,
+                                     vtkViewport *viewport, double *range);
+
+  
+  
+ private:
+  vtkTextMapper *TitleMapper;
+  vtkActor2D    *TitleActor;
+
+  vtkActor2D    **TextActors;
+
+  vtkPolyData         *ScalarBar;
+  vtkPolyDataMapper2D *ScalarBarMapper;
+  vtkActor2D          *ScalarBarActor;
+
+  vtkTimeStamp  BuildTime;
+  int LastSize[2];
+  int LastOrigin[2];
+
+  void SizeTitle(int *titleSize, int *size, vtkViewport *viewport);
+  
+  // rnv: Customization of the vtkScalarBarActor to show distribution histogram:
+  vtkPolyData*           myDistribution;             //Distribution polygonal data
+  vtkActor2D*            myDistributionActor;        //Distribution actor
+  vtkPolyDataMapper2D*   myDistributionMapper;       //Distribution mapper
+  std::vector<int>       myNbValues;                 //Nb values for the range
+  int                    myDistributionColoringType; //Distribution color type (monocolor or multicolor)
+  
+ private:
+  SMESH_ScalarBarActor(const SMESH_ScalarBarActor&);  // Not implemented.
+  void operator=(const SMESH_ScalarBarActor&);  // Not implemented.
+};
+
+#endif //SMESH_SCALAR_BAR_ACTOR_H
index 938abf0b260c0be2cc922b9d0d0e911c1fe8f697..593b7fe00c39deb1a7acd38bd5689fd4788e2e70 100644 (file)
@@ -69,7 +69,7 @@ public:
 
   ///Return the type of the current element
   virtual SMDSAbs_ElementType GetType() const = 0;
-  virtual bool IsPoly() const { return false; };
+  virtual bool IsPoly() const { return false; }
   virtual bool IsQuadratic() const;
   //! Return type of entity
   virtual SMDSAbs_EntityType  GetEntityType() const = 0;
index 03c0b7bdb11542d853733c945bbb981123288395..83b34c3a9d74c1a05cf3bcb050730581114b81ba 100644 (file)
@@ -86,14 +86,14 @@ public:
   /*!
    * \brief Saves nothing in a stream
     * \param save - the stream
-    * \retval virtual std::ostream & - the stream
+    * \retval std::ostream & - the stream
    */
   virtual std::ostream & SaveTo(std::ostream & save);
 
   /*!
    * \brief Loads nothing from a stream
     * \param load - the stream
-    * \retval virtual std::ostream & - the stream
+    * \retval std::ostream & - the stream
    */
   virtual std::istream & LoadFrom(std::istream & load);
 
@@ -236,7 +236,7 @@ public:
    *
    * This method is called when a submesh gets HYP_OK algo_state.
    * After being set, event listener is notified on each event of a submesh.
-   * By default non listener is set
+   * By default none listener is set
    */
   virtual void SetEventListener(SMESH_subMesh* subMesh);
   
@@ -323,7 +323,8 @@ public:
    */
   static std::vector< const SMDS_MeshNode*> GetCommonNodes(const SMDS_MeshElement* e1,
                                                            const SMDS_MeshElement* e2);
-protected:
+
+ protected:
 
   /*!
    * \brief store error and comment and then return ( error == COMPERR_OK )
index 4d88aed630d72a3612d6dea12b2b1412cb0620a5..b2f5a125d0d9c81a0c11459bd64e8b74f2341638 100644 (file)
@@ -63,5 +63,5 @@ SMESH_Group::SMESH_Group (int                       theID,
 
 SMESH_Group::~SMESH_Group ()
 {
-  delete myGroupDS;
+  delete myGroupDS; myGroupDS=0;
 }
index 8d942bce4a79a3d5247ed8e2761e86d9bd9d35ed..c3e62ad2aef219c0b8408e656a4fe6c97cedf386 100644 (file)
@@ -24,7 +24,6 @@
 //  File   : SMESH_Group.hxx
 //  Author : Michael Sazonov (OCC)
 //  Module : SMESH
-//  $Header$
 //
 #ifndef _SMESH_Group_HeaderFile
 #define _SMESH_Group_HeaderFile
index c2ad8b75370c1e4f3515d4dd4769604d4ef0dbf6..e7c7c274bc0de6f6a8b61969fc7045d78d04e348 100644 (file)
@@ -77,6 +77,8 @@ class SMESH_EXPORT SMESH_HypoFilter: public SMESH_HypoPredicate
   static SMESH_HypoPredicate* HasDim(const int theDim);
   static SMESH_HypoPredicate* HasType(const int theHypType);
 
+  bool IsEmpty() const { return myPredicates.empty(); }
+
   /*!
    * \brief check aHyp or/and aShape it is assigned to
    */
index 8210f156d498f34e1334d1e9c44f9450aea8a4de..9ababf9e424017ac86b4ac398eacf5bb30f552cb 100644 (file)
@@ -151,6 +151,24 @@ void SMESH_Hypothesis::SetLibName(const char* theLibName)
   _libName = string(theLibName);
 }
 
+//=======================================================================
+//function : GetMeshByPersistentID
+//purpose  : Find a mesh with given persistent ID
+//=======================================================================
+
+SMESH_Mesh* SMESH_Hypothesis::GetMeshByPersistentID(int id)
+{
+  StudyContextStruct* myStudyContext = _gen->GetStudyContext(_studyId);
+  map<int, SMESH_Mesh*>::iterator itm = itm = myStudyContext->mapMesh.begin();
+  for ( ; itm != myStudyContext->mapMesh.end(); itm++)
+  {
+    SMESH_Mesh* mesh = (*itm).second;
+    if ( mesh->GetMeshDS()->GetPersistentId() == id )
+      return mesh;
+  }
+  return 0;
+}
+
 //=============================================================================
 /*!
  * 
index 1eb5ae8c85bc733c59e30084b0b6f57d38439c06..82afd4bbcb7327781e0b057c99ea1a6ca5564e28 100644 (file)
@@ -114,6 +114,11 @@ public:
   virtual bool IsAuxiliary() const
   { return GetType() == PARAM_ALGO && _param_algo_dim < 0; }
 
+  /*!
+   * \brief Find a mesh with given persistent ID
+   */
+  SMESH_Mesh* GetMeshByPersistentID(int id);
+
 protected:
   SMESH_Gen* _gen;
   int _studyId;
index d7fb290db1224f5120d5897d6407493b346e83bf..39c2ca9762d8e6ce72a8ce054edef8dc5d140cfa 100644 (file)
@@ -101,6 +101,7 @@ SMESH_Mesh::SMESH_Mesh(int               theLocalId,
   _isAutoColor   = false;
   _isModified    = false;
   _shapeDiagonal = 0.0;
+  _rmGroupCallUp = 0;
   _myMeshDS->ShapeToMesh( PseudoShape() );
 }
 
@@ -126,6 +127,9 @@ SMESH_Mesh::~SMESH_Mesh()
     delete aGroup;
   }
   _mapGroup.clear();
+
+  if ( _rmGroupCallUp) delete _rmGroupCallUp;
+  _rmGroupCallUp = 0;
 }
 
 //=============================================================================
@@ -267,6 +271,7 @@ void SMESH_Mesh::Clear()
     while ( smIt->more() ) {
       sm = smIt->next();
       sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
+      sm->ComputeStateEngine( SMESH_subMesh::CLEAN ); // for event listeners (issue 0020918)
     }
   }
   _isModified = false;
@@ -973,7 +978,7 @@ void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* h
       }
     }
   }
-  HasModificationsToDiscard(); // to reset _isModified flag if mesh become empty
+  HasModificationsToDiscard(); // to reset _isModified flag if mesh becomes empty
 }
 
 //=============================================================================
@@ -1413,6 +1418,18 @@ list<int> SMESH_Mesh::GetGroupIds() const
   return anIds;
 }
 
+//================================================================================
+/*!
+ * \brief Set a caller of RemoveGroup() at level of CORBA API implementation.
+ * The set upCaller will be deleted by SMESH_Mesh
+ */
+//================================================================================
+
+void SMESH_Mesh::SetRemoveGroupCallUp( TRmGroupCallUp* upCaller )
+{
+  if ( _rmGroupCallUp ) delete _rmGroupCallUp;
+  _rmGroupCallUp = upCaller;
+}
 
 //=============================================================================
 /*!
@@ -1420,13 +1437,16 @@ list<int> SMESH_Mesh::GetGroupIds() const
  */
 //=============================================================================
 
-void SMESH_Mesh::RemoveGroup (const int theGroupID)
+bool SMESH_Mesh::RemoveGroup (const int theGroupID)
 {
   if (_mapGroup.find(theGroupID) == _mapGroup.end())
-    return;
+    return false;
   GetMeshDS()->RemoveGroup( _mapGroup[theGroupID]->GetGroupDS() );
   delete _mapGroup[theGroupID];
   _mapGroup.erase (theGroupID);
+  if (_rmGroupCallUp)
+    _rmGroupCallUp->RemoveGroup( theGroupID );
+  return true;
 }
 
 //=======================================================================
index ac504ced6405f0ef75833629368cb9a48b016531..c88bbd02dee23a2066f6df93a5f3c08c8417a493 100644 (file)
@@ -141,12 +141,14 @@ public:
   
   void ClearLog() throw(SALOME_Exception);
   
-  int GetId()                { return _id; }
+  int GetId() const          { return _id; }
   
   SMESHDS_Mesh * GetMeshDS() { return _myMeshDS; }
   
-  SMESH_Gen *GetGen()        { return _gen; }
+  const SMESHDS_Mesh * GetMeshDS() const { return _myMeshDS; }
   
+  SMESH_Gen *GetGen()        { return _gen; }
+
   SMESH_subMesh *GetSubMesh(const TopoDS_Shape & aSubShape)
     throw(SALOME_Exception);
   
@@ -266,10 +268,18 @@ public:
   
   SMESH_Group* GetGroup (const int theGroupID);
 
-  void RemoveGroup (const int theGroupID);
+  bool RemoveGroup (const int theGroupID);
 
   SMESH_Group* ConvertToStandalone ( int theGroupID );
 
+  struct TRmGroupCallUp
+  {
+    virtual void RemoveGroup (const int theGroupID)=0;
+    virtual ~TRmGroupCallUp() {}
+  };
+  void SetRemoveGroupCallUp( TRmGroupCallUp * upCaller );
+
+
   SMDSAbs_ElementType GetElementType( const int id, const bool iselem );
 
   void ClearMeshOrder();
@@ -303,9 +313,9 @@ protected:
   std::list <SMESH_subMesh*> _subMeshesUsingHypothesisList;
   SMESHDS_Document *         _myDocument;
   SMESHDS_Mesh *             _myMeshDS;
+  SMESH_Gen *                _gen;
   std::map <int, SMESH_subMesh*> _mapSubMesh;
   std::map <int, SMESH_Group*>   _mapGroup;
-  SMESH_Gen *                _gen;
   
   bool                       _isAutoColor;
   bool                       _isModified; //!< modified since last total re-compute, issue 0020693
@@ -316,6 +326,11 @@ protected:
 
   TListOfListOfInt           _mySubMeshOrder;
 
+  // Struct calling RemoveGroup at CORBA API implementation level, used
+  // to make an upper level be consistent with a lower one when group removal
+  // is invoked by hyp modification 
+  TRmGroupCallUp*            _rmGroupCallUp;
+
 protected:
   SMESH_Mesh() {};
   SMESH_Mesh(const SMESH_Mesh&) {};
index b695e1276a5be8fc8310f060e75eaec3f694ba97..bb96f035229472f6a3ae3f2dcf88043e988ffb45 100644 (file)
@@ -89,9 +89,16 @@ SMESH_MesherHelper::SMESH_MesherHelper(SMESH_Mesh& theMesh)
 
 SMESH_MesherHelper::~SMESH_MesherHelper()
 {
-  TID2Projector::iterator i_proj = myFace2Projector.begin();
-  for ( ; i_proj != myFace2Projector.end(); ++i_proj )
-    delete i_proj->second;
+  {
+    TID2ProjectorOnSurf::iterator i_proj = myFace2Projector.begin();
+    for ( ; i_proj != myFace2Projector.end(); ++i_proj )
+      delete i_proj->second;
+  }
+  {
+    TID2ProjectorOnCurve::iterator i_proj = myEdge2Projector.begin();
+    for ( ; i_proj != myEdge2Projector.end(); ++i_proj )
+      delete i_proj->second;
+  }
 }
 
 //=======================================================================
@@ -517,8 +524,8 @@ GeomAPI_ProjectPointOnSurf& SMESH_MesherHelper::GetProjector(const TopoDS_Face&
 {
   Handle(Geom_Surface) surface = BRep_Tool::Surface( F,loc );
   int faceID = GetMeshDS()->ShapeToIndex( F );
-  TID2Projector& i2proj = const_cast< TID2Projector&>( myFace2Projector );
-  TID2Projector::iterator i_proj = i2proj.find( faceID );
+  TID2ProjectorOnSurf& i2proj = const_cast< TID2ProjectorOnSurf&>( myFace2Projector );
+  TID2ProjectorOnSurf::iterator i_proj = i2proj.find( faceID );
   if ( i_proj == i2proj.end() )
   {
     if ( tol == 0 ) tol = BRep_Tool::Tolerance( F );
@@ -672,13 +679,23 @@ bool SMESH_MesherHelper::CheckNodeU(const TopoDS_Edge&   E,
       if ( dist > tol )
       {
         // u incorrect, project the node to the curve
-        GeomAPI_ProjectPointOnCurve projector( nodePnt, curve, f, l );
-        if ( projector.NbPoints() < 1 )
+        int edgeID = GetMeshDS()->ShapeToIndex( E );
+        TID2ProjectorOnCurve& i2proj = const_cast< TID2ProjectorOnCurve&>( myEdge2Projector );
+        TID2ProjectorOnCurve::iterator i_proj =
+          i2proj.insert( make_pair( edgeID, (GeomAPI_ProjectPointOnCurve*) 0 )).first;
+        if ( !i_proj->second  )
+        {
+          i_proj->second = new GeomAPI_ProjectPointOnCurve();
+          i_proj->second->Init( curve, f, l );
+        }
+        GeomAPI_ProjectPointOnCurve* projector = i_proj->second;
+        projector->Perform( nodePnt );
+        if ( projector->NbPoints() < 1 )
         {
           MESSAGE( "SMESH_MesherHelper::CheckNodeU() failed to project" );
           return false;
         }
-        Quantity_Parameter U = projector.LowerDistanceParameter();
+        Quantity_Parameter U = projector->LowerDistanceParameter();
         u = double( U );
         dist = nodePnt.Distance( curve->Value( U ));
         if ( distance ) *distance = dist;
index 7af79e5cff44a38b306df7a39a29c73d614303d3..2f89ce7899239f2abc9617f95c7e8c864f8032b5 100644 (file)
@@ -42,6 +42,7 @@
 #include <vector>
 
 class GeomAPI_ProjectPointOnSurf;
+class GeomAPI_ProjectPointOnCurve;
 
 typedef std::map<SMESH_TLink, const SMDS_MeshNode*>           TLinkNodeMap;
 typedef std::map<SMESH_TLink, const SMDS_MeshNode*>::iterator ItTLinkNode;
@@ -232,7 +233,7 @@ public:
                                    const int id = 0,
                                    const bool force3d = false);
   /*!
-   * Creates quadratic or linear tetraahedron
+   * Creates quadratic or linear tetrahedron
    */
   SMDS_MeshVolume* AddVolume(const SMDS_MeshNode* n1,
                              const SMDS_MeshNode* n2,
@@ -488,8 +489,10 @@ protected:
   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* > TID2Projector;
-  TID2Projector   myFace2Projector;
+  typedef std::map< int, GeomAPI_ProjectPointOnSurf* > TID2ProjectorOnSurf;
+  TID2ProjectorOnSurf myFace2Projector;
+  typedef std::map< int, GeomAPI_ProjectPointOnCurve* > TID2ProjectorOnCurve;
+  TID2ProjectorOnCurve myEdge2Projector;
 
   TopoDS_Shape    myShape;
   SMESH_Mesh*     myMesh;
index 91993b332b20909e3ac94d19b202711be3e1e6b0..69b33a94c85ad2861a6576b10c4a08d373140705 100644 (file)
@@ -1000,9 +1000,12 @@ SMESH_Hypothesis::Hypothesis_Status
     if ( ret == SMESH_Hypothesis::HYP_OK &&
          !algo->NeedDescretBoundary()    &&
          !algo->SupportSubmeshes()) {
+      TopoDS_Shape algoAssignedTo, otherAssignedTo;
+      gen->GetAlgo( *_father, _subShape, &algoAssignedTo );
       map<int, SMESH_subMesh*>::reverse_iterator i_sm = _mapDepend.rbegin();
       for ( ; ( ret == SMESH_Hypothesis::HYP_OK && i_sm != _mapDepend.rend()) ; ++i_sm )
-        if ( gen->GetAlgo( *_father, i_sm->second->_subShape ))
+        if ( gen->GetAlgo( *_father, i_sm->second->_subShape, &otherAssignedTo ) &&
+             SMESH_MesherHelper::IsSubShape( /*sub=*/otherAssignedTo, /*main=*/algoAssignedTo ))
           ret = SMESH_Hypothesis::HYP_HIDING_ALGO;
     }
   }
@@ -1544,6 +1547,8 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
     switch (event)
     {
     case MODIF_ALGO_STATE:
+      if ( !IsEmpty() )
+        ComputeStateEngine( CLEAN );
       algo = gen->GetAlgo((*_father), _subShape);
       if (algo && !algo->NeedDescretBoundary())
         CleanDependsOn(); // clean sub-meshes with event CLEAN
index 46fc68259f86e6caed67fa4f5c3d94db8bdb2f61..e86089c8fd5e330d848fd73b3b1753a4dd9b8a97 100644 (file)
@@ -156,7 +156,7 @@ class MyGroupIterator: public SMDS_ElemIterator
 //purpose  : 
 //=======================================================================
 
-SMDS_ElemIteratorPtr SMESHDS_Group::GetElements()
+SMDS_ElemIteratorPtr SMESHDS_Group::GetElements() const
 {
   return SMDS_ElemIteratorPtr( new MyGroupIterator ( myGroup ));
 }
index fc4bbc50355af1a135988c6c45ef831aa8f7da5d..5538e16351f312669c9f9323d26e9e0690cf8a49 100644 (file)
@@ -54,7 +54,7 @@ class SMESHDS_EXPORT SMESHDS_Group : public SMESHDS_GroupBase
 
   virtual bool Contains (const SMDS_MeshElement* elem);
 
-  virtual SMDS_ElemIteratorPtr GetElements();
+  virtual SMDS_ElemIteratorPtr GetElements() const;
 
   bool Add (const int theID);
 
index 9fefca27df21de2b8cca164e87b66fba69b81ad7..2782e89518b4ec70ddf06453952f56e0103a4de8 100644 (file)
@@ -66,7 +66,7 @@ class SMESHDS_EXPORT SMESHDS_GroupBase
 
   virtual bool Contains (const SMDS_MeshElement* elem);
 
-  virtual SMDS_ElemIteratorPtr GetElements() = 0;
+  virtual SMDS_ElemIteratorPtr GetElements() const = 0;
 
   int GetID (const int theIndex);
   // use it for iterations 1..Extent()
index abd5d552b66a5809209fd7a9cf046ca406bf6842..aad0ee4f2508e9340be9ad3450fe3a1d26278e7a 100644 (file)
@@ -102,7 +102,7 @@ class MyIterator: public SMDS_ElemIterator
 //purpose  : 
 //=======================================================================
 
-SMDS_ElemIteratorPtr SMESHDS_GroupOnGeom::GetElements()
+SMDS_ElemIteratorPtr SMESHDS_GroupOnGeom::GetElements() const
 {
   return SMDS_ElemIteratorPtr( new MyIterator ( GetType(), mySubMesh ));
 }
index bb6f0900d5d9cef71f297961d3097c86a09cc233..1b4b5a924ca20eb15c5548321a307079546773a1 100644 (file)
@@ -51,7 +51,7 @@ class SMESHDS_EXPORT SMESHDS_GroupOnGeom: public SMESHDS_GroupBase
 
   virtual bool Contains (const SMDS_MeshElement* elem);
 
-  virtual SMDS_ElemIteratorPtr GetElements();
+  virtual SMDS_ElemIteratorPtr GetElements() const;
 
  private:
 
index 55c27411b3a93637ce64e67b88305053d7aaec20..0ae03d0c56940461a82c0f666b4e44288b204ec2 100644 (file)
@@ -61,6 +61,7 @@ SMESHDS_Mesh::SMESHDS_Mesh(int theMeshID, bool theIsEmbeddedMode):
 {
   myScript = new SMESHDS_Script(theIsEmbeddedMode);
   myCurSubMesh = 0;
+  SetPersistentId(theMeshID);
 }
 
 //=======================================================================
@@ -69,6 +70,28 @@ bool SMESHDS_Mesh::IsEmbeddedMode()
   return myIsEmbeddedMode;
 }
 
+//================================================================================
+/*!
+ * \brief Store ID persistent during lifecycle
+ */
+//================================================================================
+
+void SMESHDS_Mesh::SetPersistentId(int id)
+{
+  if (NbNodes() == 0)
+    myPersistentID = id;
+}
+//================================================================================
+/*!
+ * \brief Return ID persistent during lifecycle
+ */
+//================================================================================
+
+int SMESHDS_Mesh::GetPersistentId() const
+{
+  return myPersistentID;
+}
+
 //=======================================================================
 //function : ShapeToMesh
 //purpose  : 
@@ -1247,6 +1270,17 @@ const TopoDS_Shape& SMESHDS_Mesh::IndexToShape(int ShapeIndex) const
   return nullShape;
 }
 
+//================================================================================
+/*!
+ * \brief Return max index of sub-mesh
+ */
+//================================================================================
+
+int SMESHDS_Mesh::MaxSubMeshIndex() const
+{
+  return myShapeIndexToSubMesh.empty() ? 0 : myShapeIndexToSubMesh.rbegin()->first;
+}
+
 //=======================================================================
 //function : ShapeToIndex
 //purpose  : 
index b53c5e879382aa7c03af4ebe87a245289ef2c242..7e852c774b307c180c60e5195066a91babbdf6d9 100644 (file)
@@ -50,7 +50,7 @@
 #include <NCollection_DataMap.hxx>
 #include <map>
 /*
- * Using of native haah_map isn't portable and don't work on WIN32 platform.
+ * Using of native hash_map isn't portable and don't work on WIN32 platform.
  * So this functionality implement on new NCollection_DataMap technology
  */
 #include "SMESHDS_DataMapOfShape.hxx"
@@ -61,6 +61,8 @@ class SMESHDS_EXPORT SMESHDS_Mesh:public SMDS_Mesh{
 public:
   SMESHDS_Mesh(int theMeshID, bool theIsEmbeddedMode);
   bool IsEmbeddedMode();
+  void SetPersistentId(int id);
+  int GetPersistentId() const;
 
   void ShapeToMesh(const TopoDS_Shape & S);
   TopoDS_Shape ShapeToMesh() const;
@@ -423,6 +425,7 @@ public:
   int ShapeToIndex(const TopoDS_Shape & aShape) const;
   const TopoDS_Shape& IndexToShape(int ShapeIndex) const;
   int MaxShapeIndex() const { return myIndexToShape.Extent(); }
+  int MaxSubMeshIndex() const;
 
   SMESHDS_SubMesh * NewSubMesh(int Index);
   int AddCompoundSubmesh(const TopoDS_Shape& S, TopAbs_ShapeEnum type = TopAbs_SHAPE);
@@ -449,7 +452,7 @@ private:
     if ( it == myShapeIndexToSubMesh.end() )
       it = myShapeIndexToSubMesh.insert( std::make_pair(Index, new SMESHDS_SubMesh() )).first;
     it->second->AddNode( aNode ); // add aNode to submesh
-    }
+  }
   
   /*int HashCode( const TopoDS_Shape& S, const Standard_Integer theUpper ) const
   {
@@ -462,7 +465,7 @@ private:
 
   ShapeToHypothesis          myShapeToHypothesis;
 
-  int                        myMeshID;
+  int                        myMeshID, myPersistentID;
   TopoDS_Shape               myShape;
 
   typedef std::map<int,SMESHDS_SubMesh*> TShapeIndexToSubMesh;
index 4531a8760494c30db65254344b120dcb03a4a07e..89857d89ccfb420af18d062df2e51fb2d4e7176a 100644 (file)
@@ -52,6 +52,11 @@ enum MeshObjectType {
   SUBMESH_SOLID,
   SUBMESH_COMPOUND,
   GROUP,
+  GROUP_NODE,
+  GROUP_EDGE,
+  GROUP_FACE,
+  GROUP_VOLUME,
+  GROUP_0D,
   COMPONENT
 };
 
index bfede041871ced4d17e2c54e8208ce7b03b0be04..1fbb375169074e23f1f0af2cab8bc7898fc396ea 100644 (file)
@@ -81,6 +81,7 @@ bool SMESH_TypeFilter::isOk (const SUIT_DataOwner* theDataOwner) const
     // 4       |     |- Applied algorithms ( selectable in Use Case Browser )
     // 5       |          |- Regular 1D
     //         |- Group Of Nodes
+    //            |- Group 1
 
     if (aLevel <= 0)
       return false;
@@ -172,6 +173,36 @@ bool SMESH_TypeFilter::isOk (const SUIT_DataOwner* theDataOwner) const
             Ok = true;
           break;
         }
+      case GROUP_NODE:
+        {
+          if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_NodeGroups))
+            Ok = true;
+          break;
+        }
+      case GROUP_EDGE:
+        {
+          if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_EdgeGroups))
+            Ok = true;
+          break;
+        }
+      case GROUP_FACE:
+        {
+          if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_FaceGroups))
+            Ok = true;
+          break;
+        }
+      case GROUP_VOLUME:
+        {
+          if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_VolumeGroups))
+            Ok = true;
+          break;
+        }
+      case GROUP_0D:
+        {
+          if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_VolumeGroups+1))
+            Ok = true;
+          break;
+        }
     }
   }
   return Ok;
index aef8dcfb4d77bc62de5971c35fe96db94e2f34ff..7e7448f59556982a622799adcf6fcd36c6458315 100644 (file)
@@ -47,9 +47,8 @@ salomeinclude_HEADERS = \
        SMESHGUI_GroupDlg.h \
        SMESHGUI_RemoveNodesDlg.h \
        SMESHGUI_RemoveElementsDlg.h \
-       SMESHGUI_MeshInfosDlg.h \
-       SMESHGUI_StandardMeshInfosDlg.h \
-       SMESHGUI_WhatIsDlg.h \
+       SMESHGUI_MeshInfo.h \
+       SMESHGUI_Measurements.h \
        SMESHGUI_Preferences_ColorDlg.h \
        SMESHGUI_Preferences_ScalarBarDlg.h \
        SMESHGUI_AddMeshElementDlg.h \
@@ -111,9 +110,8 @@ dist_libSMESH_la_SOURCES = \
        SMESHGUI_GroupDlg.cxx \
        SMESHGUI_RemoveNodesDlg.cxx \
        SMESHGUI_RemoveElementsDlg.cxx \
-       SMESHGUI_MeshInfosDlg.cxx \
-       SMESHGUI_StandardMeshInfosDlg.cxx \
-       SMESHGUI_WhatIsDlg.cxx \
+       SMESHGUI_MeshInfo.cxx \
+       SMESHGUI_Measurements.cxx \
        SMESHGUI_Preferences_ColorDlg.cxx \
        SMESHGUI_Preferences_ScalarBarDlg.cxx \
        SMESHGUI_AddMeshElementDlg.cxx \
@@ -183,9 +181,8 @@ MOC_FILES = \
        SMESHGUI_GroupDlg_moc.cxx \
        SMESHGUI_RemoveNodesDlg_moc.cxx \
        SMESHGUI_RemoveElementsDlg_moc.cxx \
-       SMESHGUI_MeshInfosDlg_moc.cxx \
-       SMESHGUI_StandardMeshInfosDlg_moc.cxx \
-       SMESHGUI_WhatIsDlg_moc.cxx \
+       SMESHGUI_MeshInfo_moc.cxx \
+       SMESHGUI_Measurements_moc.cxx \
        SMESHGUI_Preferences_ColorDlg_moc.cxx \
        SMESHGUI_Preferences_ScalarBarDlg_moc.cxx \
        SMESHGUI_AddMeshElementDlg_moc.cxx \
index 1efc41fd29c3cf65fb4d847210218ca61b121a10..fdccc873729485059e0a16cbb55fc133f33721ab 100644 (file)
@@ -48,7 +48,9 @@
 #include "SMESHGUI_Hypotheses.h"
 #include "SMESHGUI_Make2DFrom3DOp.h"
 #include "SMESHGUI_MakeNodeAtPointDlg.h"
-#include "SMESHGUI_MeshInfosDlg.h"
+//#include "SMESHGUI_MeshInfosDlg.h"
+#include "SMESHGUI_Measurements.h"
+#include "SMESHGUI_MeshInfo.h"
 #include "SMESHGUI_MeshOp.h"
 #include "SMESHGUI_MeshOrderOp.h"
 #include "SMESHGUI_MeshPatternDlg.h"
 #include "SMESHGUI_SewingDlg.h"
 #include "SMESHGUI_SingleEditDlg.h"
 #include "SMESHGUI_SmoothingDlg.h"
-#include "SMESHGUI_StandardMeshInfosDlg.h"
+//#include "SMESHGUI_StandardMeshInfosDlg.h"
 #include "SMESHGUI_SymmetryDlg.h"
 #include "SMESHGUI_TranslationDlg.h"
 #include "SMESHGUI_ScaleDlg.h"
 #include "SMESHGUI_TransparencyDlg.h"
-#include "SMESHGUI_WhatIsDlg.h"
+//#include "SMESHGUI_WhatIsDlg.h"
 #include "SMESHGUI_DuplicateNodesDlg.h"
 
 #include "SMESHGUI_Utils.h"
@@ -83,7 +85,9 @@
 
 #include <SMESH_Client.hxx>
 #include <SMESH_Actor.h>
+#include <SMESH_ScalarBarActor.h>
 #include <SMESH_TypeFilter.hxx>
+#include "SMESH_ControlsDef.hxx"
 
 // SALOME GUI includes
 #include <SalomeApp_Tools.h>
 #include <SALOMEconfig.h>
 #include CORBA_CLIENT_HEADER(SALOMEDS_Attributes)
 #include CORBA_CLIENT_HEADER(SMESH_MeshEditor)
+#include CORBA_CLIENT_HEADER(SMESH_Measurements)
 
 // Qt includes
 // #define       INCLUDE_MENUITEM_DEF // VSR commented ????????
 #include <QMenu>
+#include <QTextStream>
 
 // BOOST includes
 #include <boost/shared_ptr.hpp>
 
 // VTK includes
-#include <vtkScalarBarActor.h>
 #include <vtkCamera.h>
 #include <vtkRenderer.h>
 #include <vtkPlane.h>
+#include <vtkCallbackCommand.h>
 
 // SALOME KERNEL includes
 #include <SALOMEDS_Study.hxx>
     std::string myExtension;
 
     if ( theCommandID == 113 ) {
-      filter.append( QObject::tr( "MED files (*.med)" ) );
-      filter.append( QObject::tr( "All files (*)" ) );
+      filter.append( QObject::tr( "MED_FILES_FILTER" ) + " (*.med)" );
+      filter.append( QObject::tr( "ALL_FILES_FILTER" ) + " (*)" );
     }
     else if ( theCommandID == 112 ) {
-      filter.append( QObject::tr( "IDEAS files (*.unv)" ) );
+      filter.append( QObject::tr( "IDEAS_FILES_FILTER" ) + " (*.unv)" );
     }
     else if ( theCommandID == 111 ) {
-      filter.append( QObject::tr( "DAT files (*.dat)" ) );
+      filter.append( QObject::tr( "DAT_FILES_FILTER" ) + " (*.dat)" );
     }
 
     QString anInitialPath = "";
 
     QList<SALOMEDS::Color> aReservedColors;
 
-    QString aFilter, aTitle = QObject::tr("Export mesh");
+    QString aFilter, aTitle = QObject::tr("SMESH_EXPORT_MESH");
     QMap<QString, SMESH::MED_VERSION> aFilterMap;
     QMap<QString, int> aFilterMapSTL;
     switch ( theCommandID ) {
         // PAL18696
         QString v21 (aMesh->GetVersionString(SMESH::MED_V2_1, 2));
         QString v22 (aMesh->GetVersionString(SMESH::MED_V2_2, 2));
-        aFilterMap.insert( QString("MED ") +  v21 + " (*.med)", SMESH::MED_V2_1 );
-        aFilterMap.insert( QString("MED ") +  v22 + " (*.med)", SMESH::MED_V2_2 );
+        aFilterMap.insert( QObject::tr( "MED_VX_FILES_FILTER" ).arg( v21 ) + " (*.med)", SMESH::MED_V2_1 );
+        aFilterMap.insert( QObject::tr( "MED_VX_FILES_FILTER" ).arg( v22 ) + " (*.med)", SMESH::MED_V2_2 );
       }
       break;
     case 124:
     case 121:
-      aFilter = QObject::tr("DAT files (*.dat)");
+      aFilter = QObject::tr( "DAT_FILES_FILTER" ) + " (*.dat)";
       break;
     case 126:
     case 123:
           if (aRet != 0)
             return;
         }
-        aFilter = QObject::tr("IDEAS files (*.unv)");
+        aFilter = QObject::tr( "IDEAS_FILES_FILTER" ) + " (*.unv)";
       }
       break;
     case 140:
             return;
         }
 
-        aFilterMapSTL.insert( QObject::tr("STL ASCII (*.stl)"), 1 ); // 1 - ASCII mode
-        aFilterMapSTL.insert( QObject::tr("STL Binary (*.stl)"), 0 ); // 0 - Binary mode
+        aFilterMapSTL.insert( QObject::tr( "STL_ASCII_FILES_FILTER" ) + " (*.stl)", 1 ); // 1 - ASCII mode
+        aFilterMapSTL.insert( QObject::tr( "STL_BIN_FILES_FILTER" )   + " (*.stl)", 0 ); // 0 - Binary mode
       }
       break;
     default:
       SUIT_FileDlg* fd = new SUIT_FileDlg( SMESHGUI::desktop(), false, true, true );
       fd->setWindowTitle( aTitle );
       fd->setNameFilters( filters );
-      fd->selectNameFilter( QObject::tr("STL ASCII (*.stl)") );
+      fd->selectNameFilter( QObject::tr( "STL_ASCII_FILES_FILTER" ) + " (*.stl)" );
       if ( !anInitialPath.isEmpty() )
         fd->setDirectory( anInitialPath );
       fd->selectFile(aMeshName);
     SMESH::RepaintCurrentView();
   }
 
+  QString functorToString( SMESH::Controls::FunctorPtr f )
+  {
+    QString type = QObject::tr( "UNKNOWN_CONTROL" );
+    if ( dynamic_cast< SMESH::Controls::Volume* >( f.get() ) )
+      type = QObject::tr( "VOLUME_3D_ELEMENTS" );
+    else if ( dynamic_cast< SMESH::Controls::MaxElementLength2D* >( f.get() ) )
+      type = QObject::tr( "MAX_ELEMENT_LENGTH_2D" );
+    else if ( dynamic_cast< SMESH::Controls::MaxElementLength3D* >( f.get() ) )
+      type = QObject::tr( "MAX_ELEMENT_LENGTH_3D" );
+    else if ( dynamic_cast< SMESH::Controls::MinimumAngle* >( f.get() ) )
+      type = QObject::tr( "MINIMUMANGLE_ELEMENTS" );
+    else if ( dynamic_cast< SMESH::Controls::AspectRatio* >( f.get() ) )
+      type = QObject::tr( "ASPECTRATIO_ELEMENTS" );
+    else if ( dynamic_cast< SMESH::Controls::AspectRatio3D* >( f.get() ) )
+      type = QObject::tr( "ASPECTRATIO_3D_ELEMENTS" );
+    else if ( dynamic_cast< SMESH::Controls::Warping* >( f.get() ) )
+      type = QObject::tr( "WARP_ELEMENTS" );
+    else if ( dynamic_cast< SMESH::Controls::Taper* >( f.get() ) )
+      type = QObject::tr( "TAPER_ELEMENTS" );
+    else if ( dynamic_cast< SMESH::Controls::Skew* >( f.get() ) )
+      type = QObject::tr( "SKEW_ELEMENTS" );
+    else if ( dynamic_cast< SMESH::Controls::Area* >( f.get() ) )
+      type = QObject::tr( "AREA_ELEMENTS" );
+    else if ( dynamic_cast< SMESH::Controls::Length* >( f.get() ) )
+      type = QObject::tr( "LENGTH_EDGES" );
+    else if ( dynamic_cast< SMESH::Controls::Length2D* >( f.get() ) )
+      type = QObject::tr( "LENGTH2D_EDGES" );
+    else if ( dynamic_cast< SMESH::Controls::MultiConnection* >( f.get() ) )
+      type = QObject::tr( "MULTI_BORDERS" );
+    else if ( dynamic_cast< SMESH::Controls::MultiConnection2D* >( f.get() ) )
+      type = QObject::tr( "MULTI2D_BORDERS" );
+    else if ( dynamic_cast< SMESH::Controls::FreeNodes* >( f.get() ) )
+      type = QObject::tr( "FREE_NODES" );
+    else if ( dynamic_cast< SMESH::Controls::FreeEdges* >( f.get() ) )
+      type = QObject::tr( "FREE_EDGES" );
+    else if ( dynamic_cast< SMESH::Controls::FreeBorders* >( f.get() ) )
+      type = QObject::tr( "FREE_BORDERS" );
+    else if ( dynamic_cast< SMESH::Controls::FreeFaces* >( f.get() ) )
+      type = QObject::tr( "FREE_FACES" );
+    return type;
+  }
+
+  void SaveDistribution()
+  {
+    LightApp_SelectionMgr* aSel = SMESHGUI::selectionMgr();
+    SALOME_ListIO selected;
+    if ( aSel )
+      aSel->selectedObjects( selected );
+
+    if ( selected.Extent() == 1 ) {
+      Handle(SALOME_InteractiveObject) anIO = selected.First();
+      if ( anIO->hasEntry() ) {
+        SMESH_Actor* anActor = SMESH::FindActorByEntry( anIO->getEntry() );
+        if ( anActor && anActor->GetScalarBarActor() && anActor->GetControlMode() != SMESH_Actor::eNone ) {
+          SMESH_ScalarBarActor* aScalarBarActor = anActor->GetScalarBarActor();
+          SMESH::Controls::FunctorPtr aFunctor = anActor->GetFunctor();
+          if ( aScalarBarActor && aFunctor ) {
+            SMESH::Controls::NumericalFunctor* aNumFun = dynamic_cast<SMESH::Controls::NumericalFunctor*>( aFunctor.get() );
+            if ( aNumFun ) {
+              int nbRanges = aScalarBarActor->GetMaximumNumberOfColors();
+              std::vector<int>    nbEvents;
+              std::vector<double> funValues;
+              aNumFun->GetHistogram( nbRanges, nbEvents, funValues );
+              QString anInitialPath = "";
+              if ( SUIT_FileDlg::getLastVisitedPath().isEmpty() )
+                anInitialPath = QDir::currentPath();
+              QString aMeshName = anIO->getName();
+              QStringList filter;
+              filter.append( QObject::tr( "TEXT_FILES_FILTER" ) + " (*.txt)" );
+              filter.append( QObject::tr( "ALL_FILES_FILTER" ) + " (*)" );
+              QString aFilename = anInitialPath + "/" + aMeshName + "_" + 
+                functorToString( aFunctor ).toLower().simplified().replace( QRegExp( " |-" ), "_" ) + ".txt";
+              aFilename = SUIT_FileDlg::getFileName( SMESHGUI::desktop(),
+                                                     aFilename,
+                                                     filter,
+                                                     QObject::tr( "SMESH_SAVE_DISTRIBUTION" ),
+                                                     false );
+              if ( !aFilename.isEmpty() ) {
+                QFile f( aFilename );
+                if ( f.open( QFile::WriteOnly | QFile::Truncate ) ) {
+                  QTextStream out( &f );
+                  out << "# Mesh: " << aMeshName << endl;
+                  out << "# Control: " << functorToString( aFunctor ) << endl;
+                  out << "#" << endl;
+                  out.setFieldWidth( 10 );
+                  for ( int i = 0; i < qMin( nbEvents.size(), funValues.size()-1 ); i++ )
+                    out << funValues[i] << "\t" << funValues[i+1] << "\t" << nbEvents[i] << endl;
+                  f.close();
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+
+  void ShowDistribution() {
+    LightApp_SelectionMgr* aSel = SMESHGUI::selectionMgr();
+    SALOME_ListIO selected;
+    if ( aSel )
+      aSel->selectedObjects( selected );
+    
+    if ( selected.Extent() == 1 ) {
+      Handle(SALOME_InteractiveObject) anIO = selected.First();
+      if ( anIO->hasEntry() ) {
+       SMESH_Actor* anActor = SMESH::FindActorByEntry( anIO->getEntry() );
+       if ( anActor && anActor->GetScalarBarActor() && anActor->GetControlMode() != SMESH_Actor::eNone ) {
+         SMESH_ScalarBarActor *aScalarBarActor = anActor->GetScalarBarActor();
+         aScalarBarActor->SetDistributionVisibility(!aScalarBarActor->GetDistributionVisibility());
+       }
+      }
+    }
+  }
+
   void DisableAutoColor(){
     LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
     SALOME_ListIO selected;
     if( !aSel || !appStudy )
       return;
 
+    if( theCommandID == 1134 ) { // Clipping dialog can be activated without selection
+      if( SMESHGUI* aModule = SMESHGUI::GetSMESHGUI() ) {
+        aModule->EmitSignalDeactivateDialog();
+        if( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( aModule ) )
+          (new SMESHGUI_ClippingDlg( aModule, aViewWindow ))->show();
+      }
+      return;
+    }
+
     _PTR(Study) aStudy = appStudy->studyDS();
 
     aSel->selectedObjects( selected );
 
     if(selected.Extent() >= 1){
       switch(theCommandID){
-      case 1134:{
-        SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
-        (new SMESHGUI_ClippingDlg( SMESHGUI::GetSMESHGUI() ))->show();
-        return;
-      }
       case 1133:{
         SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
         (new SMESHGUI_TransparencyDlg( SMESHGUI::GetSMESHGUI() ))->show();
         return;
-      }}
-      SALOME_ListIteratorOfListIO It( selected );
-      for( ; It.More(); It.Next()){
-        Handle(SALOME_InteractiveObject) IObject = It.Value();
-        if(IObject->hasEntry()){
-          if(SMESH_Actor *anActor = SMESH::FindActorByEntry(IObject->getEntry())){
-            switch(theCommandID){
-            case 211:
-              anActor->SetRepresentation(SMESH_Actor::eEdge);
-              break;
-            case 212:
-              anActor->SetRepresentation(SMESH_Actor::eSurface);
-              break;
-            case 213:
-              if(anActor->IsShrunk())
-                anActor->UnShrink();
-              else
-                anActor->SetShrink();
-              break;
-            case 215:
-              anActor->SetRepresentation(SMESH_Actor::ePoint);
-              break;
-            case 231:
-              if(anActor->GetQuadratic2DRepresentation() != SMESH_Actor::eLines)
-                anActor->SetQuadratic2DRepresentation(SMESH_Actor::eLines);
-              break;
-            case 232:
-              if(anActor->GetQuadratic2DRepresentation() != SMESH_Actor::eArcs)
-                anActor->SetQuadratic2DRepresentation(SMESH_Actor::eArcs);
-              break;
-            case 1132:{
+      }
+      case 1132:{
+        QColor c, e, b, n, c0D, o;
+        int size0D = 0;
+        int Edgewidth = 0;
+        vtkFloatingPointType Shrink = 0.0;
+        vtkFloatingPointType faces_orientation_scale = 0.0;
+        bool faces_orientation_3dvectors = false;
+
+        VTK::MarkerType aMarkerTypeCurrent = VTK::MT_NONE;
+        VTK::MarkerScale aMarkerScaleCurrent = VTK::MS_NONE;
+        int aMarkerTextureCurrent = 0;
+
+        SALOME_ListIteratorOfListIO It( selected );
+        for( ; It.More(); It.Next()){
+          Handle(SALOME_InteractiveObject) IObject = It.Value();
+          if(IObject->hasEntry()){
+            if(SMESH_Actor *anActor = SMESH::FindActorByEntry(IObject->getEntry())){
               vtkFloatingPointType color[3];
               anActor->GetSufaceColor(color[0], color[1], color[2]);
               int c0 = int (color[0] * 255);
               int c1 = int (color[1] * 255);
               int c2 = int (color[2] * 255);
-              QColor c(c0, c1, c2);
+              c.setRgb(c0, c1, c2);
 
               vtkFloatingPointType edgecolor[3];
               anActor->GetEdgeColor(edgecolor[0], edgecolor[1], edgecolor[2]);
               c0 = int (edgecolor[0] * 255);
               c1 = int (edgecolor[1] * 255);
               c2 = int (edgecolor[2] * 255);
-              QColor e(c0, c1, c2);
+              e.setRgb(c0, c1, c2);
 
               vtkFloatingPointType backfacecolor[3];
               anActor->GetBackSufaceColor(backfacecolor[0], backfacecolor[1], backfacecolor[2]);
               c0 = int (backfacecolor[0] * 255);
               c1 = int (backfacecolor[1] * 255);
               c2 = int (backfacecolor[2] * 255);
-              QColor b(c0, c1, c2);
+              b.setRgb(c0, c1, c2);
 
               vtkFloatingPointType nodecolor[3];
               anActor->GetNodeColor(nodecolor[0], nodecolor[1], nodecolor[2]);
               c0 = int (nodecolor[0] * 255);
               c1 = int (nodecolor[1] * 255);
               c2 = int (nodecolor[2] * 255);
-              QColor n(c0, c1, c2);
+              n.setRgb(c0, c1, c2);
 
               vtkFloatingPointType color0D[3];
               anActor->Get0DColor(color0D[0], color0D[1], color0D[2]);
               c0 = int (color0D[0] * 255);
               c1 = int (color0D[1] * 255);
               c2 = int (color0D[2] * 255);
-              QColor c0D(c0, c1, c2);
+              c0D.setRgb(c0, c1, c2);
 
-              int size0D = (int)anActor->Get0DSize();
+              size0D = (int)anActor->Get0DSize();
               if(size0D == 0)
                 size0D = 1;
-              int Edgewidth = (int)anActor->GetLineWidth();
+              Edgewidth = (int)anActor->GetLineWidth();
               if(Edgewidth == 0)
                 Edgewidth = 1;
-              vtkFloatingPointType Shrink = anActor->GetShrinkFactor();
+              Shrink = anActor->GetShrinkFactor();
 
               vtkFloatingPointType faces_orientation_color[3];
               anActor->GetFacesOrientationColor(faces_orientation_color);
               c0 = int (faces_orientation_color[0] * 255);
               c1 = int (faces_orientation_color[1] * 255);
               c2 = int (faces_orientation_color[2] * 255);
-              QColor o(c0, c1, c2);
-
-              vtkFloatingPointType faces_orientation_scale = anActor->GetFacesOrientationScale();
-              bool faces_orientation_3dvectors = anActor->GetFacesOrientation3DVectors();
-
-              SMESHGUI_Preferences_ColorDlg *aDlg =
-                new SMESHGUI_Preferences_ColorDlg( SMESHGUI::GetSMESHGUI() );
-              aDlg->SetColor(1, c);
-              aDlg->SetColor(2, e);
-              aDlg->SetColor(3, n);
-              aDlg->SetColor(4, b);
-              aDlg->SetColor(5, c0D);
-              aDlg->SetColor(6, o);
-              aDlg->SetIntValue(1, Edgewidth);
-              aDlg->SetIntValue(2, int(Shrink*100.));
-              aDlg->SetIntValue(3, size0D);
-              aDlg->SetDoubleValue(1, faces_orientation_scale);
-              aDlg->SetBooleanValue(1, faces_orientation_3dvectors);
-
-              aDlg->setCustomMarkerMap( theMarkerMap[ aStudy->StudyId() ] );
-
-              VTK::MarkerType aMarkerTypeCurrent = anActor->GetMarkerType();
-              VTK::MarkerScale aMarkerScaleCurrent = anActor->GetMarkerScale();
-              int aMarkerTextureCurrent = anActor->GetMarkerTexture();
-              if( aMarkerTypeCurrent != VTK::MT_USER )
-                aDlg->setStandardMarker( aMarkerTypeCurrent, aMarkerScaleCurrent );
-              else
-                aDlg->setCustomMarker( aMarkerTextureCurrent );
-
-              if(aDlg->exec()){
-                QColor color = aDlg->GetColor(1);
-                QColor edgecolor = aDlg->GetColor(2);
-                QColor nodecolor = aDlg->GetColor(3);
-                QColor backfacecolor = aDlg->GetColor(4);
-                QColor color0D = aDlg->GetColor(5);
-                QColor faces_orientation_color = aDlg->GetColor(6);
+              o.setRgb(c0, c1, c2);
+
+              faces_orientation_scale = anActor->GetFacesOrientationScale();
+              faces_orientation_3dvectors = anActor->GetFacesOrientation3DVectors();
+
+              aMarkerTypeCurrent = anActor->GetMarkerType();
+              aMarkerScaleCurrent = anActor->GetMarkerScale();
+              aMarkerTextureCurrent = anActor->GetMarkerTexture();
+
+              // even if there are multiple objects in the selection,
+              // we need only the first one to get values for the dialog
+              break;
+            }
+          }
+        }
+
+        SMESHGUI_Preferences_ColorDlg *aDlg =
+          new SMESHGUI_Preferences_ColorDlg( SMESHGUI::GetSMESHGUI() );
+        aDlg->SetColor(1, c);
+        aDlg->SetColor(2, e);
+        aDlg->SetColor(3, n);
+        aDlg->SetColor(4, b);
+        aDlg->SetColor(5, c0D);
+        aDlg->SetColor(6, o);
+        aDlg->SetIntValue(1, Edgewidth);
+        aDlg->SetIntValue(2, int(Shrink*100.));
+        aDlg->SetIntValue(3, size0D);
+        aDlg->SetDoubleValue(1, faces_orientation_scale);
+        aDlg->SetBooleanValue(1, faces_orientation_3dvectors);
+        aDlg->setCustomMarkerMap( theMarkerMap[ aStudy->StudyId() ] );
+
+        if( aMarkerTypeCurrent != VTK::MT_USER )
+          aDlg->setStandardMarker( aMarkerTypeCurrent, aMarkerScaleCurrent );
+        else
+          aDlg->setCustomMarker( aMarkerTextureCurrent );
+
+        if(aDlg->exec()){
+          QColor color = aDlg->GetColor(1);
+          QColor edgecolor = aDlg->GetColor(2);
+          QColor nodecolor = aDlg->GetColor(3);
+          QColor backfacecolor = aDlg->GetColor(4);
+          QColor color0D = aDlg->GetColor(5);
+          QColor faces_orientation_color = aDlg->GetColor(6);
+
+          /* Point marker */
+          theMarkerMap[ aStudy->StudyId() ] = aDlg->getCustomMarkerMap();
+
+          SALOME_ListIteratorOfListIO It( selected );
+          for( ; It.More(); It.Next()){
+            Handle(SALOME_InteractiveObject) IObject = It.Value();
+            if(IObject->hasEntry()){
+              if(SMESH_Actor *anActor = SMESH::FindActorByEntry(IObject->getEntry())){
                 /* actor color and backface color */
                 anActor->SetSufaceColor(vtkFloatingPointType (color.red()) / 255.,
                                         vtkFloatingPointType (color.green()) / 255.,
                 anActor->SetFacesOrientationScale(aDlg->GetDoubleValue(1));
                 anActor->SetFacesOrientation3DVectors(aDlg->GetBooleanValue(1));
 
-                /* Point marker */
-                theMarkerMap[ aStudy->StudyId() ] = aDlg->getCustomMarkerMap();
-
                 VTK::MarkerType aMarkerTypeNew = aDlg->getMarkerType();
                 VTK::MarkerScale aMarkerScaleNew = aDlg->getStandardMarkerScale();
                 int aMarkerTextureNew = aDlg->getCustomMarkerID();
                   aGroupColor.B = (float)aColor.blue() / 255.0;
                   aGroupObject->SetColor( aGroupColor );
                 }
-
-                delete aDlg;
               }
+            }
+          }
+          SMESH::RepaintCurrentView();
+        }
+        delete aDlg;
+        return;
+      }
+      }
+      SALOME_ListIteratorOfListIO It( selected );
+      for( ; It.More(); It.Next()){
+        Handle(SALOME_InteractiveObject) IObject = It.Value();
+        if(IObject->hasEntry()){
+          if(SMESH_Actor *anActor = SMESH::FindActorByEntry(IObject->getEntry())){
+            switch(theCommandID){
+            case 211:
+              anActor->SetRepresentation(SMESH_Actor::eEdge);
+              break;
+            case 212:
+              anActor->SetRepresentation(SMESH_Actor::eSurface);
+              break;
+            case 213:
+              if(anActor->IsShrunk())
+                anActor->UnShrink();
+              else
+                anActor->SetShrink();
+              break;
+            case 215:
+              anActor->SetRepresentation(SMESH_Actor::ePoint);
+              break;
+            case 231:
+              if(anActor->GetQuadratic2DRepresentation() != SMESH_Actor::eLines)
+                anActor->SetQuadratic2DRepresentation(SMESH_Actor::eLines);
+              break;
+            case 232:
+              if(anActor->GetQuadratic2DRepresentation() != SMESH_Actor::eArcs)
+                anActor->SetQuadratic2DRepresentation(SMESH_Actor::eArcs);
               break;
-            }}
+            }
           }
         }
       }
     if( !selected.IsEmpty() ){
       Handle(SALOME_InteractiveObject) anIO = selected.First();
       if(!anIO.IsNull()){
-        QString aTitle;
         SMESH_Actor::eControl aControl = SMESH_Actor::eNone;
         if(SMESH_Actor *anActor = SMESH::FindActorByEntry(anIO->getEntry())){
           switch ( theCommandID ){
           case 6001:
-            aTitle = QObject::tr( "LENGTH_EDGES" );
             aControl = SMESH_Actor::eLength;
             break;
           case 6018:
-            aTitle = QObject::tr( "LENGTH2D_EDGES" );
             aControl = SMESH_Actor::eLength2D;
             break;
           case 6002:
-            aTitle = QObject::tr( "FREE_EDGES" );
             aControl = SMESH_Actor::eFreeEdges;
             break;
           case 6003:
-            aTitle = QObject::tr( "FREE_BORDERS" );
             aControl = SMESH_Actor::eFreeBorders;
             break;
           case 6004:
-            aTitle = QObject::tr( "MULTI_BORDERS" );
             aControl = SMESH_Actor::eMultiConnection;
             break;
           case 6005:
-            aTitle = QObject::tr( "FREE_NODES" );
             aControl = SMESH_Actor::eFreeNodes;
             break;
           case 6019:
-            aTitle = QObject::tr( "MULTI2D_BORDERS" );
             aControl = SMESH_Actor::eMultiConnection2D;
             break;
           case 6011:
-            aTitle = QObject::tr( "AREA_ELEMENTS" );
             aControl = SMESH_Actor::eArea;
             break;
           case 6012:
-            aTitle = QObject::tr( "TAPER_ELEMENTS" );
             aControl = SMESH_Actor::eTaper;
             break;
           case 6013:
-            aTitle = QObject::tr( "ASPECTRATIO_ELEMENTS" );
             aControl = SMESH_Actor::eAspectRatio;
             break;
           case 6017:
-            aTitle = QObject::tr( "ASPECTRATIO_3D_ELEMENTS" );
             aControl = SMESH_Actor::eAspectRatio3D;
             break;
           case 6014:
-            aTitle = QObject::tr( "MINIMUMANGLE_ELEMENTS" );
             aControl = SMESH_Actor::eMinimumAngle;
             break;
           case 6015:
-            aTitle = QObject::tr( "WARP_ELEMENTS" );
             aControl = SMESH_Actor::eWarping;
             break;
           case 6016:
-            aTitle = QObject::tr( "SKEW_ELEMENTS" );
             aControl = SMESH_Actor::eSkew;
             break;
           case 6009:
-            aTitle = QObject::tr( "SMESH_VOLUME" );
             aControl = SMESH_Actor::eVolume3D;
             break;
           case 6021:
-            aTitle = QObject::tr( "FREE_FACES" );
             aControl = SMESH_Actor::eFreeFaces;
             break;
+          case 6022:
+            aControl = SMESH_Actor::eMaxElementLength2D;
+            break;
+          case 6023:
+            aControl = SMESH_Actor::eMaxElementLength3D;
+            break;
           }
           anActor->SetControlMode(aControl);
-          anActor->GetScalarBarActor()->SetTitle(aTitle.toLatin1().data());
+          anActor->GetScalarBarActor()->SetTitle( functorToString( anActor->GetFunctor() ).toLatin1().constData() );
           SMESH::RepaintCurrentView();
         }
       }
@@ -1296,8 +1445,15 @@ LightApp_Module( "SMESH" )
   myState = -1;
   myDisplayer = 0;
 
+  myEventCallbackCommand = vtkCallbackCommand::New();
+  myEventCallbackCommand->Delete();
+  myEventCallbackCommand->SetClientData( this );
+  myEventCallbackCommand->SetCallback( SMESHGUI::ProcessEvents );
+  myPriority = 0.0;
+
   SMESH::GetFilterManager();
   SMESH::GetPattern();
+  SMESH::GetMeasurements();
 
   /* load resources for all available meshers */
   SMESH::InitAvailableHypotheses();
@@ -1312,8 +1468,10 @@ SMESHGUI::~SMESHGUI()
 {
 #ifdef WITHGENERICOBJ
   SMESH::GetFilterManager()->Destroy();
+  SMESH::GetMeasurements()->Destroy();
 #endif
   SMESH::GetFilterManager() = SMESH::FilterManager::_nil();
+  SMESH::GetMeasurements() = SMESH::Measurements::_nil();
 }
 
 //=============================================================================
@@ -1660,6 +1818,19 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       SMESHGUI_Preferences_ScalarBarDlg::ScalarBarProperties( this );
       break;
     }
+  case 202:
+    {
+      // dump control distribution data to the text file
+      ::SaveDistribution();
+      break;
+    }
+
+  case 203:
+    {
+      // show/ distribution
+      ::ShowDistribution();
+      break;
+    }
 
     // Auto-color
   case 1136:
@@ -2238,7 +2409,9 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
     }
 
   case 900:                                     // MESH INFOS
+  case 903:                                     // WHAT IS
     {
+      int page = theCommandID == 900 ? SMESHGUI_MeshInfoDlg::BaseInfo : SMESHGUI_MeshInfoDlg::ElemInfo;
       EmitSignalDeactivateDialog();
       LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
       SALOME_ListIO selected;
@@ -2246,21 +2419,20 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
         aSel->selectedObjects( selected );
 
       if ( selected.Extent() > 1 ) { // a dlg for each IO
-        SALOME_ListIO IOs;
-        SALOME_ListIteratorOfListIO It (selected);
+        SALOME_ListIteratorOfListIO It( selected );
         for ( ; It.More(); It.Next() ) {
-          IOs.Clear(); IOs.Append( It.Value() );
-          aSel->setSelectedObjects( IOs );
-          ( new SMESHGUI_MeshInfosDlg( this ) )->show();
+          SMESHGUI_MeshInfoDlg* dlg = new SMESHGUI_MeshInfoDlg( SMESHGUI::desktop(), page );
+          dlg->showInfo( It.Value() ); 
+          dlg->show();
         }
-        // restore selection
-        aSel->setSelectedObjects( selected );
       }
-      else
-        ( new SMESHGUI_MeshInfosDlg( this ) )->show();
+      else {
+        SMESHGUI_MeshInfoDlg* dlg = new SMESHGUI_MeshInfoDlg( SMESHGUI::desktop(), page );
+        dlg->show();
+      }
       break;
     }
-
+    /*
   case 902:                                     // STANDARD MESH INFOS
     {
       EmitSignalDeactivateDialog();
@@ -2285,13 +2457,13 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
         ( new SMESHGUI_StandardMeshInfosDlg( this ) )->show();
       break;
     }
-
   case 903:                                     // WHAT IS
     {
       EmitSignalDeactivateDialog();
       ( new SMESHGUI_WhatIsDlg( this ) )->show();
       break;
     }
+    */
 
   case 904:                                     // FIND ELEM
     {
@@ -2786,6 +2958,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case 6005:
   case 6009:
   case 6021:
+  case 6022:
+  case 6023:
     if ( vtkwnd ) {
 
       LightApp_SelectionMgr* mgr = selectionMgr();
@@ -2846,6 +3020,15 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       }
       break;
     }
+  case 501:
+  case 502:
+    {
+      int page = theCommandID == 501 ? SMESHGUI_MeasureDlg::MinDistance : SMESHGUI_MeasureDlg::BoundingBox;
+      EmitSignalDeactivateDialog();
+      SMESHGUI_MeasureDlg* dlg = new SMESHGUI_MeasureDlg( SMESHGUI::desktop(), page );
+      dlg->show();
+      break;
+    }
   }
 
   anApp->updateActions(); //SRN: To update a Save button in the toolbar
@@ -3010,12 +3193,14 @@ void SMESHGUI::initialize( CAM_Application* app )
   createSMESHAction(  814, "UNDERLYING_ELEMS","ICON_UNDERLYING_ELEMS" );
   createSMESHAction(  813, "DEL_GROUP",       "ICON_DEL_GROUP" );
   createSMESHAction(  900, "ADV_INFO",        "ICON_ADV_INFO" );
-  createSMESHAction(  902, "STD_INFO",        "ICON_STD_INFO" );
+  //createSMESHAction(  902, "STD_INFO",        "ICON_STD_INFO" );
   createSMESHAction(  903, "WHAT_IS",         "ICON_WHAT_IS" );
   createSMESHAction(  904, "FIND_ELEM",       "ICON_FIND_ELEM" );
   createSMESHAction( 6001, "LENGTH",          "ICON_LENGTH",        0, true );
   createSMESHAction( 6002, "FREE_EDGE",       "ICON_FREE_EDGE",     0, true );
   createSMESHAction( 6021, "FREE_FACES",      "ICON_FREE_FACES",    0, true );
+  createSMESHAction( 6022, "MAX_ELEMENT_LENGTH_2D", "ICON_MAX_ELEMENT_LENGTH_2D", 0, true );
+  createSMESHAction( 6023, "MAX_ELEMENT_LENGTH_3D", "ICON_MAX_ELEMENT_LENGTH_3D", 0, true );
   createSMESHAction( 6003, "FREE_BORDER",     "ICON_FREE_EDGE_2D",  0, true );
   createSMESHAction( 6004, "CONNECTION",      "ICON_CONNECTION",    0, true );
   createSMESHAction( 6005, "FREE_NODE",       "ICON_FREE_NODE",     0, true );
@@ -3067,6 +3252,8 @@ void SMESHGUI::initialize( CAM_Application* app )
   createSMESHAction(  419, "SPLIT_TO_TETRA",  "ICON_SPLIT_TO_TETRA" );
   createSMESHAction(  200, "RESET" );
   createSMESHAction(  201, "SCALAR_BAR_PROP" );
+  createSMESHAction(  202, "SAVE_DISTRIBUTION" );
+  createSMESHAction(  203, "SHOW_DISTRIBUTION","",0, true );
   createSMESHAction(  211, "WIRE",           "ICON_WIRE", 0, true );
   createSMESHAction(  212, "SHADE",          "ICON_SHADE", 0, true );
   createSMESHAction(  213, "SHRINK",         "ICON_SHRINK", 0, true );
@@ -3096,6 +3283,9 @@ void SMESHGUI::initialize( CAM_Application* app )
   createSMESHAction( 1137, "DISABLE_AUTO_COLOR" );
   createSMESHAction( 2000, "CTRL" );
 
+  createSMESHAction( 501, "MEASURE_MIN_DIST", "ICON_MEASURE_MIN_DIST" );
+  createSMESHAction( 502, "MEASURE_BND_BOX",  "ICON_MEASURE_BND_BOX" );
+
   createSMESHAction( 300, "ERASE" );
   createSMESHAction( 301, "DISPLAY" );
   createSMESHAction( 302, "DISPLAY_ONLY" );
@@ -3109,18 +3299,23 @@ void SMESHGUI::initialize( CAM_Application* app )
   createSMESHAction( 4040, "QUADRATIC_HEXAHEDRON", "ICON_DLG_QUADRATIC_HEXAHEDRON" );
 
   // ----- create menu --------------
-  int fileId   = createMenu( tr( "MEN_FILE" ),   -1,  1 ),
-      editId   = createMenu( tr( "MEN_EDIT" ),   -1,  3 ),
-      toolsId  = createMenu( tr( "MEN_TOOLS" ),  -1,  5, 50 ),
-      meshId   = createMenu( tr( "MEN_MESH" ),   -1, 70, 10 ),
-      ctrlId   = createMenu( tr( "MEN_CTRL" ),   -1, 60, 10 ),
-      modifyId = createMenu( tr( "MEN_MODIFY" ), -1, 40, 10 ),
-      viewId   = createMenu( tr( "MEN_VIEW" ),   -1,  2 );
+  int fileId    = createMenu( tr( "MEN_FILE" ),    -1,  1 ),
+      editId    = createMenu( tr( "MEN_EDIT" ),    -1,  3 ),
+      toolsId   = createMenu( tr( "MEN_TOOLS" ),   -1,  5, 50 ),
+      meshId    = createMenu( tr( "MEN_MESH" ),    -1, 70, 10 ),
+      ctrlId    = createMenu( tr( "MEN_CTRL" ),    -1, 60, 10 ),
+      modifyId  = createMenu( tr( "MEN_MODIFY" ),  -1, 40, 10 ),
+      measureId = createMenu( tr( "MEN_MEASURE" ), -1, 50, 10 ),
+      viewId    = createMenu( tr( "MEN_VIEW" ),    -1,  2 );
 
   createMenu( separator(), fileId );
 
   int importId = createMenu( tr( "MEN_IMPORT" ), fileId, -1, 10 ),
       exportId = createMenu( tr( "MEN_EXPORT" ), fileId, -1, 10 ),
+      nodeId   = createMenu( tr( "MEN_NODE_CTRL" ), ctrlId, -1, 10 ),
+      edgeId   = createMenu( tr( "MEN_EDGE_CTRL" ), ctrlId, -1, 10 ),
+      faceId   = createMenu( tr( "MEN_FACE_CTRL" ), ctrlId, -1, 10 ),
+      volumeId = createMenu( tr( "MEN_VOLUME_CTRL" ), ctrlId, -1, 10 ),
       addId    = createMenu( tr( "MEN_ADD" ),    modifyId, 402 ),
       removeId = createMenu( tr( "MEN_REMOVE" ), modifyId, 403 ),
       renumId  = createMenu( tr( "MEN_RENUM" ),  modifyId, 404 ),
@@ -3166,30 +3361,29 @@ void SMESHGUI::initialize( CAM_Application* app )
   createMenu( 813, meshId, -1 );
   createMenu( separator(), meshId, -1 );
   createMenu( 900, meshId, -1 );
-  createMenu( 902, meshId, -1 );
+  //createMenu( 902, meshId, -1 );
   createMenu( 903, meshId, -1 );
   createMenu( 904, meshId, -1 );
   createMenu( separator(), meshId, -1 );
 
-  createMenu( 6003, ctrlId, -1 );
-  createMenu( 6001, ctrlId, -1 );
-  createMenu( 6004, ctrlId, -1 );
-  createMenu( separator(), ctrlId, -1 );
-  createMenu( 6005, ctrlId, -1 );
-  createMenu( 6002, ctrlId, -1 );
-  createMenu( 6018, ctrlId, -1 );
-  createMenu( 6019, ctrlId, -1 );
-  createMenu( 6011, ctrlId, -1 );
-  createMenu( 6012, ctrlId, -1 );
-  createMenu( 6013, ctrlId, -1 );
-  createMenu( 6014, ctrlId, -1 );
-  createMenu( 6015, ctrlId, -1 );
-  createMenu( 6016, ctrlId, -1 );
-  createMenu( separator(), ctrlId, -1 );
-  createMenu( 6017, ctrlId, -1 );
-  createMenu( 6009, ctrlId, -1 );
-  createMenu( 6021, ctrlId, -1 );
-  createMenu( separator(), ctrlId, -1 );
+  createMenu( 6005, nodeId, -1 );
+  createMenu( 6002, edgeId, -1 );
+  createMenu( 6003, edgeId, -1 );
+  createMenu( 6001, edgeId, -1 );
+  createMenu( 6004, edgeId, -1 );
+  createMenu( 6021, faceId, -1 );
+  createMenu( 6018, faceId, -1 );
+  createMenu( 6019, faceId, -1 );
+  createMenu( 6011, faceId, -1 );
+  createMenu( 6012, faceId, -1 );
+  createMenu( 6013, faceId, -1 );
+  createMenu( 6014, faceId, -1 );
+  createMenu( 6015, faceId, -1 );
+  createMenu( 6016, faceId, -1 );
+  createMenu( 6022, faceId, -1 );
+  createMenu( 6017, volumeId, -1 );
+  createMenu( 6009, volumeId, -1 );
+  createMenu( 6023, volumeId, -1 );
 
   createMenu( 4000, addId, -1 );
   createMenu( 4009, addId, -1 );
@@ -3242,6 +3436,8 @@ void SMESHGUI::initialize( CAM_Application* app )
   createMenu( 417, modifyId, -1 );
   createMenu( 418, modifyId, -1 );
 
+  createMenu( 501, measureId, -1 );
+  createMenu( 502, measureId, -1 );
   createMenu( 214, viewId, -1 );
 
   // ----- create toolbars --------------
@@ -3268,17 +3464,19 @@ void SMESHGUI::initialize( CAM_Application* app )
   //createTool( 815, meshTb );
   createTool( separator(), meshTb );
   createTool( 900, meshTb );
-  createTool( 902, meshTb );
+  //createTool( 902, meshTb );
   createTool( 903, meshTb );
   createTool( 904, meshTb );
   createTool( separator(), meshTb );
 
-  createTool( 6001, ctrlTb );
+  createTool( 6005, ctrlTb );
+  createTool( separator(), ctrlTb );
+  createTool( 6002, ctrlTb );
   createTool( 6003, ctrlTb );
+  createTool( 6001, ctrlTb );
   createTool( 6004, ctrlTb );
   createTool( separator(), ctrlTb );
-  createTool( 6005, ctrlTb );
-  createTool( 6002, ctrlTb );
+  createTool( 6021, ctrlTb );
   createTool( 6018, ctrlTb );
   createTool( 6019, ctrlTb );
   createTool( 6011, ctrlTb );
@@ -3287,10 +3485,11 @@ void SMESHGUI::initialize( CAM_Application* app )
   createTool( 6014, ctrlTb );
   createTool( 6015, ctrlTb );
   createTool( 6016, ctrlTb );
+  createTool( 6022, ctrlTb );
   createTool( separator(), ctrlTb );
   createTool( 6017, ctrlTb );
   createTool( 6009, ctrlTb );
-  createTool( 6021, ctrlTb );
+  createTool( 6023, ctrlTb );
   createTool( separator(), ctrlTb );
 
   createTool( 4000, addRemTb );
@@ -3398,7 +3597,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   createPopupItem( 713, OB, mesh, "&& isComputable" );     // MESH ORDER
   createPopupItem( 214, OB, mesh_group );                  // UPDATE
   createPopupItem( 900, OB, mesh_group );                  // ADV_INFO
-  createPopupItem( 902, OB, mesh );                        // STD_INFO
+  //createPopupItem( 902, OB, mesh );                        // STD_INFO
   createPopupItem( 903, OB, mesh_group );                  // WHAT_IS
   createPopupItem( 904, OB, mesh_group );                  // FIND_ELEM
   popupMgr()->insert( separator(), -1, 0 );
@@ -3434,7 +3633,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   popupMgr()->insert( separator(), -1, 0 );
   createPopupItem( 214, View, mesh_group ); // UPDATE
   createPopupItem( 900, View, mesh_group ); // ADV_INFO
-  createPopupItem( 902, View, mesh );       // STD_INFO
+  //createPopupItem( 902, View, mesh );       // STD_INFO
   createPopupItem( 903, View, mesh_group ); // WHAT_IS
   createPopupItem( 904, View, mesh_group ); // FIND_ELEM
   popupMgr()->insert( separator(), -1, 0 );
@@ -3551,14 +3750,6 @@ void SMESHGUI::initialize( CAM_Application* app )
   popupMgr()->insert( action( 1133 ), -1, -1 );
   popupMgr()->setRule( action( 1133 ), aMeshInVTK + "&& isVisible", QtxPopupMgr::VisibleRule );
 
-  //-------------------------------------------------
-  // Clipping
-  //-------------------------------------------------
-  popupMgr()->insert( action( 1134 ), -1, -1 );
-  popupMgr()->setRule( action( 1134 ), aMeshInVTK + "&& selcount=1 && isVisible", QtxPopupMgr::VisibleRule );
-
-  popupMgr()->insert( separator(), -1, -1 );
-
   //-------------------------------------------------
   // Controls
   //-------------------------------------------------
@@ -3575,80 +3766,102 @@ void SMESHGUI::initialize( CAM_Application* app )
 
   popupMgr()->insert( separator(), anId, -1 );
 
-  popupMgr()->insert( action( 6003 ), anId, -1 ); // FREE_BORDER
+  int aSubId = popupMgr()->insert( tr( "MEN_NODE_CTRL" ), anId, -1 ); // NODE CONTROLS
+
+  popupMgr()->insert( action( 6005 ), aSubId, -1 ); // FREE_NODE
+  popupMgr()->setRule( action( 6005 ), aMeshInVtkHasNodes, QtxPopupMgr::VisibleRule );
+  popupMgr()->setRule( action( 6005 ), "controlMode = 'eFreeNodes'", QtxPopupMgr::ToggleRule );
+
+  aSubId = popupMgr()->insert( tr( "MEN_EDGE_CTRL" ), anId, -1 ); // EDGE CONTROLS
+
+  popupMgr()->insert( action( 6002 ), aSubId, -1 ); // FREE_EDGE
+  popupMgr()->setRule( action( 6002 ), aMeshInVtkHasEdges, QtxPopupMgr::VisibleRule );
+  popupMgr()->setRule( action( 6002 ), "controlMode = 'eFreeEdges'", QtxPopupMgr::ToggleRule );
+
+  popupMgr()->insert( action( 6003 ), aSubId, -1 ); // FREE_BORDER
   popupMgr()->setRule( action( 6003 ), aMeshInVtkHasEdges, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( 6003 ), "controlMode = 'eFreeBorders'", QtxPopupMgr::ToggleRule );
 
-  popupMgr()->insert( action( 6001 ), anId, -1 ); // LENGTH
+  popupMgr()->insert( action( 6001 ), aSubId, -1 ); // LENGTH
   popupMgr()->setRule( action( 6001 ), aMeshInVtkHasEdges, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( 6001 ), "controlMode = 'eLength'", QtxPopupMgr::ToggleRule );
 
-  popupMgr()->insert( action( 6004 ), anId, -1 ); // CONNECTION
+  popupMgr()->insert( action( 6004 ), aSubId, -1 ); // CONNECTION
   popupMgr()->setRule( action( 6004 ), aMeshInVtkHasEdges, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( 6004 ), "controlMode = 'eMultiConnection'", QtxPopupMgr::ToggleRule );
 
-  popupMgr()->insert( separator(), anId, -1 );
+  aSubId = popupMgr()->insert( tr( "MEN_FACE_CTRL" ), anId, -1 ); // FACE CONTROLS
 
-  popupMgr()->insert( action( 6005 ), anId, -1 ); // FREE_NODE
-  popupMgr()->setRule( action( 6005 ), aMeshInVtkHasNodes, QtxPopupMgr::VisibleRule );
-  popupMgr()->setRule( action( 6005 ), "controlMode = 'eFreeNodes'", QtxPopupMgr::ToggleRule );
-
-  popupMgr()->insert( action( 6002 ), anId, -1 ); // FREE_EDGE
-  popupMgr()->setRule( action( 6002 ), aMeshInVtkHasEdges, QtxPopupMgr::VisibleRule );
-  popupMgr()->setRule( action( 6002 ), "controlMode = 'eFreeEdges'", QtxPopupMgr::ToggleRule );
+  popupMgr()->insert( action( 6021 ), aSubId, -1 ); // FREE_FACE
+  popupMgr()->setRule( action( 6021 ), aMeshInVtkHasFaces /*aMeshInVtkHasVolumes*/,
+                                       QtxPopupMgr::VisibleRule );
+  popupMgr()->setRule( action( 6021 ), "controlMode = 'eFreeFaces'", QtxPopupMgr::ToggleRule );
 
-  popupMgr()->insert( action( 6018 ), anId, -1 ); // LENGTH_2D
+  popupMgr()->insert( action( 6018 ), aSubId, -1 ); // LENGTH_2D
   popupMgr()->setRule( action( 6018 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( 6018 ), "controlMode = 'eLength2D'", QtxPopupMgr::ToggleRule );
 
-  popupMgr()->insert( action( 6019 ), anId, -1 ); // CONNECTION_2D
+  popupMgr()->insert( action( 6019 ), aSubId, -1 ); // CONNECTION_2D
   popupMgr()->setRule( action( 6019 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( 6019 ), "controlMode = 'eMultiConnection2D'", QtxPopupMgr::ToggleRule );
 
-  popupMgr()->insert( action( 6011 ), anId, -1 ); // AREA
+  popupMgr()->insert( action( 6011 ), aSubId, -1 ); // AREA
   popupMgr()->setRule( action( 6011 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( 6011 ), "controlMode = 'eArea'", QtxPopupMgr::ToggleRule );
 
-  popupMgr()->insert( action( 6012 ), anId, -1 ); // TAPER
+  popupMgr()->insert( action( 6012 ), aSubId, -1 ); // TAPER
   popupMgr()->setRule( action( 6012 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( 6012 ), "controlMode = 'eTaper'", QtxPopupMgr::ToggleRule );
 
-  popupMgr()->insert( action( 6013 ), anId, -1 ); // ASPECT
+  popupMgr()->insert( action( 6013 ), aSubId, -1 ); // ASPECT
   popupMgr()->setRule( action( 6013 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( 6013 ), "controlMode = 'eAspectRatio'", QtxPopupMgr::ToggleRule );
 
-  popupMgr()->insert( action( 6014 ), anId, -1 ); // MIN_ANG
+  popupMgr()->insert( action( 6014 ), aSubId, -1 ); // MIN_ANG
   popupMgr()->setRule( action( 6014 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( 6014 ), "controlMode = 'eMinimumAngle'", QtxPopupMgr::ToggleRule );
 
-  popupMgr()->insert( action( 6015 ), anId, -1 ); // WARP
+  popupMgr()->insert( action( 6015 ), aSubId, -1 ); // WARP
   popupMgr()->setRule( action( 6015 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( 6015 ), "controlMode = 'eWarping'", QtxPopupMgr::ToggleRule );
 
-  popupMgr()->insert( action( 6016 ), anId, -1 ); // SKEW
+  popupMgr()->insert( action( 6016 ), aSubId, -1 ); // SKEW
   popupMgr()->setRule( action( 6016 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( 6016 ), "controlMode = 'eSkew'", QtxPopupMgr::ToggleRule );
 
-  popupMgr()->insert( separator(), anId, -1 );
+  popupMgr()->insert( action( 6022 ), aSubId, -1 ); // MAX_ELEMENT_LENGTH_2D
+  popupMgr()->setRule( action( 6022 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
+  popupMgr()->setRule( action( 6022 ), "controlMode = 'eMaxElementLength2D'", QtxPopupMgr::ToggleRule );
 
-  popupMgr()->insert( action( 6017 ), anId, -1 ); // ASPECT_3D
+  aSubId = popupMgr()->insert( tr( "MEN_VOLUME_CTRL" ), anId, -1 ); // VOLUME CONTROLS
+
+  popupMgr()->insert( action( 6017 ), aSubId, -1 ); // ASPECT_3D
   popupMgr()->setRule( action( 6017 ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( 6017 ), "controlMode = 'eAspectRatio3D'", QtxPopupMgr::ToggleRule );
 
-  popupMgr()->insert ( action( 6009 ), anId, -1 ); // VOLUME_3D
+  popupMgr()->insert ( action( 6009 ), aSubId, -1 ); // VOLUME_3D
   popupMgr()->setRule( action( 6009 ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( 6009 ), "controlMode = 'eVolume3D'", QtxPopupMgr::ToggleRule );
 
-  popupMgr()->insert( action( 6021 ), anId, -1 ); // FREE_FACE
-  popupMgr()->setRule( action( 6021 ), aMeshInVtkHasFaces /*aMeshInVtkHasVolumes*/,
-                                       QtxPopupMgr::VisibleRule );
-  popupMgr()->setRule( action( 6021 ), "controlMode = 'eFreeFaces'", QtxPopupMgr::ToggleRule );
+  popupMgr()->insert( action( 6023 ), aSubId, -1 ); // MAX_ELEMENT_LENGTH_3D
+  popupMgr()->setRule( action( 6023 ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule );
+  popupMgr()->setRule( action( 6023 ), "controlMode = 'eMaxElementLength3D'", QtxPopupMgr::ToggleRule );
 
   popupMgr()->insert( separator(), anId, -1 );
 
   popupMgr()->insert( action( 201 ), anId, -1 ); // SCALAR_BAR_PROP
   popupMgr()->setRule( action( 201 ), aMeshInVTK + "&& controlMode <> 'eNone'", QtxPopupMgr::VisibleRule );
 
+  popupMgr()->insert( separator(), anId, -1 );
+
+  popupMgr()->insert( action( 202 ), anId, -1 ); // SAVE_DISTRIBUTION
+  popupMgr()->setRule( action( 202 ), aMeshInVTK + "&& isNumFunctor", QtxPopupMgr::VisibleRule );
+
+  popupMgr()->insert( action( 203 ), anId, -1 ); // SHOW_DISTRIBUTION
+  popupMgr()->setRule( action( 203 ), aMeshInVTK + "&& isNumFunctor", QtxPopupMgr::VisibleRule );
+  popupMgr()->setRule( action( 203 ), aMeshInVTK + "&& isNumFunctor && isDistributionVisible", QtxPopupMgr::ToggleRule);
+
+
   popupMgr()->insert( separator(), -1, -1 );
 
   //-------------------------------------------------
@@ -3667,8 +3880,19 @@ void SMESHGUI::initialize( CAM_Application* app )
 
   popupMgr()->insert( separator(), -1, -1 );
 
+  //-------------------------------------------------
+  // Clipping
+  //-------------------------------------------------
+  popupMgr()->insert( action( 1134 ), -1, -1 );
+  popupMgr()->setRule( action( 1134 ), "client='VTKViewer'", QtxPopupMgr::VisibleRule );
+
+  popupMgr()->insert( separator(), -1, -1 );
+
   connect( application(), SIGNAL( viewManagerActivated( SUIT_ViewManager* ) ),
            this, SLOT( onViewManagerActivated( SUIT_ViewManager* ) ) );
+
+  connect( application(), SIGNAL( viewManagerRemoved( SUIT_ViewManager* ) ),
+           this, SLOT( onViewManagerRemoved( SUIT_ViewManager* ) ) );
 }
 
 //================================================================================
@@ -3825,6 +4049,49 @@ void SMESHGUI::onViewManagerActivated( SUIT_ViewManager* mgr )
     SMESH::UpdateSelectionProp( this );
 }
 
+void SMESHGUI::onViewManagerRemoved( SUIT_ViewManager* theViewManager )
+{
+  if( theViewManager && theViewManager->getType() == SVTK_Viewer::Type() )
+    myClippingPlaneInfoMap.erase( theViewManager );
+}
+
+void SMESHGUI::addActorAsObserver( SMESH_Actor* theActor )
+{
+  theActor->AddObserver( SMESH::DeleteActorEvent,
+                         myEventCallbackCommand.GetPointer(),
+                         myPriority );
+}
+
+void SMESHGUI::ProcessEvents( vtkObject* theObject,
+                              unsigned long theEvent,
+                              void* theClientData,
+                              void* theCallData )
+{
+  if( SMESHGUI* aSMESHGUI = reinterpret_cast<SMESHGUI*>( theClientData ) ) {
+    if( theObject && theEvent == SMESH::DeleteActorEvent ) {
+      if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( theObject ) ) {
+        SMESHGUI_ClippingPlaneInfoMap& aClippingPlaneInfoMap = aSMESHGUI->getClippingPlaneInfoMap();
+        SMESHGUI_ClippingPlaneInfoMap::iterator anIter1 = aClippingPlaneInfoMap.begin();
+        for( ; anIter1 != aClippingPlaneInfoMap.end(); anIter1++ ) {
+          SMESHGUI_ClippingPlaneInfoList& aClippingPlaneInfoList = anIter1->second;
+          SMESHGUI_ClippingPlaneInfoList::iterator anIter2 = aClippingPlaneInfoList.begin();
+          for( ; anIter2 != aClippingPlaneInfoList.end(); anIter2++ ) {
+            SMESH::ClippingPlaneInfo& aClippingPlaneInfo = *anIter2;
+            std::list<vtkActor*>& anActorList = aClippingPlaneInfo.ActorList;
+            SMESH::TActorList::iterator anIter3 = anActorList.begin();
+            for ( ; anIter3 != anActorList.end(); anIter3++ ) {
+              if( anActor == *anIter3 ) {
+                anActorList.erase( anIter3 );
+                break;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
 void SMESHGUI::createPreferences()
 {
   // General tab ------------------------------------------------------------------------
@@ -3889,9 +4156,9 @@ void SMESHGUI::createPreferences()
   setPreferenceProperty( computeGroup, "columns", 2 );
   int notifyMode = addPreference( tr( "PREF_NOTIFY_MODE" ), computeGroup, LightApp_Preferences::Selector, "SMESH", "show_result_notification" );
   modes.clear();
-  modes.append( "Never" );
-  modes.append( "Errors only" );
-  modes.append( "Always" );
+  modes.append( tr( "PREF_NOTIFY_NEVER" ) );
+  modes.append( tr( "PREF_NOTIFY_ERROR" ) );
+  modes.append( tr( "PREF_NOTIFY_ALWAYS" ) );
   indices.clear();
   indices.append( 0 );
   indices.append( 1 );
@@ -3899,6 +4166,18 @@ void SMESHGUI::createPreferences()
   setPreferenceProperty( notifyMode, "strings", modes );
   setPreferenceProperty( notifyMode, "indexes", indices );
 
+  int infoGroup = addPreference( tr( "PREF_GROUP_INFO" ), genTab );
+  setPreferenceProperty( computeGroup, "columns", 2 );
+  int elemInfo = addPreference( tr( "PREF_ELEM_INFO" ), infoGroup, LightApp_Preferences::Selector, "SMESH", "mesh_elem_info" );
+  modes.clear();
+  modes.append( tr( "PREF_ELEM_INFO_SIMPLE" ) );
+  modes.append( tr( "PREF_ELEM_INFO_TREE" ) );
+  indices.clear();
+  indices.append( 0 );
+  indices.append( 1 );
+  setPreferenceProperty( elemInfo, "strings", modes );
+  setPreferenceProperty( elemInfo, "indexes", indices );
+
   int segGroup = addPreference( tr( "PREF_GROUP_SEGMENT_LENGTH" ), genTab );
   setPreferenceProperty( segGroup, "columns", 2 );
   int segLen = addPreference( tr( "PREF_SEGMENT_LENGTH" ), segGroup, LightApp_Preferences::IntSpin,
@@ -4118,6 +4397,18 @@ void SMESHGUI::createPreferences()
   setPreferenceProperty( hh, "min", 0.0 );
   setPreferenceProperty( hh, "max", 1.0 );
   setPreferenceProperty( hh, "step", 0.1 );
+  
+  int distributionGr = addPreference( tr( "SMESH_DISTRIBUTION_SCALARBAR" ), sbarTab, LightApp_Preferences::Auto, "SMESH", "distribution_visibility" );
+  int coloringType = addPreference( tr( "SMESH_DISTRIBUTION_COLORING_TYPE" ), distributionGr, LightApp_Preferences::Selector, "SMESH", "distribution_coloring_type" );
+  setPreferenceProperty( distributionGr, "columns", 3 );
+  QStringList types;
+  types.append( tr( "SMESH_MONOCOLOR" ) ); 
+  types.append( tr( "SMESH_MULTICOLOR" ) );
+  indices.clear(); indices.append( 0 ); indices.append( 1 );
+  setPreferenceProperty( coloringType, "strings", types );
+  setPreferenceProperty( coloringType, "indexes", indices );
+  addPreference( tr( "SMESH_DISTRIBUTION_COLOR" ), distributionGr, LightApp_Preferences::Color, "SMESH", "distribution_color" );
+
 }
 
 void SMESHGUI::preferencesChanged( const QString& sect, const QString& name )
@@ -4337,12 +4628,9 @@ SALOMEDS::Color SMESHGUI::getUniqueColor( const QList<SALOMEDS::Color>& theReser
       if( aTolerance < 1 )
         break;
     }
-    //cout << "Iteration N" << anIterations << " (tolerance=" << aTolerance << ")"<< endl;
 
     aHue = (int)( 360.0 * rand() / RAND_MAX );
-    //cout << "Hue = " << aHue << endl;
 
-    //cout << "Auto colors : ";
     bool ok = true;
     QList<SALOMEDS::Color>::const_iterator it = theReservedColors.constBegin();
     QList<SALOMEDS::Color>::const_iterator itEnd = theReservedColors.constEnd();
@@ -4353,21 +4641,17 @@ SALOMEDS::Color SMESHGUI::getUniqueColor( const QList<SALOMEDS::Color>& theReser
 
       int h, s, v;
       aQColor.getHsv( &h, &s, &v );
-      //cout << h << " ";
       if( abs( h - aHue ) < aTolerance )
       {
         ok = false;
-        //cout << "break (diff = " << abs( h - aHue ) << ")";
         break;
       }
     }
-    //cout << endl;
 
     if( ok )
       break;
   }
 
-  //cout << "Hue of the returned color = " << aHue << endl;
   QColor aColor;
   aColor.setHsv( aHue, 255, 255 );
 
@@ -4455,6 +4739,37 @@ void SMESHGUI::storeVisualParameters (int savePoint)
     // saving VTK actors properties
     if (vType == SVTK_Viewer::Type())
     {
+      // store the clipping planes attached to the view manager
+      SMESHGUI_ClippingPlaneInfoList aClippingPlaneInfoList;
+      SMESHGUI_ClippingPlaneInfoMap::const_iterator anIter = myClippingPlaneInfoMap.find( vman );
+      if( anIter != myClippingPlaneInfoMap.end() )
+        aClippingPlaneInfoList = anIter->second;
+
+      if( !aClippingPlaneInfoList.empty() ) {
+        SMESHGUI_ClippingPlaneInfoList::const_iterator anIter = aClippingPlaneInfoList.begin();
+        for( int anId = 0; anIter != aClippingPlaneInfoList.end(); anIter++, anId++ )
+        {
+          const SMESH::ClippingPlaneInfo& aClippingPlaneInfo = *anIter;
+          SMESH::OrientedPlane* aPlane = aClippingPlaneInfo.Plane;
+
+          QString aPropertyName( "ClippingPlane" );
+          aPropertyName += gSeparator;
+          aPropertyName += QString::number( vtkViewers );
+          aPropertyName += gSeparator;
+          aPropertyName += QString::number( anId );
+
+          QString aPropertyValue = QString::number( (int)aPlane->GetOrientation() ).toLatin1().constData();
+          aPropertyValue += gDigitsSep;
+          aPropertyValue += QString::number( aPlane->GetDistance() ).toLatin1().constData();
+          aPropertyValue += gDigitsSep;
+          aPropertyValue += QString::number( aPlane->myAngle[0] ).toLatin1().constData();
+          aPropertyValue += gDigitsSep;
+          aPropertyValue += QString::number( aPlane->myAngle[1] ).toLatin1().constData();
+
+          ip->setProperty( aPropertyName.toStdString(), aPropertyValue.toStdString() );
+        }
+      }
+
       QVector<SUIT_ViewWindow*> views = vman->getViews();
       for (int i = 0, iEnd = vman->getViewsCount(); i < iEnd; i++)
       {
@@ -4580,22 +4895,25 @@ void SMESHGUI::storeVisualParameters (int savePoint)
 
                   // Clipping
                   param = vtkParam + "ClippingPlane";
-                  int nPlanes = aSmeshActor->GetNumberOfClippingPlanes();
-                  if (!nPlanes)
-                    ip->setParameter(entry, param, "Off");
-                  for (int ipl = 0; ipl < nPlanes; ipl++) {
-                    //vtkPlane* plane = aSmeshActor->GetClippingPlane(ipl);
-                    SMESH::Orientation anOrientation;
-                    double aDistance;
-                    vtkFloatingPointType anAngle[2];
-                    SMESHGUI_ClippingDlg::GetPlaneParam(aSmeshActor, ipl, anOrientation, aDistance, anAngle);
-                    std::string planeValue = QString::number((int)anOrientation).toLatin1().data();
-                    planeValue += gDigitsSep; planeValue += QString::number(aDistance).toLatin1().data();
-                    planeValue += gDigitsSep; planeValue += QString::number(anAngle[0]).toLatin1().data();
-                    planeValue += gDigitsSep; planeValue += QString::number(anAngle[1]).toLatin1().data();
-
-                    ip->setParameter(entry, param + QString::number(ipl+1).toLatin1().data(), planeValue);
+                  int aPlaneId = 0;
+                  if( !aClippingPlaneInfoList.empty() ) {
+                    SMESHGUI_ClippingPlaneInfoList::const_iterator anIter1 = aClippingPlaneInfoList.begin();
+                    for( int anId = 0; anIter1 != aClippingPlaneInfoList.end(); anIter1++, anId++ )
+                    {
+                      const SMESH::ClippingPlaneInfo& aClippingPlaneInfo = *anIter1;
+                      std::list<vtkActor*> anActorList = aClippingPlaneInfo.ActorList;
+                      SMESH::TActorList::iterator anIter2 = anActorList.begin();
+                      for ( ; anIter2 != anActorList.end(); anIter2++ ) {
+                        if( aSmeshActor == *anIter2 ) {
+                          ip->setParameter( entry, param + QString::number( ++aPlaneId ).toLatin1().constData(),
+                                            QString::number( anId ).toLatin1().constData() );                          
+                          break;
+                        }
+                      }
+                    }
                   }
+                  if( aPlaneId == 0 )
+                    ip->setParameter( entry, param, "Off" );
                 } // if (io->hasEntry())
               } // SMESH_Actor && hasIO
             } // isVisible
@@ -4607,6 +4925,25 @@ void SMESHGUI::storeVisualParameters (int savePoint)
   } // for (viewManagers)
 }
 
+// data structures for clipping planes processing
+typedef struct {
+  int Id;
+  vtkIdType Orientation;
+  vtkFloatingPointType Distance;
+  vtkFloatingPointType Angle[2];
+} TPlaneData;
+typedef std::list<TPlaneData>         TPlaneDataList;
+typedef std::map<int, TPlaneDataList> TPlaneDataMap;
+
+typedef std::list<vtkActor*>          TActorList;
+typedef struct {
+  int PlaneId;
+  TActorList ActorList;
+  SUIT_ViewManager* ViewManager;
+} TPlaneInfo;
+typedef std::list<TPlaneInfo>         TPlaneInfoList;
+typedef std::map<int, TPlaneInfoList> TPlaneInfoMap;
+
 /*!
  * \brief Restore visual parameters
  *
@@ -4631,8 +4968,9 @@ void SMESHGUI::restoreVisualParameters (int savePoint)
                                                              savePoint);
   _PTR(IParameters) ip = ClientFactory::getIParameters(ap);
 
-  // restore map of custom markers
+  // restore map of custom markers and map of clipping planes
   VTK::MarkerMap& aMarkerMap = myMarkerMap[ studyDS->StudyId() ];
+  TPlaneDataMap aPlaneDataMap;
 
   std::vector<std::string> properties = ip->getProperties();
   for (std::vector<std::string>::iterator propIt = properties.begin(); propIt != properties.end(); ++propIt)
@@ -4642,52 +4980,103 @@ void SMESHGUI::restoreVisualParameters (int savePoint)
     QString aPropertyValue( ip->getProperty( property ).c_str() );
 
     QStringList aPropertyNameList = aPropertyName.split( gSeparator, QString::SkipEmptyParts );
-    if( aPropertyNameList.size() != 2 )
+    if( aPropertyNameList.isEmpty() )
       continue;
 
-    int anId = 0;
-    bool ok = false;
-    if( aPropertyNameList[0] == "texture" )
-      anId = aPropertyNameList[1].toInt( &ok );
+    QString aPropertyType = aPropertyNameList[0];
+    if( aPropertyType == "texture" )
+    {
+      if( aPropertyNameList.size() != 2 )
+        continue;
 
-    if( !ok || anId < 1 )
-      continue;
+      bool ok = false;
+      int anId = aPropertyNameList[1].toInt( &ok );
+      if( !ok || anId < 1 )
+        continue;
 
-    QStringList aPropertyValueList = aPropertyValue.split( gPathSep, QString::SkipEmptyParts );
-    if( aPropertyValueList.size() != 2 )
-      continue;
+      QStringList aPropertyValueList = aPropertyValue.split( gPathSep, QString::SkipEmptyParts );
+      if( aPropertyValueList.size() != 2 )
+        continue;
 
-    std::string aMarkerFileName = aPropertyValueList[0].toStdString();
-    QString aMarkerTextureString = aPropertyValueList[1];
-    QStringList aMarkerTextureStringList = aMarkerTextureString.split( gDigitsSep, QString::SkipEmptyParts );
-    if( aMarkerTextureStringList.size() != 3 )
-      continue;
+      std::string aMarkerFileName = aPropertyValueList[0].toStdString();
+      QString aMarkerTextureString = aPropertyValueList[1];
+      QStringList aMarkerTextureStringList = aMarkerTextureString.split( gDigitsSep, QString::SkipEmptyParts );
+      if( aMarkerTextureStringList.size() != 3 )
+        continue;
 
-    ok = false;
-    ushort aWidth = aMarkerTextureStringList[0].toUShort( &ok );
-    if( !ok )
-      continue;
+      ok = false;
+      ushort aWidth = aMarkerTextureStringList[0].toUShort( &ok );
+      if( !ok )
+        continue;
 
-    ok = false;
-    ushort aHeight = aMarkerTextureStringList[1].toUShort( &ok );
-    if( !ok )
-      continue;
+      ok = false;
+      ushort aHeight = aMarkerTextureStringList[1].toUShort( &ok );
+      if( !ok )
+        continue;
 
-    VTK::MarkerTexture aMarkerTexture;
-    aMarkerTexture.push_back( aWidth );
-    aMarkerTexture.push_back( aHeight );
+      VTK::MarkerTexture aMarkerTexture;
+      aMarkerTexture.push_back( aWidth );
+      aMarkerTexture.push_back( aHeight );
 
-    QString aMarkerTextureData = aMarkerTextureStringList[2];
-    for( int i = 0, n = aMarkerTextureData.length(); i < n; i++ )
-    {
-      QChar aChar = aMarkerTextureData.at( i );
-      if( aChar.isDigit() )
-        aMarkerTexture.push_back( aChar.digitValue() );
+      QString aMarkerTextureData = aMarkerTextureStringList[2];
+      for( int i = 0, n = aMarkerTextureData.length(); i < n; i++ )
+      {
+        QChar aChar = aMarkerTextureData.at( i );
+        if( aChar.isDigit() )
+          aMarkerTexture.push_back( aChar.digitValue() );
+      }
+
+      aMarkerMap[ anId ] = VTK::MarkerData( aMarkerFileName, aMarkerTexture );
     }
+    else if( aPropertyType == "ClippingPlane" )
+    {
+      if( aPropertyNameList.size() != 3 )
+        continue;
 
-    aMarkerMap[ anId ] = VTK::MarkerData( aMarkerFileName, aMarkerTexture );
+      bool ok = false;
+      int aViewId = aPropertyNameList[1].toInt( &ok );
+      if( !ok || aViewId < 0 )
+        continue;
+
+      ok = false;
+      int aClippingPlaneId = aPropertyNameList[2].toInt( &ok );
+      if( !ok || aClippingPlaneId < 0 )
+        continue;
+
+      QStringList aPropertyValueList = aPropertyValue.split( gDigitsSep, QString::SkipEmptyParts );
+      if( aPropertyValueList.size() != 4 )
+        continue;
+
+      TPlaneData aPlaneData;
+      aPlaneData.Id = aClippingPlaneId;
+
+      ok = false;
+      aPlaneData.Orientation = aPropertyValueList[0].toInt( &ok );
+      if( !ok )
+        continue;
+
+      ok = false;
+      aPlaneData.Distance = aPropertyValueList[1].toDouble( &ok );
+      if( !ok )
+        continue;
+
+      ok = false;
+      aPlaneData.Angle[0] = aPropertyValueList[2].toDouble( &ok );
+      if( !ok )
+        continue;
+
+      ok = false;
+      aPlaneData.Angle[1] = aPropertyValueList[3].toDouble( &ok );
+      if( !ok )
+        continue;
+
+      TPlaneDataList& aPlaneDataList = aPlaneDataMap[ aViewId ];
+      aPlaneDataList.push_back( aPlaneData );      
+    }
   }
 
+  TPlaneInfoMap aPlaneInfoMap;
+
   std::vector<std::string> entries = ip->getEntries();
 
   for (std::vector<std::string>::iterator entIt = entries.begin(); entIt != entries.end(); ++entIt)
@@ -4734,39 +5123,40 @@ void SMESHGUI::restoreVisualParameters (int savePoint)
         if (vtkActors.IsBound(viewIndex))
           aSmeshActor = vtkActors.Find(viewIndex);
 
+        QList<SUIT_ViewManager*> lst;
+        getApp()->viewManagers(viewerTypStr, lst);
+
+        // SVTK ViewManager always has 1 ViewWindow, so view index is index of view manager
+        SUIT_ViewManager* vman = NULL;
+        if (viewIndex >= 0 && viewIndex < lst.count())
+          vman = lst.at(viewIndex);
+
         if (paramNameStr == "Visibility")
         {
-          if (!aSmeshActor && displayer())
+          if (!aSmeshActor && displayer() && vman)
           {
-            QList<SUIT_ViewManager*> lst;
-            getApp()->viewManagers(viewerTypStr, lst);
-
-            // SVTK ViewManager always has 1 ViewWindow, so view index is index of view manager
-            if (viewIndex >= 0 && viewIndex < lst.count()) {
-              SUIT_ViewManager* vman = lst.at(viewIndex);
-              SUIT_ViewModel* vmodel = vman->getViewModel();
-              // SVTK view model can be casted to SALOME_View
-              displayer()->Display(entry, true, dynamic_cast<SALOME_View*>(vmodel));
-
-              // store displayed actor in a temporary map for quicker
-              // access later when restoring other parameters
-              SVTK_ViewWindow* vtkView = (SVTK_ViewWindow*) vman->getActiveView();
-              vtkRenderer* Renderer = vtkView->getRenderer();
-              VTK::ActorCollectionCopy aCopy(Renderer->GetActors());
-              vtkActorCollection* theActors = aCopy.GetActors();
-              theActors->InitTraversal();
-              bool isFound = false;
-              vtkActor *ac = theActors->GetNextActor();
-              for (; ac != NULL && !isFound; ac = theActors->GetNextActor()) {
-                if (ac->IsA("SMESH_Actor")) {
-                  SMESH_Actor* aGeomAc = SMESH_Actor::SafeDownCast(ac);
-                  if (aGeomAc->hasIO()) {
-                    Handle(SALOME_InteractiveObject) io =
-                      Handle(SALOME_InteractiveObject)::DownCast(aGeomAc->getIO());
-                    if (io->hasEntry() && strcmp(io->getEntry(), entry.toLatin1().data()) == 0) {
-                      isFound = true;
-                      vtkActors.Bind(viewIndex, aGeomAc);
-                    }
+            SUIT_ViewModel* vmodel = vman->getViewModel();
+            // SVTK view model can be casted to SALOME_View
+            displayer()->Display(entry, true, dynamic_cast<SALOME_View*>(vmodel));
+
+            // store displayed actor in a temporary map for quicker
+            // access later when restoring other parameters
+            SVTK_ViewWindow* vtkView = (SVTK_ViewWindow*) vman->getActiveView();
+            vtkRenderer* Renderer = vtkView->getRenderer();
+            VTK::ActorCollectionCopy aCopy(Renderer->GetActors());
+            vtkActorCollection* theActors = aCopy.GetActors();
+            theActors->InitTraversal();
+            bool isFound = false;
+            vtkActor *ac = theActors->GetNextActor();
+            for (; ac != NULL && !isFound; ac = theActors->GetNextActor()) {
+              if (ac->IsA("SMESH_Actor")) {
+                SMESH_Actor* aGeomAc = SMESH_Actor::SafeDownCast(ac);
+                if (aGeomAc->hasIO()) {
+                  Handle(SALOME_InteractiveObject) io =
+                    Handle(SALOME_InteractiveObject)::DownCast(aGeomAc->getIO());
+                  if (io->hasEntry() && strcmp(io->getEntry(), entry.toLatin1().data()) == 0) {
+                    isFound = true;
+                    vtkActors.Bind(viewIndex, aGeomAc);
                   }
                 }
               }
@@ -4883,14 +5273,16 @@ void SMESHGUI::restoreVisualParameters (int savePoint)
             }
             // Clipping
             else if (paramNameStr.startsWith("ClippingPlane")) {
-              cout << "$$$ ClippingPlane 1" << endl;
-              if (paramNameStr == "ClippingPlane1" || val == "Off")
-                aSmeshActor->RemoveAllClippingPlanes();
-              if (val != "Off") {
-                cout << "$$$ ClippingPlane 2" << endl;
-                QStringList vals = val.split(gDigitsSep, QString::SkipEmptyParts);
-                if (vals.count() == 4) { // format check: 4 values
-                  cout << "$$$ ClippingPlane 3" << endl;
+              QStringList vals = val.split(gDigitsSep, QString::SkipEmptyParts);
+              // old format - val looks like "Off" or "0:0.5:0:0" (orientation, distance, two angles)
+              // new format - val looks like "Off" or "0" (plane id)
+              // (note: in new format "Off" value is used only for consistency,
+              //  so it is processed together with values in old format)
+              bool anIsOldFormat = ( vals.count() == 4 || val == "Off" );
+              if( anIsOldFormat ) {
+                if (paramNameStr == "ClippingPlane1" || val == "Off")
+                  aSmeshActor->RemoveAllClippingPlanes();
+                if (val != "Off") {
                   SMESH::Orientation anOrientation = (SMESH::Orientation)vals[0].toInt();
                   double aDistance = vals[1].toFloat();
                   vtkFloatingPointType anAngle[2];
@@ -4903,8 +5295,43 @@ void SMESHGUI::restoreVisualParameters (int savePoint)
                   if (viewIndex >= 0 && viewIndex < lst.count()) {
                     SUIT_ViewManager* vman = lst.at(viewIndex);
                     SVTK_ViewWindow* vtkView = (SVTK_ViewWindow*) vman->getActiveView();
-                    SMESHGUI_ClippingDlg::AddPlane(aSmeshActor, vtkView,
-                                                   anOrientation, aDistance, anAngle);
+
+                    SMESHGUI_ClippingPlaneInfoList& aClippingPlaneInfoList = myClippingPlaneInfoMap[ vman ];
+
+                    SMESH::TActorList anActorList;
+                    anActorList.push_back( aSmeshActor );
+                    SMESH::OrientedPlane* aPlane =
+                      SMESHGUI_ClippingDlg::AddPlane(anActorList, vtkView, anOrientation, aDistance, anAngle);
+                    if( aPlane ) {
+                      SMESH::ClippingPlaneInfo aClippingPlaneInfo;
+                      aClippingPlaneInfo.Plane = aPlane;
+                      aClippingPlaneInfo.ActorList = anActorList;
+                      aClippingPlaneInfoList.push_back( aClippingPlaneInfo );
+                    }
+                  }
+                }
+              }
+              else {
+                bool ok = false;
+                int aPlaneId = val.toInt( &ok );
+                if( ok && aPlaneId >= 0 ) {
+                  bool anIsDefinedPlane = false;
+                  TPlaneInfoList& aPlaneInfoList = aPlaneInfoMap[ viewIndex ];
+                  TPlaneInfoList::iterator anIter = aPlaneInfoList.begin();
+                  for( ; anIter != aPlaneInfoList.end(); anIter++ ) {
+                    TPlaneInfo& aPlaneInfo = *anIter;
+                    if( aPlaneInfo.PlaneId == aPlaneId ) {
+                      aPlaneInfo.ActorList.push_back( aSmeshActor );
+                      anIsDefinedPlane = true;
+                      break;
+                    }
+                  }
+                  if( !anIsDefinedPlane ) {
+                    TPlaneInfo aPlaneInfo;
+                    aPlaneInfo.PlaneId = aPlaneId;
+                    aPlaneInfo.ActorList.push_back( aSmeshActor );
+                    aPlaneInfo.ViewManager = vman;
+                    aPlaneInfoList.push_back( aPlaneInfo );
                   }
                 }
               }
@@ -4915,6 +5342,55 @@ void SMESHGUI::restoreVisualParameters (int savePoint)
     } // for names/parameters iterator
   } // for entries iterator
 
+  // add clipping planes to actors according to the restored parameters
+  // and update the clipping plane map
+  TPlaneInfoMap::const_iterator anIter1 = aPlaneInfoMap.begin();
+  for( ; anIter1 != aPlaneInfoMap.end(); anIter1++ ) {
+    int aViewId = anIter1->first;
+    const TPlaneInfoList& aPlaneInfoList = anIter1->second;
+
+    TPlaneDataMap::const_iterator anIter2 = aPlaneDataMap.find( aViewId );
+    if( anIter2 == aPlaneDataMap.end() )
+      continue;
+    const TPlaneDataList& aPlaneDataList = anIter2->second;
+
+    TPlaneInfoList::const_iterator anIter3 = aPlaneInfoList.begin();
+    for( ; anIter3 != aPlaneInfoList.end(); anIter3++ ) {
+      const TPlaneInfo& aPlaneInfo = *anIter3;
+      int aPlaneId = aPlaneInfo.PlaneId;
+      const TActorList& anActorList = aPlaneInfo.ActorList;
+      SUIT_ViewManager* aViewManager = aPlaneInfo.ViewManager;
+      if( !aViewManager )
+        continue;
+
+      SVTK_ViewWindow* aViewWindow = dynamic_cast<SVTK_ViewWindow*>( aViewManager->getActiveView() );
+      if( !aViewWindow )
+        continue;
+
+      SMESHGUI_ClippingPlaneInfoList& aClippingPlaneInfoList = myClippingPlaneInfoMap[ aViewManager ];
+
+      TPlaneDataList::const_iterator anIter4 = aPlaneDataList.begin();
+      for( ; anIter4 != aPlaneDataList.end(); anIter4++ ) {
+        const TPlaneData& aPlaneData = *anIter4;
+        if( aPlaneData.Id == aPlaneId ) {
+          SMESH::OrientedPlane* aPlane =
+            SMESHGUI_ClippingDlg::AddPlane( anActorList,
+                                            aViewWindow,
+                                            (SMESH::Orientation)aPlaneData.Orientation,
+                                            aPlaneData.Distance,
+                                            aPlaneData.Angle );
+          if( aPlane ) {
+            SMESH::ClippingPlaneInfo aClippingPlaneInfo;
+            aClippingPlaneInfo.Plane = aPlane;
+            aClippingPlaneInfo.ActorList = anActorList;
+            aClippingPlaneInfoList.push_back( aClippingPlaneInfo );
+          }
+          break;
+        }
+      }
+    }
+  }
+
   // update all VTK views
   QList<SUIT_ViewManager*> lst;
   getApp()->viewManagers(lst);
index bb2b29c043327e39d8300d011fbec3bb729b414a..7aa14367f3afd342e117c550deacc95edf9caa6a 100644 (file)
 #include <SALOMEconfig.h>
 #include CORBA_SERVER_HEADER(SMESH_Gen)
 
+// VTK includes
+#include <vtkSmartPointer.h>
+#include <vtkType.h>
+
+class vtkActor;
+class vtkCallbackCommand;
+class vtkObject;
+
 class QDialog;
 
 class SUIT_Desktop;
@@ -52,10 +60,24 @@ class SalomeApp_Study;
 class LightApp_Selection;
 class LightApp_SelectionMgr;
 
+class SMESH_Actor;
 class SMESHGUI_FilterLibraryDlg;
 
 typedef std::map<int, VTK::MarkerMap> SMESHGUI_StudyId2MarkerMap;
 
+namespace SMESH
+{
+  class OrientedPlane;
+  struct ClippingPlaneInfo
+  {
+    OrientedPlane*       Plane;
+    std::list<vtkActor*> ActorList;
+  };
+}
+
+typedef std::list<SMESH::ClippingPlaneInfo>                         SMESHGUI_ClippingPlaneInfoList;
+typedef std::map<SUIT_ViewManager*, SMESHGUI_ClippingPlaneInfoList> SMESHGUI_ClippingPlaneInfoMap;
+
 //=================================================================================
 // class    : SMESHGUI
 // purpose  :
@@ -122,6 +144,10 @@ public :
   virtual void                    storeVisualParameters  (int savePoint);
   virtual void                    restoreVisualParameters(int savePoint);
 
+  virtual void                    addActorAsObserver( SMESH_Actor* theActor );
+
+  SMESHGUI_ClippingPlaneInfoMap&  getClippingPlaneInfoMap() { return myClippingPlaneInfoMap; }
+
 public slots:
   virtual bool                    deactivateModule( SUIT_Study* );
   virtual bool                    activateModule( SUIT_Study* );
@@ -130,6 +156,7 @@ public slots:
 private slots:
   void                            OnGUIEvent();
   void                            onViewManagerActivated( SUIT_ViewManager* );
+  void                            onViewManagerRemoved( SUIT_ViewManager* );
   void                            onOperationCommited( SUIT_Operation* );
   void                            onOperationAborted( SUIT_Operation* );
   void                            onHypothesisEdit( int result );
@@ -159,6 +186,11 @@ protected:
 
   virtual bool                    reusableOperation( const int id ); 
 
+  static void                     ProcessEvents( vtkObject* theObject, 
+                                                 unsigned long theEvent,
+                                                 void* theClientData, 
+                                                 void* theCallData );
+
 private:
   void                            OnEditDelete();
   int                             addVtkFontPref( const QString& label, 
@@ -175,6 +207,10 @@ private :
   SMESHGUI_FilterLibraryDlg*      myFilterLibraryDlg;
 
   SMESHGUI_StudyId2MarkerMap      myMarkerMap;
+  SMESHGUI_ClippingPlaneInfoMap   myClippingPlaneInfoMap;
+
+  vtkSmartPointer<vtkCallbackCommand> myEventCallbackCommand;
+  vtkFloatingPointType            myPriority;
 };
 
 #endif // SMESHGUI_H
index 13bdc8eb44e3c04518864cba9480e5b489f2bd76..ac190be77b4c17d6a890f56631cf20e4e67b2fd2 100644 (file)
 #include <SUIT_OverrideCursor.h>
 #include <SUIT_MessageBox.h>
 #include <SUIT_ResourceMgr.h>
+#include <SUIT_ViewManager.h>
 
 #include <SALOME_ListIO.hxx>
 
+#include <SalomeApp_Study.h>
+
 #include <LightApp_Application.h>
-#include <LightApp_SelectionMgr.h>
+
+#include <VTKViewer_Algorithm.h>
 
 #include <SVTK_ViewWindow.h>
 
 #include <QGridLayout>
 #include <QGroupBox>
 #include <QKeyEvent>
+#include <QListWidget>
 
 // VTK includes
 #include <vtkMath.h>
-#include <vtkPlane.h>
 #include <vtkDataSet.h>
 #include <vtkDataSetMapper.h>
 #include <vtkPlaneSource.h>
 #include <vtkProperty.h>
+#include <vtkRenderer.h>
 
 #define SPACING 6
 #define MARGIN  11
 
-class OrientedPlane: public vtkPlane
+//=================================================================================
+// class    : OrientedPlane
+// purpose  :
+//=================================================================================
+SMESH::OrientedPlane* SMESH::OrientedPlane::New()
 {
-  QPointer<SVTK_ViewWindow> myViewWindow;
-
-  vtkDataSetMapper* myMapper;
-
-public:
-  static OrientedPlane *New()
-  {
-    return new OrientedPlane();
-  }
-  static OrientedPlane *New(SVTK_ViewWindow* theViewWindow)
-  {
-    return new OrientedPlane(theViewWindow);
-  }
-  vtkTypeMacro (OrientedPlane, vtkPlane);
-
-  SMESH::Orientation myOrientation;
-  float myDistance;
-  double myAngle[2];
+  return new OrientedPlane();
+}
 
-  vtkPlaneSource* myPlaneSource;
-  SALOME_Actor *myActor;
+SMESH::OrientedPlane* SMESH::OrientedPlane::New(SVTK_ViewWindow* theViewWindow)
+{
+  return new OrientedPlane(theViewWindow);
+}
 
-  void SetOrientation (SMESH::Orientation theOrientation) { myOrientation = theOrientation; }
-  SMESH::Orientation GetOrientation() { return myOrientation; }
+void SMESH::OrientedPlane::ShallowCopy(SMESH::OrientedPlane* theOrientedPlane)
+{
+  SetNormal(theOrientedPlane->GetNormal());
+  SetOrigin(theOrientedPlane->GetOrigin());
 
-  void SetDistance (float theDistance) { myDistance = theDistance; }
-  float GetDistance() { return myDistance; }
+  myOrientation = theOrientedPlane->GetOrientation();
+  myDistance = theOrientedPlane->GetDistance();
 
-  void ShallowCopy (OrientedPlane* theOrientedPlane)
-  {
-    SetNormal(theOrientedPlane->GetNormal());
-    SetOrigin(theOrientedPlane->GetOrigin());
+  myAngle[0] = theOrientedPlane->myAngle[0];
+  myAngle[1] = theOrientedPlane->myAngle[1];
 
-    myOrientation = theOrientedPlane->GetOrientation();
-    myDistance = theOrientedPlane->GetDistance();
+  myPlaneSource->SetNormal(theOrientedPlane->myPlaneSource->GetNormal());
+  myPlaneSource->SetOrigin(theOrientedPlane->myPlaneSource->GetOrigin());
+  myPlaneSource->SetPoint1(theOrientedPlane->myPlaneSource->GetPoint1());
+  myPlaneSource->SetPoint2(theOrientedPlane->myPlaneSource->GetPoint2());
+}
 
-    myAngle[0] = theOrientedPlane->myAngle[0];
-    myAngle[1] = theOrientedPlane->myAngle[1];
+SMESH::OrientedPlane::OrientedPlane(SVTK_ViewWindow* theViewWindow):
+  myViewWindow(theViewWindow),
+  myOrientation(SMESH::XY),
+  myDistance(0.5)
+{
+  Init();
+  myViewWindow->AddActor(myActor);
+}
 
-    myPlaneSource->SetNormal(theOrientedPlane->myPlaneSource->GetNormal());
-    myPlaneSource->SetOrigin(theOrientedPlane->myPlaneSource->GetOrigin());
-    myPlaneSource->SetPoint1(theOrientedPlane->myPlaneSource->GetPoint1());
-    myPlaneSource->SetPoint2(theOrientedPlane->myPlaneSource->GetPoint2());
-  }
+SMESH::OrientedPlane::OrientedPlane():
+  myOrientation(SMESH::XY),
+  myViewWindow(NULL),
+  myDistance(0.5)
+{
+  Init();
+}
 
-protected:
-  OrientedPlane(SVTK_ViewWindow* theViewWindow):
-    myViewWindow(theViewWindow),
-    myOrientation(SMESH::XY),
-    myDistance(0.5)
-  {
-    Init();
-    myViewWindow->AddActor(myActor);
-  }
+void SMESH::OrientedPlane::Init()
+{
+  myPlaneSource = vtkPlaneSource::New();
+
+  myAngle[0] = myAngle[1] = 0.0;
+
+  // Create and display actor
+  myMapper = vtkDataSetMapper::New();
+  myMapper->SetInput(myPlaneSource->GetOutput());
+
+  myActor = SALOME_Actor::New();
+  myActor->VisibilityOff();
+  myActor->PickableOff();
+  myActor->SetInfinitive(true);
+  myActor->SetMapper(myMapper);
+
+  vtkFloatingPointType anRGB[3];
+  vtkProperty* aProp = vtkProperty::New();
+  SMESH::GetColor( "SMESH", "fill_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 170, 255 ) );
+  aProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
+  aProp->SetOpacity(0.75);
+  myActor->SetProperty(aProp);
+  aProp->Delete();
+
+  vtkProperty* aBackProp = vtkProperty::New();
+  SMESH::GetColor( "SMESH", "backface_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 0, 255 ) );
+  aBackProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
+  aBackProp->SetOpacity(0.75);
+  myActor->SetBackfaceProperty(aBackProp);
+  aBackProp->Delete();
+}
 
-  OrientedPlane():
-    myOrientation(SMESH::XY),
-    myViewWindow(NULL),
-    myDistance(0.5)
-  {
-    Init();
-  }
+SMESH::OrientedPlane::~OrientedPlane()
+{
+  if (myViewWindow)
+    myViewWindow->RemoveActor(myActor);
+  myActor->Delete();
+    
+  myMapper->RemoveAllInputs();
+  myMapper->Delete();
 
-  void Init()
-  {
-    myPlaneSource = vtkPlaneSource::New();
-
-    myAngle[0] = myAngle[1] = 0.0;
-
-    // Create and display actor
-    myMapper = vtkDataSetMapper::New();
-    myMapper->SetInput(myPlaneSource->GetOutput());
-
-    myActor = SALOME_Actor::New();
-    myActor->VisibilityOff();
-    myActor->PickableOff();
-    myActor->SetInfinitive(true);
-    myActor->SetMapper(myMapper);
-
-    vtkFloatingPointType anRGB[3];
-    vtkProperty* aProp = vtkProperty::New();
-    SMESH::GetColor( "SMESH", "fill_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 170, 255 ) );
-    aProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
-    aProp->SetOpacity(0.75);
-    myActor->SetProperty(aProp);
-    aProp->Delete();
-
-    vtkProperty* aBackProp = vtkProperty::New();
-    SMESH::GetColor( "SMESH", "backface_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 0, 255 ) );
-    aBackProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
-    aBackProp->SetOpacity(0.75);
-    myActor->SetBackfaceProperty(aBackProp);
-    aBackProp->Delete();
-  }
+  // commented: porting to vtk 5.0
+  //    myPlaneSource->UnRegisterAllOutputs();
+  myPlaneSource->Delete();
+}
 
-  ~OrientedPlane(){
-    if (myViewWindow)
-      myViewWindow->RemoveActor(myActor);
-    myActor->Delete();
-    
-    myMapper->RemoveAllInputs();
-    myMapper->Delete();
+//=================================================================================
+// class    : ActorItem
+// purpose  :
+//=================================================================================
+class ActorItem : public QListWidgetItem
+{
+public:
+  ActorItem( SMESH_Actor* theActor, const QString& theName, QListWidget* theListWidget ) :
+    QListWidgetItem( theName, theListWidget ),
+    myActor( theActor ) {}
 
-    // commented: porting to vtk 5.0
-    //    myPlaneSource->UnRegisterAllOutputs();
-    myPlaneSource->Delete();
-  };
+  SMESH_Actor* getActor() const { return myActor; }
 
 private:
-  // Not implemented.
-  OrientedPlane (const OrientedPlane&);
-  void operator= (const OrientedPlane&);
-
+  SMESH_Actor* myActor;
 };
 
-struct TSetVisiblity {
-  TSetVisiblity(int theIsVisible): myIsVisible(theIsVisible){}
-  void operator()(SMESH::TVTKPlane& theOrientedPlane){
-    theOrientedPlane->myActor->SetVisibility(myIsVisible);
+//=================================================================================
+// class    : TSetVisibility
+// purpose  :
+//=================================================================================
+struct TSetVisibility {
+  TSetVisibility(int theIsVisible): myIsVisible(theIsVisible){}
+  void operator()(SMESH::TPlaneData& thePlaneData){
+    thePlaneData.Plane.GetPointer()->myActor->SetVisibility(myIsVisible);
   }
   int myIsVisible;
 };
@@ -200,13 +203,13 @@ struct TSetVisiblity {
 // used in SMESHGUI::restoreVisualParameters() to avoid
 // declaration of OrientedPlane outside of SMESHGUI_ClippingDlg.cxx
 //=================================================================================
-void SMESHGUI_ClippingDlg::AddPlane (SMESH_Actor*         theActor,
-                                     SVTK_ViewWindow*     theViewWindow,
-                                     SMESH::Orientation   theOrientation,
-                                     double               theDistance,
-                                     vtkFloatingPointType theAngle[2])
+SMESH::OrientedPlane* SMESHGUI_ClippingDlg::AddPlane (SMESH::TActorList          theActorList,
+                                                      SVTK_ViewWindow*           theViewWindow,
+                                                      SMESH::Orientation         theOrientation,
+                                                      double                     theDistance,
+                                                      const vtkFloatingPointType theAngle[2])
 {
-  OrientedPlane* aPlane = OrientedPlane::New(theViewWindow);
+  SMESH::OrientedPlane* aPlane = SMESH::OrientedPlane::New(theViewWindow);
 
   aPlane->myAngle[0] = theAngle[0];
   aPlane->myAngle[1] = theAngle[1];
@@ -256,14 +259,26 @@ void SMESHGUI_ClippingDlg::AddPlane (SMESH_Actor*         theActor,
     vtkMath::Cross(aNormal,aDir[1],aDir[0]);
   }
 
-  // ???
-  theActor->SetPlaneParam(aNormal, theDistance, aPlane);
+  vtkFloatingPointType aBounds[6];
+  vtkFloatingPointType anOrigin[3];
+  bool anIsOk = SMESH::ComputeClippingPlaneParameters( theActorList,
+                                                       aNormal,
+                                                       theDistance,
+                                                       aBounds,
+                                                       anOrigin );
+  if( !anIsOk )
+    return NULL;
 
-  vtkDataSet* aDataSet = theActor->GetInput();
-  vtkFloatingPointType *aPnt = aDataSet->GetCenter();
+  aPlane->SetNormal( aNormal );
+  aPlane->SetOrigin( anOrigin );
 
-  vtkFloatingPointType* anOrigin = aPlane->GetOrigin();
-  vtkFloatingPointType aDel = aDataSet->GetLength()/2.0;
+  vtkFloatingPointType aPnt[3] = { ( aBounds[0] + aBounds[1] ) / 2.,
+                                   ( aBounds[2] + aBounds[3] ) / 2.,
+                                   ( aBounds[4] + aBounds[5] ) / 2. };
+
+  vtkFloatingPointType aDel = pow( pow( aBounds[1] - aBounds[0], 2 ) +
+                                   pow( aBounds[3] - aBounds[2], 2 ) +
+                                   pow( aBounds[5] - aBounds[4], 2 ), 0.5 );
 
   vtkFloatingPointType aDelta[2][3] = {{aDir[0][0]*aDel, aDir[0][1]*aDel, aDir[0][2]*aDel},
                                        {aDir[1][0]*aDel, aDir[1][1]*aDel, aDir[1][2]*aDel}};
@@ -299,28 +314,13 @@ void SMESHGUI_ClippingDlg::AddPlane (SMESH_Actor*         theActor,
   aPlaneSource->SetPoint1(aPnt1[0],aPnt1[1],aPnt1[2]);
   aPlaneSource->SetPoint2(aPnt2[0],aPnt2[1],aPnt2[2]);
 
-  theActor->AddClippingPlane(aPlane);
-  aPlane->Delete();
-}
+  SMESH::TActorList::iterator anIter = theActorList.begin();
+  for ( ; anIter != theActorList.end(); anIter++ )
+    if( vtkActor* aVTKActor = *anIter )
+      if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) )
+        anActor->AddClippingPlane( aPlane );
 
-//=================================================================================
-// used in SMESHGUI::restoreVisualParameters() to avoid
-// declaration of OrientedPlane outside of SMESHGUI_ClippingDlg.cxx
-//=================================================================================
-void SMESHGUI_ClippingDlg::GetPlaneParam (SMESH_Actor*          theActor,
-                                          int                   thePlaneIndex,
-                                          SMESH::Orientation&   theOrientation,
-                                          double&               theDistance,
-                                          vtkFloatingPointType* theAngle)
-{
-  if (vtkPlane* aPln = theActor->GetClippingPlane(thePlaneIndex)) {
-    if (OrientedPlane* aPlane = OrientedPlane::SafeDownCast(aPln)) {
-      theOrientation = aPlane->GetOrientation();
-      theDistance = aPlane->GetDistance();
-      theAngle[0] = aPlane->myAngle[0];
-      theAngle[1] = aPlane->myAngle[1];
-    }
-  }
+  return aPlane;
 }
 
 //=================================================================================
@@ -328,11 +328,10 @@ void SMESHGUI_ClippingDlg::GetPlaneParam (SMESH_Actor*          theActor,
 // purpose  :
 //
 //=================================================================================
-SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule ):
+SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule, SVTK_ViewWindow* theViewWindow ):
   QDialog( SMESH::GetDesktop(theModule) ),
-  mySelector(SMESH::GetViewWindow(theModule)->GetSelector()),
-  mySelectionMgr(SMESH::GetSelectionMgr(theModule)),
-  mySMESHGUI(theModule)
+  mySMESHGUI(theModule),
+  myViewWindow(theViewWindow)
 {
   setModal( false );
   setAttribute( Qt::WA_DeleteOnClose, true );
@@ -345,7 +344,7 @@ SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule ):
 
   // Controls for selecting, creating, deleting planes
   QGroupBox* GroupPlanes = new QGroupBox(tr("CLIP_PLANES"), this);
-  QHBoxLayout* GroupPlanesLayout = new QHBoxLayout(GroupPlanes);
+  QGridLayout* GroupPlanesLayout = new QGridLayout(GroupPlanes);
   GroupPlanesLayout->setSpacing(SPACING);
   GroupPlanesLayout->setMargin(MARGIN);
 
@@ -355,10 +354,21 @@ SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule ):
 
   buttonDelete = new QPushButton(tr("SMESH_BUT_DELETE"), GroupPlanes);
 
-  GroupPlanesLayout->addWidget(ComboBoxPlanes);
-  GroupPlanesLayout->addStretch();
-  GroupPlanesLayout->addWidget(buttonNew);
-  GroupPlanesLayout->addWidget(buttonDelete);
+  QLabel* aLabel = new QLabel(tr("MESHES_SUBMESHES_GROUPS"), GroupPlanes);
+
+  ActorList = new QListWidget(GroupPlanes);
+  ActorList->setSelectionMode(QAbstractItemView::SingleSelection);
+
+  SelectAllCheckBox = new QCheckBox(tr("SELECT_ALL"), GroupPlanes);
+
+  GroupPlanesLayout->addWidget(ComboBoxPlanes,    0, 0);
+  GroupPlanesLayout->addWidget(new QWidget(),     0, 1);
+  GroupPlanesLayout->addWidget(buttonNew,         0, 2);
+  GroupPlanesLayout->addWidget(buttonDelete,      0, 3);
+  GroupPlanesLayout->addWidget(aLabel,            1, 0, 1, 4);
+  GroupPlanesLayout->addWidget(ActorList,         2, 0, 1, 4);
+  GroupPlanesLayout->addWidget(SelectAllCheckBox, 3, 0, 1, 4);
+  GroupPlanesLayout->setColumnStretch( 1, 1 );
 
   // Controls for defining plane parameters
   QGroupBox* GroupParameters = new QGroupBox(tr("SMESH_PARAMETERS"), this);
@@ -437,9 +447,10 @@ SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule ):
 
   SpinBoxDistance->SetValue(0.5);
 
-  myActor = 0;
   myIsSelectPlane = false;
-  onSelectionChanged();
+
+  initializePlaneData();
+  synchronize();
 
   myHelpFileName = "clipping_page.html";
 
@@ -447,6 +458,8 @@ SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule ):
   connect(ComboBoxPlanes, SIGNAL(activated(int)), this, SLOT(onSelectPlane(int)));
   connect(buttonNew, SIGNAL(clicked()), this, SLOT(ClickOnNew()));
   connect(buttonDelete, SIGNAL(clicked()), this, SLOT(ClickOnDelete()));
+  connect(ActorList, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(onActorItemChanged(QListWidgetItem*)));
+  connect(SelectAllCheckBox, SIGNAL(stateChanged(int)), this, SLOT(onSelectAll(int)));
   connect(ComboBoxOrientation, SIGNAL(activated(int)), this, SLOT(onSelectOrientation(int)));
   connect(SpinBoxDistance, SIGNAL(valueChanged(double)), this, SLOT(SetCurrentPlaneParam()));
   connect(SpinBoxRot1, SIGNAL(valueChanged(double)), this, SLOT(SetCurrentPlaneParam()));
@@ -458,7 +471,6 @@ SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule ):
   connect(buttonApply, SIGNAL(clicked()), this, SLOT(ClickOnApply()));
   connect(buttonHelp, SIGNAL(clicked()), this, SLOT(ClickOnHelp()));
   connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), this, SLOT(ClickOnCancel()));
-  connect(mySelectionMgr,  SIGNAL(currentSelectionChanged()), this, SLOT(onSelectionChanged()));
   /* to close dialog if study frame change */
   connect(mySMESHGUI, SIGNAL (SignalStudyFrameChanged()), this, SLOT(ClickOnCancel()));
 
@@ -472,10 +484,9 @@ SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule ):
 SMESHGUI_ClippingDlg::~SMESHGUI_ClippingDlg()
 {
   // no need to delete child widgets, Qt does it all for us
-  std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(false));
-  if (mySMESHGUI)
-    if (SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow(mySMESHGUI))
-      SMESH::RenderViewWindow(aViewWindow);
+  std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisibility(false));
+  if (myViewWindow)
+    SMESH::RenderViewWindow(myViewWindow);
 }
 
 double SMESHGUI_ClippingDlg::getDistance() const
@@ -504,27 +515,56 @@ double SMESHGUI_ClippingDlg::getRotation2() const
 //=======================================================================
 void SMESHGUI_ClippingDlg::ClickOnApply()
 {
-  if (!myActor)
-    return;
-
-  if (SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow(mySMESHGUI)) {
+  if (myViewWindow) {
     SUIT_OverrideCursor wc;
     
     QWidget *aCurrWid = this->focusWidget();
     aCurrWid->clearFocus();
     aCurrWid->setFocus();
 
-    myActor->RemoveAllClippingPlanes();
-
-    SMESH::TPlanes::iterator anIter = myPlanes.begin();
-    for ( ; anIter != myPlanes.end(); anIter++) {
-      OrientedPlane* anOrientedPlane = OrientedPlane::New(aViewWindow);
-      anOrientedPlane->ShallowCopy(anIter->GetPointer());
-      myActor->AddClippingPlane(anOrientedPlane);
-      anOrientedPlane->Delete();
+    SMESHGUI_ClippingPlaneInfoMap& aClippingPlaneInfoMap = mySMESHGUI->getClippingPlaneInfoMap();
+    SMESHGUI_ClippingPlaneInfoList& aClippingPlaneInfoList = aClippingPlaneInfoMap[ myViewWindow->getViewManager() ];
+
+    // clean memory allocated for planes
+    SMESHGUI_ClippingPlaneInfoList::iterator anIter1 = aClippingPlaneInfoList.begin();
+    for( ; anIter1 != aClippingPlaneInfoList.end(); anIter1++ )
+      if( SMESH::OrientedPlane* aPlane = (*anIter1).Plane )
+        aPlane->Delete();
+
+    aClippingPlaneInfoList.clear();
+
+    VTK::ActorCollectionCopy aCopy( myViewWindow->getRenderer()->GetActors() );
+    vtkActorCollection* anAllActors = aCopy.GetActors();
+    anAllActors->InitTraversal();
+    while( vtkActor* aVTKActor = anAllActors->GetNextActor() )
+      if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) )
+        anActor->RemoveAllClippingPlanes();
+
+    SMESH::TPlaneDataVector::iterator anIter2 = myPlanes.begin();
+    for( ; anIter2 != myPlanes.end(); anIter2++ ) {
+      SMESH::TPlaneData aPlaneData = *anIter2;
+      SMESH::TPlane aPlane = aPlaneData.Plane;
+      SMESH::TActorList anActorList = aPlaneData.ActorList;
+      if( anActorList.empty() )
+        continue;
+
+      SMESH::OrientedPlane* anOrientedPlane = SMESH::OrientedPlane::New(myViewWindow);
+      anOrientedPlane->ShallowCopy(aPlane.GetPointer());
+
+      SMESH::TActorList::iterator anIter3 = anActorList.begin();
+      for( ; anIter3 != anActorList.end(); anIter3++ )
+        if( vtkActor* aVTKActor = *anIter3 )
+          if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) )
+            anActor->AddClippingPlane(anOrientedPlane);
+
+      SMESH::ClippingPlaneInfo aClippingPlaneInfo;
+      aClippingPlaneInfo.Plane = anOrientedPlane;
+      aClippingPlaneInfo.ActorList = anActorList;
+
+      aClippingPlaneInfoList.push_back( aClippingPlaneInfo );
     }
 
-    SMESH::RenderViewWindow(aViewWindow);
+    SMESH::RenderViewWindow( myViewWindow );
   }
 }
 
@@ -571,53 +611,17 @@ void SMESHGUI_ClippingDlg::ClickOnHelp()
   }
 }
 
-//=================================================================================
-// function : onSelectionChanged()
-// purpose  : Called when selection is changed
-//=================================================================================
-void SMESHGUI_ClippingDlg::onSelectionChanged()
-{
-  if (SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow(mySMESHGUI)) {
-    const SALOME_ListIO& aList = mySelector->StoredIObjects();
-    if (aList.Extent() > 0) {
-      Handle(SALOME_InteractiveObject) IOS = aList.First();
-      myActor = SMESH::FindActorByEntry(IOS->getEntry());
-      if (myActor) {
-        std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(false));
-        myPlanes.clear();
-
-        vtkIdType anId = 0, anEnd = myActor->GetNumberOfClippingPlanes();
-        for ( ; anId < anEnd; anId++) {
-          if (vtkImplicitFunction* aFunction = myActor->GetClippingPlane(anId)) {
-            if(OrientedPlane* aPlane = OrientedPlane::SafeDownCast(aFunction)){
-              OrientedPlane* anOrientedPlane = OrientedPlane::New(aViewWindow);
-              SMESH::TVTKPlane aTVTKPlane(anOrientedPlane);
-              anOrientedPlane->Delete();
-              aTVTKPlane->ShallowCopy(aPlane);
-              myPlanes.push_back(aTVTKPlane);
-            }
-          }
-        }
-
-        std::for_each(myPlanes.begin(),myPlanes.end(),
-                      TSetVisiblity(PreviewCheckBox->isChecked()));
-      }
-    }
-    SMESH::RenderViewWindow(aViewWindow);
-  }
-  Sinchronize();
-}
-
 //=======================================================================
 // function : onSelectPlane()
 // purpose  :
 //=======================================================================
 void SMESHGUI_ClippingDlg::onSelectPlane (int theIndex)
 {
-  if (!myActor || myPlanes.empty())
+  if (myPlanes.empty())
     return;
 
-  OrientedPlane* aPlane = myPlanes[theIndex].GetPointer();
+  SMESH::TPlaneData aPlaneData = myPlanes[theIndex];
+  SMESH::OrientedPlane* aPlane = aPlaneData.Plane.GetPointer();
 
   // Orientation
   SMESH::Orientation anOrientation = aPlane->GetOrientation();
@@ -644,6 +648,11 @@ void SMESHGUI_ClippingDlg::onSelectPlane (int theIndex)
     break;
   }
   myIsSelectPlane = false;
+
+  // Actors
+  bool anIsBlocked = ActorList->blockSignals( true );
+  updateActorList();
+  ActorList->blockSignals( anIsBlocked );
 }
 
 //=======================================================================
@@ -652,19 +661,31 @@ void SMESHGUI_ClippingDlg::onSelectPlane (int theIndex)
 //=======================================================================
 void SMESHGUI_ClippingDlg::ClickOnNew()
 {
-  if (!myActor)
-    return;
+  if(myViewWindow){
+    SMESH::OrientedPlane* aPlane = SMESH::OrientedPlane::New(myViewWindow);
+    SMESH::TPlane aTPlane(aPlane);
+
+    SMESH::TActorList anActorList;
+    VTK::ActorCollectionCopy aCopy( myViewWindow->getRenderer()->GetActors() );
+    vtkActorCollection* anAllActors = aCopy.GetActors();
+    anAllActors->InitTraversal();
+    while( vtkActor* aVTKActor = anAllActors->GetNextActor() )
+      if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) )
+        anActorList.push_back( anActor );
 
-  if(SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow(mySMESHGUI)){
-    OrientedPlane* aPlane = OrientedPlane::New(aViewWindow);
-    SMESH::TVTKPlane aTVTKPlane(aPlane);
-    myPlanes.push_back(aTVTKPlane);
+    SMESH::TPlaneData aPlaneData(aTPlane, anActorList);
+
+    myPlanes.push_back(aPlaneData);
 
     if (PreviewCheckBox->isChecked())
-      aTVTKPlane->myActor->VisibilityOn();
-    
-    Sinchronize();
+      aTPlane->myActor->VisibilityOn();
+
+    bool anIsBlocked = ActorList->blockSignals( true );
+
+    synchronize();
     SetCurrentPlaneParam();
+
+    ActorList->blockSignals( anIsBlocked );
   }
 }
 
@@ -674,20 +695,105 @@ void SMESHGUI_ClippingDlg::ClickOnNew()
 //=======================================================================
 void SMESHGUI_ClippingDlg::ClickOnDelete()
 {
-  if (!myActor || myPlanes.empty())
+  if (myPlanes.empty())
     return;
 
   int aPlaneIndex = ComboBoxPlanes->currentIndex();
 
-  SMESH::TPlanes::iterator anIter = myPlanes.begin() + aPlaneIndex;
-  anIter->GetPointer()->myActor->SetVisibility(false);
+  SMESH::TPlaneDataVector::iterator anIter = myPlanes.begin() + aPlaneIndex;
+  SMESH::TPlaneData aPlaneData = *anIter;
+  aPlaneData.Plane.GetPointer()->myActor->SetVisibility(false);
   myPlanes.erase(anIter);
 
   if(AutoApplyCheckBox->isChecked())
     ClickOnApply();
 
-  Sinchronize();
-  SMESH::RenderViewWindow(SMESH::GetCurrentVtkView());
+  synchronize();
+  SMESH::RenderViewWindow( myViewWindow );
+}
+
+//=======================================================================
+// function : updateActorItem()
+// purpose  :
+//=======================================================================
+void SMESHGUI_ClippingDlg::updateActorItem( QListWidgetItem* theItem,
+                                            bool theUpdateSelectAll,
+                                            bool theUpdateClippingPlaneMap )
+{
+  // update Select All check box
+  if( theUpdateSelectAll ) {
+    int aNbItems = ActorList->count(), aNbChecked = 0;
+    for( int i = 0; i < aNbItems; i++ )
+      if( QListWidgetItem* anItem = ActorList->item( i ) )
+        if( anItem->checkState() == Qt::Checked )
+          aNbChecked++;
+
+    Qt::CheckState aCheckState = Qt::Unchecked;
+    if( aNbChecked == aNbItems )
+      aCheckState = Qt::Checked;
+    else if( aNbChecked > 0 )
+      aCheckState = Qt::PartiallyChecked;
+
+    bool anIsBlocked = SelectAllCheckBox->blockSignals( true );
+    SelectAllCheckBox->setCheckState( aCheckState );
+    SelectAllCheckBox->blockSignals( anIsBlocked );
+  }
+
+  // update clipping plane map
+  if( theUpdateClippingPlaneMap ) {
+    int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
+    if( ActorItem* anItem = dynamic_cast<ActorItem*>( theItem ) ) {
+      if( SMESH_Actor* anActor = anItem->getActor() ) {
+        SMESH::TPlaneData& aPlaneData = myPlanes[ aCurPlaneIndex ];
+        SMESH::TActorList& anActorList = aPlaneData.ActorList;
+        bool anIsPushed = false;
+        SMESH::TActorList::iterator anIter = anActorList.begin();
+        for ( ; anIter != anActorList.end(); anIter++ ) {
+          if( anActor == *anIter ) {
+            anIsPushed = true;
+            break;
+          }
+        }
+        if( theItem->checkState() == Qt::Checked && !anIsPushed )
+          anActorList.push_back( anActor );
+        else if( theItem->checkState() == Qt::Unchecked && anIsPushed )
+          anActorList.remove( anActor );
+      }
+    }
+  }
+}
+
+//=======================================================================
+// function : onActorItemChanged()
+// purpose  :
+//=======================================================================
+void SMESHGUI_ClippingDlg::onActorItemChanged( QListWidgetItem* theItem )
+{
+  updateActorItem( theItem, true, true );
+  SetCurrentPlaneParam();
+}
+
+//=======================================================================
+// function : onSelectAll()
+// purpose  :
+//=======================================================================
+void SMESHGUI_ClippingDlg::onSelectAll( int theState )
+{
+  if( theState == Qt::PartiallyChecked ) {
+    SelectAllCheckBox->setCheckState( Qt::Checked );
+    return;
+  }
+
+  bool anIsBlocked = ActorList->blockSignals( true );
+  for( int i = 0, n = ActorList->count(); i < n; i++ ) {
+    if( QListWidgetItem* anItem = ActorList->item( i ) ) {
+      anItem->setCheckState( theState == Qt::Checked ? Qt::Checked : Qt::Unchecked );
+      updateActorItem( anItem, false, true );
+    }
+  }
+  SelectAllCheckBox->setTristate( false );
+  ActorList->blockSignals( anIsBlocked );
+  SetCurrentPlaneParam();
 }
 
 //=======================================================================
@@ -717,10 +823,10 @@ void SMESHGUI_ClippingDlg::onSelectOrientation (int theItem)
 }
 
 //=======================================================================
-// function : Sinchronize()
+// function : synchronize()
 // purpose  :
 //=======================================================================
-void SMESHGUI_ClippingDlg::Sinchronize()
+void SMESHGUI_ClippingDlg::synchronize()
 {
   int aNbPlanes = myPlanes.size();
   ComboBoxPlanes->clear();
@@ -737,17 +843,22 @@ void SMESHGUI_ClippingDlg::Sinchronize()
   bool anIsControlsEnable = (aPos >= 0);
   if (anIsControlsEnable) {
     onSelectPlane(aPos);
+    updateActorList();
   } else {
     ComboBoxPlanes->addItem(tr("NO_PLANES"));
+    ActorList->clear();
     SpinBoxRot1->SetValue(0.0);
     SpinBoxRot2->SetValue(0.0);
     SpinBoxDistance->SetValue(0.5);
   }
 
+  ActorList->setEnabled(anIsControlsEnable);
+  SelectAllCheckBox->setEnabled(anIsControlsEnable);
   buttonDelete->setEnabled(anIsControlsEnable);
-  buttonApply->setEnabled(anIsControlsEnable);
-  PreviewCheckBox->setEnabled(anIsControlsEnable);
-  AutoApplyCheckBox->setEnabled(anIsControlsEnable);
+  // the following 3 controls should be enabled
+  //buttonApply->setEnabled(anIsControlsEnable);
+  //PreviewCheckBox->setEnabled(anIsControlsEnable);
+  //AutoApplyCheckBox->setEnabled(anIsControlsEnable);
   ComboBoxOrientation->setEnabled(anIsControlsEnable);
   SpinBoxDistance->setEnabled(anIsControlsEnable);
   SpinBoxRot1->setEnabled(anIsControlsEnable);
@@ -775,7 +886,8 @@ void SMESHGUI_ClippingDlg::SetCurrentPlaneParam()
 
   int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
 
-  OrientedPlane* aPlane = myPlanes[aCurPlaneIndex].GetPointer();
+  SMESH::TPlaneData aPlaneData = myPlanes[aCurPlaneIndex];
+  SMESH::OrientedPlane* aPlane = aPlaneData.Plane.GetPointer();
 
   vtkFloatingPointType aNormal[3];
   SMESH::Orientation anOrientation;
@@ -833,52 +945,69 @@ void SMESHGUI_ClippingDlg::SetCurrentPlaneParam()
   aPlane->SetOrientation(anOrientation);
   aPlane->SetDistance(getDistance());
 
-  myActor->SetPlaneParam(aNormal, getDistance(), aPlane);
-
-  vtkDataSet* aDataSet = myActor->GetInput();
-  vtkFloatingPointType *aPnt = aDataSet->GetCenter();
-
-  vtkFloatingPointType* anOrigin = aPlane->GetOrigin();
-  vtkFloatingPointType aDel = aDataSet->GetLength()/2.0;
-
-  vtkFloatingPointType aDelta[2][3] = {{aDir[0][0]*aDel, aDir[0][1]*aDel, aDir[0][2]*aDel},
-                                       {aDir[1][0]*aDel, aDir[1][1]*aDel, aDir[1][2]*aDel}};
-  vtkFloatingPointType aParam, aPnt0[3], aPnt1[3], aPnt2[3];
-
-  vtkFloatingPointType aPnt01[3] = {aPnt[0] - aDelta[0][0] - aDelta[1][0],
-                                    aPnt[1] - aDelta[0][1] - aDelta[1][1],
-                                    aPnt[2] - aDelta[0][2] - aDelta[1][2]};
-  vtkFloatingPointType aPnt02[3] = {aPnt01[0] + aNormal[0],
-                                    aPnt01[1] + aNormal[1],
-                                    aPnt01[2] + aNormal[2]};
-  vtkPlane::IntersectWithLine(aPnt01,aPnt02,aNormal,anOrigin,aParam,aPnt0);
-
-  vtkFloatingPointType aPnt11[3] = {aPnt[0] - aDelta[0][0] + aDelta[1][0],
-                                    aPnt[1] - aDelta[0][1] + aDelta[1][1],
-                                    aPnt[2] - aDelta[0][2] + aDelta[1][2]};
-  vtkFloatingPointType aPnt12[3] = {aPnt11[0] + aNormal[0],
-                                    aPnt11[1] + aNormal[1],
-                                    aPnt11[2] + aNormal[2]};
-  vtkPlane::IntersectWithLine(aPnt11,aPnt12,aNormal,anOrigin,aParam,aPnt1);
-
-  vtkFloatingPointType aPnt21[3] = {aPnt[0] + aDelta[0][0] - aDelta[1][0],
-                                    aPnt[1] + aDelta[0][1] - aDelta[1][1],
-                                    aPnt[2] + aDelta[0][2] - aDelta[1][2]};
-  vtkFloatingPointType aPnt22[3] = {aPnt21[0] + aNormal[0],
-                                    aPnt21[1] + aNormal[1],
-                                    aPnt21[2] + aNormal[2]};
-  vtkPlane::IntersectWithLine(aPnt21,aPnt22,aNormal,anOrigin,aParam,aPnt2);
-
-  vtkPlaneSource* aPlaneSource = aPlane->myPlaneSource;
-  aPlaneSource->SetNormal(aNormal[0],aNormal[1],aNormal[2]);
-  aPlaneSource->SetOrigin(aPnt0[0],aPnt0[1],aPnt0[2]);
-  aPlaneSource->SetPoint1(aPnt1[0],aPnt1[1],aPnt1[2]);
-  aPlaneSource->SetPoint2(aPnt2[0],aPnt2[1],aPnt2[2]);
+  SMESH::TActorList anActorList = aPlaneData.ActorList;
+
+  vtkFloatingPointType aBounds[6];
+  vtkFloatingPointType anOrigin[3];
+  bool anIsOk = SMESH::ComputeClippingPlaneParameters( anActorList,
+                                                       aNormal,
+                                                       getDistance(),
+                                                       aBounds,
+                                                       anOrigin );
+
+  aPlane->myActor->SetVisibility( anIsOk && PreviewCheckBox->isChecked() );
+
+  if( anIsOk ) {
+    aPlane->SetNormal( aNormal );
+    aPlane->SetOrigin( anOrigin );
+
+    vtkFloatingPointType aPnt[3] = { ( aBounds[0] + aBounds[1] ) / 2.,
+                                     ( aBounds[2] + aBounds[3] ) / 2.,
+                                     ( aBounds[4] + aBounds[5] ) / 2. };
+
+    vtkFloatingPointType aDel = pow( pow( aBounds[1] - aBounds[0], 2 ) +
+                                     pow( aBounds[3] - aBounds[2], 2 ) +
+                                     pow( aBounds[5] - aBounds[4], 2 ), 0.5 );
+
+    vtkFloatingPointType aDelta[2][3] = {{aDir[0][0]*aDel, aDir[0][1]*aDel, aDir[0][2]*aDel},
+                                         {aDir[1][0]*aDel, aDir[1][1]*aDel, aDir[1][2]*aDel}};
+    vtkFloatingPointType aParam, aPnt0[3], aPnt1[3], aPnt2[3];
+
+    vtkFloatingPointType aPnt01[3] = {aPnt[0] - aDelta[0][0] - aDelta[1][0],
+                                      aPnt[1] - aDelta[0][1] - aDelta[1][1],
+                                      aPnt[2] - aDelta[0][2] - aDelta[1][2]};
+    vtkFloatingPointType aPnt02[3] = {aPnt01[0] + aNormal[0],
+                                      aPnt01[1] + aNormal[1],
+                                      aPnt01[2] + aNormal[2]};
+    vtkPlane::IntersectWithLine(aPnt01,aPnt02,aNormal,anOrigin,aParam,aPnt0);
+
+    vtkFloatingPointType aPnt11[3] = {aPnt[0] - aDelta[0][0] + aDelta[1][0],
+                                      aPnt[1] - aDelta[0][1] + aDelta[1][1],
+                                      aPnt[2] - aDelta[0][2] + aDelta[1][2]};
+    vtkFloatingPointType aPnt12[3] = {aPnt11[0] + aNormal[0],
+                                      aPnt11[1] + aNormal[1],
+                                      aPnt11[2] + aNormal[2]};
+    vtkPlane::IntersectWithLine(aPnt11,aPnt12,aNormal,anOrigin,aParam,aPnt1);
+
+    vtkFloatingPointType aPnt21[3] = {aPnt[0] + aDelta[0][0] - aDelta[1][0],
+                                      aPnt[1] + aDelta[0][1] - aDelta[1][1],
+                                      aPnt[2] + aDelta[0][2] - aDelta[1][2]};
+    vtkFloatingPointType aPnt22[3] = {aPnt21[0] + aNormal[0],
+                                      aPnt21[1] + aNormal[1],
+                                      aPnt21[2] + aNormal[2]};
+    vtkPlane::IntersectWithLine(aPnt21,aPnt22,aNormal,anOrigin,aParam,aPnt2);
+
+    vtkPlaneSource* aPlaneSource = aPlane->myPlaneSource;
+    aPlaneSource->SetNormal(aNormal[0],aNormal[1],aNormal[2]);
+    aPlaneSource->SetOrigin(aPnt0[0],aPnt0[1],aPnt0[2]);
+    aPlaneSource->SetPoint1(aPnt1[0],aPnt1[1],aPnt1[2]);
+    aPlaneSource->SetPoint2(aPnt2[0],aPnt2[1],aPnt2[2]);
+  }
 
   if(AutoApplyCheckBox->isChecked())
     ClickOnApply();
 
-  SMESH::RenderViewWindow(SMESH::GetCurrentVtkView());
+  SMESH::RenderViewWindow( myViewWindow );
 }
 
 //=======================================================================
@@ -887,8 +1016,8 @@ void SMESHGUI_ClippingDlg::SetCurrentPlaneParam()
 //=======================================================================
 void SMESHGUI_ClippingDlg::OnPreviewToggle (bool theIsToggled)
 {
-  std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(theIsToggled));
-  SMESH::RenderViewWindow(SMESH::GetCurrentVtkView());
+  std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisibility(theIsToggled));
+  SMESH::RenderViewWindow( myViewWindow );
 }
 
 //=================================================================================
@@ -906,3 +1035,124 @@ void SMESHGUI_ClippingDlg::keyPressEvent( QKeyEvent* e )
     ClickOnHelp();
   }
 }
+
+//=================================================================================
+// function : initializePlaneData()
+// purpose  :
+//=================================================================================
+void SMESHGUI_ClippingDlg::initializePlaneData()
+{
+  const SMESHGUI_ClippingPlaneInfoMap& aClippingPlaneInfoMap = mySMESHGUI->getClippingPlaneInfoMap();
+  SMESHGUI_ClippingPlaneInfoMap::const_iterator anIter1 = aClippingPlaneInfoMap.find( myViewWindow->getViewManager() );
+  if( anIter1 != aClippingPlaneInfoMap.end() ) {
+    const SMESHGUI_ClippingPlaneInfoList& aClippingPlaneInfoList = anIter1->second;
+    SMESHGUI_ClippingPlaneInfoList::const_iterator anIter2 = aClippingPlaneInfoList.begin();
+    for( ; anIter2 != aClippingPlaneInfoList.end(); anIter2++ ) {
+      const SMESH::ClippingPlaneInfo& aClippingPlaneInfo = *anIter2;
+      SMESH::TPlane aTPlane( aClippingPlaneInfo.Plane );
+      SMESH::TPlaneData aPlaneData( aTPlane, aClippingPlaneInfo.ActorList );
+      myPlanes.push_back( aPlaneData );
+    }
+  }
+  std::for_each( myPlanes.begin(),myPlanes.end(), TSetVisibility( PreviewCheckBox->isChecked() ) );
+}
+
+//=================================================================================
+// function : updateActorList()
+// purpose  :
+//=================================================================================
+void SMESHGUI_ClippingDlg::updateActorList()
+{
+  ActorList->clear();
+
+  SalomeApp_Study* anAppStudy = SMESHGUI::activeStudy();
+  if( !anAppStudy )
+    return;
+
+  _PTR(Study) aStudy = anAppStudy->studyDS();
+  if( !aStudy )
+    return;
+
+  if( !myViewWindow )
+    return;
+
+  int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
+  const SMESH::TPlaneData& aPlaneData = myPlanes[ aCurPlaneIndex ];
+  const SMESH::TActorList& anActorList = aPlaneData.ActorList;
+
+  VTK::ActorCollectionCopy aCopy( myViewWindow->getRenderer()->GetActors() );
+  vtkActorCollection* anAllActors = aCopy.GetActors();
+  anAllActors->InitTraversal();
+  while( vtkActor* aVTKActor = anAllActors->GetNextActor() ) {
+    if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) ) {
+      if( anActor->hasIO() ) {
+        Handle(SALOME_InteractiveObject) anIO = anActor->getIO();
+        if( _PTR(SObject) aSObj = aStudy->FindObjectID( anIO->getEntry() ) ) {
+          bool anIsChecked = false;
+          SMESH::TActorList::const_iterator anIter = anActorList.begin();
+          for ( ; anIter != anActorList.end(); anIter++ ) {
+            if( vtkActor* aVTKActorRef = *anIter ) {
+              if( SMESH_Actor* anActorRef = SMESH_Actor::SafeDownCast( aVTKActorRef ) ) {
+                if( anActorRef == anActor ) {
+                  anIsChecked = true;
+                  break;
+                }
+              }
+            }
+          }
+          QString aName = QString( aSObj->GetName().c_str() );
+          QListWidgetItem* anItem = new ActorItem( anActor, aName, ActorList );
+          anItem->setCheckState( anIsChecked ? Qt::Checked : Qt::Unchecked );
+          updateActorItem( anItem, true, false );
+        }
+      }
+    }
+  }
+}
+
+//=================================================================================
+// function : getCurrentActors()
+// purpose  :
+//=================================================================================
+SMESH::TActorList SMESHGUI_ClippingDlg::getCurrentActors()
+{
+  SMESH::TActorList anActorList;
+  for( int i = 0, n = ActorList->count(); i < n; i++ )
+    if( ActorItem* anItem = dynamic_cast<ActorItem*>( ActorList->item( i ) ) )
+      if( anItem->checkState() == Qt::Checked )
+        if( SMESH_Actor* anActor = anItem->getActor() )
+          anActorList.push_back( anActor );
+  return anActorList;
+}
+
+//=================================================================================
+// function : dumpPlaneData()
+// purpose  :
+//=================================================================================
+void SMESHGUI_ClippingDlg::dumpPlaneData() const
+{
+  printf( "----------- Plane Data -----------\n" );
+  int anId = 1;
+  SMESH::TPlaneDataVector::const_iterator anIter1 = myPlanes.begin();
+  for ( ; anIter1 != myPlanes.end(); anIter1++, anId++ ) {
+    SMESH::TPlaneData aPlaneData = *anIter1;
+    SMESH::TPlane aPlane = aPlaneData.Plane;
+    vtkFloatingPointType* aNormal = aPlane->GetNormal();
+    vtkFloatingPointType* anOrigin = aPlane->GetOrigin();
+    printf( "Plane N%d:\n", anId );
+    printf( "  Normal = ( %f, %f, %f )\n", aNormal[0], aNormal[1], aNormal[2] );
+    printf( "  Origin = ( %f, %f, %f )\n", anOrigin[0], anOrigin[1], anOrigin[2] );
+
+    SMESH::TActorList anActorList = aPlaneData.ActorList;
+    SMESH::TActorList::const_iterator anIter2 = anActorList.begin();
+    for ( ; anIter2 != anActorList.end(); anIter2++ ) {
+      if( vtkActor* aVTKActor = *anIter2 ) {
+        if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) )
+          printf( "  - Actor: '%s'\n", anActor->getName() );
+      }
+      else
+        printf( "  - Actor: NULL\n");
+    }
+  }
+  printf( "----------------------------------\n" );
+}
index 0c70ca9c212aaaea79dace5f175ed6bd2ae031c8..87a4b7b9d72f4fc1752b8f49b2fceccf8efd4517 100644 (file)
 
 // Qt includes
 #include <QDialog>
+#include <QPointer>
 
 // VTK includes
+#include <vtkPlane.h>
 #include <vtkSmartPointer.h>
 
 // STL includes
+#include <list>
+#include <map>
 #include <vector>
 
 class QLabel;
 class QPushButton;
 class QCheckBox;
 class QComboBox;
-class LightApp_SelectionMgr;
-class SVTK_Selector;
+class QListWidget;
+class QListWidgetItem;
+class SALOME_Actor;
 class SMESHGUI;
 class SMESH_Actor;
-class OrientedPlane;
 class SMESHGUI_SpinBox;
+class vtkActor;
+class vtkDataSetMapper;
+class vtkPlaneSource;
 
 namespace SMESH
 {
-  typedef vtkSmartPointer<OrientedPlane> TVTKPlane;
-  typedef std::vector<TVTKPlane> TPlanes;
   enum Orientation { XY, YZ, ZX };
-};
 
+  class OrientedPlane: public vtkPlane
+  {
+    QPointer<SVTK_ViewWindow> myViewWindow;
+    vtkDataSetMapper* myMapper;
+
+  public:
+    static OrientedPlane *New();
+    static OrientedPlane *New(SVTK_ViewWindow* theViewWindow);
+    vtkTypeMacro (OrientedPlane, vtkPlane);
+
+    SMESH::Orientation myOrientation;
+    float myDistance;
+    double myAngle[2];
+
+    vtkPlaneSource* myPlaneSource;
+    SALOME_Actor *myActor;
+
+    void SetOrientation (SMESH::Orientation theOrientation) { myOrientation = theOrientation; }
+    SMESH::Orientation GetOrientation() { return myOrientation; }
+
+    void SetDistance (float theDistance) { myDistance = theDistance; }
+    float GetDistance() { return myDistance; }
+
+    void ShallowCopy (OrientedPlane* theOrientedPlane);
+
+  protected:
+    OrientedPlane(SVTK_ViewWindow* theViewWindow);
+    OrientedPlane();
+
+    void Init();
+
+    ~OrientedPlane();
+  private:
+    // Not implemented.
+    OrientedPlane (const OrientedPlane&);
+    void operator= (const OrientedPlane&);
+  };
+
+  typedef vtkSmartPointer<OrientedPlane>    TPlane;
+  typedef std::list<vtkActor*>              TActorList;
+
+  struct TPlaneData
+  {
+    TPlaneData( TPlane thePlane,
+                TActorList theActorList )
+    {
+      Plane = thePlane;
+      ActorList = theActorList;
+    }
+    TPlane     Plane;
+    TActorList ActorList;
+  };
+
+  typedef std::vector<TPlane>               TPlaneVector;
+  typedef std::vector<TPlaneData>           TPlaneDataVector;
+};
 
 //=================================================================================
 // class    : SMESHGUI_ClippingDlg
@@ -70,7 +130,7 @@ class SMESHGUI_EXPORT SMESHGUI_ClippingDlg : public QDialog
   Q_OBJECT
 
 public:
-  SMESHGUI_ClippingDlg( SMESHGUI* );
+  SMESHGUI_ClippingDlg( SMESHGUI*, SVTK_ViewWindow* );
   ~SMESHGUI_ClippingDlg();
   
   double                  getDistance() const;
@@ -78,35 +138,42 @@ public:
   double                  getRotation1() const;
   double                  getRotation2() const;
   void                    setRotation( const double, const double );
-  void                    Sinchronize();
 
   // used in SMESHGUI::restoreVisualParameters() to avoid
   // declaration of OrientedPlane outside of SMESHGUI_ClippingDlg.cxx
-  static void             AddPlane (SMESH_Actor*         theActor,
-                                    SVTK_ViewWindow*     theViewWindow,
-                                    SMESH::Orientation   theOrientation,
-                                    double               theDistance,
-                                    vtkFloatingPointType theAngle[2]);
-
-  static void             GetPlaneParam (SMESH_Actor*          theActor,
-                                         int                   thePlaneIndex,
-                                         SMESH::Orientation&   theOrientation,
-                                         double&               theDistance,
-                                         vtkFloatingPointType* theAngle);
+  static SMESH::OrientedPlane* AddPlane (SMESH::TActorList          theActorList,
+                                         SVTK_ViewWindow*           theViewWindow,
+                                         SMESH::Orientation         theOrientation,
+                                         double                     theDistance,
+                                         const vtkFloatingPointType theAngle[2]);
 
 protected:  
   void                    keyPressEvent( QKeyEvent* );
 
 private:
-  LightApp_SelectionMgr*  mySelectionMgr;
-  SVTK_Selector*          mySelector;
+  void                    initializePlaneData();
+
+  void                    synchronize();
+
+  void                    updateActorList();
+  SMESH::TActorList       getCurrentActors();
+
+  void                    updateActorItem( QListWidgetItem* theItem,
+                                           bool theUpdateSelectAll,
+                                           bool theUpdateClippingPlaneMap );
+
+  void                    dumpPlaneData() const;
+
+private:
   SMESHGUI*               mySMESHGUI;
-  SMESH_Actor*            myActor;
-  SMESH::TPlanes          myPlanes;
+  SVTK_ViewWindow*        myViewWindow;
+  SMESH::TPlaneDataVector myPlanes;
   
   QComboBox*              ComboBoxPlanes;
   QPushButton*            buttonNew;
   QPushButton*            buttonDelete;
+  QListWidget*            ActorList;
+  QCheckBox*              SelectAllCheckBox;
   QLabel*                 TextLabelOrientation;
   QComboBox*              ComboBoxOrientation;
   QLabel*                 TextLabelDistance;
@@ -129,9 +196,10 @@ public slots:
   void                    onSelectPlane( int );
   void                    ClickOnNew();
   void                    ClickOnDelete();
+  void                    onActorItemChanged( QListWidgetItem* );
+  void                    onSelectAll( int );
   void                    onSelectOrientation( int );
   void                    SetCurrentPlaneParam();
-  void                    onSelectionChanged();
   void                    OnPreviewToggle( bool );
   void                    ClickOnOk();
   void                    ClickOnCancel();
index 99da50cf28f01ba72cebbf27ec5770a2b05f4854..ee88f766262184a064d2372f1dba5adeaad7b08c 100755 (executable)
@@ -1379,6 +1379,8 @@ const char* SMESHGUI_FilterTable::getPrecision( const int aType )
     retval = "len_tol_precision"; break;
   case SMESH::FT_Length:
   case SMESH::FT_Length2D:
+  case SMESH::FT_MaxElementLength2D:
+  case SMESH::FT_MaxElementLength3D:
     retval = "length_precision"; break;
   case SMESH::FT_Volume3D:
     retval = "vol_precision"; break;
@@ -1795,6 +1797,7 @@ const QMap<int, QString>& SMESHGUI_FilterTable::getCriteria (const int theType)
       aCriteria[ SMESH::FT_Taper              ] = tr("TAPER");
       aCriteria[ SMESH::FT_Skew               ] = tr("SKEW");
       aCriteria[ SMESH::FT_Area               ] = tr("AREA");
+      aCriteria[ SMESH::FT_MaxElementLength2D ] = tr("MAX_ELEMENT_LENGTH_2D");
       aCriteria[ SMESH::FT_FreeEdges          ] = tr("FREE_EDGES");
       aCriteria[ SMESH::FT_RangeOfIds         ] = tr("RANGE_OF_IDS");
       aCriteria[ SMESH::FT_BelongToGeom       ] = tr("BELONG_TO_GEOM");
@@ -1817,14 +1820,15 @@ const QMap<int, QString>& SMESHGUI_FilterTable::getCriteria (const int theType)
     static QMap<int, QString> aCriteria;
     if (aCriteria.isEmpty())
     {
-      aCriteria[ SMESH::FT_AspectRatio3D     ] = tr("ASPECT_RATIO_3D");
-      aCriteria[ SMESH::FT_RangeOfIds        ] = tr("RANGE_OF_IDS");
-      aCriteria[ SMESH::FT_BelongToGeom      ] = tr("BELONG_TO_GEOM");
-      aCriteria[ SMESH::FT_LyingOnGeom       ] = tr("LYING_ON_GEOM");
-      aCriteria[ SMESH::FT_BadOrientedVolume ] = tr("BAD_ORIENTED_VOLUME");
-      aCriteria[ SMESH::FT_Volume3D          ] = tr("VOLUME_3D");
-      aCriteria[ SMESH::FT_LinearOrQuadratic ] = tr("LINEAR");
-      aCriteria[ SMESH::FT_GroupColor        ] = tr("GROUP_COLOR");
+      aCriteria[ SMESH::FT_AspectRatio3D      ] = tr("ASPECT_RATIO_3D");
+      aCriteria[ SMESH::FT_RangeOfIds         ] = tr("RANGE_OF_IDS");
+      aCriteria[ SMESH::FT_BelongToGeom       ] = tr("BELONG_TO_GEOM");
+      aCriteria[ SMESH::FT_LyingOnGeom        ] = tr("LYING_ON_GEOM");
+      aCriteria[ SMESH::FT_BadOrientedVolume  ] = tr("BAD_ORIENTED_VOLUME");
+      aCriteria[ SMESH::FT_Volume3D           ] = tr("VOLUME_3D");
+      aCriteria[ SMESH::FT_MaxElementLength3D ] = tr("MAX_ELEMENT_LENGTH_3D");
+      aCriteria[ SMESH::FT_LinearOrQuadratic  ] = tr("LINEAR");
+      aCriteria[ SMESH::FT_GroupColor         ] = tr("GROUP_COLOR");
       aCriteria[ SMESH::FT_ElemGeomType       ] = tr("GEOM_TYPE");
     }
     return aCriteria;
diff --git a/src/SMESHGUI/SMESHGUI_Measurements.cxx b/src/SMESHGUI/SMESHGUI_Measurements.cxx
new file mode 100644 (file)
index 0000000..b07c08d
--- /dev/null
@@ -0,0 +1,1231 @@
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//  File   : SMESHGUI_Measurements.cxx
+//  Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
+
+#include "SMESHGUI_Measurements.h"
+
+#include "SMESH_Actor.h"
+#include "SMESHGUI.h"
+#include "SMESHGUI_IdValidator.h"
+#include "SMESHGUI_Utils.h"
+#include "SMESHGUI_VTKUtils.h"
+#include <SMESH_TypeFilter.hxx>
+#include <SMESH_LogicalFilter.hxx>
+
+#include <LightApp_SelectionMgr.h>
+#include <SUIT_OverrideCursor.h>
+#include <SUIT_ResourceMgr.h>
+#include <SVTK_ViewWindow.h>
+#include <SALOME_ListIteratorOfListIO.hxx>
+
+#include <QButtonGroup>
+#include <QGridLayout>
+#include <QGroupBox>
+#include <QHBoxLayout>
+#include <QKeyEvent>
+#include <QLabel>
+#include <QLineEdit>
+#include <QPushButton>
+#include <QRadioButton>
+#include <QTabWidget>
+#include <QVBoxLayout>
+
+#include <vtkPoints.h>
+#include <vtkUnstructuredGrid.h>
+#include <vtkIdList.h>
+#include <vtkCellArray.h>
+#include <vtkUnsignedCharArray.h>
+#include <vtkDataSetMapper.h>
+#include <VTKViewer_CellLocationsArray.h>
+#include <vtkProperty.h>
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
+#include CORBA_SERVER_HEADER(SMESH_Measurements)
+
+const int SPACING = 6;            // layout spacing
+const int MARGIN  = 9;            // layout margin
+const int MAX_NB_FOR_EDITOR = 40; // max nb of items in the ID list editor field
+
+// Uncomment as soon as elements are supported by Min Distance operation
+//#define MINDIST_ENABLE_ELEMENT
+
+// Uncomment as soon as objects are supported by Min Distance operation
+//#define MINDIST_ENABLE_OBJECT
+
+/*!
+  \class SMESHGUI_MinDistance
+  \brief Minimum distance measurement widget.
+  
+  Widget to calculate minimum distance between two objects.
+*/
+
+/*!
+  \brief Constructor.
+  \param parent parent widget
+*/
+SMESHGUI_MinDistance::SMESHGUI_MinDistance( QWidget* parent )
+: QWidget( parent ), myCurrentTgt( FirstTgt ), myFirstActor( 0 ), mySecondActor( 0 ), myPreview( 0 )
+{
+  QGroupBox*    aFirstTgtGrp = new QGroupBox( tr( "FIRST_TARGET" ), this );
+  QRadioButton* aFNode       = new QRadioButton( tr( "NODE" ),    aFirstTgtGrp );
+  QRadioButton* aFElem       = new QRadioButton( tr( "ELEMENT" ), aFirstTgtGrp );
+  QRadioButton* aFObject     = new QRadioButton( tr( "OBJECT" ),  aFirstTgtGrp );
+  myFirstTgt                 = new QLineEdit( aFirstTgtGrp );
+
+  QGridLayout* fl = new QGridLayout( aFirstTgtGrp );
+  fl->setMargin( MARGIN );
+  fl->setSpacing( SPACING );
+  fl->addWidget( aFNode,     0, 0 );
+  fl->addWidget( aFElem,     0, 1 );
+  fl->addWidget( aFObject,   0, 2 );
+  fl->addWidget( myFirstTgt, 1, 0, 1, 3 );
+
+  myFirst = new QButtonGroup( this );
+  myFirst->addButton( aFNode,   NodeTgt );
+  myFirst->addButton( aFElem,   ElementTgt );
+  myFirst->addButton( aFObject, ObjectTgt );
+
+  QGroupBox*    aSecondTgtGrp = new QGroupBox( tr( "SECOND_TARGET" ), this );
+  QRadioButton* aSOrigin      = new QRadioButton( tr( "ORIGIN" ),  aSecondTgtGrp );
+  QRadioButton* aSNode        = new QRadioButton( tr( "NODE" ),    aSecondTgtGrp );
+  QRadioButton* aSElem        = new QRadioButton( tr( "ELEMENT" ), aSecondTgtGrp );
+  QRadioButton* aSObject      = new QRadioButton( tr( "OBJECT" ),  aSecondTgtGrp );
+  mySecondTgt                 = new QLineEdit( aSecondTgtGrp );
+
+  QGridLayout* sl = new QGridLayout( aSecondTgtGrp );
+  sl->setMargin( MARGIN );
+  sl->setSpacing( SPACING );
+  sl->addWidget( aSOrigin,   0, 0 );
+  sl->addWidget( aSNode,     0, 1 );
+  sl->addWidget( aSElem,     0, 2 );
+  sl->addWidget( aSObject,   0, 3 );
+  sl->addWidget( mySecondTgt, 1, 0, 1, 4 );
+
+  mySecond = new QButtonGroup( this );
+  mySecond->addButton( aSOrigin, OriginTgt );
+  mySecond->addButton( aSNode,   NodeTgt );
+  mySecond->addButton( aSElem,   ElementTgt );
+  mySecond->addButton( aSObject, ObjectTgt );
+
+  QPushButton* aCompute = new QPushButton( tr( "COMPUTE" ), this );
+  
+  QGroupBox* aResults = new QGroupBox( tr( "RESULT" ), this );
+  QLabel* aDxLab   = new QLabel( "dX", aResults );
+  myDX             = new QLineEdit( aResults );
+  QLabel* aDyLab   = new QLabel( "dY", aResults );
+  myDY             = new QLineEdit( aResults );
+  QLabel* aDzLab   = new QLabel( "dZ", aResults );
+  myDZ             = new QLineEdit( aResults );
+  QLabel* aDistLab = new QLabel( tr( "DISTANCE" ), aResults );
+  myDistance       = new QLineEdit( aResults );
+
+  QGridLayout* rl = new QGridLayout( aResults );
+  rl->setMargin( MARGIN );
+  rl->setSpacing( SPACING );
+  rl->addWidget( aDxLab,     0, 0 );
+  rl->addWidget( myDX,       0, 1 );
+  rl->addWidget( aDyLab,     1, 0 );
+  rl->addWidget( myDY,       1, 1 );
+  rl->addWidget( aDzLab,     2, 0 );
+  rl->addWidget( myDZ,       2, 1 );
+  rl->addWidget( aDistLab,   0, 2 );
+  rl->addWidget( myDistance, 0, 3 );
+
+  QGridLayout* l = new QGridLayout( this );
+  l->setMargin( MARGIN );
+  l->setSpacing( SPACING );
+
+  l->addWidget( aFirstTgtGrp,  0, 0, 1, 2 );
+  l->addWidget( aSecondTgtGrp, 1, 0, 1, 2 );
+  l->addWidget( aCompute,      2, 0 );
+  l->addWidget( aResults,      3, 0, 1, 2 );
+  l->setColumnStretch( 1, 5 );
+  l->setRowStretch( 4, 5 );
+
+  aFNode->setChecked( true );
+  aSOrigin->setChecked( true );
+#ifndef MINDIST_ENABLE_ELEMENT
+  aFElem->setEnabled( false );   // NOT AVAILABLE YET
+  aSElem->setEnabled( false );   // NOT AVAILABLE YET
+#endif
+#ifndef MINDIST_ENABLE_OBJECT
+  aFObject->setEnabled( false ); // NOT AVAILABLE YET
+  aSObject->setEnabled( false ); // NOT AVAILABLE YET
+#endif
+  myDX->setReadOnly( true );
+  myDY->setReadOnly( true );
+  myDZ->setReadOnly( true );
+  myDistance->setReadOnly( true );
+
+  myValidator = new SMESHGUI_IdValidator( this, 1 );
+
+  myFirstTgt->installEventFilter( this );
+  mySecondTgt->installEventFilter( this );
+
+  connect( myFirst,     SIGNAL( buttonClicked( int ) ),  this, SLOT( firstChanged() ) );
+  connect( mySecond,    SIGNAL( buttonClicked( int ) ),  this, SLOT( secondChanged() ) );
+  connect( aCompute,    SIGNAL( clicked() ),             this, SLOT( compute() ) );
+  connect( myFirstTgt,  SIGNAL( textEdited( QString ) ), this, SLOT( firstEdited() ) );
+  connect( mySecondTgt, SIGNAL( textEdited( QString ) ), this, SLOT( secondEdited() ) );
+
+  QList<SUIT_SelectionFilter*> filters;
+  filters.append( new SMESH_TypeFilter( MESHorSUBMESH ) );
+  filters.append( new SMESH_TypeFilter( GROUP ) );
+  myFilter = new SMESH_LogicalFilter( filters, SMESH_LogicalFilter::LO_OR );
+
+  mySecondTgt->setEnabled( mySecond->checkedId() != OriginTgt );
+  clear();
+
+  //setTarget( FirstTgt );
+}
+
+/*!
+  \brief Destructor
+*/
+SMESHGUI_MinDistance::~SMESHGUI_MinDistance()
+{
+  erasePreview();
+  if ( myPreview )
+    myPreview->Delete();
+}
+
+/*!
+  \brief Event filter
+  \param o object
+  \param o event
+  \return \c true if event is filtered or \c false otherwise
+*/
+bool SMESHGUI_MinDistance::eventFilter( QObject* o, QEvent* e )
+{
+  if ( e->type() == QEvent::FocusIn ) {
+    if ( o == myFirstTgt )
+      setTarget( FirstTgt );
+    else if ( o == mySecondTgt )
+      setTarget( SecondTgt );
+  }
+  return QWidget::eventFilter( o, e );
+}
+
+/*!
+  \brief Setup selection mode depending on the current widget state
+*/
+void SMESHGUI_MinDistance::updateSelection()
+{
+  LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
+
+  disconnect( selMgr, 0, this, 0 );
+  selMgr->clearFilters();
+  
+  bool nodeMode = ( myCurrentTgt == FirstTgt  && myFirst->checkedId() == NodeTgt ) ||
+                  ( myCurrentTgt == SecondTgt && mySecond->checkedId() == NodeTgt );
+  bool elemMode = ( myCurrentTgt == FirstTgt  && myFirst->checkedId() == ElementTgt ) ||
+                  ( myCurrentTgt == SecondTgt && mySecond->checkedId() == ElementTgt );
+  bool objMode  = ( myCurrentTgt == FirstTgt  && myFirst->checkedId() == ObjectTgt ) ||
+                  ( myCurrentTgt == SecondTgt && mySecond->checkedId() == ObjectTgt ) ||
+                  ( myCurrentTgt == NoTgt );
+
+  if ( nodeMode ) {
+    SMESH::SetPointRepresentation( true );
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
+      aViewWindow->SetSelectionMode( NodeSelection );
+  }
+  else if ( elemMode ) {
+    SMESH::SetPointRepresentation( false );
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
+      aViewWindow->SetSelectionMode( CellSelection );
+  }
+  else if ( objMode ) {
+    SMESH::SetPointRepresentation( false );
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
+      aViewWindow->SetSelectionMode( ActorSelection );
+    selMgr->installFilter( myFilter );
+  }
+
+  connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( selectionChanged() ) );
+
+  if ( myCurrentTgt == FirstTgt )
+    firstEdited();
+  else if ( myCurrentTgt == SecondTgt )
+    secondEdited();
+
+  //selectionChanged();
+}
+
+/*!
+  \brief Deactivate widget
+*/
+void SMESHGUI_MinDistance::deactivate()
+{
+  disconnect( SMESHGUI::selectionMgr(), 0, this, 0 );
+}
+
+/*!
+  \brief Set current target for selection
+  \param target new target ID
+*/
+void SMESHGUI_MinDistance::setTarget( int target )
+{
+  if ( myCurrentTgt != target ) {
+    myCurrentTgt = target;
+    updateSelection();
+  }
+}
+
+/*!
+  \brief Erase preview actor
+*/
+void SMESHGUI_MinDistance::erasePreview()
+{
+  SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow();
+  if ( aViewWindow && myPreview ) {
+    aViewWindow->RemoveActor( myPreview );
+    aViewWindow->Repaint();
+  }
+}
+
+/*!
+  \brief Display preview actor
+*/
+void SMESHGUI_MinDistance::displayPreview()
+{
+  SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow();
+  if ( aViewWindow && myPreview ) {
+    aViewWindow->AddActor( myPreview );
+    aViewWindow->Repaint();
+  }
+}
+
+/*!
+  \brief Create preview actor
+  \param x1 X coordinate of first point
+  \param y1 X coordinate of first point
+  \param z1 Y coordinate of first point
+  \param x2 Y coordinate of second point
+  \param y2 Z coordinate of second point
+  \param z2 Z coordinate of second point
+*/
+void SMESHGUI_MinDistance::createPreview( double x1, double y1, double z1, double x2, double y2, double z2 )
+{
+  if ( myPreview )
+    myPreview->Delete();
+
+  vtkUnstructuredGrid* aGrid = vtkUnstructuredGrid::New();
+  // create points
+  vtkPoints* aPoints = vtkPoints::New();
+  aPoints->SetNumberOfPoints( 2 );
+  aPoints->SetPoint( 0, x1, y1, z1 );
+  aPoints->SetPoint( 1, x2, y2, z2 );
+  aGrid->SetPoints( aPoints );
+  aPoints->Delete();
+  // create cells
+  vtkIdList* anIdList = vtkIdList::New();
+  anIdList->SetNumberOfIds( 2 );
+  vtkCellArray* aCells = vtkCellArray::New();
+  aCells->Allocate( 2, 0);
+  vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
+  aCellTypesArray->SetNumberOfComponents( 1 );
+  aCellTypesArray->Allocate( 1 );
+  anIdList->SetId( 0, 0 ); anIdList->SetId( 1, 1 );
+  aCells->InsertNextCell( anIdList );
+  aCellTypesArray->InsertNextValue( VTK_LINE );
+  anIdList->Delete();
+  VTKViewer_CellLocationsArray* aCellLocationsArray = VTKViewer_CellLocationsArray::New();
+  aCellLocationsArray->SetNumberOfComponents( 1 );
+  aCellLocationsArray->SetNumberOfTuples( 1 );
+  aCells->InitTraversal();
+  for( vtkIdType idType = 0, *pts, npts; aCells->GetNextCell( npts, pts ); idType++ )
+    aCellLocationsArray->SetValue( idType, aCells->GetTraversalLocation( npts ) );
+  aGrid->SetCells( aCellTypesArray, aCellLocationsArray, aCells );
+  aCellLocationsArray->Delete();
+  aCellTypesArray->Delete();
+  aCells->Delete();
+  // create actor
+  vtkDataSetMapper* aMapper = vtkDataSetMapper::New();
+  aMapper->SetInput( aGrid );
+  aGrid->Delete();
+  myPreview = SALOME_Actor::New();
+  myPreview->PickableOff();
+  myPreview->SetMapper( aMapper );
+  aMapper->Delete();
+  vtkProperty* aProp = vtkProperty::New();
+  aProp->SetRepresentationToWireframe();
+  aProp->SetColor( 250, 0, 250 );
+  aProp->SetPointSize( 5 );
+  aProp->SetLineWidth( 3 );
+  myPreview->SetProperty( aProp );
+  aProp->Delete();
+}
+
+/*!
+  \brief Called when selection is changed
+*/
+void SMESHGUI_MinDistance::selectionChanged()
+{
+  SUIT_OverrideCursor wc;
+
+  SALOME_ListIO selected;
+  SMESHGUI::selectionMgr()->selectedObjects( selected );
+
+  if ( selected.Extent() == 1 ) {
+    Handle(SALOME_InteractiveObject) IO = selected.First();
+    SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
+    if ( !CORBA::is_nil( obj ) ) {
+      if ( myCurrentTgt == FirstTgt ) {
+       myFirstSrc = obj;
+       myFirstActor = SMESH::FindActorByEntry( IO->getEntry() );
+       if ( myFirst->checkedId() == ObjectTgt ) {
+         QString aName;
+         SMESH::GetNameOfSelectedIObjects( SMESHGUI::selectionMgr(), aName );
+         myFirstTgt->setText( aName );
+       }
+       else {
+         SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector();
+         QString ID;
+         int nb = 0;
+         if ( myFirstActor && selector ) {
+           nb = myFirst->checkedId() == NodeTgt ? 
+             SMESH::GetNameOfSelectedElements( selector, IO, ID ) :
+             SMESH::GetNameOfSelectedNodes( selector, IO, ID );
+         }
+         if ( nb == 1 )
+           myFirstTgt->setText( ID.trimmed() );
+         else
+           myFirstTgt->clear();
+       }
+      }
+      else if ( myCurrentTgt == SecondTgt ) {
+       mySecondSrc = obj;
+       mySecondActor = SMESH::FindActorByEntry( IO->getEntry() );
+       if ( mySecond->checkedId() == ObjectTgt ) {
+         QString aName;
+         SMESH::GetNameOfSelectedIObjects( SMESHGUI::selectionMgr(), aName );
+         mySecondTgt->setText( aName );
+       }
+       else {
+         SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector();
+         QString ID;
+         int nb = 0;
+         if ( mySecondActor && selector ) {
+           nb = mySecond->checkedId() == NodeTgt ? 
+             SMESH::GetNameOfSelectedElements( selector, IO, ID ) :
+             SMESH::GetNameOfSelectedNodes( selector, IO, ID );
+         }
+         if ( nb == 1 )
+           mySecondTgt->setText( ID.trimmed() );
+         else
+           mySecondTgt->clear();
+       }
+      }
+    }
+  }
+  clear();
+}
+
+/*!
+  \brief Called when first target mode is changed by the user
+*/
+void SMESHGUI_MinDistance::firstChanged()
+{
+  myFirstSrc = SMESH::SMESH_IDSource::_nil();
+  myFirstTgt->clear();
+  myFirstTgt->setReadOnly( myFirst->checkedId() == ObjectTgt );
+  myFirstTgt->setValidator( myFirst->checkedId() == ObjectTgt ? 0 : myValidator );
+  setTarget( FirstTgt );
+  updateSelection();
+  clear();
+}
+
+/*!
+  \brief Called when second target mode is changed by the user
+*/
+void SMESHGUI_MinDistance::secondChanged()
+{
+  mySecondSrc = SMESH::SMESH_IDSource::_nil();
+  mySecondTgt->setEnabled( mySecond->checkedId() != OriginTgt );
+  mySecondTgt->setReadOnly( mySecond->checkedId() == ObjectTgt );
+  mySecondTgt->setValidator( mySecond->checkedId() == ObjectTgt ? 0 : myValidator );
+  mySecondTgt->clear();
+  setTarget( mySecond->checkedId() != OriginTgt ? SecondTgt : NoTgt );
+  updateSelection();
+  clear();
+}
+
+/*!
+  \brief Called when first target is edited by the user
+*/
+void SMESHGUI_MinDistance::firstEdited()
+{
+  setTarget( FirstTgt );
+  if ( sender() == myFirstTgt )
+    clear();
+  SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector();
+  if ( myFirstActor && selector ) {
+    Handle(SALOME_InteractiveObject) IO = myFirstActor->getIO();
+    if ( myFirst->checkedId() == NodeTgt || myFirst->checkedId() == ElementTgt ) {
+      TColStd_MapOfInteger ID;
+      ID.Add( myFirstTgt->text().toLong() );
+      selector->AddOrRemoveIndex( IO, ID, false );
+    }
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
+      aViewWindow->highlight( IO, true, true );
+  }
+}
+
+/*!
+  \brief Called when second target is edited by the user
+*/
+void SMESHGUI_MinDistance::secondEdited()
+{
+  setTarget( SecondTgt );
+  if ( sender() == mySecondTgt )
+    clear();
+  SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector();
+  if ( mySecondActor && selector ) {
+    Handle(SALOME_InteractiveObject) IO = mySecondActor->getIO();
+    if ( mySecond->checkedId() == NodeTgt || mySecond->checkedId() == ElementTgt ) {
+      TColStd_MapOfInteger ID;
+      ID.Add( mySecondTgt->text().toLong() );
+      selector->AddOrRemoveIndex( IO, ID, false );
+    }
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
+      aViewWindow->highlight( IO, true, true );
+  }
+}
+
+/*!
+  \brief Compute the minimum distance between targets
+*/
+void SMESHGUI_MinDistance::compute()
+{
+  SUIT_OverrideCursor wc;
+  SMESH::SMESH_IDSource_var s1;
+  SMESH::SMESH_IDSource_var s2;
+  bool isOrigin = mySecond->checkedId() == OriginTgt;
+
+  // process first target
+  if ( !CORBA::is_nil( myFirstSrc ) ) {
+    if ( myFirst->checkedId() == NodeTgt || myFirst->checkedId() == ElementTgt ) {
+      SMESH::SMESH_Mesh_var m = myFirstSrc->GetMesh();
+      long id = myFirstTgt->text().toLong();
+      if ( !CORBA::is_nil( m ) && id ) {
+       SMESH::long_array_var ids = new SMESH::long_array();
+       ids->length( 1 );
+       ids[0] = id;
+       SMESH::SMESH_MeshEditor_var me = m->GetMeshEditor();
+       s1 = me->MakeIDSource( ids.in(), myFirst->checkedId() == NodeTgt ? SMESH::NODE : SMESH::FACE );
+      }
+    }
+    else {
+      s1 = myFirstSrc;
+    }
+  }
+
+  // process second target
+  if ( !CORBA::is_nil( mySecondSrc ) ) {
+    if ( mySecond->checkedId() == NodeTgt || mySecond->checkedId() == ElementTgt ) {
+      SMESH::SMESH_Mesh_var m = mySecondSrc->GetMesh();
+      long id = mySecondTgt->text().toLong();
+      if ( !CORBA::is_nil( m ) && id ) {
+       SMESH::long_array_var ids = new SMESH::long_array();
+       ids->length( 1 );
+       ids[0] = id;
+       SMESH::SMESH_MeshEditor_var me = m->GetMeshEditor();
+       s2 = me->MakeIDSource( ids.in(), mySecond->checkedId() == NodeTgt ? SMESH::NODE : SMESH::FACE );
+      }
+    }
+    else {
+      s2 = mySecondSrc;
+    }
+  }
+
+  if ( !CORBA::is_nil( s1 ) && ( !CORBA::is_nil( s2 ) || isOrigin ) ) {
+    // compute min distance
+    int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
+    SMESH::Measurements_var measure = SMESHGUI::GetSMESHGen()->CreateMeasurements();
+    SMESH::Measure result = measure->MinDistance( s1.in(), s2.in() );
+    measure->Destroy();
+    myDX->setText( QString::number( result.minX, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+    myDY->setText( QString::number( result.minY, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+    myDZ->setText( QString::number( result.minZ, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+    myDistance->setText( QString::number( result.value, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+    // update preview actor
+    erasePreview();
+    double x1, y1, z1, x2, y2, z2;
+    SMESH::double_array_var coord = s1->GetMesh()->GetNodeXYZ( result.node1 );
+    x1 = coord[0]; y1 = coord[1]; z1 = coord[2];
+    if ( isOrigin ) {
+      x2 = y2 = z2 = 0.;
+    }
+    else {
+      coord = s2->GetMesh()->GetNodeXYZ( result.node2 );
+      x2 = coord[0]; y2 = coord[1]; z2 = coord[2];
+    }
+    createPreview( x1, y1, z1, x2, y2, z2 );
+    displayPreview();
+  }
+  else {
+    clear();
+  }
+}
+
+/*!
+  \brief Reset the widget to the initial state (nullify result fields)
+*/
+void SMESHGUI_MinDistance::clear()
+{
+  myDX->clear();
+  myDY->clear();
+  myDZ->clear();
+  myDistance->clear();
+  erasePreview();
+}
+
+/*!
+  \class SMESHGUI_BoundingBox
+  \brief Bounding box measurement widget.
+  
+  Widget to calculate bounding box of the selected object(s).
+*/
+
+/*!
+  \brief Constructor.
+  \param parent parent widget
+*/
+SMESHGUI_BoundingBox::SMESHGUI_BoundingBox( QWidget* parent )
+: QWidget( parent ), myActor( 0 ), myPreview( 0 )
+{
+  QGroupBox* aSourceGrp = new QGroupBox( tr( "SOURCE" ), this );
+  QRadioButton* aObjects  = new QRadioButton( tr( "OBJECTS" ),  aSourceGrp );
+  QRadioButton* aNodes    = new QRadioButton( tr( "NODES" ),    aSourceGrp );
+  QRadioButton* aElements = new QRadioButton( tr( "ELEMENTS" ), aSourceGrp );
+  mySource = new QLineEdit( aSourceGrp );
+  
+  QGridLayout* fl = new QGridLayout( aSourceGrp );
+  fl->setMargin( MARGIN );
+  fl->setSpacing( SPACING );
+  fl->addWidget( aObjects,   0, 0 );
+  fl->addWidget( aNodes,     0, 1 );
+  fl->addWidget( aElements,  0, 2 );
+  fl->addWidget( mySource,   1, 0, 1, 3 );
+  
+  mySourceMode = new QButtonGroup( this );
+  mySourceMode->addButton( aObjects,  ObjectsSrc );
+  mySourceMode->addButton( aNodes,    NodesSrc );
+  mySourceMode->addButton( aElements, ElementsSrc );
+
+  QPushButton* aCompute = new QPushButton( tr( "COMPUTE" ), this );
+
+  QGroupBox* aResults = new QGroupBox( tr( "RESULT" ), this );
+  QLabel* aXminLab = new QLabel( "Xmin", aResults );
+  myXmin           = new QLineEdit( aResults );
+  QLabel* aXmaxLab = new QLabel( "Xmax", aResults );
+  myXmax           = new QLineEdit( aResults );
+  QLabel* aDxLab   = new QLabel( "dX", aResults );
+  myDX             = new QLineEdit( aResults );
+  QLabel* aYminLab = new QLabel( "Ymin", aResults );
+  myYmin           = new QLineEdit( aResults );
+  QLabel* aYmaxLab = new QLabel( "Ymax", aResults );
+  myYmax           = new QLineEdit( aResults );
+  QLabel* aDyLab   = new QLabel( "dY", aResults );
+  myDY             = new QLineEdit( aResults );
+  QLabel* aZminLab = new QLabel( "Zmin", aResults );
+  myZmin           = new QLineEdit( aResults );
+  QLabel* aZmaxLab = new QLabel( "Zmax", aResults );
+  myZmax           = new QLineEdit( aResults );
+  QLabel* aDzLab   = new QLabel( "dZ", aResults );
+  myDZ             = new QLineEdit( aResults );
+
+  QGridLayout* rl  = new QGridLayout( aResults );
+  rl->setMargin( MARGIN );
+  rl->setSpacing( SPACING );
+  rl->addWidget( aXminLab,   0, 0 );
+  rl->addWidget( myXmin,     0, 1 );
+  rl->addWidget( aXmaxLab,   0, 2 );
+  rl->addWidget( myXmax,     0, 3 );
+  rl->addWidget( aDxLab,     0, 4 );
+  rl->addWidget( myDX,       0, 5 );
+  rl->addWidget( aYminLab,   1, 0 );
+  rl->addWidget( myYmin,     1, 1 );
+  rl->addWidget( aYmaxLab,   1, 2 );
+  rl->addWidget( myYmax,     1, 3 );
+  rl->addWidget( aDyLab,     1, 4 );
+  rl->addWidget( myDY,       1, 5 );
+  rl->addWidget( aZminLab,   2, 0 );
+  rl->addWidget( myZmin,     2, 1 );
+  rl->addWidget( aZmaxLab,   2, 2 );
+  rl->addWidget( myZmax,     2, 3 );
+  rl->addWidget( aDzLab,     2, 4 );
+  rl->addWidget( myDZ,       2, 5 );
+
+  QGridLayout* l = new QGridLayout( this );
+  l->setMargin( MARGIN );
+  l->setSpacing( SPACING );
+
+  l->addWidget( aSourceGrp, 0, 0, 1, 2 );
+  l->addWidget( aCompute,   1, 0 );
+  l->addWidget( aResults,   2, 0, 1, 2 );
+  l->setColumnStretch( 1, 5 );
+  l->setRowStretch( 3, 5 );
+
+  aObjects->setChecked( true );
+  myXmin->setReadOnly( true );
+  myXmax->setReadOnly( true );
+  myDX->setReadOnly( true );
+  myYmin->setReadOnly( true );
+  myYmax->setReadOnly( true );
+  myDY->setReadOnly( true );
+  myZmin->setReadOnly( true );
+  myZmax->setReadOnly( true );
+  myDZ->setReadOnly( true );
+
+  myValidator = new SMESHGUI_IdValidator( this );
+
+  connect( mySourceMode, SIGNAL( buttonClicked( int ) ),  this, SLOT( sourceChanged() ) );
+  connect( aCompute,     SIGNAL( clicked() ),             this, SLOT( compute() ) );
+  connect( mySource,     SIGNAL( textEdited( QString ) ), this, SLOT( sourceEdited() ) );
+
+  QList<SUIT_SelectionFilter*> filters;
+  filters.append( new SMESH_TypeFilter( MESHorSUBMESH ) );
+  filters.append( new SMESH_TypeFilter( GROUP ) );
+  myFilter = new SMESH_LogicalFilter( filters, SMESH_LogicalFilter::LO_OR );
+
+  clear();
+}
+
+/*!
+  \brief Destructor
+*/
+SMESHGUI_BoundingBox::~SMESHGUI_BoundingBox()
+{
+  erasePreview();
+  if ( myPreview )
+    myPreview->Delete();
+}
+
+/*!
+  \brief Setup selection mode depending on the current widget state
+*/
+void SMESHGUI_BoundingBox::updateSelection()
+{
+  LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
+
+  disconnect( selMgr, 0, this, 0 );
+  selMgr->clearFilters();
+  
+  bool nodeMode = mySourceMode->checkedId() == NodesSrc;
+  bool elemMode = mySourceMode->checkedId() == ElementsSrc;
+  bool objMode  = mySourceMode->checkedId() == ObjectsSrc;
+
+  if ( nodeMode ) {
+    SMESH::SetPointRepresentation( true );
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
+      aViewWindow->SetSelectionMode( NodeSelection );
+  }
+  else if ( elemMode ) {
+    SMESH::SetPointRepresentation( false );
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
+      aViewWindow->SetSelectionMode( CellSelection );
+  }
+  else if ( objMode ) {
+    SMESH::SetPointRepresentation( false );
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
+      aViewWindow->SetSelectionMode( ActorSelection );
+    selMgr->installFilter( myFilter );
+  }
+
+  connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( selectionChanged() ) );
+
+  sourceEdited();
+
+  //selectionChanged();
+}
+
+/*!
+  \brief Deactivate widget
+*/
+void SMESHGUI_BoundingBox::deactivate()
+{
+  disconnect( SMESHGUI::selectionMgr(), 0, this, 0 );
+}
+
+/*!
+  \brief Erase preview actor
+*/
+void SMESHGUI_BoundingBox::erasePreview()
+{
+  SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow();
+  if ( aViewWindow && myPreview ) {
+    aViewWindow->RemoveActor( myPreview );
+    aViewWindow->Repaint();
+  }
+}
+
+/*!
+  \brief Display preview actor
+*/
+void SMESHGUI_BoundingBox::displayPreview()
+{
+  SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow();
+  if ( aViewWindow && myPreview ) {
+    aViewWindow->AddActor( myPreview );
+    aViewWindow->Repaint();
+  }
+}
+
+/*!
+  \brief Create preview actor
+  \param minX min X coordinate of bounding box
+  \param maxX max X coordinate of bounding box
+  \param minY min Y coordinate of bounding box
+  \param maxY max Y coordinate of bounding box
+  \param minZ min Z coordinate of bounding box
+  \param maxZ max Z coordinate of bounding box
+*/
+void SMESHGUI_BoundingBox::createPreview( double minX, double maxX, double minY, double maxY, double minZ, double maxZ )
+{
+  if ( myPreview )
+    myPreview->Delete();
+
+  vtkUnstructuredGrid* aGrid = vtkUnstructuredGrid::New();
+  // create points
+  vtkPoints* aPoints = vtkPoints::New();
+  aPoints->SetNumberOfPoints( 8 );
+  aPoints->SetPoint( 0, minX, minY, minZ );
+  aPoints->SetPoint( 1, maxX, minY, minZ );
+  aPoints->SetPoint( 2, minX, maxY, minZ );
+  aPoints->SetPoint( 3, maxX, maxY, minZ );
+  aPoints->SetPoint( 4, minX, minY, maxZ );
+  aPoints->SetPoint( 5, maxX, minY, maxZ );
+  aPoints->SetPoint( 6, minX, maxY, maxZ );
+  aPoints->SetPoint( 7, maxX, maxY, maxZ );
+  aGrid->SetPoints( aPoints );
+  aPoints->Delete();
+  // create cells
+  // connectivity: 0-1 0-4 0-2 1-5 1-3 2-6 2-3 3-7 4-6 4-5 5-7 6-7
+  vtkIdList* anIdList = vtkIdList::New();
+  anIdList->SetNumberOfIds( 2 );
+  vtkCellArray* aCells = vtkCellArray::New();
+  aCells->Allocate( 2*12, 0);
+  vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
+  aCellTypesArray->SetNumberOfComponents( 1 );
+  aCellTypesArray->Allocate( 12 );
+  anIdList->SetId( 0, 0 ); anIdList->SetId( 1, 1 );
+  aCells->InsertNextCell( anIdList );
+  aCellTypesArray->InsertNextValue( VTK_LINE );
+  anIdList->SetId( 0, 0 ); anIdList->SetId( 1, 4 );
+  aCells->InsertNextCell( anIdList );
+  aCellTypesArray->InsertNextValue( VTK_LINE );
+  anIdList->SetId( 0, 0 ); anIdList->SetId( 1, 2 );
+  aCells->InsertNextCell( anIdList );
+  aCellTypesArray->InsertNextValue( VTK_LINE );
+  anIdList->SetId( 0, 1 ); anIdList->SetId( 1, 5 );
+  aCells->InsertNextCell( anIdList );
+  aCellTypesArray->InsertNextValue( VTK_LINE );
+  anIdList->SetId( 0, 1 ); anIdList->SetId( 1, 3 );
+  aCells->InsertNextCell( anIdList );
+  aCellTypesArray->InsertNextValue( VTK_LINE );
+  anIdList->SetId( 0, 2 ); anIdList->SetId( 1, 6 );
+  aCells->InsertNextCell( anIdList );
+  aCellTypesArray->InsertNextValue( VTK_LINE );
+  anIdList->SetId( 0, 2 ); anIdList->SetId( 1, 3 );
+  aCells->InsertNextCell( anIdList );
+  aCellTypesArray->InsertNextValue( VTK_LINE );
+  anIdList->SetId( 0, 3 ); anIdList->SetId( 1, 7 );
+  aCells->InsertNextCell( anIdList );
+  aCellTypesArray->InsertNextValue( VTK_LINE );
+  anIdList->SetId( 0, 4 ); anIdList->SetId( 1, 6 );
+  aCells->InsertNextCell( anIdList );
+  aCellTypesArray->InsertNextValue( VTK_LINE );
+  anIdList->SetId( 0, 4 ); anIdList->SetId( 1, 5 );
+  aCells->InsertNextCell( anIdList );
+  aCellTypesArray->InsertNextValue( VTK_LINE );
+  anIdList->SetId( 0, 5 ); anIdList->SetId( 1, 7 );
+  aCells->InsertNextCell( anIdList );
+  aCellTypesArray->InsertNextValue( VTK_LINE );
+  anIdList->SetId( 0, 6 ); anIdList->SetId( 1, 7 );
+  aCells->InsertNextCell( anIdList );
+  aCellTypesArray->InsertNextValue( VTK_LINE );
+  anIdList->Delete();
+  VTKViewer_CellLocationsArray* aCellLocationsArray = VTKViewer_CellLocationsArray::New();
+  aCellLocationsArray->SetNumberOfComponents( 1 );
+  aCellLocationsArray->SetNumberOfTuples( 12 );
+  aCells->InitTraversal();
+  for( vtkIdType idType = 0, *pts, npts; aCells->GetNextCell( npts, pts ); idType++ )
+    aCellLocationsArray->SetValue( idType, aCells->GetTraversalLocation( npts ) );
+  aGrid->SetCells( aCellTypesArray, aCellLocationsArray, aCells );
+  aCellLocationsArray->Delete();
+  aCellTypesArray->Delete();
+  aCells->Delete();
+  // create actor
+  vtkDataSetMapper* aMapper = vtkDataSetMapper::New();
+  aMapper->SetInput( aGrid );
+  aGrid->Delete();
+  myPreview = SALOME_Actor::New();
+  myPreview->PickableOff();
+  myPreview->SetMapper( aMapper );
+  aMapper->Delete();
+  vtkProperty* aProp = vtkProperty::New();
+  aProp->SetRepresentationToWireframe();
+  aProp->SetColor( 250, 0, 250 );
+  aProp->SetPointSize( 5 );
+  aProp->SetLineWidth( 3 );
+  myPreview->SetProperty( aProp );
+  aProp->Delete();
+}
+
+/*!
+  \brief Called when selection is changed
+*/
+void SMESHGUI_BoundingBox::selectionChanged()
+{
+  SUIT_OverrideCursor wc;
+
+  SALOME_ListIO selected;
+  SMESHGUI::selectionMgr()->selectedObjects( selected );
+
+  if ( selected.Extent() == 1 ) {
+    Handle(SALOME_InteractiveObject) IO = selected.First();
+    SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
+    if ( !CORBA::is_nil( obj ) ) {
+      mySrc.clear();
+      mySrc.append( obj );
+      myActor = SMESH::FindActorByEntry( IO->getEntry() );
+      if ( mySourceMode->checkedId() == ObjectsSrc ) {
+       QString aName;
+       SMESH::GetNameOfSelectedIObjects( SMESHGUI::selectionMgr(), aName );
+       mySource->setText( aName );
+      }
+      else {
+       SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector();
+       QString ID;
+       int nb = 0;
+       if ( myActor && selector ) {
+         nb = mySourceMode->checkedId() == NodesSrc ? 
+           SMESH::GetNameOfSelectedElements( selector, IO, ID ) :
+           SMESH::GetNameOfSelectedNodes( selector, IO, ID );
+       }
+       if ( nb > 0 ) {
+         myIDs = ID.trimmed();
+         if ( nb < MAX_NB_FOR_EDITOR ) {
+           mySource->setReadOnly( false );
+           if ( mySource->validator() != myValidator )
+             mySource->setValidator( myValidator );
+           mySource->setText( ID.trimmed() );
+         }
+         else {
+           mySource->setReadOnly( true );
+           mySource->setValidator( 0 );
+           mySource->setText( tr( "SELECTED_NB_OBJ" ).arg( nb )
+                              .arg( mySourceMode->checkedId() == NodesSrc ? tr( "NB_NODES" ) : tr( "NB_ELEMENTS") ) );
+         }
+       }
+       else {
+         myIDs = "";
+         mySource->clear();
+         mySource->setReadOnly( false );
+         mySource->setValidator( myValidator );
+       }
+      }
+    }
+  }
+  else if ( selected.Extent() > 1 ) {
+    myIDs = "";
+    SALOME_ListIteratorOfListIO It( selected );
+    mySrc.clear();
+    myActor = 0;
+    if ( mySourceMode->checkedId() == ObjectsSrc ) {
+      for( ; It.More(); It.Next()){
+       Handle(SALOME_InteractiveObject) IO = It.Value();
+       SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
+       if ( !CORBA::is_nil( obj ) ) {
+         mySrc.append( obj );
+       }
+      }
+      QString aName;
+      SMESH::GetNameOfSelectedIObjects( SMESHGUI::selectionMgr(), aName );
+      mySource->setText( aName );
+    }
+    else {
+      mySource->clear();
+    }
+  }
+  clear();
+}
+
+/*!
+  \brief Called when source mode is changed by the user
+*/
+void SMESHGUI_BoundingBox::sourceChanged()
+{
+  myIDs = "";
+  mySource->clear();
+  mySource->setReadOnly( mySourceMode->checkedId() == ObjectsSrc );
+  mySource->setValidator( mySourceMode->checkedId() == ObjectsSrc ? 0 : myValidator );
+  updateSelection();
+  clear();
+}
+
+/*!
+  \brief Called when source mode is edited by the user
+*/
+void SMESHGUI_BoundingBox::sourceEdited()
+{
+  if ( sender() == mySource )
+    clear();
+  SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector();
+  if ( myActor && selector ) {
+    Handle(SALOME_InteractiveObject) IO = myActor->getIO();
+    if ( mySourceMode->checkedId() == NodesSrc || mySourceMode->checkedId() == ElementsSrc ) {
+      TColStd_MapOfInteger ID;
+      if ( !mySource->isReadOnly() )
+       myIDs = mySource->text();
+      QStringList ids = myIDs.split( " ", QString::SkipEmptyParts );
+      foreach ( QString id, ids )
+       ID.Add( id.trimmed().toLong() );
+      selector->AddOrRemoveIndex( IO, ID, false );
+    }
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
+      aViewWindow->highlight( IO, true, true );
+  }
+}
+
+/*!
+  \brief Calculate bounding box of the selected object(s)
+*/
+void SMESHGUI_BoundingBox::compute()
+{
+  SUIT_OverrideCursor wc;
+  SMESH::ListOfIDSources_var srcList = new SMESH::ListOfIDSources();
+  if ( mySourceMode->checkedId() == NodesSrc || mySourceMode->checkedId() == ElementsSrc ) {
+    if ( mySrc.count() > 0 && !CORBA::is_nil( mySrc[0] ) ) {
+      SMESH::SMESH_Mesh_var m = mySrc[0]->GetMesh();
+      QStringList ids = myIDs.split( " ", QString::SkipEmptyParts );
+      if ( !CORBA::is_nil( m ) && ids.count() > 0 ) {
+       SMESH::long_array_var ids_in = new SMESH::long_array();
+       ids_in->length( ids.count() );
+       for( int i = 0; i < ids.count(); i++ )
+         ids_in[i] = ids[i].trimmed().toLong();
+       SMESH::SMESH_MeshEditor_var me = m->GetMeshEditor();
+       SMESH::SMESH_IDSource_var s = me->MakeIDSource( ids_in.in(), mySourceMode->checkedId() == NodesSrc ? SMESH::NODE : SMESH::FACE ); 
+       srcList->length( 1 );
+       srcList[0] = s;
+      }
+    }
+  }
+  else {
+    srcList->length( mySrc.count() );
+    for( int i = 0; i < mySrc.count(); i++ )
+      srcList[i] = mySrc[i];
+  }
+  if ( srcList->length() > 0 ) {
+    // compute bounding box
+    int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
+    SMESH::Measurements_var measure = SMESHGUI::GetSMESHGen()->CreateMeasurements();
+    SMESH::Measure result = measure->BoundingBox( srcList.in() );
+    measure->Destroy();
+    myXmin->setText( QString::number( result.minX, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+    myXmax->setText( QString::number( result.maxX, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+    myDX->setText( QString::number( result.maxX-result.minX, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+    myYmin->setText( QString::number( result.minY, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+    myYmax->setText( QString::number( result.maxY, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+    myDY->setText( QString::number( result.maxY-result.minY, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+    myZmin->setText( QString::number( result.minZ, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+    myZmax->setText( QString::number( result.maxZ, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+    myDZ->setText( QString::number( result.maxZ-result.minZ, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+    // update preview actor
+    erasePreview();
+    createPreview( result.minX, result.maxX, result.minY, result.maxY, result.minZ, result.maxZ );
+    displayPreview();
+  }
+  else {
+    clear();
+  }
+}
+
+/*!
+  \brief Reset the widget to the initial state (nullify result fields)
+*/
+void SMESHGUI_BoundingBox::clear()
+{
+  myXmin->clear();
+  myXmax->clear();
+  myDX->clear();
+  myYmin->clear();
+  myYmax->clear();
+  myDY->clear();
+  myZmin->clear();
+  myZmax->clear();
+  myDZ->clear();
+  erasePreview();
+}
+
+/*!
+  \class SMESHGUI_MeshInfoDlg
+  \brief Centralized dialog box for the measurements
+*/
+
+/*!
+  \brief Constructor
+  \param parent parent widget
+  \param page specifies the dialog page to be shown at the start-up
+*/
+SMESHGUI_MeasureDlg::SMESHGUI_MeasureDlg( QWidget* parent, int page )
+: QDialog( parent )
+{
+  setModal( false );
+  setAttribute( Qt::WA_DeleteOnClose, true );
+  setWindowTitle( tr( "MEASUREMENTS" ) );
+  setSizeGripEnabled( true );
+
+  SUIT_ResourceMgr* resMgr = SMESHGUI::resourceMgr();
+
+  myTabWidget = new QTabWidget( this );
+
+  // min distance
+
+  myMinDist = new SMESHGUI_MinDistance( myTabWidget );
+  myTabWidget->addTab( myMinDist, resMgr->loadPixmap( "SMESH", tr( "ICON_MEASURE_MIN_DIST" ) ), tr( "MIN_DIST" ) );
+
+  // bounding box
+  
+  myBndBox = new SMESHGUI_BoundingBox( myTabWidget );
+  myTabWidget->addTab( myBndBox, resMgr->loadPixmap( "SMESH", tr( "ICON_MEASURE_BND_BOX" ) ), tr( "BND_BOX" ) );
+
+  // buttons
+  QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
+  okBtn->setAutoDefault( true );
+  okBtn->setDefault( true );
+  okBtn->setFocus();
+  QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this );
+  helpBtn->setAutoDefault( true );
+
+  QHBoxLayout* btnLayout = new QHBoxLayout;
+  btnLayout->setSpacing( SPACING );
+  btnLayout->setMargin( 0 );
+  btnLayout->addWidget( okBtn );
+  btnLayout->addStretch( 10 );
+  btnLayout->addWidget( helpBtn );
+
+  QVBoxLayout* l = new QVBoxLayout ( this );
+  l->setMargin( MARGIN );
+  l->setSpacing( SPACING );
+  l->addWidget( myTabWidget );
+  l->addStretch();
+  l->addLayout( btnLayout );
+
+  myTabWidget->setCurrentIndex( qMax( (int)MinDistance, qMin( (int)BoundingBox, page ) ) );
+
+  connect( okBtn,       SIGNAL( clicked() ),              this, SLOT( reject() ) );
+  connect( helpBtn,     SIGNAL( clicked() ),              this, SLOT( help() ) );
+  connect( myTabWidget, SIGNAL( currentChanged( int  ) ), this, SLOT( updateSelection() ) );
+  connect( SMESHGUI::GetSMESHGUI(),  SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ) );
+  connect( SMESHGUI::GetSMESHGUI(),  SIGNAL( SignalCloseAllDialogs() ),        this, SLOT( reject() ) );
+
+  updateSelection();
+}
+
+/*!
+  \brief Destructor
+*/
+SMESHGUI_MeasureDlg::~SMESHGUI_MeasureDlg()
+{
+}
+
+/*!
+  \brief Perform clean-up actions on the dialog box closing.
+*/
+void SMESHGUI_MeasureDlg::reject()
+{
+  LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
+  selMgr->clearFilters();
+  SMESH::SetPointRepresentation( false );
+  if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
+    aViewWindow->SetSelectionMode( ActorSelection );
+  QDialog::reject();
+}
+
+/*!
+  \brief Process keyboard event
+  \param e key press event
+*/
+void SMESHGUI_MeasureDlg::keyPressEvent( QKeyEvent* e )
+{
+  QDialog::keyPressEvent( e );
+  if ( !e->isAccepted() && e->key() == Qt::Key_F1 ) {
+    e->accept();
+    help();
+  }
+}
+
+/*!
+  \brief Reactivate dialog box, when mouse pointer goes into it.
+*/
+void SMESHGUI_MeasureDlg::enterEvent( QEvent* )
+{
+  activate();
+}
+
+/*!
+  \brief Setup selection mode depending on the current dialog box state.
+*/
+void SMESHGUI_MeasureDlg::updateSelection()
+{
+  if ( myTabWidget->currentIndex() == MinDistance )
+    myMinDist->updateSelection();
+  else if ( myTabWidget->currentIndex() == BoundingBox )
+    myBndBox->updateSelection();
+    
+}
+
+/*!
+  \brief Show help page
+*/
+void SMESHGUI_MeasureDlg::help()
+{
+  SMESH::ShowHelpFile( myTabWidget->currentIndex() == MinDistance ?
+                      "measurements_page.html#min_distance_anchor" : 
+                      "measurements_page.html#bounding_box_anchor" );
+}
+
+/*!
+  \brief Activate dialog box
+*/
+void SMESHGUI_MeasureDlg::activate()
+{
+  SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
+  SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this );
+  myTabWidget->setEnabled( true );
+  updateSelection();
+}
+
+/*!
+  \brief Deactivate dialog box
+*/
+void SMESHGUI_MeasureDlg::deactivate()
+{
+  myMinDist->deactivate();
+  myBndBox->deactivate();
+  myTabWidget->setEnabled( false );
+  disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
+}
diff --git a/src/SMESHGUI/SMESHGUI_Measurements.h b/src/SMESHGUI/SMESHGUI_Measurements.h
new file mode 100644 (file)
index 0000000..b9b58c8
--- /dev/null
@@ -0,0 +1,172 @@
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//  File   : SMESHGUI_Measurements.h
+//  Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
+
+#ifndef SMESHGUI_MEASUREMENTS_H
+#define SMESHGUI_MEASUREMENTS_H
+
+#include "SMESH_SMESHGUI.hxx"
+
+#include <QDialog>
+
+class QButtonGroup;
+class QLineEdit;
+class QTabWidget;
+class SUIT_SelectionFilter;
+class SALOME_Actor;
+class SMESH_Actor;
+class SMESHGUI_IdValidator;
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Mesh)
+
+class SMESHGUI_EXPORT SMESHGUI_MinDistance : public QWidget
+{
+  Q_OBJECT;
+
+  enum { NoTgt, FirstTgt, SecondTgt };
+  enum { OriginTgt, NodeTgt, ElementTgt, ObjectTgt };
+
+public:
+  SMESHGUI_MinDistance( QWidget* = 0 );
+  ~SMESHGUI_MinDistance();
+
+  bool eventFilter( QObject*, QEvent* );
+  void updateSelection();
+  void deactivate();
+
+private: 
+  void setTarget( int );
+  void erasePreview();
+  void displayPreview();
+  void createPreview( double, double, double, double, double, double );
+
+private slots:
+  void selectionChanged();
+  void firstChanged();
+  void secondChanged();
+  void firstEdited();
+  void secondEdited();
+  void compute();
+  void clear();
+
+private:
+  QButtonGroup*             myFirst;
+  QButtonGroup*             mySecond;
+  QLineEdit*                myFirstTgt;
+  QLineEdit*                mySecondTgt;
+  QLineEdit*                myDX;
+  QLineEdit*                myDY;
+  QLineEdit*                myDZ;
+  QLineEdit*                myDistance;
+  int                       myCurrentTgt;
+  SMESH::SMESH_IDSource_var myFirstSrc;
+  SMESH::SMESH_IDSource_var mySecondSrc;
+  SMESH_Actor*              myFirstActor;
+  SMESH_Actor*              mySecondActor;
+  SMESHGUI_IdValidator*     myValidator;
+  SUIT_SelectionFilter*     myFilter;
+  SALOME_Actor*             myPreview;
+};
+
+class SMESHGUI_EXPORT SMESHGUI_BoundingBox : public QWidget
+{
+  Q_OBJECT;
+
+  enum { ObjectsSrc, NodesSrc, ElementsSrc };
+  
+public:
+  SMESHGUI_BoundingBox( QWidget* = 0 );
+  ~SMESHGUI_BoundingBox();
+
+  void updateSelection();
+  void deactivate();
+
+private:
+  void erasePreview();
+  void displayPreview();
+  void createPreview( double, double, double, double, double, double );
+
+private slots:
+  void selectionChanged();
+  void sourceChanged();
+  void sourceEdited();
+  void compute();
+  void clear();
+
+private:
+  typedef QList<SMESH::SMESH_IDSource_var> SourceList;
+  QButtonGroup*             mySourceMode;
+  QLineEdit*                mySource;
+  QLineEdit*                myXmin;
+  QLineEdit*                myXmax;
+  QLineEdit*                myDX;
+  QLineEdit*                myYmin;
+  QLineEdit*                myYmax;
+  QLineEdit*                myDY;
+  QLineEdit*                myZmin;
+  QLineEdit*                myZmax;
+  QLineEdit*                myDZ;
+  SourceList                mySrc;
+  SMESH_Actor*              myActor;
+  SMESHGUI_IdValidator*     myValidator;
+  QString                   myIDs;
+  SUIT_SelectionFilter*     myFilter;
+  SALOME_Actor*             myPreview;
+};
+
+class SMESHGUI_EXPORT SMESHGUI_MeasureDlg : public QDialog
+{ 
+  Q_OBJECT;
+
+  enum { NodeMode, ElemMode };
+
+public:
+  //! Measurement type
+  enum { 
+    MinDistance,   //!< minimum distance
+    BoundingBox    //!< bounding box
+  };
+
+  SMESHGUI_MeasureDlg( QWidget* = 0, int = MinDistance );
+  ~SMESHGUI_MeasureDlg();
+
+  void reject();
+
+protected:
+  void keyPressEvent( QKeyEvent* );
+  void enterEvent( QEvent* );
+
+private slots:
+  void help();
+  void updateSelection();
+  void activate();
+  void deactivate();
+
+private:
+  QTabWidget*           myTabWidget;
+  SMESHGUI_MinDistance* myMinDist;   
+  SMESHGUI_BoundingBox* myBndBox;
+};
+
+#endif // SMESHGUI_MEASUREMENTS_H
diff --git a/src/SMESHGUI/SMESHGUI_MeshInfo.cxx b/src/SMESHGUI/SMESHGUI_MeshInfo.cxx
new file mode 100644 (file)
index 0000000..16a33b1
--- /dev/null
@@ -0,0 +1,1335 @@
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//  File   : SMESHGUI_MeshInfo.cxx
+//  Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
+
+#include "SMESHGUI_MeshInfo.h"
+
+#include "SMESH_Actor.h"
+#include "SMESHGUI.h"
+#include "SMESHGUI_IdValidator.h"
+#include "SMESHGUI_Utils.h"
+#include "SMESHGUI_VTKUtils.h"
+#include "SMDSAbs_ElementType.hxx"
+#include "SMDS_Mesh.hxx"
+
+#include <LightApp_SelectionMgr.h>
+#include <SUIT_OverrideCursor.h>
+#include <SUIT_ResourceMgr.h>
+#include <SVTK_ViewWindow.h>
+
+#include <SALOMEDSClient_Study.hxx>
+
+#include <QApplication>
+#include <QButtonGroup>
+#include <QGridLayout>
+#include <QHBoxLayout>
+#include <QHeaderView>
+#include <QItemDelegate>
+#include <QKeyEvent>
+#include <QLabel>
+#include <QLineEdit>
+#include <QPushButton>
+#include <QRadioButton>
+#include <QTabWidget>
+#include <QTextBrowser>
+#include <QTreeWidget>
+#include <QVBoxLayout>
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Group)
+
+const int SPACING = 6;
+const int MARGIN  = 9;
+
+/*!
+  \class SMESHGUI_MeshInfo
+  \brief Base mesh information widget
+  
+  Displays the base information about mesh object: mesh, sub-mesh, group or arbitrary ID source.
+*/
+
+/*!
+  \brief Constructor.
+  \param parent parent widget
+*/
+SMESHGUI_MeshInfo::SMESHGUI_MeshInfo( QWidget* parent )
+  : QFrame( parent ), myWidgets( iElementsEnd )
+{
+  setFrameStyle( StyledPanel | Sunken );
+
+  QGridLayout* l = new QGridLayout( this );
+  l->setMargin( MARGIN );
+  l->setSpacing( SPACING );
+
+  // object
+  QLabel* aNameLab     = new QLabel( tr( "NAME_LAB" ), this );
+  QLabel* aName        = createField();
+  aName->setMinimumWidth( 150 );
+  QLabel* aObjLab      = new QLabel( tr( "OBJECT_LAB" ), this );
+  QLabel* aObj         = createField();
+  aObj->setMinimumWidth( 150 );
+  myWidgets[0] << aNameLab << aName;
+  myWidgets[1] << aObjLab  << aObj;
+
+  // nodes
+  QWidget* aNodesLine  = createLine();
+  QLabel*  aNodesLab   = new QLabel( tr( "NODES_LAB" ), this );
+  QLabel*  aNodes      = createField();
+  myWidgets[2] << aNodesLine;
+  myWidgets[3] << aNodesLab << aNodes;
+
+  // elements
+  QWidget* aElemLine   = createLine();
+  QLabel*  aElemLab    = new QLabel( tr( "ELEMENTS_LAB" ),  this );
+  QLabel*  aElemTotal  = new QLabel( tr( "TOTAL_LAB" ),     this );
+  QLabel*  aElemLin    = new QLabel( tr( "LINEAR_LAB" ),    this );
+  QLabel*  aElemQuad   = new QLabel( tr( "QUADRATIC_LAB" ), this );
+  myWidgets[4] << aElemLine;
+  myWidgets[5] << aElemLab << aElemTotal << aElemLin << aElemQuad;
+
+  // ... 0D elements
+  QWidget* a0DLine     = createLine();
+  QLabel*  a0DLab      = new QLabel( tr( "0D_LAB" ), this );
+  QLabel*  a0DTotal    = createField();
+  myWidgets[6] << a0DLine;
+  myWidgets[7] << a0DLab << a0DTotal;
+
+  // ... 1D elements
+  QWidget* a1DLine     = createLine();
+  QLabel*  a1DLab      = new QLabel( tr( "1D_LAB" ), this );
+  QLabel*  a1DTotal    = createField();
+  QLabel*  a1DLin      = createField();
+  QLabel*  a1DQuad     = createField();
+  myWidgets[8] << a1DLine;
+  myWidgets[9] << a1DLab << a1DTotal << a1DLin << a1DQuad;
+
+  // ... 2D elements
+  QWidget* a2DLine     = createLine();
+  QLabel*  a2DLab      = new QLabel( tr( "2D_LAB" ), this );
+  QLabel*  a2DTotal    = createField();
+  QLabel*  a2DLin      = createField();
+  QLabel*  a2DQuad     = createField();
+  QLabel*  a2DTriLab   = new QLabel( tr( "TRIANGLES_LAB" ), this );
+  QLabel*  a2DTriTotal = createField();
+  QLabel*  a2DTriLin   = createField();
+  QLabel*  a2DTriQuad  = createField();
+  QLabel*  a2DQuaLab   = new QLabel( tr( "QUADRANGLES_LAB" ), this );
+  QLabel*  a2DQuaTotal = createField();
+  QLabel*  a2DQuaLin   = createField();
+  QLabel*  a2DQuaQuad  = createField();
+  QLabel*  a2DPolLab   = new QLabel( tr( "POLYGONS_LAB" ), this );
+  QLabel*  a2DPolTotal = createField();
+  myWidgets[10] << a2DLine;
+  myWidgets[11] << a2DLab    << a2DTotal    << a2DLin    << a2DQuad;
+  myWidgets[12] << a2DTriLab << a2DTriTotal << a2DTriLin << a2DTriQuad;
+  myWidgets[13] << a2DQuaLab << a2DQuaTotal << a2DQuaLin << a2DQuaQuad;
+  myWidgets[14] << a2DPolLab << a2DPolTotal;
+
+  // ... 3D elements
+  QWidget* a3DLine     = createLine();
+  QLabel*  a3DLab      = new QLabel( tr( "3D_LAB" ), this );
+  QLabel*  a3DTotal    = createField();
+  QLabel*  a3DLin      = createField();
+  QLabel*  a3DQuad     = createField();
+  QLabel*  a3DTetLab   = new QLabel( tr( "TETRAHEDRONS_LAB" ), this );
+  QLabel*  a3DTetTotal = createField();
+  QLabel*  a3DTetLin   = createField();
+  QLabel*  a3DTetQuad  = createField();
+  QLabel*  a3DHexLab   = new QLabel( tr( "HEXAHEDONRS_LAB" ), this );
+  QLabel*  a3DHexTotal = createField();
+  QLabel*  a3DHexLin   = createField();
+  QLabel*  a3DHexQuad  = createField();
+  QLabel*  a3DPyrLab   = new QLabel( tr( "PYRAMIDS_LAB" ), this );
+  QLabel*  a3DPyrTotal = createField();
+  QLabel*  a3DPyrLin   = createField();
+  QLabel*  a3DPyrQuad  = createField();
+  QLabel*  a3DPriLab   = new QLabel( tr( "PRISMS_LAB" ), this );
+  QLabel*  a3DPriTotal = createField();
+  QLabel*  a3DPriLin   = createField();
+  QLabel*  a3DPriQuad  = createField();
+  QLabel*  a3DPolLab   = new QLabel( tr( "POLYHEDRONS_LAB" ), this );
+  QLabel*  a3DPolTotal = createField();
+  myWidgets[15] << a3DLine;
+  myWidgets[16] << a3DLab    << a3DTotal    << a3DLin    << a3DQuad;
+  myWidgets[17] << a3DTetLab << a3DTetTotal << a3DTetLin << a3DTetQuad;
+  myWidgets[18] << a3DHexLab << a3DHexTotal << a3DHexLin << a3DHexQuad;
+  myWidgets[19] << a3DPyrLab << a3DPyrTotal << a3DPyrLin << a3DPyrQuad;
+  myWidgets[20] << a3DPriLab << a3DPriTotal << a3DPriLin << a3DPriQuad;
+  myWidgets[21] << a3DPolLab << a3DPolTotal;
+
+  setFontAttributes( aNameLab,   Bold );
+  setFontAttributes( aObjLab,    Bold );
+  setFontAttributes( aNodesLab,  Bold );
+  setFontAttributes( aElemLab,   Bold );
+  setFontAttributes( aElemTotal, Italic );
+  setFontAttributes( aElemLin,   Italic );
+  setFontAttributes( aElemQuad,  Italic );
+  setFontAttributes( a0DLab,     Bold );
+  setFontAttributes( a1DLab,     Bold );
+  setFontAttributes( a2DLab,     Bold );
+  setFontAttributes( a3DLab,     Bold );
+
+  l->addWidget( aNameLab,     0, 0 );
+  l->addWidget( aName,        0, 1, 1, 3 );
+  l->addWidget( aObjLab,      1, 0 );
+  l->addWidget( aObj,         1, 1, 1, 3 );
+  l->addWidget( aNodesLine,   2, 0, 1, 4 );
+  l->addWidget( aNodesLab,    3, 0 );
+  l->addWidget( aNodes,       3, 1 );
+  l->addWidget( aElemLine,    4, 0, 1, 4 );
+  l->addWidget( aElemLab,     5, 0 );
+  l->addWidget( aElemTotal,   5, 1 );
+  l->addWidget( aElemLin,     5, 2 );
+  l->addWidget( aElemQuad,    5, 3 );
+  l->addWidget( a0DLine,      6, 1, 1, 3 );
+  l->addWidget( a0DLab,       7, 0 );
+  l->addWidget( a0DTotal,     7, 1 );
+  l->addWidget( a1DLine,      8, 1, 1, 3 );
+  l->addWidget( a1DLab,       9, 0 );
+  l->addWidget( a1DTotal,     9, 1 );
+  l->addWidget( a1DLin,       9, 2 );
+  l->addWidget( a1DQuad,      9, 3 );
+  l->addWidget( a2DLine,     10, 1, 1, 3 );
+  l->addWidget( a2DLab,      11, 0 );
+  l->addWidget( a2DTotal,    11, 1 );
+  l->addWidget( a2DLin,      11, 2 );
+  l->addWidget( a2DQuad,     11, 3 );
+  l->addWidget( a2DTriLab,   12, 0 );
+  l->addWidget( a2DTriTotal, 12, 1 );
+  l->addWidget( a2DTriLin,   12, 2 );
+  l->addWidget( a2DTriQuad,  12, 3 );
+  l->addWidget( a2DQuaLab,   13, 0 );
+  l->addWidget( a2DQuaTotal, 13, 1 );
+  l->addWidget( a2DQuaLin,   13, 2 );
+  l->addWidget( a2DQuaQuad,  13, 3 );
+  l->addWidget( a2DPolLab,   14, 0 );
+  l->addWidget( a2DPolTotal, 14, 1 );
+  l->addWidget( a3DLine,     15, 1, 1, 3 );
+  l->addWidget( a3DLab,      16, 0 );
+  l->addWidget( a3DTotal,    16, 1 );
+  l->addWidget( a3DLin,      16, 2 );
+  l->addWidget( a3DQuad,     16, 3 );
+  l->addWidget( a3DTetLab,   17, 0 );
+  l->addWidget( a3DTetTotal, 17, 1 );
+  l->addWidget( a3DTetLin,   17, 2 );
+  l->addWidget( a3DTetQuad,  17, 3 );
+  l->addWidget( a3DHexLab,   18, 0 );
+  l->addWidget( a3DHexTotal, 18, 1 );
+  l->addWidget( a3DHexLin,   18, 2 );
+  l->addWidget( a3DHexQuad,  18, 3 );
+  l->addWidget( a3DPyrLab,   19, 0 );
+  l->addWidget( a3DPyrTotal, 19, 1 );
+  l->addWidget( a3DPyrLin,   19, 2 );
+  l->addWidget( a3DPyrQuad,  19, 3 );
+  l->addWidget( a3DPriLab,   20, 0 );
+  l->addWidget( a3DPriTotal, 20, 1 );
+  l->addWidget( a3DPriLin,   20, 2 );
+  l->addWidget( a3DPriQuad,  20, 3 );
+  l->addWidget( a3DPolLab,   21, 0 );
+  l->addWidget( a3DPolTotal, 21, 1 );
+  l->setColumnStretch( 0, 0 );
+  l->setColumnStretch( 1, 5 );
+  l->setColumnStretch( 2, 5 );
+  l->setColumnStretch( 3, 5 );
+  l->setRowStretch( 22, 5 );
+
+  clear();
+}
+
+/*!
+  \brief Destructor
+*/
+SMESHGUI_MeshInfo::~SMESHGUI_MeshInfo()
+{
+}
+
+/*!
+  \brief Show information on the mesh object.
+  \param obj object being processed (mesh, sub-mesh, group, ID source)
+*/
+void SMESHGUI_MeshInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
+{
+  clear();
+  if ( !CORBA::is_nil( obj ) ) {
+    _PTR(SObject) sobj = ObjectToSObject( obj );
+    if ( sobj ) 
+      myWidgets[iName][iSingle]->setProperty( "text", sobj->GetName().c_str() );
+    SMESH::SMESH_Mesh_var      aMesh    = SMESH::SMESH_Mesh::_narrow( obj );
+    SMESH::SMESH_subMesh_var   aSubMesh = SMESH::SMESH_subMesh::_narrow( obj );
+    SMESH::SMESH_GroupBase_var aGroup   = SMESH::SMESH_GroupBase::_narrow( obj );
+    if ( !aMesh->_is_nil() ) {
+      myWidgets[iObject][iSingle]->setProperty( "text", tr( "OBJECT_MESH" ) );
+    }
+    else if ( !aSubMesh->_is_nil() ) {
+      myWidgets[iObject][iSingle]->setProperty( "text", tr( "OBJECT_SUBMESH" ) );
+    }
+    else if ( !aGroup->_is_nil() ) {
+      QString objType;
+      switch( aGroup->GetType() ) {
+      case SMESH::NODE:
+       objType = tr( "OBJECT_GROUP_NODES" );
+       break;
+      case SMESH::EDGE:
+       objType = tr( "OBJECT_GROUP_EDGES" );
+       break;
+      case SMESH::FACE:
+       objType = tr( "OBJECT_GROUP_FACES" );
+       break;
+      case SMESH::VOLUME:
+       objType = tr( "OBJECT_GROUP_VOLUMES" );
+       break;
+      case SMESH::ELEM0D:
+       objType = tr( "OBJECT_GROUP_0DELEMS" );
+       break;
+      default:
+       objType = tr( "OBJECT_GROUP" );
+       break;
+      }
+      myWidgets[iObject][iSingle]->setProperty( "text", objType );
+    }
+    SMESH::long_array_var info = obj->GetMeshInfo();
+    myWidgets[iNodes][iTotal]->setProperty( "text", QString::number( info[SMDSEntity_Node] ) );
+    myWidgets[i0D][iTotal]->setProperty( "text", QString::number( info[SMDSEntity_0D] ) );
+    long nbEdges = info[SMDSEntity_Edge] + info[SMDSEntity_Quad_Edge];
+    myWidgets[i1D][iTotal]->setProperty( "text", QString::number( nbEdges ) );
+    myWidgets[i1D][iLinear]->setProperty( "text", QString::number( info[SMDSEntity_Edge] ) );
+    myWidgets[i1D][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Edge] ) );
+    long nbTriangles   = info[SMDSEntity_Triangle]   + info[SMDSEntity_Quad_Triangle];
+    long nbQuadrangles = info[SMDSEntity_Quadrangle] + info[SMDSEntity_Quad_Quadrangle];
+    long nb2DLinear    = info[SMDSEntity_Triangle] + info[SMDSEntity_Quadrangle] + info[SMDSEntity_Polygon];
+    long nb2DQuadratic = info[SMDSEntity_Quad_Triangle] + info[SMDSEntity_Quad_Quadrangle];
+    myWidgets[i2D][iTotal]->setProperty( "text", QString::number( nb2DLinear + nb2DQuadratic ) );
+    myWidgets[i2D][iLinear]->setProperty( "text", QString::number( nb2DLinear ) );
+    myWidgets[i2D][iQuadratic]->setProperty( "text", QString::number( nb2DQuadratic ) );
+    myWidgets[i2DTriangles][iTotal]->setProperty( "text", QString::number( nbTriangles ) );
+    myWidgets[i2DTriangles][iLinear]->setProperty( "text", QString::number( info[SMDSEntity_Triangle] ) );
+    myWidgets[i2DTriangles][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Triangle] ) );
+    myWidgets[i2DQuadrangles][iTotal]->setProperty( "text", QString::number( nbQuadrangles ) );
+    myWidgets[i2DQuadrangles][iLinear]->setProperty( "text", QString::number( info[SMDSEntity_Quadrangle] ) );
+    myWidgets[i2DQuadrangles][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Quadrangle] ) );
+    myWidgets[i2DPolygons][iTotal]->setProperty( "text", QString::number( info[SMDSEntity_Polygon] ) );
+    long nbTetrahedrons = info[SMDSEntity_Tetra]   + info[SMDSEntity_Quad_Tetra];
+    long nbHexahedrons  = info[SMDSEntity_Hexa]    + info[SMDSEntity_Quad_Hexa];
+    long nbPyramids     = info[SMDSEntity_Pyramid] + info[SMDSEntity_Quad_Pyramid];
+    long nbPrisms       = info[SMDSEntity_Penta]   + info[SMDSEntity_Quad_Penta];
+    long nb3DLinear     = info[SMDSEntity_Tetra] + info[SMDSEntity_Hexa] + info[SMDSEntity_Pyramid] + info[SMDSEntity_Penta] + info[SMDSEntity_Polyhedra];
+    long nb3DQuadratic  = info[SMDSEntity_Quad_Tetra] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_Quad_Pyramid] + info[SMDSEntity_Quad_Penta];
+    myWidgets[i3D][iTotal]->setProperty( "text", QString::number( nb3DLinear + nb3DQuadratic ) );
+    myWidgets[i3D][iLinear]->setProperty( "text", QString::number( nb3DLinear ) );
+    myWidgets[i3D][iQuadratic]->setProperty( "text", QString::number( nb3DQuadratic ) );
+    myWidgets[i3DTetrahedrons][iTotal]->setProperty( "text", QString::number( nbTetrahedrons ) );
+    myWidgets[i3DTetrahedrons][iLinear]->setProperty( "text", QString::number( info[SMDSEntity_Tetra] ) );
+    myWidgets[i3DTetrahedrons][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Tetra] ) );
+    myWidgets[i3DHexahedrons][iTotal]->setProperty( "text", QString::number( nbHexahedrons ) );
+    myWidgets[i3DHexahedrons][iLinear]->setProperty( "text", QString::number( info[SMDSEntity_Hexa] ) );
+    myWidgets[i3DHexahedrons][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Hexa] ) );
+    myWidgets[i3DPyramids][iTotal]->setProperty( "text", QString::number( nbPyramids ) );
+    myWidgets[i3DPyramids][iLinear]->setProperty( "text", QString::number( info[SMDSEntity_Pyramid] ) );
+    myWidgets[i3DPyramids][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Pyramid] ) );
+    myWidgets[i3DPrisms][iTotal]->setProperty( "text", QString::number( nbPrisms ) );
+    myWidgets[i3DPrisms][iLinear]->setProperty( "text", QString::number( info[SMDSEntity_Penta] ) );
+    myWidgets[i3DPrisms][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Penta] ) );
+    myWidgets[i3DPolyhedrons][iTotal]->setProperty( "text", QString::number( info[SMDSEntity_Polyhedra] ) );
+  }
+}
+
+/*!
+  \brief Reset the widget to the initial state (nullify all fields).
+*/
+void SMESHGUI_MeshInfo::clear()
+{
+  myWidgets[iName][iSingle]->setProperty( "text", QString() );
+  myWidgets[iObject][iSingle]->setProperty( "text", QString() );
+  myWidgets[iNodes][iTotal]->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i0D][iTotal]->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i1D][iTotal]->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i1D][iLinear]->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i1D][iQuadratic]->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i2D][iTotal]->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i2D][iLinear]->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i2D][iQuadratic]->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i2DTriangles][iTotal]->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i2DTriangles][iLinear]->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i2DTriangles][iQuadratic]->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i2DQuadrangles][iTotal]->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i2DQuadrangles][iLinear]->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i2DQuadrangles][iQuadratic]->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i2DPolygons][iTotal]->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i3D][iTotal]->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i3D][iLinear]->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i3D][iQuadratic]->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i3DTetrahedrons][iTotal]->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i3DTetrahedrons][iLinear]->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i3DTetrahedrons][iQuadratic]->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i3DHexahedrons][iTotal]->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i3DHexahedrons][iLinear]->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i3DHexahedrons][iQuadratic]->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i3DPyramids][iTotal]->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i3DPyramids][iLinear]->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i3DPyramids][iQuadratic]->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i3DPrisms][iTotal]->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i3DPrisms][iLinear]->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i3DPrisms][iQuadratic]->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i3DPolyhedrons][iTotal]->setProperty( "text", QString::number( 0 ) );
+}
+
+/*!
+  \brief Create info field
+  \return new info field
+*/
+QLabel* SMESHGUI_MeshInfo::createField()
+{
+  QLabel* lab = new QLabel( this );
+  lab->setFrameStyle( StyledPanel | Sunken );
+  lab->setAlignment( Qt::AlignCenter );
+  lab->setAutoFillBackground( true );
+  QPalette pal = lab->palette();
+  pal.setColor( QPalette::Window, QApplication::palette().color( QPalette::Active, QPalette::Base ) );
+  lab->setPalette( pal );
+  lab->setMinimumWidth( 70 );
+  return lab;
+}
+
+/*!
+  \brief Create horizontal rule.
+  \return new line object
+*/
+QWidget* SMESHGUI_MeshInfo::createLine()
+{
+  QFrame* line = new QFrame( this );
+  line->setFrameStyle( HLine | Sunken );
+  return line;
+}
+
+/*!
+  \brief Change widget font attributes (bold, italic, ...).
+  \param w widget
+  \param attr font attributes (XORed flags)
+  \param val value to be set to attributes
+*/
+void SMESHGUI_MeshInfo::setFontAttributes( QWidget* w, int attr, bool val )
+{
+  if ( w && attr ) {
+    QFont f = w->font();
+    if ( attr & Bold   ) f.setBold( val );
+    if ( attr & Italic ) f.setItalic( val );
+    w->setFont( f );
+  }
+}
+
+/*!
+  \brief Show/hide group(s) of fields.
+  \param start beginning of the block
+  \param end end of the block
+  \param on visibility flag
+*/
+void SMESHGUI_MeshInfo::setFieldsVisible( int start, int end, bool on )
+{
+  start = qMax( 0, start );
+  end   = qMin( end, (int)iElementsEnd );
+  for ( int i = start; i < end; i++ ) {
+    wlist wl = myWidgets[i];
+    foreach ( QWidget* w, wl ) w->setVisible( on );
+  }
+}
+
+/*!
+  \class SMESHGUI_ElemInfo
+  \brief Base class for the mesh element information widget.
+*/
+
+/*!
+  \brief Constructor
+  \param parent parent widget
+*/
+SMESHGUI_ElemInfo::SMESHGUI_ElemInfo( QWidget* parent )
+: QWidget( parent ), myActor( 0 ), myID( 0 ), myIsElement( -1 )
+{
+}
+
+/*!
+  \brief Destructor
+*/
+SMESHGUI_ElemInfo::~SMESHGUI_ElemInfo()
+{
+}
+
+/*!
+  \brief Set mesh data source (actor)
+  \param actor mesh object actor
+*/
+void SMESHGUI_ElemInfo::setSource( SMESH_Actor* actor )
+{
+  if ( myActor != actor ) {
+    myActor = actor;
+    myID = 0;
+    myIsElement = -1;
+    clear();
+  }
+}
+
+/*!
+  \brief Show mesh element information
+  \param long id mesh node / element ID
+  \param isElem show mesh element information if \c true or mesh node information if \c false
+*/
+void SMESHGUI_ElemInfo::showInfo( long id, bool isElem )
+{
+  myID = id;
+  myIsElement = isElem;
+}
+
+/*!
+  \fn void SMESHGUI_ElemInfo::clear()
+  \brief Clear mesh element information widget
+*/
+
+/*!
+  \brief Get node connectivity
+  \param node mesh node
+  \return node connectivity map
+*/
+SMESHGUI_ElemInfo::Connectivity SMESHGUI_ElemInfo::nodeConnectivity( const SMDS_MeshNode* node )
+{
+  Connectivity elmap;
+  if ( node ) {
+    SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
+    while ( it && it->more() ) {
+      const SMDS_MeshElement* ne = it->next();
+      elmap[ ne->GetType() ] << ne->GetID();
+    }
+  }
+  return elmap;
+}
+
+/*!
+  \brief Format connectivity data to string representation
+  \param connectivity connetivity map
+  \param type element type
+  \return string representation of the connectivity
+*/
+QString SMESHGUI_ElemInfo::formatConnectivity( Connectivity connectivity, int type )
+{
+  QStringList str;
+  if ( connectivity.contains( type ) ) {
+    QList<int> elements = connectivity[ type ];
+    qSort( elements );
+    foreach( int id, elements )
+      str << QString::number( id );
+  }
+  return str.join( " " );
+}
+
+/*!
+  \brief Calculate gravity center of the mesh element
+  \param element mesh element
+*/
+SMESHGUI_ElemInfo::XYZ SMESHGUI_ElemInfo::gravityCenter( const SMDS_MeshElement* element )
+{
+  XYZ xyz;
+  if ( element ) {
+    SMDS_ElemIteratorPtr nodeIt = element->nodesIterator();
+    while ( nodeIt->more() ) {
+      const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+      xyz.add( node->X(), node->Y(), node->Z() );
+    }
+    xyz.divide( element->NbNodes() );
+  }
+  return xyz;
+}
+
+/*!
+  \class SMESHGUI_SimpleElemInfo
+  \brief Represents mesh element information in the simple text area.
+*/
+
+/*!
+  \brief Constructor
+  \param parent parent widget
+*/
+SMESHGUI_SimpleElemInfo::SMESHGUI_SimpleElemInfo( QWidget* parent )
+: SMESHGUI_ElemInfo( parent )
+{
+  myInfo = new QTextBrowser( this );
+  QVBoxLayout* l = new QVBoxLayout( this );
+  l->setMargin( 0 );
+  l->addWidget( myInfo );
+}
+
+/*!
+  \brief Show mesh element information
+  \param long id mesh node / element ID
+  \param isElem show mesh element information if \c true or mesh node information if \c false
+*/
+void SMESHGUI_SimpleElemInfo::showInfo( long id, bool isElem )
+{
+  if ( myID == id && myIsElement == isElem ) return;
+
+  SMESHGUI_ElemInfo::showInfo( id, isElem );
+
+  clear();
+  
+  if ( myActor ) {
+    int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
+    if ( !isElem ) {
+      //
+      // show node info
+      //
+      const SMDS_MeshElement* e = myActor->GetObject()->GetMesh()->FindNode( id );
+      if ( !e ) return;
+      const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( e );
+      
+      // node ID
+      myInfo->append( QString( "<b>%1 #%2</b>" ).arg( tr( "NODE" ) ).arg( id ) );
+      // separator
+      myInfo->append( "" );
+      // coordinates
+      myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( tr( "COORDINATES" ) ).
+                     arg( node->X(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
+                     arg( node->Y(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
+                     arg( node->Z(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+      // separator
+      myInfo->append( "" );
+      // connectivity
+      Connectivity connectivity = nodeConnectivity( node );
+      if ( !connectivity.isEmpty() ) {
+       myInfo->append( QString( "<b>%1:</b>" ).arg( tr( "CONNECTIVITY" ) ) );
+       QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
+       if ( !con.isEmpty() )
+         myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "0D_ELEMENTS" ) ).arg( con ) );
+       con = formatConnectivity( connectivity, SMDSAbs_Edge );
+       if ( !con.isEmpty() )
+         myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "EDGES" ) ).arg( con ) );
+       con = formatConnectivity( connectivity, SMDSAbs_Face );
+       if ( !con.isEmpty() )
+         myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "FACES" ) ).arg( con ) );
+       con = formatConnectivity( connectivity, SMDSAbs_Volume );
+       if ( !con.isEmpty() )
+         myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "VOLUMES" ) ).arg( con ) );
+      }
+      else {
+       myInfo->append( QString( "<b>%1</b>" ).arg( tr( "FREE_NODE" ) ).arg( id ) );
+      }
+    }
+    else {
+      //
+      // show element info
+      // 
+      const SMDS_MeshElement* e = myActor->GetObject()->GetMesh()->FindElement( id );
+      if ( !e ) return;
+
+      // element ID && type
+      QString stype;
+      switch( e->GetType() ) {
+      case SMDSAbs_0DElement:
+       stype = tr( "0D ELEMENT" ); break;
+      case SMDSAbs_Edge:
+       stype = tr( "EDGE" ); break;
+      case SMDSAbs_Face:
+       stype = tr( "FACE" ); break;
+      case SMDSAbs_Volume:
+       stype = tr( "VOLUME" ); break;
+      default: 
+       break;
+      }
+      if ( stype.isEmpty() ) return;
+      myInfo->append( QString( "<b>%1 #%2</b>" ).arg( stype ).arg( id ) );
+      // separator
+      myInfo->append( "" );
+      // geometry type
+      QString gtype;
+      switch( e->GetEntityType() ) {
+      case SMDSEntity_Triangle:
+      case SMDSEntity_Quad_Triangle:
+       gtype = tr( "TRIANGLE" ); break;
+      case SMDSEntity_Quadrangle:
+      case SMDSEntity_Quad_Quadrangle:
+       gtype = tr( "QUADRANGLE" ); break;
+      case SMDSEntity_Polygon:
+      case SMDSEntity_Quad_Polygon:
+       gtype = tr( "QUADRANGLE" ); break;
+      case SMDSEntity_Tetra:
+      case SMDSEntity_Quad_Tetra:
+       gtype = tr( "TETRAHEDRON" ); break;
+      case SMDSEntity_Pyramid:
+      case SMDSEntity_Quad_Pyramid:
+       gtype = tr( "PYRAMID" ); break;
+      case SMDSEntity_Hexa:
+      case SMDSEntity_Quad_Hexa:
+       gtype = tr( "HEXAHEDRON" ); break;
+      case SMDSEntity_Penta:
+      case SMDSEntity_Quad_Penta:
+       gtype = tr( "PRISM" ); break;
+      case SMDSEntity_Polyhedra:
+      case SMDSEntity_Quad_Polyhedra:
+       gtype = tr( "POLYHEDRON" ); break;
+      default: 
+       break;
+      }
+      if ( !gtype.isEmpty() )
+       myInfo->append( QString( "<b>%1:</b> %2" ).arg( tr( "TYPE" ) ).arg( gtype ) );
+      // quadratic flag and gravity center (any element except 0D)
+      if ( e->GetEntityType() > SMDSEntity_0D && e->GetEntityType() < SMDSEntity_Last ) {
+       // quadratic flag
+       myInfo->append( QString( "<b>%1?</b> %2" ).arg( tr( "QUADRATIC" ) ).arg( e->IsQuadratic() ? tr( "YES" ) : tr( "NO" ) ) );
+       // separator
+       myInfo->append( "" );
+       // gravity center
+       XYZ gc = gravityCenter( e );
+       myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( tr( "GRAVITY_CENTER" ) ).arg( gc.x() ).arg( gc.y() ).arg( gc.z() ) );
+      }
+      // separator
+      myInfo->append( "" );
+      // connectivity
+      SMDS_ElemIteratorPtr nodeIt = e->nodesIterator();
+      for ( int idx = 1; nodeIt->more(); idx++ ) {
+       const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+       // node number and ID
+       myInfo->append( QString( "<b>%1 %2/%3</b> - #%4" ).arg( tr( "NODE" ) ).arg( idx ).arg( e->NbNodes() ).arg( node->GetID() ) );
+       // node coordinates
+       myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( tr( "COORDINATES" ) ).
+                       arg( node->X(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
+                       arg( node->Y(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
+                       arg( node->Z(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+       // node connectivity
+       Connectivity connectivity = nodeConnectivity( node );
+       if ( !connectivity.isEmpty() ) {
+         myInfo->append( QString( "<b>%1:</b>" ).arg( tr( "CONNECTIVITY" ) ) );
+         QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
+         if ( !con.isEmpty() )
+           myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "0D_ELEMENTS" ) ).arg( con ) );
+         con = formatConnectivity( connectivity, SMDSAbs_Edge );
+         if ( !con.isEmpty() )
+           myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "EDGES" ) ).arg( con ) );
+         con = formatConnectivity( connectivity, SMDSAbs_Face );
+         if ( !con.isEmpty() )
+           myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "FACES" ) ).arg( con ) );
+         con = formatConnectivity( connectivity, SMDSAbs_Volume );
+         if ( !con.isEmpty() )
+           myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "VOLUMES" ) ).arg( con ) );
+       }
+       else {
+         myInfo->append( QString( "<b>%1</b>" ).arg( tr( "FREE_NODE" ) ).arg( id ) );
+       }
+       // separator
+       myInfo->append( "" );
+      }
+    }
+  }
+}
+
+/*!
+  \brief Clear mesh element information widget
+*/
+void SMESHGUI_SimpleElemInfo::clear()
+{
+  myInfo->clear();
+}
+
+/*!
+  \class SMESHGUI_TreeElemInfo::ItemDelegate
+  \brief Item delegate for tree mesh info widget
+  \internal
+*/
+class SMESHGUI_TreeElemInfo::ItemDelegate : public QItemDelegate
+{
+public:
+  ItemDelegate( QObject* );
+  QWidget* createEditor( QWidget*, const QStyleOptionViewItem&, const QModelIndex& ) const;
+};
+
+/*!
+  \brief Constructor
+  \internal
+*/
+SMESHGUI_TreeElemInfo::ItemDelegate::ItemDelegate( QObject* parent ) : QItemDelegate( parent )
+{
+}
+
+/*!
+  \brief Create item editor widget
+  \internal
+*/
+QWidget* SMESHGUI_TreeElemInfo::ItemDelegate::createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const
+{
+  QWidget* w = index.column() == 0 ? 0: QItemDelegate::createEditor( parent, option, index );
+  if ( qobject_cast<QLineEdit*>( w ) ) qobject_cast<QLineEdit*>( w )->setReadOnly(  true );
+  return w;
+}
+
+/*!
+  \class SMESHGUI_TreeElemInfo
+  \brief Represents mesh element information in the tree-like form.
+*/
+
+/*!
+  \brief Constructor
+  \param parent parent widget
+*/
+SMESHGUI_TreeElemInfo::SMESHGUI_TreeElemInfo( QWidget* parent )
+: SMESHGUI_ElemInfo( parent )
+{
+  myInfo = new QTreeWidget( this );
+  myInfo->setColumnCount( 2 );
+  myInfo->setHeaderLabels( QStringList() << tr( "PROPERTY" ) << tr( "VALUE" ) );
+  myInfo->header()->setStretchLastSection( true );
+  myInfo->header()->setResizeMode( 0, QHeaderView::ResizeToContents );
+  myInfo->setItemDelegate( new ItemDelegate( myInfo ) );
+  QVBoxLayout* l = new QVBoxLayout( this );
+  l->setMargin( 0 );
+  l->addWidget( myInfo );
+}
+
+/*!
+  \brief Show mesh element information
+  \param long id mesh node / element ID
+  \param isElem show mesh element information if \c true or mesh node information if \c false
+*/
+void SMESHGUI_TreeElemInfo::showInfo( long id, bool isElem )
+{
+  if ( myID == id && myIsElement == isElem ) return;
+
+  SMESHGUI_ElemInfo::showInfo( id, isElem );
+
+  clear();
+  
+  if ( myActor ) {
+    int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
+    if ( !isElem ) {
+      //
+      // show node info
+      //
+      const SMDS_MeshElement* e = myActor->GetObject()->GetMesh()->FindNode( id );
+      if ( !e ) return;
+      const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( e );
+      
+      // node ID
+      QTreeWidgetItem* nodeItem = createItem( 0, -1 );
+      nodeItem->setText( 0, tr( "NODE" ) );
+      nodeItem->setText( 1, QString( "#%1" ).arg( id ) );
+      nodeItem->setExpanded( true );
+      // coordinates
+      QTreeWidgetItem* coordItem = createItem( nodeItem, 0 );
+      coordItem->setText( 0, tr( "COORDINATES" ) );
+      coordItem->setExpanded( true );
+      QTreeWidgetItem* xItem = createItem( coordItem );
+      xItem->setText( 0, "X" );
+      xItem->setText( 1, QString::number( node->X(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+      QTreeWidgetItem* yItem = createItem( coordItem );
+      yItem->setText( 0, "Y" );
+      yItem->setText( 1, QString::number( node->Y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+      QTreeWidgetItem* zItem = createItem( coordItem );
+      zItem->setText( 0, "Z" );
+      zItem->setText( 1, QString::number( node->Z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+      // connectivity
+      QTreeWidgetItem* conItem = createItem( nodeItem, 0 );
+      conItem->setText( 0, tr( "CONNECTIVITY" ) );
+      conItem->setExpanded( true );
+      Connectivity connectivity = nodeConnectivity( node );
+      if ( !connectivity.isEmpty() ) {
+       QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
+       if ( !con.isEmpty() ) {
+         QTreeWidgetItem* i = createItem( conItem );
+         i->setText( 0, tr( "0D_ELEMENTS" ) );
+         i->setText( 1, con );
+       }
+       con = formatConnectivity( connectivity, SMDSAbs_Edge );
+       if ( !con.isEmpty() ) {
+         QTreeWidgetItem* i = createItem( conItem );
+         i->setText( 0, tr( "EDGES" ) );
+         i->setText( 1, con );
+       }
+       con = formatConnectivity( connectivity, SMDSAbs_Face );
+       if ( !con.isEmpty() ) {
+         QTreeWidgetItem* i = createItem( conItem );
+         i->setText( 0, tr( "FACES" ) );
+         i->setText( 1, con );
+       }
+       con = formatConnectivity( connectivity, SMDSAbs_Volume );
+       if ( !con.isEmpty() ) {
+         QTreeWidgetItem* i = createItem( conItem );
+         i->setText( 0, tr( "VOLUMES" ) );
+         i->setText( 1, con );
+       }
+      }
+      else {
+       conItem->setText( 1, tr( "FREE_NODE" ) );
+      }
+    }
+    else {
+      //
+      // show element info
+      // 
+      const SMDS_MeshElement* e = myActor->GetObject()->GetMesh()->FindElement( id );
+      if ( !e ) return;
+
+      // element ID && type
+      QString stype;
+      switch( e->GetType() ) {
+      case SMDSAbs_0DElement:
+       stype = tr( "0D ELEMENT" ); break;
+      case SMDSAbs_Edge:
+       stype = tr( "EDGE" ); break;
+      case SMDSAbs_Face:
+       stype = tr( "FACE" ); break;
+      case SMDSAbs_Volume:
+       stype = tr( "VOLUME" ); break;
+      default: 
+       break;
+      }
+      if ( stype.isEmpty() ) return;
+      QTreeWidgetItem* elemItem = createItem( 0, -1 );
+      elemItem->setText( 0, stype );
+      elemItem->setText( 1, QString( "#%1" ).arg( id ) );
+      elemItem->setExpanded( true );
+      // geometry type
+      QString gtype;
+      switch( e->GetEntityType() ) {
+      case SMDSEntity_Triangle:
+      case SMDSEntity_Quad_Triangle:
+       gtype = tr( "TRIANGLE" ); break;
+      case SMDSEntity_Quadrangle:
+      case SMDSEntity_Quad_Quadrangle:
+       gtype = tr( "QUADRANGLE" ); break;
+      case SMDSEntity_Polygon:
+      case SMDSEntity_Quad_Polygon:
+       gtype = tr( "QUADRANGLE" ); break;
+      case SMDSEntity_Tetra:
+      case SMDSEntity_Quad_Tetra:
+       gtype = tr( "TETRAHEDRON" ); break;
+      case SMDSEntity_Pyramid:
+      case SMDSEntity_Quad_Pyramid:
+       gtype = tr( "PYRAMID" ); break;
+      case SMDSEntity_Hexa:
+      case SMDSEntity_Quad_Hexa:
+       gtype = tr( "HEXAHEDRON" ); break;
+      case SMDSEntity_Penta:
+      case SMDSEntity_Quad_Penta:
+       gtype = tr( "PRISM" ); break;
+      case SMDSEntity_Polyhedra:
+      case SMDSEntity_Quad_Polyhedra:
+       gtype = tr( "POLYHEDRON" ); break;
+      default: 
+       break;
+      }
+      if ( !gtype.isEmpty() ) {
+       QTreeWidgetItem* typeItem = createItem( elemItem, 0 );
+       typeItem->setText( 0, tr( "TYPE" ) );
+       typeItem->setText( 1, gtype );
+      }
+      // quadratic flag and gravity center (any element except 0D)
+      if ( e->GetEntityType() > SMDSEntity_0D && e->GetEntityType() < SMDSEntity_Last ) {
+       // quadratic flag
+       QTreeWidgetItem* quadItem = createItem( elemItem, 0 );
+       quadItem->setText( 0, tr( "QUADRATIC" ) );
+       quadItem->setText( 1, e->IsQuadratic() ? tr( "YES" ) : tr( "NO" ) );
+       // gravity center
+       XYZ gc = gravityCenter( e );
+       QTreeWidgetItem* gcItem = createItem( elemItem, 0 );
+       gcItem->setText( 0, tr( "GRAVITY_CENTER" ) );
+       gcItem->setExpanded( true );
+       QTreeWidgetItem* xItem = createItem( gcItem );
+       xItem->setText( 0, "X" );
+       xItem->setText( 1, QString::number( gc.x(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+       QTreeWidgetItem* yItem = createItem( gcItem );
+       yItem->setText( 0, "Y" );
+       yItem->setText( 1, QString::number( gc.y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+       QTreeWidgetItem* zItem = createItem( gcItem );
+       zItem->setText( 0, "Z" );
+       zItem->setText( 1, QString::number( gc.z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+      }
+      // connectivity
+      QTreeWidgetItem* conItem = createItem( elemItem, 0 );
+      conItem->setText( 0, tr( "CONNECTIVITY" ) );
+      conItem->setExpanded( true );
+      SMDS_ElemIteratorPtr nodeIt = e->nodesIterator();
+      for ( int idx = 1; nodeIt->more(); idx++ ) {
+       const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+       // node number and ID
+       QTreeWidgetItem* nodeItem = createItem( conItem, 0 );
+       nodeItem->setText( 0, QString( "%1 %2/%3" ).arg( tr( "NODE" ) ).arg( idx ).arg( e->NbNodes() ) );
+       nodeItem->setText( 1, QString( "#%1" ).arg( node->GetID() ) );
+       //nodeItem->setExpanded( true );
+       // node coordinates
+       QTreeWidgetItem* coordItem = createItem( nodeItem );
+       coordItem->setText( 0, tr( "COORDINATES" ) );
+       coordItem->setExpanded( true );
+       QTreeWidgetItem* xItem = createItem( coordItem );
+       xItem->setText( 0, "X" );
+       xItem->setText( 1, QString::number( node->X(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+       QTreeWidgetItem* yItem = createItem( coordItem );
+       yItem->setText( 0, "Y" );
+       yItem->setText( 1, QString::number( node->Y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+       QTreeWidgetItem* zItem = createItem( coordItem );
+       zItem->setText( 0, "Z" );
+       zItem->setText( 1, QString::number( node->Z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+       // node connectivity
+       QTreeWidgetItem* nconItem = createItem( nodeItem );
+       nconItem->setText( 0, tr( "CONNECTIVITY" ) );
+       nconItem->setExpanded( true );
+       Connectivity connectivity = nodeConnectivity( node );
+       if ( !connectivity.isEmpty() ) {
+         QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
+         if ( !con.isEmpty() ) {
+           QTreeWidgetItem* i = createItem( nconItem );
+           i->setText( 0, tr( "0D_ELEMENTS" ) );
+           i->setText( 1, con );
+         }
+         con = formatConnectivity( connectivity, SMDSAbs_Edge );
+         if ( !con.isEmpty() ) {
+           QTreeWidgetItem* i = createItem( nconItem );
+           i->setText( 0, tr( "EDGES" ) );
+           i->setText( 1, con );
+         }
+         con = formatConnectivity( connectivity, SMDSAbs_Face );
+         if ( !con.isEmpty() ) {
+           QTreeWidgetItem* i = createItem( nconItem );
+           i->setText( 0, tr( "FACES" ) );
+           i->setText( 1, con );
+         }
+         con = formatConnectivity( connectivity, SMDSAbs_Volume );
+         if ( !con.isEmpty() ) {
+           QTreeWidgetItem* i = createItem( nconItem );
+           i->setText( 0, tr( "VOLUMES" ) );
+           i->setText( 1, con );
+         }
+       }
+      }
+    }
+  }
+}
+
+/*!
+  \brief Clear mesh element information widget
+*/
+void SMESHGUI_TreeElemInfo::clear()
+{
+  myInfo->clear();
+  myInfo->repaint();
+}
+
+/*!
+  \brief Create new tree item.
+  \param parnt parent tree widget item
+  \param column item column to be set bold, if it is -1, bold font will be set for all columns
+  \return new tree widget item
+*/
+QTreeWidgetItem* SMESHGUI_TreeElemInfo::createItem( QTreeWidgetItem* parent, int column )
+{
+  QTreeWidgetItem* item;
+  if ( parent )
+    item = new QTreeWidgetItem( parent );
+  else
+    item = new QTreeWidgetItem( myInfo );
+
+  item->setFlags( item->flags() | Qt::ItemIsEditable );
+
+  QFont f = item->font( 0 );
+  f.setBold( true );
+  if ( column >= 0 && column < myInfo->columnCount() ) {
+    item->setFont( column, f );
+  }
+  else if ( column == -1 ) {
+    for ( int i = 0; i < myInfo->columnCount(); i++ )
+      item->setFont( i, f );
+  }
+  return item;
+}
+
+/*!
+  \class SMESHGUI_MeshInfoDlg
+  \brief Mesh information dialog box
+*/
+
+/*!
+  \brief Constructor
+  \param parent parent widget
+  \param page specifies the dialog page to be shown at the start-up
+*/
+SMESHGUI_MeshInfoDlg::SMESHGUI_MeshInfoDlg( QWidget* parent, int page )
+: QDialog( parent ), myActor( 0 )
+{
+  setModal( false );
+  setAttribute( Qt::WA_DeleteOnClose, true );
+  setWindowTitle( tr( "MESH_INFO" ) );
+  setSizeGripEnabled( true );
+
+  myTabWidget = new QTabWidget( this );
+
+  // base info 
+
+  myBaseInfo = new SMESHGUI_MeshInfo( myTabWidget );
+  myTabWidget->addTab( myBaseInfo, tr( "BASE_INFO" ) );
+
+  // elem info 
+  
+  QWidget* w = new QWidget( myTabWidget );
+
+  myMode = new QButtonGroup( this );
+  myMode->addButton( new QRadioButton( tr( "NODE_MODE" ), w ), NodeMode );
+  myMode->addButton( new QRadioButton( tr( "ELEM_MODE" ), w ), ElemMode );
+  myMode->button( NodeMode )->setChecked( true );
+  myID = new QLineEdit( w );
+  myID->setValidator( new SMESHGUI_IdValidator( this, 1 ) );
+
+  int mode = SMESHGUI::resourceMgr()->integerValue( "SMESH", "mesh_elem_info", 1 );
+  mode = qMin( 1, qMax( 0, mode ) );
+  
+  if ( mode == 0 ) 
+    myElemInfo = new SMESHGUI_SimpleElemInfo( w );
+  else
+    myElemInfo = new SMESHGUI_TreeElemInfo( w );
+
+  QGridLayout* elemLayout = new QGridLayout( w );
+  elemLayout->setMargin( MARGIN );
+  elemLayout->setSpacing( SPACING );
+  elemLayout->addWidget( myMode->button( NodeMode ), 0, 0 );
+  elemLayout->addWidget( myMode->button( ElemMode ), 0, 1 );
+  elemLayout->addWidget( myID, 0, 2 );
+  elemLayout->addWidget( myElemInfo, 1, 0, 1, 3 );
+  
+  myTabWidget->addTab( w, tr( "ELEM_INFO" ) );
+
+  QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
+  okBtn->setAutoDefault( true );
+  okBtn->setDefault( true );
+  okBtn->setFocus();
+  QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this );
+  helpBtn->setAutoDefault( true );
+
+  QHBoxLayout* btnLayout = new QHBoxLayout;
+  btnLayout->setSpacing( SPACING );
+  btnLayout->setMargin( 0 );
+
+  btnLayout->addWidget( okBtn );
+  btnLayout->addStretch( 10 );
+  btnLayout->addWidget( helpBtn );
+
+  QVBoxLayout* l = new QVBoxLayout ( this );
+  l->setMargin( MARGIN );
+  l->setSpacing( SPACING );
+  l->addWidget( myTabWidget );
+  l->addStretch();
+  l->addLayout( btnLayout );
+
+  myTabWidget->setCurrentIndex( qMax( (int)BaseInfo, qMin( (int)ElemInfo, page ) ) );
+
+  connect( okBtn,       SIGNAL( clicked() ),              this, SLOT( reject() ) );
+  connect( helpBtn,     SIGNAL( clicked() ),              this, SLOT( help() ) );
+  connect( myTabWidget, SIGNAL( currentChanged( int  ) ), this, SLOT( updateSelection() ) );
+  connect( myMode,      SIGNAL( buttonClicked( int  ) ),  this, SLOT( modeChanged() ) );
+  connect( myID,        SIGNAL( textEdited( QString  ) ), this, SLOT( idChanged() ) );
+  connect( SMESHGUI::GetSMESHGUI(),  SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ) );
+  connect( SMESHGUI::GetSMESHGUI(),  SIGNAL( SignalCloseAllDialogs() ),        this, SLOT( reject() ) );
+
+  updateSelection();
+}
+
+/*!
+  \brief Destructor
+*/
+SMESHGUI_MeshInfoDlg::~SMESHGUI_MeshInfoDlg()
+{
+}
+
+/*!
+  \brief Show mesh information
+  \param IO interactive object
+*/
+void SMESHGUI_MeshInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO )
+{
+  SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
+  if ( !CORBA::is_nil( obj ) ) {
+    myBaseInfo->showInfo( obj );
+    
+    myActor = SMESH::FindActorByEntry( IO->getEntry() );
+    SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector();
+    QString ID;
+    int nb = 0;
+    if ( myActor && selector ) {
+      nb = myMode->checkedId() == NodeMode ? 
+       SMESH::GetNameOfSelectedElements( selector, IO, ID ) :
+       SMESH::GetNameOfSelectedNodes( selector, IO, ID );
+    }
+    if ( nb == 1 ) {
+      myID->setText( ID.trimmed() );
+      myElemInfo->setSource( myActor ) ;
+      myElemInfo->showInfo( ID.toLong(), myMode->checkedId() == ElemMode );
+    }
+    else {
+      myID->clear();
+      myElemInfo->clear();
+    }
+  }
+}
+
+/*!
+  \brief Perform clean-up actions on the dialog box closing.
+*/
+void SMESHGUI_MeshInfoDlg::reject()
+{
+  LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
+  selMgr->clearFilters();
+  SMESH::SetPointRepresentation( false );
+  if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
+    aViewWindow->SetSelectionMode( ActorSelection );
+  QDialog::reject();
+}
+
+/*!
+  \brief Process keyboard event
+  \param e key press event
+*/
+void SMESHGUI_MeshInfoDlg::keyPressEvent( QKeyEvent* e )
+{
+  QDialog::keyPressEvent( e );
+  if ( !e->isAccepted() && e->key() == Qt::Key_F1 ) {
+    e->accept();
+    help();
+  }
+}
+
+/*!
+  \brief Reactivate dialog box, when mouse pointer goes into it.
+*/
+void SMESHGUI_MeshInfoDlg::enterEvent( QEvent* )
+{
+  activate();
+}
+
+/*!
+  \brief Setup selection mode depending on the current dialog box state.
+*/
+void SMESHGUI_MeshInfoDlg::updateSelection()
+{
+  LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
+
+  disconnect( selMgr, 0, this, 0 );
+  selMgr->clearFilters();
+
+  if ( myTabWidget->currentIndex() == BaseInfo ) {
+    SMESH::SetPointRepresentation( false );
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
+      aViewWindow->SetSelectionMode( ActorSelection );
+  }
+  else {
+    if ( myMode->checkedId() == NodeMode ) {
+      SMESH::SetPointRepresentation( true );
+      if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
+       aViewWindow->SetSelectionMode( NodeSelection );
+    }
+    else {
+      SMESH::SetPointRepresentation( false );
+      if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
+       aViewWindow->SetSelectionMode( CellSelection );
+    }
+  }
+
+  int oldID = myID->text().toLong();
+  SMESH_Actor* oldActor = myActor;
+  myID->clear();
+  
+  connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
+  updateInfo();
+  
+  if ( oldActor == myActor && myActor && oldID ) {
+    myID->setText( QString::number( oldID ) );
+    idChanged();
+  }
+}
+
+/*!
+  \brief Show help page
+*/
+void SMESHGUI_MeshInfoDlg::help()
+{
+  SMESH::ShowHelpFile( myTabWidget->currentIndex() == BaseInfo ?
+                      "mesh_infos_page.html#advanced_mesh_infos_anchor" : 
+                      "mesh_infos_page.html#mesh_element_info_anchor" );
+}
+
+/*!
+  \brief Show mesh information
+*/
+void SMESHGUI_MeshInfoDlg::updateInfo()
+{
+  SUIT_OverrideCursor wc;
+
+  SALOME_ListIO selected;
+  SMESHGUI::selectionMgr()->selectedObjects( selected );
+
+  if ( selected.Extent() == 1 ) {
+    Handle(SALOME_InteractiveObject) IO = selected.First();
+    showInfo( IO );
+  }
+//   else {
+//     myBaseInfo->clear();
+//     myElemInfo->clear();
+//   }
+}
+
+/*!
+  \brief Activate dialog box
+*/
+void SMESHGUI_MeshInfoDlg::activate()
+{
+  SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
+  SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this );
+  myTabWidget->setEnabled( true );
+  updateSelection();
+}
+
+/*!
+  \brief Deactivate dialog box
+*/
+void SMESHGUI_MeshInfoDlg::deactivate()
+{
+  myTabWidget->setEnabled( false );
+  disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
+}
+
+/*!
+  \brief Called when users switches between node / element modes.
+*/
+void SMESHGUI_MeshInfoDlg::modeChanged()
+{
+  myID->clear();
+  updateSelection();
+}
+
+/*!
+  \brief Caled when users prints mesh element ID in the corresponding field.
+*/
+void SMESHGUI_MeshInfoDlg::idChanged()
+{
+  SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector();
+  if ( myActor && selector ) {
+    Handle(SALOME_InteractiveObject) IO = myActor->getIO();
+    TColStd_MapOfInteger ID;
+    ID.Add( myID->text().toLong() );
+    selector->AddOrRemoveIndex( IO, ID, false );
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
+      aViewWindow->highlight( IO, true, true );
+    myElemInfo->showInfo( myID->text().toLong(), myMode->checkedId() == ElemMode );
+  }
+}
diff --git a/src/SMESHGUI/SMESHGUI_MeshInfo.h b/src/SMESHGUI/SMESHGUI_MeshInfo.h
new file mode 100644 (file)
index 0000000..ae22e5a
--- /dev/null
@@ -0,0 +1,220 @@
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//  File   : SMESHGUI_MeshInfo.h
+//  Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
+
+#ifndef SMESHGUI_MESHINFO_H
+#define SMESHGUI_MESHINFO_H
+
+#include "SMESH_SMESHGUI.hxx"
+#include <SALOME_InteractiveObject.hxx>
+
+#include <QFrame>
+#include <QDialog>
+#include <QList>
+#include <QMap>
+#include <QVector>
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Mesh)
+
+class QButtonGroup;
+class QLabel;
+class QLineEdit;
+class QTabWidget;
+class QTextBrowser;
+class QTreeWidget;
+class QTreeWidgetItem;
+class SMESH_Actor;
+class SMDS_MeshNode;
+class SMDS_MeshElement;
+
+class SMESHGUI_EXPORT SMESHGUI_MeshInfo : public QFrame
+{
+  Q_OBJECT;
+  
+  enum {
+    iName,
+    iObject,
+    iNodesStart,
+    iNodes,
+    iNodesEnd,
+    iElementsStart = iNodesEnd, 
+    iElements,
+    i0DStart,
+    i0D,
+    i0DEnd,
+    i1DStart       = i0DEnd,
+    i1D,
+    i1DEnd,
+    i2DStart       = i1DEnd,
+    i2D,
+    i2DTriangles,
+    i2DQuadrangles,
+    i2DPolygons,
+    i2DEnd,
+    i3DStart       = i2DEnd,
+    i3D,
+    i3DTetrahedrons,
+    i3DHexahedrons,
+    i3DPyramids,
+    i3DPrisms,
+    i3DPolyhedrons,
+    i3DEnd,
+    iElementsEnd   = i3DEnd
+  };
+
+  enum {
+    iSingle = 1,
+    iTotal  = iSingle,
+    iLinear,
+    iQuadratic
+  };
+
+  typedef QList<QWidget*> wlist;
+  typedef QVector<wlist>  iwlist;
+
+public:
+  SMESHGUI_MeshInfo( QWidget* = 0 );
+  ~SMESHGUI_MeshInfo();
+
+  void     showInfo( SMESH::SMESH_IDSource_ptr );
+  void     clear();
+
+private:
+  enum { Bold = 0x01, Italic = 0x02 };
+
+  QLabel*  createField();
+  QWidget* createLine();
+  void     setFontAttributes( QWidget*, int, bool = true );
+  void     setFieldsVisible( int, int, bool );
+
+private:
+  iwlist   myWidgets;
+};
+
+class SMESHGUI_EXPORT SMESHGUI_ElemInfo : public QWidget
+{
+  Q_OBJECT;
+
+public:
+  SMESHGUI_ElemInfo( QWidget* = 0 );
+  ~SMESHGUI_ElemInfo();
+
+  void         setSource( SMESH_Actor* );
+  virtual void showInfo( long, bool );
+  virtual void clear() = 0;
+
+protected:
+  struct XYZ
+  {
+    double myX, myY, myZ;
+    XYZ() { myX = myY = myZ = 0.0; }
+    void add( double x, double y, double z ) { myX += x; myY += y; myZ += z; }
+    void divide( double a ) { if ( a != 0.) { myX /= a; myY /= a; myZ /= a; } }
+    double x() const  { return myX; }
+    double y() const  { return myY; }
+    double z() const  { return myZ; }
+  };
+  typedef QMap< int, QList<int> > Connectivity;
+
+  Connectivity nodeConnectivity( const SMDS_MeshNode* );
+  QString      formatConnectivity( Connectivity, int );
+  XYZ          gravityCenter( const SMDS_MeshElement* );
+
+protected:
+  SMESH_Actor* myActor;
+  long         myID;
+  int          myIsElement;
+};
+
+class SMESHGUI_EXPORT SMESHGUI_SimpleElemInfo : public SMESHGUI_ElemInfo
+{
+public:
+  SMESHGUI_SimpleElemInfo( QWidget* = 0 );
+
+  void          showInfo( long, bool );
+  void          clear();
+
+private:
+  QTextBrowser* myInfo;
+};
+
+class SMESHGUI_EXPORT SMESHGUI_TreeElemInfo : public SMESHGUI_ElemInfo
+{
+  class ItemDelegate;
+
+public:
+  SMESHGUI_TreeElemInfo( QWidget* = 0 );
+
+  void             showInfo( long, bool );
+  void             clear();
+
+private:
+  QTreeWidgetItem* createItem( QTreeWidgetItem* = 0, int = 100 );
+  
+private:
+  QTreeWidget*     myInfo;
+};
+
+class SMESHGUI_EXPORT SMESHGUI_MeshInfoDlg : public QDialog
+{ 
+  Q_OBJECT;
+
+  enum { NodeMode, ElemMode };
+
+public:
+  //! Information type
+  enum { 
+    BaseInfo,  //!< base mesh information
+    ElemInfo   //!< mesh element information
+  };
+
+  SMESHGUI_MeshInfoDlg( QWidget* = 0, int = BaseInfo );
+  ~SMESHGUI_MeshInfoDlg();
+
+  void showInfo( const Handle(SALOME_InteractiveObject)& );
+  void reject();
+
+protected:
+  void keyPressEvent( QKeyEvent* );
+  void enterEvent( QEvent* );
+
+private slots:
+  void help();
+  void updateSelection();
+  void updateInfo();
+  void activate();
+  void deactivate();
+  void modeChanged();
+  void idChanged();
+
+private:
+  QTabWidget*        myTabWidget;
+  SMESHGUI_MeshInfo* myBaseInfo;
+  QButtonGroup*      myMode;
+  QLineEdit*         myID;
+  SMESHGUI_ElemInfo* myElemInfo;   
+  SMESH_Actor*       myActor;
+};
+
+#endif // SMESHGUI_MESHINFO_H
index 84107dc27e1734034a7e4ef3f121fb0af41d4169..48b4fae6e4e507ec06c8c9d22307ab09611cb6c4 100644 (file)
@@ -860,6 +860,7 @@ void SMESHGUI_MeshOp::existingHyps( const int theDim,
           if ( !aHypVar->_is_nil() )
           {
             HypothesisData* aData = SMESH::GetHypothesisData( aHypVar->GetName() );
+            if ( !aData) continue;
             if ( ( theDim == -1 || aData->Dim.contains( theDim ) ) &&
                  ( isCompatible ( theAlgoData, aData, theHypType )) &&
                  ( isAux == aData->IsAux ))
@@ -1858,7 +1859,7 @@ SMESH::SMESH_Hypothesis_var SMESHGUI_MeshOp::getAlgo( const int theDim )
       {
         // Call hypothesis creation server method (without GUI)
         SMESH::SMESH_Hypothesis_var aHyp =
-          SMESH::CreateHypothesis(aHypName, aHypData->Label, true);
+          SMESH::CreateHypothesis(aHypName, aHypName, true);
 #ifdef WITHGENERICOBJ
         if (!CORBA::is_nil(aHyp))
           aHyp->Destroy();
@@ -1876,7 +1877,7 @@ SMESH::SMESH_Hypothesis_var SMESHGUI_MeshOp::getAlgo( const int theDim )
           aCreator->create(true, aHypName, myDlg, 0, QString::null );
         else {
           SMESH::SMESH_Hypothesis_var aHyp =
-            SMESH::CreateHypothesis(aHypName, aHypData->Label, true);
+            SMESH::CreateHypothesis(aHypName, aHypName, true);
 #ifdef WITHGENERICOBJ
           if (!CORBA::is_nil(aHyp))
             aHyp->Destroy();
index bf53ecd7f45494486cf94181afc7e8a622650530..7d48093e2b86701e4d8f4b300570f5e5f0636f15 100644 (file)
@@ -27,6 +27,7 @@
 //
 #include "SMESHGUI_MeshUtils.h"
 
+#include "SMESHGUI.h"
 #include "SMESHGUI_Utils.h"
 
 // SALOME KERNEL includes
@@ -38,6 +39,7 @@
 // IDL includes
 #include <SALOMEconfig.h>
 #include CORBA_SERVER_HEADER(SMESH_Group)
+#include CORBA_SERVER_HEADER(SMESH_Measurements)
 
 namespace SMESH
 {
@@ -122,4 +124,13 @@ namespace SMESH
     }
     return name;
   }
+
+  SMESH::Measurements_var& GetMeasurements()
+  {
+    static SMESH::Measurements_var aMeasurements;
+    if (CORBA::is_nil(aMeasurements)) {
+      aMeasurements = SMESHGUI::GetSMESHGen()->CreateMeasurements();
+    }
+    return aMeasurements;
+  }
 } // end of namespace SMESH
index 5a959cb397d5e3f0981ad623cb30038560bb4972..a5371f56b88dfcdcf2d9458f532ee24f9c6438a9 100644 (file)
@@ -42,6 +42,7 @@
 // IDL includes
 #include <SALOMEconfig.h>
 #include CORBA_SERVER_HEADER(SMESH_Mesh)
+#include CORBA_SERVER_HEADER(SMESH_Measurements)
 
 class SALOMEDSClient_SObject;
 
@@ -54,6 +55,8 @@ namespace SMESH
     QString        UniqueMeshName( const QString&, const QString& = QString() );
   SMESHGUI_EXPORT
     QString        UniqueName( const QString&, _PTR(SObject) = _PTR(SObject)(), const QString& = QString() );
+
+  SMESHGUI_EXPORT  SMESH::Measurements_var& GetMeasurements();
 }
 
 #endif // SMESHGUI_MESHUTILS_H
index ec3a4d14f0fcd1ec219e17335c558e63a432918a..43640501edc55d560f353831905bbacb412253f6 100644 (file)
@@ -33,6 +33,8 @@
 #include "SMESHGUI_Utils.h"
 
 #include <SMESH_Actor.h>
+#include <SMESH_ScalarBarActor.h>
+#include <SMESH_ControlsDef.hxx>
 
 // SALOME GUI includes
 #include <SUIT_Desktop.h>
@@ -63,7 +65,6 @@
 
 // VTK includes
 #include <vtkTextProperty.h>
-#include <vtkScalarBarActor.h>
 #include <vtkLookupTable.h>
 
 #define MINIMUM_WIDTH 70
@@ -279,8 +280,35 @@ SMESHGUI_Preferences_ScalarBarDlg::SMESHGUI_Preferences_ScalarBarDlg( SMESHGUI*
   myOriginDimGrpLayout->addWidget( myHeightSpin, 1, 3 );
 
   aTopLayout->addWidget( myOriginDimGrp );
+  /******************************************************************************/
 
-  /***************************************************************/
+  // Destribution
+  myDistributionGrp = new QGroupBox ( tr( "SMESH_DISTRIBUTION_SCALARBAR" ), this );
+  myDistributionGrp->setCheckable(true);
+  QHBoxLayout* aDistributionGrpLayout = new QHBoxLayout( myDistributionGrp );
+  aDistributionGrpLayout->setSpacing( SPACING_SIZE ); aDistributionGrpLayout->setMargin( MARGIN_SIZE );
+
+  myDistribColorGrp = new QButtonGroup( this );
+
+  myDMonoColor  = new QRadioButton( tr( "SMESH_MONOCOLOR" ) ,  myDistributionGrp );
+  myDMultiColor = new QRadioButton( tr( "SMESH_MULTICOLOR" ),  myDistributionGrp );
+  myDMonoColor->setChecked( true );
+
+  myDistribColorGrp->addButton(myDMonoColor);myDistribColorGrp->setId(myDMonoColor,1);
+  myDistribColorGrp->addButton(myDMultiColor);myDistribColorGrp->setId(myDMultiColor,2);
+  
+  aDistributionGrpLayout->addWidget( myDMultiColor );
+  aDistributionGrpLayout->addWidget( myDMonoColor );
+  
+  //Color of the Distribution in monocolor case:
+  myDistributionColorLbl = new QLabel( tr( "SMESH_DISTRIBUTION_COLOR" ), myDistributionGrp );
+  aDistributionGrpLayout->addWidget( myDistributionColorLbl );
+  myMonoColorBtn = new QtxColorButton( myDistributionGrp  );
+  aDistributionGrpLayout->addWidget(myMonoColorBtn);
+  
+  aTopLayout->addWidget(myDistributionGrp);
+  
+  /******************************************************************************/
   // Common buttons
   myButtonGrp = new QGroupBox( this );
   QHBoxLayout* myButtonGrpLayout = new QHBoxLayout( myButtonGrp );
@@ -376,6 +404,25 @@ SMESHGUI_Preferences_ScalarBarDlg::SMESHGUI_Preferences_ScalarBarDlg( SMESHGUI*
 
   setOriginAndSize(myIniX, myIniY, myIniW, myIniH);
 
+
+  bool distributionVisibility = mgr->booleanValue("SMESH","distribution_visibility");
+  myDistributionGrp->setChecked(distributionVisibility);
+
+  int coloringType = mgr->integerValue("SMESH", "distribution_coloring_type", 0);
+  if( coloringType == SMESH_MONOCOLOR_TYPE ) {
+    myDMultiColor->setChecked(true);
+    onDistributionChanged(myDistribColorGrp->id(myDMultiColor));
+  } else {
+    myDMonoColor->setChecked(true);
+    onDistributionChanged(myDistribColorGrp->id(myDMonoColor));
+  }
+  
+  QColor distributionColor = mgr->colorValue("SMESH", "distribution_color",
+                                            QColor(255, 255, 255));
+  myMonoColorBtn->setColor(distributionColor);
+  
+  
+
   // --> then init from selection if necessary
   onSelectionChanged();
 
@@ -388,10 +435,11 @@ SMESHGUI_Preferences_ScalarBarDlg::SMESHGUI_Preferences_ScalarBarDlg( SMESHGUI*
   connect( myXSpin,             SIGNAL( valueChanged( double ) ), this, SLOT( onXYChanged() ) );
   connect( myYSpin,             SIGNAL( valueChanged( double ) ), this, SLOT( onXYChanged() ) );
   connect( aOrientationGrp,     SIGNAL( buttonClicked( int ) ),   this, SLOT( onOrientationChanged() ) );
+  connect( myDistribColorGrp,   SIGNAL( buttonClicked( int ) ),   this, SLOT( onDistributionChanged( int ) ) );
   connect( mySelectionMgr,      SIGNAL( currentSelectionChanged() ), this, SLOT( onSelectionChanged() ) );
   connect( mySMESHGUI,          SIGNAL( SignalCloseAllDialogs() ),   this, SLOT( onCancel() ) );
 
-  myHelpFileName = "about_quality_controls_page.html";
+  myHelpFileName = "quality_page.html";
 }
 
 //=================================================================================================
@@ -430,7 +478,7 @@ bool SMESHGUI_Preferences_ScalarBarDlg::onApply()
   // Scalar Bar properties
   if (!myActor)
     return false;
-  vtkScalarBarActor* myScalarBarActor = myActor->GetScalarBarActor();
+  SMESH_ScalarBarActor* myScalarBarActor = myActor->GetScalarBarActor();
 
   vtkTextProperty* aTitleTextPrp = myScalarBarActor->GetTitleTextProperty();
   QColor aTColor = myTitleColorBtn->color();
@@ -461,7 +509,18 @@ bool SMESHGUI_Preferences_ScalarBarDlg::onApply()
   myScalarBarActor->SetLabelTextProperty( aLabelsTextPrp );
 
   myScalarBarActor->SetNumberOfLabels( myLabelsSpin->value() );
-  myScalarBarActor->SetMaximumNumberOfColors( myColorsSpin->value() );
+  if( myColorsSpin->value() != myScalarBarActor->GetMaximumNumberOfColors() ) {
+    myScalarBarActor->SetMaximumNumberOfColors( myColorsSpin->value() );
+    SMESH::Controls::FunctorPtr fn = myActor->GetFunctor();       
+    SMESH::Controls::NumericalFunctor* aNumericalFunctor = dynamic_cast<SMESH::Controls::NumericalFunctor*>(fn.get());
+    if( aNumericalFunctor ) {
+      int nbIntervals = myColorsSpin->value();
+      std::vector<int> nbEvents;
+      std::vector<double> funValues;
+      aNumericalFunctor->GetHistogram(nbIntervals, nbEvents, funValues);
+      myScalarBarActor->SetDistribution(nbEvents);
+    }
+  }
 
   if ( myHorizRadioBtn->isChecked() )
     myScalarBarActor->SetOrientationToHorizontal();
@@ -472,6 +531,21 @@ bool SMESHGUI_Preferences_ScalarBarDlg::onApply()
   myScalarBarActor->SetWidth( myWidthSpin->value() );
   myScalarBarActor->SetHeight( myHeightSpin->value() );
 
+  // Distribution
+  myScalarBarActor->SetDistributionVisibility((int)myDistributionGrp->isChecked());
+  if( myDistributionGrp->isChecked() ) {
+    int ColoringType = myDMultiColor->isChecked() ? SMESH_MULTICOLOR_TYPE : SMESH_MONOCOLOR_TYPE;
+    myScalarBarActor->SetDistributionColoringType(ColoringType);
+    if( !myDMultiColor->isChecked() ) {
+      QColor aTColor = myMonoColorBtn->color();
+      double rgb[3];
+      rgb [0] = aTColor.red()/255.;
+      rgb [1] = aTColor.green()/255.;
+      rgb [2] = aTColor.blue()/255.;
+      myScalarBarActor->SetDistributionColor(rgb);
+    }
+  }
+
   double aMin = myMinEdit->text().toDouble();
   double aMax = myMaxEdit->text().toDouble();
   vtkLookupTable* myLookupTable =
@@ -540,7 +614,7 @@ void SMESHGUI_Preferences_ScalarBarDlg::onSelectionChanged()
       SMESH_Actor* anActor = SMESH::FindActorByEntry(anIO->getEntry());
       if ( anActor && anActor->GetScalarBarActor() && anActor->GetControlMode() != SMESH_Actor::eNone ) {
         myActor = anActor;
-        vtkScalarBarActor* myScalarBarActor = myActor->GetScalarBarActor();
+        SMESH_ScalarBarActor* myScalarBarActor = myActor->GetScalarBarActor();
 
         if ( myScalarBarActor->GetLookupTable() ) {
           vtkFloatingPointType *range = myScalarBarActor->GetLookupTable()->GetRange();
@@ -581,6 +655,17 @@ void SMESHGUI_Preferences_ScalarBarDlg::onSelectionChanged()
         myIniH = myScalarBarActor->GetHeight();
         setOriginAndSize( myIniX, myIniY, myIniW, myIniH );
 
+       myDistributionGrp->setChecked((bool)myScalarBarActor->GetDistributionVisibility());
+       int coloringType = myScalarBarActor->GetDistributionColoringType();
+       myScalarBarActor->GetDistributionColor( aTColor );
+       myMonoColorBtn->setColor( QColor( (int)( aTColor[0]*255 ), (int)( aTColor[1]*255 ), (int)( aTColor[2]*255 ) ) );
+       if ( coloringType == SMESH_MONOCOLOR_TYPE ) {
+         myDMonoColor->setChecked(true);
+         onDistributionChanged(myDistribColorGrp->id(myDMonoColor));    
+       } else {
+         myDMultiColor->setChecked(true);
+         onDistributionChanged(myDistribColorGrp->id(myDMultiColor));
+       }
         myRangeGrp->setEnabled( true );
         myFontGrp->setEnabled( true );
         myLabColorGrp->setEnabled( true );
@@ -651,6 +736,19 @@ void SMESHGUI_Preferences_ScalarBarDlg::setOriginAndSize( const double x,
   onXYChanged();
 }
 
+
+//=================================================================================================
+/*!
+ *  SMESHGUI_Preferences_ScalarBarDlg::onDistributionChanged
+ *
+ *  Called when coloring type of the distribution is changed
+ */
+//=================================================================================================
+void SMESHGUI_Preferences_ScalarBarDlg::onDistributionChanged( int id ) {
+  myMonoColorBtn->setEnabled(myDistribColorGrp->id(myDMonoColor) == id);
+  myDistributionColorLbl->setEnabled(myDistribColorGrp->id(myDMonoColor) == id);
+}
+
 //=================================================================================================
 /*!
  *  SMESHGUI_Preferences_ScalarBarDlg::onOrientationChanged
index c71c43cda4d14dc0896306547a58948e8b48b372..42058ee2b144bae6d006a58257ce35c93b87e038 100644 (file)
@@ -40,6 +40,8 @@ class QLineEdit;
 class QPushButton;
 class QToolButton;
 class QRadioButton;
+class QButtonGroup;
+class QLabel;
 
 class SMESHGUI;
 class SMESH_Actor;
@@ -77,6 +79,7 @@ protected slots:
   void                     onSelectionChanged();
   void                     onXYChanged();
   void                     onOrientationChanged();
+  void                     onDistributionChanged( int );
 
 private:
   SMESHGUI*                mySMESHGUI;
@@ -117,7 +120,14 @@ private:
   SMESHGUI_SpinBox*        myWidthSpin;
   SMESHGUI_SpinBox*        myHeightSpin;
 
+  QGroupBox*               myDistributionGrp;
+  QRadioButton*            myDMonoColor;
+  QRadioButton*            myDMultiColor;
+  QtxColorButton*          myMonoColorBtn;
+  QLabel*                  myDistributionColorLbl;
+
   QGroupBox*               myButtonGrp;
+  QButtonGroup*            myDistribColorGrp;
   QPushButton*             myOkBtn;
   QPushButton*             myApplyBtn;
   QPushButton*             myCancelBtn;
index 887cdea084b5665689c2885312237483fc86ff87..df7c9c1c6cfcd0092ac8c7254a49a22ccbb0b3bf 100644 (file)
@@ -34,6 +34,7 @@
 
 #include <SMESH_Type.h>
 #include <SMESH_Actor.h>
+#include <SMESH_ScalarBarActor.h>
 
 // SALOME GUI includes
 #include <SalomeApp_Study.h>
@@ -114,6 +115,7 @@ QVariant SMESHGUI_Selection::parameter( const int ind, const QString& p ) const
   else if ( p=="shrinkMode" )    val = QVariant( shrinkMode( ind ) );
   else if ( p=="entityMode" )    val = QVariant( entityMode( ind ) );
   else if ( p=="controlMode" )   val = QVariant( controlMode( ind ) );
+  else if ( p=="isNumFunctor" )  val = QVariant( isNumFunctor( ind ) );
   else if ( p=="displayMode" )   val = QVariant( displayMode( ind ) );
   else if ( p=="isComputable" )  val = QVariant( isComputable( ind ) );
   else if ( p=="isPreComputable" )  val = QVariant( isPreComputable( ind ) );
@@ -122,6 +124,7 @@ QVariant SMESHGUI_Selection::parameter( const int ind, const QString& p ) const
   else if ( p=="facesOrientationMode" ) val = QVariant( facesOrientationMode( ind ) );
   else if ( p=="groupType" )     val = QVariant( groupType( ind ) );
   else if ( p=="quadratic2DMode") val =  QVariant(quadratic2DMode(ind));
+  else if ( p=="isDistributionVisible") val = QVariant(isDistributionVisible(ind));
 
   if( val.isValid() )
     return val;
@@ -216,6 +219,16 @@ QString SMESHGUI_Selection::quadratic2DMode( int ind ) const
   return "Unknown";
 }
 
+//=======================================================================
+//function : isDistributionVisible
+//purpose  : Visible/Invisible distribution of the ScalarBar Actor
+//=======================================================================
+
+bool SMESHGUI_Selection::isDistributionVisible(int ind) const {
+  SMESH_Actor* actor = getActor( ind );
+  return (actor && actor->GetScalarBarActor() && actor->GetScalarBarActor()->GetDistributionVisibility());
+} 
+
 //=======================================================================
 //function : shrinkMode
 //purpose  : return either 'IsSrunk', 'IsNotShrunk' or 'IsNotShrinkable'
@@ -271,6 +284,8 @@ QString SMESHGUI_Selection::controlMode( int ind ) const
     case SMESH_Actor::eMultiConnection2D: return "eMultiConnection2D";
     case SMESH_Actor::eArea:              return "eArea";
     case SMESH_Actor::eVolume3D:          return "eVolume3D";
+    case SMESH_Actor::eMaxElementLength2D: return "eMaxElementLength2D";
+    case SMESH_Actor::eMaxElementLength3D: return "eMaxElementLength3D";
     case SMESH_Actor::eTaper:             return "eTaper";
     case SMESH_Actor::eAspectRatio:       return "eAspectRatio";
     case SMESH_Actor::eAspectRatio3D:     return "eAspectRatio3D";
@@ -283,6 +298,35 @@ QString SMESHGUI_Selection::controlMode( int ind ) const
   return "eNone";
 }
 
+bool SMESHGUI_Selection::isNumFunctor( int ind ) const
+{
+  bool result = false;
+  SMESH_Actor* actor = getActor( ind );
+  if ( actor ) {
+    switch( actor->GetControlMode() ) {
+    case SMESH_Actor::eLength:
+    case SMESH_Actor::eLength2D:
+    case SMESH_Actor::eMultiConnection:
+    case SMESH_Actor::eMultiConnection2D:
+    case SMESH_Actor::eArea:
+    case SMESH_Actor::eVolume3D:
+    case SMESH_Actor::eMaxElementLength2D:
+    case SMESH_Actor::eMaxElementLength3D:
+    case SMESH_Actor::eTaper:
+    case SMESH_Actor::eAspectRatio:
+    case SMESH_Actor::eAspectRatio3D:
+    case SMESH_Actor::eMinimumAngle:
+    case SMESH_Actor::eWarping:
+    case SMESH_Actor::eSkew:
+      result = true;
+      break;
+    default:
+      break;
+    }
+  }
+  return result;
+}
+
 //=======================================================================
 //function : facesOrientationMode
 //purpose  : 
@@ -590,4 +634,3 @@ QString SMESHGUI_Selection::groupType( int ind ) const
   }
   return type;
 }
-
index 2320041def32adb2f85a442f745ebffab518f7f0..2ad545d982deed9a34807f88d8eb970e87ba0371 100644 (file)
@@ -61,6 +61,8 @@ public:
 
   virtual QString         quadratic2DMode(int ) const;
 
+  virtual bool            isDistributionVisible(int ) const;
+
   // parameters got from actor return nothing if an actor is not visible
   virtual QList<QVariant> elemTypes( int ) const;
   virtual QList<QVariant> labeledTypes( int ) const;
@@ -68,6 +70,7 @@ public:
   virtual QString         shrinkMode( int ) const;
   virtual QList<QVariant> entityMode( int ) const;
   virtual QString         controlMode( int ) const;
+  virtual bool            isNumFunctor( int ) const;
   virtual QString         facesOrientationMode( int ) const;
   virtual QString         groupType( int ) const;
   
index 6f921cd220b89ec61998a93c0776ca269c1b05a9..dfe7788315b6dea065c0b093f302042cc2b26d0b 100644 (file)
@@ -205,6 +205,20 @@ namespace SMESH
     return SObjectToObject(theSObject,aStudy);
   }
 
+  _PTR(SObject) ObjectToSObject( CORBA::Object_ptr theObject )
+  {
+    _PTR(SObject) res;
+    SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>
+      (SUIT_Session::session()->activeApplication());
+    if ( app ) {
+      QString IOR = app->orb()->object_to_string( theObject );
+      SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( app->activeStudy() );
+      if ( study && !IOR.isEmpty() )
+       res = study->studyDS()->FindObjectIOR( IOR.toLatin1().constData() );
+    }
+    return res;
+  }
+
   CORBA::Object_var IObjectToObject (const Handle(SALOME_InteractiveObject)& theIO)
   {
     if (!theIO.IsNull()) {
index 555d233824a07d03acc00f1934bdf7ac0fe4a9c6..996a34761753bd54b4e7dcdba11ae570a45dff0d 100644 (file)
@@ -129,6 +129,9 @@ SMESHGUI_EXPORT
       return TInterface::_nil();
     }
 
+SMESHGUI_EXPORT
+  _PTR(SObject) ObjectToSObject( CORBA::Object_ptr );
+
 SMESHGUI_EXPORT
   CORBA::Object_var IObjectToObject( const Handle(SALOME_InteractiveObject)& );
 
index 72ce1e852964e41b4f20fc343c98c3852a99f16c..c663c74da3ff9bedb28fbc0e97251ee23ee3bcb1 100644 (file)
@@ -65,6 +65,7 @@
 #include CORBA_CLIENT_HEADER(SMESH_Group)
 
 // VTK includes
+#include <vtkMath.h>
 #include <vtkRenderer.h>
 #include <vtkActorCollection.h>
 #include <vtkUnstructuredGrid.h>
@@ -605,6 +606,9 @@ namespace SMESH
         }
       }
     }
+    if( anActor )
+      if( SMESHGUI* aSMESHGUI = SMESHGUI::GetSMESHGUI() )
+        aSMESHGUI->addActorAsObserver( anActor );
     return anActor;
   }
 
@@ -1167,4 +1171,108 @@ namespace SMESH
 
     }
   }
+
+  //----------------------------------------------------------------------------
+  // internal function
+  void ComputeBoundsParam( vtkFloatingPointType theBounds[6],
+                           vtkFloatingPointType theDirection[3],
+                           vtkFloatingPointType theMinPnt[3],
+                           vtkFloatingPointType& theMaxBoundPrj,
+                           vtkFloatingPointType& theMinBoundPrj )
+  {
+    //Enlarge bounds in order to avoid conflicts of precision
+    for(int i = 0; i < 6; i += 2){
+      static double EPS = 1.0E-3;
+      vtkFloatingPointType aDelta = (theBounds[i+1] - theBounds[i])*EPS;
+      theBounds[i] -= aDelta;
+      theBounds[i+1] += aDelta;
+    }
+
+    vtkFloatingPointType aBoundPoints[8][3] = { {theBounds[0],theBounds[2],theBounds[4]},
+                                                {theBounds[1],theBounds[2],theBounds[4]},
+                                                {theBounds[0],theBounds[3],theBounds[4]},
+                                                {theBounds[1],theBounds[3],theBounds[4]},
+                                                {theBounds[0],theBounds[2],theBounds[5]},
+                                                {theBounds[1],theBounds[2],theBounds[5]}, 
+                                                {theBounds[0],theBounds[3],theBounds[5]}, 
+                                                {theBounds[1],theBounds[3],theBounds[5]}};
+
+    int aMaxId = 0, aMinId = aMaxId;
+    theMaxBoundPrj = vtkMath::Dot(theDirection,aBoundPoints[aMaxId]);
+    theMinBoundPrj = theMaxBoundPrj;
+    for(int i = 1; i < 8; i++){
+      vtkFloatingPointType aTmp = vtkMath::Dot(theDirection,aBoundPoints[i]);
+      if(theMaxBoundPrj < aTmp){
+        theMaxBoundPrj = aTmp;
+        aMaxId = i;
+      }
+      if(theMinBoundPrj > aTmp){
+        theMinBoundPrj = aTmp;
+        aMinId = i;
+      }
+    }
+    vtkFloatingPointType *aMinPnt = aBoundPoints[aMaxId];
+    theMinPnt[0] = aMinPnt[0];
+    theMinPnt[1] = aMinPnt[1];
+    theMinPnt[2] = aMinPnt[2];
+  }
+
+  // internal function
+  void DistanceToPosition( vtkFloatingPointType theBounds[6],
+                           vtkFloatingPointType theDirection[3],
+                           vtkFloatingPointType theDist,
+                           vtkFloatingPointType thePos[3] )
+  {
+    vtkFloatingPointType aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];
+    ComputeBoundsParam(theBounds,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj);
+    vtkFloatingPointType aLength = (aMaxBoundPrj-aMinBoundPrj)*theDist;
+    thePos[0] = aMinPnt[0]-theDirection[0]*aLength;
+    thePos[1] = aMinPnt[1]-theDirection[1]*aLength;
+    thePos[2] = aMinPnt[2]-theDirection[2]*aLength;
+  }
+
+  // internal function (currently unused, left just in case)
+  void PositionToDistance( vtkFloatingPointType theBounds[6],
+                           vtkFloatingPointType theDirection[3],
+                           vtkFloatingPointType thePos[3],
+                           vtkFloatingPointType& theDist )
+  {
+    vtkFloatingPointType aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];
+    ComputeBoundsParam(theBounds,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj);
+    vtkFloatingPointType aPrj = vtkMath::Dot(theDirection,thePos);
+    theDist = (aPrj-aMinBoundPrj)/(aMaxBoundPrj-aMinBoundPrj);
+  }
+
+  bool ComputeClippingPlaneParameters( std::list<vtkActor*> theActorList,
+                                       vtkFloatingPointType theNormal[3],
+                                       vtkFloatingPointType theDist,
+                                       vtkFloatingPointType theBounds[6],
+                                       vtkFloatingPointType theOrigin[3] )
+  {
+    bool anIsOk = false;
+    theBounds[0] = theBounds[2] = theBounds[4] = VTK_DOUBLE_MAX;
+    theBounds[1] = theBounds[3] = theBounds[5] = -VTK_DOUBLE_MAX;
+    std::list<vtkActor*>::iterator anIter = theActorList.begin();
+    for( ; anIter != theActorList.end(); anIter++ ) {
+      if( vtkActor* aVTKActor = *anIter ) {
+        if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) ) {
+          vtkFloatingPointType aBounds[6];
+          anActor->GetUnstructuredGrid()->GetBounds( aBounds );
+          theBounds[0] = std::min( theBounds[0], aBounds[0] );
+          theBounds[1] = std::max( theBounds[1], aBounds[1] );
+          theBounds[2] = std::min( theBounds[2], aBounds[2] );
+          theBounds[3] = std::max( theBounds[3], aBounds[3] );
+          theBounds[4] = std::min( theBounds[4], aBounds[4] );
+          theBounds[5] = std::max( theBounds[5], aBounds[5] );
+          anIsOk = true;
+        }
+      }
+    }
+
+    if( !anIsOk )
+      return false;
+
+    DistanceToPosition( theBounds, theNormal, theDist, theOrigin );
+    return true;
+  }
 } // end of namespace SMESH
index 508ce767e881cc83dada67234b83ba5d746cdd99..5a9b09c25eccb9a48040e389f2a991a22032d0ad 100644 (file)
@@ -57,6 +57,8 @@ class SMESHGUI;
 class SMESH_Actor;
 class SALOME_Actor;
 
+class vtkActor;
+
 namespace SMESH
 {
   //----------------------------------------------------------------------------
@@ -185,6 +187,14 @@ SMESHGUI_EXPORT
 
 SMESHGUI_EXPORT
   void SetControlsPrecision( const long );
+
+  //----------------------------------------------------------------------------
+SMESHGUI_EXPORT
+  bool ComputeClippingPlaneParameters( std::list<vtkActor*> theActorList,
+                                       vtkFloatingPointType theNormal[3],
+                                       vtkFloatingPointType theDist,
+                                       vtkFloatingPointType theBounds[6],
+                                       vtkFloatingPointType theOrigin[3] );
 };
 
 #endif // SMESHGUI_VTKUTILS_H
index c22f4e96e906a5d232333e2a101e99d4035214da..856e88f32740868bc79b378612eac71dfd14f826 100644 (file)
             <source>ICON_MAP</source>
             <translation>mesh_pattern.png</translation>
         </message>
+        <message>
+            <source>ICON_MAX_ELEMENT_LENGTH_2D</source>
+            <translation>mesh_max_element_length_2d.png</translation>
+        </message>
+        <message>
+            <source>ICON_MAX_ELEMENT_LENGTH_3D</source>
+            <translation>mesh_max_element_length_3d.png</translation>
+        </message>
         <message>
             <source>ICON_OBJBROWSER_SMESH</source>
             <translation>mesh.png</translation>
         </message>
         <message>
             <source>ICON_WHAT_IS</source>
-            <translation>mesh_whatis.png</translation>
+            <translation>mesh_elem_info.png</translation>
         </message>
         <message>
             <source>ICON_WIRE</source>
             <source>ICON_SPLIT_TO_TETRA</source>
             <translation>split_into_tetra.png</translation>
         </message>
+        <message>
+            <source>ICON_MEASURE_MIN_DIST</source>
+            <translation>mesh_min_dist.png</translation>
+        </message>
+        <message>
+            <source>ICON_MEASURE_BND_BOX</source>
+            <translation>mesh_bounding_box.png</translation>
+        </message>
     </context>
 </TS>
index a42af721797f2efc9b640ac9a15420001a3addb2..8ea5465e14a27963617f211e25130656eed5d0c4 100644 (file)
@@ -3,6 +3,42 @@
 <TS version="2.0" language="en_US">
 <context>
     <name>@default</name>
+    <message>
+        <source>SMESH_EXPORT_MESH</source>
+        <translation>Export mesh</translation>
+    </message>
+    <message>
+        <source>MED_FILES_FILTER</source>
+        <translation>MED files</translation>
+    </message>
+    <message>
+        <source>IDEAS_FILES_FILTER</source>
+        <translation>IDEAS files</translation>
+    </message>
+    <message>
+        <source>DAT_FILES_FILTER</source>
+        <translation>DAT files</translation>
+    </message>
+    <message>
+        <source>TEXT_FILES_FILTER</source>
+        <translation>TXT files</translation>
+    </message>
+    <message>
+        <source>MED_VX_FILES_FILTER</source>
+        <translation>MED %1 files</translation>
+    </message>
+    <message>
+        <source>STL_ASCII_FILES_FILTER</source>
+        <translation>STL ASCII files</translation>
+    </message>
+    <message>
+        <source>STL_BIN_FILES_FILTER</source>
+        <translation>STL binary files</translation>
+    </message>
+    <message>
+        <source>ALL_FILES_FILTER</source>
+        <translation>All files</translation>
+    </message>
     <message>
         <source>AREA_ELEMENTS</source>
         <translation>Area</translation>
         <source>LOCAL_ALGO</source>
         <translation>Local</translation>
     </message>
+    <message>
+        <source>MAX_ELEMENT_LENGTH_2D</source>
+        <translation>Max Element Length 2D</translation>
+    </message>
+    <message>
+        <source>MAX_ELEMENT_LENGTH_3D</source>
+        <translation>Max Element Length 3D</translation>
+    </message>
     <message>
         <source>MEN_ADD</source>
         <translation>Add</translation>
     </message>
     <message>
         <source>MEN_ADV_INFO</source>
-        <translation>Advanced Mesh Infos</translation>
+        <translation>Mesh Information</translation>
     </message>
     <message>
         <source>MEN_ALL</source>
         <source>MEN_CTRL</source>
         <translation>Controls</translation>
     </message>
+    <message>
+        <source>MEN_NODE_CTRL</source>
+        <translation>Node Controls</translation>
+    </message>
+    <message>
+        <source>MEN_EDGE_CTRL</source>
+        <translation>Edge Controls</translation>
+    </message>
+    <message>
+        <source>MEN_FACE_CTRL</source>
+        <translation>Face Controls</translation>
+    </message>
+    <message>
+        <source>MEN_VOLUME_CTRL</source>
+        <translation>Volume Controls</translation>
+    </message>
     <message>
         <source>MEN_CUT</source>
         <translation>Cutting of Quadrangles</translation>
         <source>MEN_MAP</source>
         <translation>Pattern Mapping</translation>
     </message>
+    <message>
+        <source>MEN_MAX_ELEMENT_LENGTH_2D</source>
+        <translation>Max Element Length 2D</translation>
+    </message>
+    <message>
+        <source>MEN_MAX_ELEMENT_LENGTH_3D</source>
+        <translation>Max Element Length 3D</translation>
+    </message>
     <message>
         <source>MEN_MED</source>
         <translation>MED file</translation>
         <source>MEN_MODIFY</source>
         <translation>Modification</translation>
     </message>
+    <message>
+        <source>MEN_MEASURE</source>
+        <translation>Measurements</translation>
+    </message>
+    <message>
+        <source>MEN_MEASURE_MIN_DIST</source>
+        <translation>Minimum Distance</translation>
+    </message>
+    <message>
+        <source>STB_MEASURE_MIN_DIST</source>
+        <translation>Calculate minimum distance between two objects</translation>
+    </message>
+    <message>
+        <source>TOP_MEASURE_MIN_DIST</source>
+        <translation>Minimum distance</translation>
+    </message>
+    <message>
+        <source>MEN_MEASURE_BND_BOX</source>
+        <translation>Bounding Box</translation>
+    </message>
+    <message>
+        <source>STB_MEASURE_BND_BOX</source>
+        <translation>Calculate bounding box for the selected object(s)</translation>
+    </message>
+    <message>
+        <source>TOP_MEASURE_BND_BOX</source>
+        <translation>Bounding box</translation>
+    </message>
     <message>
         <source>MEN_MOVE</source>
         <translation>Move Node</translation>
         <source>MEN_RESET</source>
         <translation>Reset</translation>
     </message>
+    <message>
+        <source>MEN_SAVE_DISTRIBUTION</source>
+        <translation>Export Distribution...</translation>
+    </message>
+    <message>
+        <source>MEN_SHOW_DISTRIBUTION</source>
+        <translation>Show Distribution</translation>
+    </message>
     <message>
         <source>MEN_REVOLUTION</source>
         <translation>Revolution</translation>
     </message>
     <message>
         <source>MEN_WHAT_IS</source>
-        <translation>Mesh Element Info</translation>
+        <translation>Mesh Element Information</translation>
     </message>
     <message>
         <source>MEN_WIRE</source>
@@ -1741,6 +1845,14 @@ add the exported data to its contents?</translation>
         <source>SMESH_POSITION_SIZE_SCALARBAR</source>
         <translation>Origin &amp;&amp; Size</translation>
     </message>
+    <message>
+        <source>SMESH_DISTRIBUTION_SCALARBAR</source>
+        <translation>Distribution</translation>
+    </message>
+    <message>
+        <source>SMESH_SHOW_DISTRIBUTION_SCALARBAR</source>
+        <translation>Show Distribution</translation>
+    </message>
     <message>
         <source>SMESH_PRECISION</source>
         <translation>Precision</translation>
@@ -1985,6 +2097,22 @@ add the exported data to its contents?</translation>
     <message>
         <source>SMESH_VERTICAL</source>
         <translation>Vertical</translation>
+    </message>    
+    <message>
+        <source>SMESH_DISTRIBUTION_COLORING_TYPE</source>
+        <translation>Coloring Type</translation>
+    </message>
+    <message>
+        <source>SMESH_MONOCOLOR</source>
+        <translation>Monocolor</translation>
+    </message>
+    <message>
+        <source>SMESH_DISTRIBUTION_COLOR</source>
+        <translation>Distribution color:</translation>
+    </message>
+    <message>
+        <source>SMESH_MULTICOLOR</source>
+        <translation>Multicolor</translation>
     </message>
     <message>
         <source>SMESH_VISU_PROBLEM</source>
@@ -2112,7 +2240,7 @@ Please check preferences of Mesh module.
     </message>
     <message>
         <source>STB_ADV_INFO</source>
-        <translation>Advanced Mesh Infos</translation>
+        <translation>Show base information about the mesh object</translation>
     </message>
     <message>
         <source>STB_ALL</source>
@@ -2350,6 +2478,14 @@ Please check preferences of Mesh module.
         <source>STB_MAP</source>
         <translation>Pattern mapping</translation>
     </message>
+    <message>
+        <source>STB_MAX_ELEMENT_LENGTH_2D</source>
+        <translation>Max Element Length 2D</translation>
+    </message>
+    <message>
+        <source>STB_MAX_ELEMENT_LENGTH_3D</source>
+        <translation>Max Element Length 3D</translation>
+    </message>
     <message>
         <source>STB_MED</source>
         <translation>Import MED file</translation>
@@ -2470,6 +2606,14 @@ Please check preferences of Mesh module.
         <source>STB_RESET</source>
         <translation>Reset</translation>
     </message>
+    <message>
+        <source>STB_SAVE_DISTRIBUTION</source>
+        <translation>Save distribution to the file</translation>
+    </message>
+        <message>
+        <source>STB_SHOW_DISTRIBUTION</source>
+        <translation>Show Distribution</translation>
+    </message>
     <message>
         <source>STB_REVOLUTION</source>
         <translation>Revolution</translation>
@@ -2596,7 +2740,7 @@ Please check preferences of Mesh module.
     </message>
     <message>
         <source>STB_WHAT_IS</source>
-        <translation>Mesh Element Info</translation>
+        <translation>Show information about the mesh node or element</translation>
     </message>
     <message>
         <source>STB_WIRE</source>
@@ -2632,7 +2776,7 @@ Please check preferences of Mesh module.
     </message>
     <message>
         <source>TOP_ADV_INFO</source>
-        <translation>Advanced Mesh Infos</translation>
+        <translation>Mesh Information</translation>
     </message>
     <message>
         <source>TOP_ALL</source>
@@ -2870,6 +3014,14 @@ Please check preferences of Mesh module.
         <source>TOP_MAP</source>
         <translation>Pattern mapping</translation>
     </message>
+    <message>
+        <source>TOP_MAX_ELEMENT_LENGTH_2D</source>
+        <translation>Max Element Length 2D</translation>
+    </message>
+    <message>
+        <source>TOP_MAX_ELEMENT_LENGTH_3D</source>
+        <translation>Max Element Length 3D</translation>
+    </message>
     <message>
         <source>TOP_MED</source>
         <translation>Import MED file</translation>
@@ -2990,6 +3142,14 @@ Please check preferences of Mesh module.
         <source>TOP_RESET</source>
         <translation>Reset</translation>
     </message>
+    <message>
+        <source>TOP_SAVE_DISTRIBUTION</source>
+        <translation>Export distribution</translation>
+    </message>
+    <message>
+        <source>TOP_SHOW_DISTRIBUTION</source>
+        <translation>Show Distribution</translation>
+    </message>
     <message>
         <source>TOP_REVOLUTION</source>
         <translation>Revolution</translation>
@@ -3116,15 +3276,19 @@ Please check preferences of Mesh module.
     </message>
     <message>
         <source>TOP_WHAT_IS</source>
-        <translation>Mesh Element Info</translation>
+        <translation>Mesh Element Information</translation>
     </message>
     <message>
         <source>TOP_WIRE</source>
         <translation>Wireframe</translation>
     </message>
+    <message>
+        <source>UNKNOWN_CONTROL</source>
+        <translation>Unknown</translation>
+    </message>
     <message>
         <source>VOLUME_3D_ELEMENTS</source>
-        <translation>Area</translation>
+        <translation>Volume</translation>
     </message>
     <message>
         <source>WARP_ELEMENTS</source>
@@ -3224,6 +3388,10 @@ Input value precision can be adjusted using
         <source>NB_NODES_REMOVED</source>
         <translation>Removed %1 node(s).</translation>
     </message>
+    <message>
+        <source>SMESH_SAVE_DISTRIBUTION</source>
+        <translation>Export Distribution</translation>
+    </message>
 </context>
 <context>
     <name>SMESHGUI</name>
@@ -3312,6 +3480,30 @@ Please, create VTK viewer and try again</translation>
         <source>PREF_NOTIFY_MODE</source>
         <translation>Show a computation result notification</translation>
     </message>
+    <message>
+        <source>PREF_NOTIFY_NEVER</source>
+        <translation>Never</translation>
+    </message>
+    <message>
+        <source>PREF_NOTIFY_ERROR</source>
+        <translation>Errors only</translation>
+    </message>
+    <message>
+        <source>PREF_NOTIFY_ALWAYS</source>
+        <translation>Always</translation>
+    </message>
+    <message>
+        <source>PREF_ELEM_INFO</source>
+        <translation>Mesh element information</translation>
+    </message>
+    <message>
+        <source>PREF_ELEM_INFO_SIMPLE</source>
+        <translation>Simple</translation>
+    </message>
+    <message>
+        <source>PREF_ELEM_INFO_TREE</source>
+        <translation>Tree</translation>
+    </message>
     <message>
         <source>SMESH_PREF_GROUP_PRECISION</source>
         <translation>Input fields precision</translation>
@@ -3361,7 +3553,11 @@ Please, create VTK viewer and try again</translation>
         <translation>Selection</translation>
     </message>
     <message>
-        <source>PREF_HIGHLIGHT_COLOR</source>
+        <source>PREF_GROUP_INFO</source>
+        <translation>Mesh information</translation>
+    </message>
+    <message>
+      <source>PREF_HIGHLIGHT_COLOR</source>
         <translation>Highlight color</translation>
     </message>
     <message>
@@ -4221,6 +4417,14 @@ Please enter correct value and try again</translation>
         <source>LYING_ON_GEOM</source>
         <translation>Lying on Geom</translation>
     </message>
+    <message>
+        <source>MAX_ELEMENT_LENGTH_2D</source>
+        <translation>Max Element Length 2D</translation>
+    </message>
+    <message>
+        <source>MAX_ELEMENT_LENGTH_3D</source>
+        <translation>Max Element Length 3D</translation>
+    </message>
     <message>
         <source>MINIMUM_ANGLE</source>
         <translation>Minimum angle</translation>
@@ -5169,6 +5373,14 @@ It is impossible to read point coordinates from file</translation>
         <source>CLIP_PLANES</source>
         <translation>Clipping planes</translation>
     </message>
+    <message>
+        <source>MESHES_SUBMESHES_GROUPS</source>
+        <translation>Meshes, sub-meshes and groups</translation>
+    </message>
+    <message>
+        <source>SELECT_ALL</source>
+        <translation>Select all</translation>
+    </message>
     <message>
         <source>ROTATION_AROUND_X_Y2Z</source>
         <translation>Rotation around X (Y to Z):</translation>
@@ -5339,4 +5551,346 @@ It is impossible to read point coordinates from file</translation>
         <translation>Group name is not specified</translation>
     </message>
 </context>
+<context>
+    <name>SMESHGUI_MeshInfo</name>
+    <message>
+        <source>NAME_LAB</source>
+        <translation>Name:</translation>
+    </message>
+    <message>
+        <source>OBJECT_LAB</source>
+        <translation>Object:</translation>
+    </message>
+    <message>
+        <source>NODES_LAB</source>
+        <translation>Nodes:</translation>
+    </message>
+    <message>
+        <source>ELEMENTS_LAB</source>
+        <translation>Elements:</translation>
+    </message>
+    <message>
+        <source>TOTAL_LAB</source>
+        <translation>Total</translation>
+    </message>
+    <message>
+        <source>LINEAR_LAB</source>
+        <translation>Linear</translation>
+    </message>
+    <message>
+        <source>QUADRATIC_LAB</source>
+        <translation>Quadratic</translation>
+    </message>
+    <message>
+        <source>0D_LAB</source>
+        <translation>0D:</translation>
+    </message>
+    <message>
+        <source>1D_LAB</source>
+        <translation>1D (edges):</translation>
+    </message>
+    <message>
+        <source>2D_LAB</source>
+        <translation>2D (faces):</translation>
+    </message>
+    <message>
+        <source>TRIANGLES_LAB</source>
+        <translation>Triangles:</translation>
+    </message>
+    <message>
+        <source>QUADRANGLES_LAB</source>
+        <translation>Quadrandgles:</translation>
+    </message>
+    <message>
+        <source>POLYGONS_LAB</source>
+        <translation>Polygons:</translation>
+    </message>
+    <message>
+        <source>3D_LAB</source>
+        <translation>3D (volumes):</translation>
+    </message>
+    <message>
+        <source>TETRAHEDRONS_LAB</source>
+        <translation>Tetrahedrons:</translation>
+    </message>
+    <message>
+        <source>HEXAHEDONRS_LAB</source>
+        <translation>Hexahedrons:</translation>
+    </message>
+    <message>
+        <source>PYRAMIDS_LAB</source>
+        <translation>Pyramids:</translation>
+    </message>
+    <message>
+        <source>PRISMS_LAB</source>
+        <translation>Prisms:</translation>
+    </message>
+    <message>
+        <source>POLYHEDRONS_LAB</source>
+        <translation>Polyhedrons:</translation>
+    </message>
+    <message>
+        <source>OBJECT_MESH</source>
+        <translation>Mesh</translation>
+    </message>
+    <message>
+        <source>OBJECT_SUBMESH</source>
+        <translation>Sub-mesh</translation>
+    </message>
+    <message>
+        <source>OBJECT_GROUP</source>
+        <translation>Group</translation>
+    </message>
+    <message>
+        <source>OBJECT_GROUP_NODES</source>
+        <translation>Group of nodes</translation>
+    </message>
+    <message>
+        <source>OBJECT_GROUP_EDGES</source>
+        <translation>Group of edges</translation>
+    </message>
+    <message>
+        <source>OBJECT_GROUP_FACES</source>
+        <translation>Group of faces</translation>
+    </message>
+    <message>
+        <source>OBJECT_GROUP_VOLUMES</source>
+        <translation>Group of volumes</translation>
+    </message>
+    <message>
+        <source>OBJECT_GROUP_0DELEMS</source>
+        <translation>Group of 0D elements</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_MeshInfoDlg</name>
+    <message>
+        <source>MESH_INFO</source>
+        <translation>Mesh Information</translation>
+    </message>
+    <message>
+        <source>BASE_INFO</source>
+        <translation>Base Info</translation>
+    </message>
+    <message>
+        <source>ELEM_INFO</source>
+        <translation>Element Info</translation>
+    </message>
+    <message>
+        <source>NODE_MODE</source>
+        <translation>Node</translation>
+    </message>
+    <message>
+        <source>ELEM_MODE</source>
+        <translation>Element</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_ElemInfo</name>
+    <message>
+        <source>COORDINATES</source>
+        <translation>COORDINATES</translation>
+    </message>
+    <message>
+        <source>CONNECTIVITY</source>
+        <translation>CONNECTIVITY</translation>
+    </message>
+    <message>
+        <source>GRAVITY_CENTER</source>
+        <translation>GRAVITY CENTER</translation>
+    </message>
+    <message>
+        <source>NODE</source>
+        <translation>NODE</translation>
+    </message>
+    <message>
+        <source>0D_ELEMENT</source>
+        <translation>0D ELEMENT</translation>
+    </message>
+    <message>
+        <source>0D_ELEMENTS</source>
+        <translation>0D ELEMENTS</translation>
+    </message>
+    <message>
+        <source>EDGE</source>
+        <translation>EDGE</translation>
+    </message>
+    <message>
+        <source>EDGES</source>
+        <translation>EDGES</translation>
+    </message>
+    <message>
+        <source>FACE</source>
+        <translation>FACE</translation>
+    </message>
+    <message>
+        <source>FACES</source>
+        <translation>FACES</translation>
+    </message>
+    <message>
+        <source>VOLUME</source>
+        <translation>VOLUME</translation>
+    </message>
+    <message>
+        <source>VOLUMES</source>
+        <translation>VOLUMES</translation>
+    </message>
+    <message>
+        <source>FREE_NODE</source>
+        <translation>Free node (no connectivity)</translation>
+    </message>
+    <message>
+        <source>TYPE</source>
+        <translation>TYPE</translation>
+    </message>
+    <message>
+        <source>TRIANGLE</source>
+        <translation>Triangle</translation>
+    </message>
+    <message>
+        <source>QUADRANGLE</source>
+        <translation>Quadrangle</translation>
+    </message>
+    <message>
+        <source>POLYGON</source>
+        <translation>Polygon</translation>
+    </message>
+    <message>
+        <source>TETRAHEDRON</source>
+        <translation>Tetrahedron</translation>
+    </message>
+    <message>
+        <source>HEXAHEDRON</source>
+        <translation>Hexahedron</translation>
+    </message>
+    <message>
+        <source>PYRAMID</source>
+        <translation>Pyramid</translation>
+    </message>
+    <message>
+        <source>PRISM</source>
+        <translation>Prism</translation>
+    </message>
+    <message>
+        <source>POLYHEDRON</source>
+        <translation>Polyhedron</translation>
+    </message>
+    <message>
+        <source>QUADRATIC</source>
+        <translation>QUADRATIC</translation>
+    </message>
+    <message>
+        <source>YES</source>
+        <translation>Yes</translation>
+    </message>
+    <message>
+        <source>NO</source>
+        <translation>No</translation>
+    </message>
+    <message>
+        <source>GRAVITY_CENTER</source>
+        <translation>GRAVITY CENTER</translation>
+    </message>
+    <message>
+        <source>PROPERTY</source>
+        <translation>Property</translation>
+    </message>
+    <message>
+        <source>VALUE</source>
+        <translation>Value</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_MinDistance</name>
+    <message>
+        <source>FIRST_TARGET</source>
+        <translation>First target</translation>
+    </message>
+    <message>
+        <source>SECOND_TARGET</source>
+        <translation>Second target</translation>
+    </message>
+    <message>
+        <source>NODE</source>
+        <translation>Node</translation>
+    </message>
+    <message>
+        <source>ELEMENT</source>
+        <translation>Element</translation>
+    </message>
+    <message>
+        <source>OBJECT</source>
+        <translation>Object</translation>
+    </message>
+    <message>
+        <source>ORIGIN</source>
+        <translation>Origin</translation>
+    </message>
+    <message>
+        <source>COMPUTE</source>
+        <translation>Compute</translation>
+    </message>
+    <message>
+        <source>RESULT</source>
+        <translation>Distance between targets</translation>
+    </message>
+    <message>
+        <source>DISTANCE</source>
+        <translation>Distance</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_MeasureDlg</name>
+    <message>
+        <source>MEASUREMENTS</source>
+        <translation>Measurements</translation>
+    </message>
+    <message>
+        <source>MIN_DIST</source>
+        <translation>Minimum Distance</translation>
+    </message>
+    <message>
+        <source>BND_BOX</source>
+        <translation>Bounding Box</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_BoundingBox</name>
+    <message>
+        <source>SOURCE</source>
+        <translation>Source</translation>
+    </message>
+    <message>
+        <source>OBJECTS</source>
+        <translation>Objects</translation>
+    </message>
+    <message>
+        <source>NODES</source>
+        <translation>Nodes</translation>
+    </message>
+    <message>
+        <source>ELEMENTS</source>
+        <translation>Elements</translation>
+    </message>
+    <message>
+        <source>COMPUTE</source>
+        <translation>Compute</translation>
+    </message>
+    <message>
+        <source>RESULT</source>
+        <translation>Bounding Box</translation>
+    </message>
+    <message>
+        <source>SELECTED_NB_OBJ</source>
+        <translation>%1 %2 selected</translation>
+    </message>
+    <message>
+        <source>NB_NODES</source>
+        <translation>nodes</translation>
+    </message>
+    <message>
+        <source>NB_ELEMENTS</source>
+        <translation>elements</translation>
+    </message>
+</context>
 </TS>
index 9a2a3c6a4b9dfabb169ec30a6f1335a28afca9ec..53f2855287fc93c18661d779da406f69fe69eb58 100644 (file)
@@ -46,6 +46,7 @@ salomeinclude_HEADERS = \
        SMESH_Pattern_i.hxx \
        SMESH_2smeshpy.hxx \
        SMESH_NoteBook.hxx \
+       SMESH_Measurements_i.hxx \
        SMESH.hxx
 
 # Scripts to be installed.
@@ -76,7 +77,8 @@ dist_libSMESHEngine_la_SOURCES = \
        SMESH_Group_i.cxx \
        SMESH_Pattern_i.cxx \
        SMESH_2smeshpy.cxx \
-       SMESH_NoteBook.cxx 
+       SMESH_NoteBook.cxx \
+       SMESH_Measurements_i.cxx
 
 # Executables targets
 bin_PROGRAMS = SMESHEngine
index 1f4a1de143548ed7f9ac5316b699725feb59cd8b..dfb378f245374942c3cbcde707e2a473220d9af9 100644 (file)
@@ -342,6 +342,7 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand )
   // Concatenate( [mesh1, ...], ... )
   // CreateHypothesis( theHypType, theLibName )
   // Compute( mesh, geom )
+  // Evaluate( mesh, geom )
   // mesh creation
   TCollection_AsciiString method = theCommand->GetMethod();
 
@@ -395,6 +396,20 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand )
     }
   }
 
+  // smeshgen.Evaluate( mesh, geom ) --> mesh.Evaluate(geom)
+  if ( method == "Evaluate" )
+  {
+    const _pyID& meshID = theCommand->GetArg( 1 );
+    map< _pyID, Handle(_pyMesh) >::iterator id_mesh = myMeshes.find( meshID );
+    if ( id_mesh != myMeshes.end() ) {
+      theCommand->SetObject( meshID );
+      _pyID geom = theCommand->GetArg( 2 );
+      theCommand->RemoveArgs();
+      theCommand->SetArg( 1, geom );
+      return;
+    }
+  }
+
   // objects erasing creation command if no more it's commands invoked:
   // SMESH_Pattern, FilterManager
   if ( method == "GetPattern" || method == "CreateFilterManager" ) {
index 4bc9f1aa21b83508a9877ff3048e81a59e56d891..3fd8ff22f55a148a5f5850cee01970b20d3f9c9d 100644 (file)
@@ -274,6 +274,8 @@ namespace SMESH
       case FT_Skew:             myStream<< "aSkew";             break;
       case FT_Area:             myStream<< "aArea";             break;
       case FT_Volume3D:         myStream<< "aVolume3D";         break;
+      case FT_MaxElementLength2D:myStream<< "aMaxElementLength2D";break;
+      case FT_MaxElementLength3D:myStream<< "aMaxElementLength3D";break;
       case FT_FreeBorders:      myStream<< "aFreeBorders";      break;
       case FT_FreeEdges:        myStream<< "aFreeEdges";        break;
       case FT_FreeNodes:        myStream<< "aFreeNodes";        break;
@@ -307,6 +309,15 @@ namespace SMESH
     return *this;
   }
 
+  TPythonDump& 
+  TPythonDump::
+  operator<<(SMESH::Measurements_i* theArg)
+  {
+    myStream<<"aMeasurements";
+    return *this;
+  }
+
+
   TPythonDump& TPythonDump:: operator<<(SMESH_Gen_i* theArg)
   {
     myStream << SMESHGenName(); return *this;
@@ -684,6 +695,7 @@ TCollection_AsciiString SMESH_Gen_i::DumpPython_impl
   TCollection_AsciiString aScript;
   aScript = "def RebuildData(theStudy):\n\t";
   aScript += helper + "aFilterManager = " + aSMESHGen + ".CreateFilterManager()\n\t";
+  aScript += helper + "aMeasurements = " + aSMESHGen + ".CreateMeasurements()\n\t";
   if ( isPublished )
     aScript += aSMESHGen + ".SetCurrentStudy(theStudy)";
   else
index 477e92a1372ef2bb9bc50ff6c7b4c4ed0234331b..d2a7ae648d7b2510cbef06115cb41d1a3276743c 100644 (file)
@@ -596,6 +596,28 @@ CORBA::Double NumericalFunctor_i::GetValue( CORBA::Long theId )
   return myNumericalFunctorPtr->GetValue( theId );
 }
 
+SMESH::Histogram* NumericalFunctor_i::GetHistogram(CORBA::Short nbIntervals)
+{
+  std::vector<int> nbEvents;
+  std::vector<double> funValues;
+  myNumericalFunctorPtr->GetHistogram(nbIntervals,nbEvents,funValues);
+
+  nbIntervals = CORBA::Short( std::min( nbEvents.size(), funValues.size() - 1));
+  SMESH::Histogram_var histogram = new SMESH::Histogram;
+  if ( nbIntervals > 0 )
+  {
+    histogram->length( nbIntervals );
+    for ( int i = 0; i < nbIntervals; ++i )
+    {
+      HistogramRectangle& rect = histogram[i];
+      rect.nbEvents = nbEvents[i];
+      rect.min = funValues[i];
+      rect.max = funValues[i+1];
+    }
+  }
+  return histogram._retn();
+}
+
 void NumericalFunctor_i::SetPrecision( CORBA::Long thePrecision )
 {
   myNumericalFunctorPtr->SetPrecision( thePrecision );
@@ -738,6 +760,36 @@ FunctorType Volume3D_i::GetFunctorType()
   return SMESH::FT_Volume3D;
 }
 
+/*
+  Class       : MaxElementLength2D_i
+  Description : Functor for calculating maximum length of 2D element
+*/
+MaxElementLength2D_i::MaxElementLength2D_i()
+{
+  myNumericalFunctorPtr.reset( new Controls::MaxElementLength2D() );
+  myFunctorPtr = myNumericalFunctorPtr;
+}
+
+FunctorType MaxElementLength2D_i::GetFunctorType()
+{
+  return SMESH::FT_MaxElementLength2D;
+}
+
+/*
+  Class       : MaxElementLength3D_i
+  Description : Functor for calculating maximum length of 3D element
+*/
+MaxElementLength3D_i::MaxElementLength3D_i()
+{
+  myNumericalFunctorPtr.reset( new Controls::MaxElementLength3D() );
+  myFunctorPtr = myNumericalFunctorPtr;
+}
+
+FunctorType MaxElementLength3D_i::GetFunctorType()
+{
+  return SMESH::FT_MaxElementLength3D;
+}
+
 /*
   Class       : Length_i
   Description : Functor for calculating length off edge
@@ -1838,6 +1890,24 @@ Volume3D_ptr FilterManager_i::CreateVolume3D()
 }
 
 
+MaxElementLength2D_ptr FilterManager_i::CreateMaxElementLength2D()
+{
+  SMESH::MaxElementLength2D_i* aServant = new SMESH::MaxElementLength2D_i();
+  SMESH::MaxElementLength2D_var anObj = aServant->_this();
+  TPythonDump()<<aServant<<" = "<<this<<".CreateMaxElementLength2D()";
+  return anObj._retn();
+}
+
+
+MaxElementLength3D_ptr FilterManager_i::CreateMaxElementLength3D()
+{
+  SMESH::MaxElementLength3D_i* aServant = new SMESH::MaxElementLength3D_i();
+  SMESH::MaxElementLength3D_var anObj = aServant->_this();
+  TPythonDump()<<aServant<<" = "<<this<<".CreateMaxElementLength3D()";
+  return anObj._retn();
+}
+
+
 Length_ptr FilterManager_i::CreateLength()
 {
   SMESH::Length_i* aServant = new SMESH::Length_i();
@@ -2274,6 +2344,16 @@ SMESH::array_of_ElementType* Filter_i::GetTypes()
   return types._retn();
 }
 
+//=======================================================================
+//function : GetMesh
+//purpose  : Returns mesh
+//=======================================================================
+
+SMESH::SMESH_Mesh_ptr Filter_i::GetMesh()
+{
+  return SMESH_Mesh::_duplicate( myMesh );
+}
+
 //=======================================================================
 // name    : getCriteria
 // Purpose : Retrieve criterions from predicate
@@ -2573,6 +2653,12 @@ CORBA::Boolean Filter_i::SetCriteria( const SMESH::Filter::Criteria& theCriteria
       case SMESH::FT_Volume3D:
         aFunctor = aFilterMgr->CreateVolume3D();
         break;
+      case SMESH::FT_MaxElementLength2D:
+        aFunctor = aFilterMgr->CreateMaxElementLength2D();
+        break;
+      case SMESH::FT_MaxElementLength3D:
+        aFunctor = aFilterMgr->CreateMaxElementLength3D();
+        break;
 
       // Predicates
 
@@ -2870,6 +2956,8 @@ static inline LDOMString toString( CORBA::Long theType )
     case FT_Skew            : return "Skew";
     case FT_Area            : return "Area";
     case FT_Volume3D        : return "Volume3D";
+    case FT_MaxElementLength2D: return "Max element length 2D";
+    case FT_MaxElementLength3D: return "Max element length 3D";
     case FT_BelongToGeom    : return "Belong to Geom";
     case FT_BelongToPlane   : return "Belong to Plane";
     case FT_BelongToCylinder: return "Belong to Cylinder";
@@ -2912,6 +3000,8 @@ static inline SMESH::FunctorType toFunctorType( const LDOMString& theStr )
   else if ( theStr.equals( "Skew"                         ) ) return FT_Skew;
   else if ( theStr.equals( "Area"                         ) ) return FT_Area;
   else if ( theStr.equals( "Volume3D"                     ) ) return FT_Volume3D;
+  else if ( theStr.equals( "Max element length 2D"        ) ) return FT_MaxElementLength2D;
+  else if ( theStr.equals( "Max element length 3D"        ) ) return FT_MaxElementLength3D;
   else if ( theStr.equals( "Belong to Geom"               ) ) return FT_BelongToGeom;
   else if ( theStr.equals( "Belong to Plane"              ) ) return FT_BelongToPlane;
   else if ( theStr.equals( "Belong to Cylinder"           ) ) return FT_BelongToCylinder;
index aefc71ef621b5ae1ef4e530b95b1714263274be1..bef8c2252bbcd31da25d2639f6c3d6cc35ae83f4 100644 (file)
@@ -157,6 +157,7 @@ namespace SMESH
   {
   public:
     CORBA::Double                   GetValue( CORBA::Long theElementId );
+    SMESH::Histogram*               GetHistogram(CORBA::Short nbIntervals);
     void                            SetPrecision( CORBA::Long thePrecision );
     CORBA::Long                     GetPrecision();
     Controls::NumericalFunctorPtr   GetNumericalFunctor();
@@ -270,6 +271,32 @@ namespace SMESH
   };
   
   
+  /*
+    Class       : MaxElementLength2D_i
+    Description : Functor for calculating maximum length of 2D element
+  */
+  class SMESH_I_EXPORT MaxElementLength2D_i: public virtual POA_SMESH::MaxElementLength2D,
+                                             public virtual NumericalFunctor_i
+  {
+  public:
+    MaxElementLength2D_i();
+    FunctorType                     GetFunctorType();
+  };
+  
+  
+  /*
+    Class       : MaxElementLength3D_i
+    Description : Functor for calculating maximum length of 3D element
+  */
+  class SMESH_I_EXPORT MaxElementLength3D_i: public virtual POA_SMESH::MaxElementLength3D,
+                                             public virtual NumericalFunctor_i
+  {
+  public:
+    MaxElementLength3D_i();
+    FunctorType                     GetFunctorType();
+  };
+  
+  
   /*
     Class       : Length_i
     Description : Functor for calculating length of edge
@@ -802,18 +829,6 @@ namespace SMESH
     void
     SetMesh( SMESH_Mesh_ptr );
 
-    virtual
-    SMESH::long_array* 
-    GetIDs();
-    
-    virtual
-    SMESH::long_array*
-    GetMeshInfo();
-
-    virtual
-    SMESH::array_of_ElementType*
-    GetTypes();
-
     static
     void
     GetElementsId( Predicate_i*,
@@ -847,6 +862,14 @@ namespace SMESH
 
     Predicate_i*     GetPredicate_i();
 
+    // =========================
+    // SMESH_IDSource interface
+    // =========================
+    virtual SMESH::long_array*           GetIDs();
+    virtual SMESH::long_array*           GetMeshInfo();
+    virtual SMESH::array_of_ElementType* GetTypes();
+    virtual SMESH::SMESH_Mesh_ptr        GetMesh();
+
   private:
     Controls::Filter myFilter;
     Predicate_i*     myPredicate;
@@ -910,6 +933,8 @@ namespace SMESH
     Skew_ptr                  CreateSkew();
     Area_ptr                  CreateArea();
     Volume3D_ptr              CreateVolume3D();
+    MaxElementLength2D_ptr    CreateMaxElementLength2D();
+    MaxElementLength3D_ptr    CreateMaxElementLength3D();
     Length_ptr                CreateLength();
     Length2D_ptr              CreateLength2D();
     MultiConnection_ptr       CreateMultiConnection();
index 08ce77e368ad2765934599304aa5c5ef888df523..a0ce885aa9b82da691eb9324039d8106acf82db3 100644 (file)
@@ -932,7 +932,6 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char* theFileName,
   // Python Dump
   TPythonDump aPythonDump;
   aPythonDump << "([";
-  //TCollection_AsciiString aStr ("([");
 
   if (theStatus == SMESH::DRS_OK) {
     SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder();
@@ -943,7 +942,6 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char* theFileName,
     // Iterate through all meshes and create mesh objects
     for ( list<string>::iterator it = aNames.begin(); it != aNames.end(); it++ ) {
       // Python Dump
-      //if (i > 0) aStr += ", ";
       if (i > 0) aPythonDump << ", ";
 
       // create mesh
@@ -956,12 +954,9 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char* theFileName,
       if ( !aSO->_is_nil() ) {
         // Python Dump
         aPythonDump << aSO;
-        //aStr += aSO->GetID();
       } else {
         // Python Dump
         aPythonDump << "mesh_" << i;
-//         aStr += "mesh_";
-//         aStr += TCollection_AsciiString(i);
       }
 
       // Read mesh data (groups are published automatically by ImportMEDFile())
@@ -1431,7 +1426,9 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh,
         myLocShape = SMESH_Mesh::PseudoShape();
       // call implementation compute
       ::SMESH_Mesh& myLocMesh = meshServant->GetImpl();
-      return myGen.Compute( myLocMesh, myLocShape);
+      bool ok = myGen.Compute( myLocMesh, myLocShape);
+      meshServant->CreateGroupServants(); // algos can create groups (issue 0020918)
+      return ok;
     }
   }
   catch ( std::bad_alloc ) {
@@ -2323,6 +2320,38 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
   DriverMED_W_SMESHDS_Mesh myWriter;
   myWriter.SetFile( meshfile.ToCString() );
 
+  // IMP issue 20918
+  // SetStoreName() to groups before storing hypotheses to let them refer to
+  // groups using "store name", which is "Group <group_persistent_id>"
+  {
+    SALOMEDS::ChildIterator_var itBig = myCurrentStudy->NewChildIterator( theComponent );
+    for ( ; itBig->More(); itBig->Next() ) {
+      SALOMEDS::SObject_var gotBranch = itBig->Value();
+      if ( gotBranch->Tag() > GetAlgorithmsRootTag() ) {
+        CORBA::Object_var anObject = SObjectToObject( gotBranch );
+        if ( !CORBA::is_nil( anObject ) ) {
+          SMESH::SMESH_Mesh_var myMesh = SMESH::SMESH_Mesh::_narrow( anObject ) ;
+          if ( !myMesh->_is_nil() ) {
+            SMESH::ListOfGroups_var groups = myMesh->GetGroups();
+            for ( int i = 0; i < groups->length(); ++i )
+            {
+              SMESH_GroupBase_i* grImpl = SMESH::DownCast<SMESH_GroupBase_i*>( groups[i]);
+              if ( grImpl )
+              {
+                CORBA::String_var objStr = GetORB()->object_to_string( grImpl->_this() );
+                int anId = myStudyContext->findId( string( objStr.in() ) );
+                char grpName[ 30 ];
+                sprintf( grpName, "Group %d", anId );
+                SMESHDS_GroupBase* aGrpBaseDS = grImpl->GetGroupDS();
+                aGrpBaseDS->SetStoreName( grpName );
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+
   // Write data
   // ---> create HDF file
   aFile = new HDFfile( (char*) filename.ToCString() );
@@ -2519,13 +2548,21 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
             aDataset->CloseOnDisk();
 
             // issue 0020693. Store _isModified flag
-            int isModified = myImpl->GetImpl().GetIsModified();
+            int isModified = myLocMesh.GetIsModified();
             aSize[ 0 ] = 1;
             aDataset = new HDFdataset( "_isModified", aTopGroup, HDF_INT32, aSize, 1 );
             aDataset->CreateOnDisk();
             aDataset->WriteOnDisk( &isModified );
             aDataset->CloseOnDisk();
 
+            // issue 20918. Store Persistent Id of SMESHDS_Mesh
+            int meshPersistentId = mySMESHDSMesh->GetPersistentId();
+            aSize[ 0 ] = 1;
+            aDataset = new HDFdataset( "meshPersistentId", aTopGroup, HDF_INT32, aSize, 1 );
+            aDataset->CreateOnDisk();
+            aDataset->WriteOnDisk( &meshPersistentId );
+            aDataset->CloseOnDisk();
+
             // write reference on a shape if exists
             SALOMEDS::SObject_var myRef;
             bool shapeRefFound = false;
@@ -2869,17 +2906,19 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
                       dynamic_cast<SMESH_GroupBase_i*>( GetServant( aSubObject ).in() );
                     if ( !myGroupImpl )
                       continue;
+                    SMESHDS_GroupBase* aGrpBaseDS = myGroupImpl->GetGroupDS();
+                    if ( !aGrpBaseDS )
+                      continue;
                     
                     CORBA::String_var objStr = GetORB()->object_to_string( aSubObject );
                     int anId = myStudyContext->findId( string( objStr.in() ) );
-                    
+
                     // For each group, create a dataset named "Group <group_persistent_id>"
                     // and store the group's user name into it
-                    char grpName[ 30 ];
-                    sprintf( grpName, "Group %d", anId );
+                    const char* grpName = aGrpBaseDS->GetStoreName();
                     char* aUserName = myGroupImpl->GetName();
                     aSize[ 0 ] = strlen( aUserName ) + 1;
-                    
+
                     aDataset = new HDFdataset( grpName, aGroup, HDF_STRING, aSize, 1 );
                     aDataset->CreateOnDisk();
                     aDataset->WriteOnDisk( aUserName );
@@ -2901,46 +2940,36 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
                     aDataset->WriteOnDisk( anRGB );
                     aDataset->CloseOnDisk();
 
-                    // Store the group contents into MED file
-                    if ( myLocMesh.GetGroup( myGroupImpl->GetLocalID() ) ) {
-                      
-                      if(MYDEBUG) MESSAGE( "VSR - SMESH_Gen_i::Save(): saving group with StoreName = "
-                                          << grpName << " to MED file" );
-                      SMESHDS_GroupBase* aGrpBaseDS =
-                        myLocMesh.GetGroup( myGroupImpl->GetLocalID() )->GetGroupDS();
-                      aGrpBaseDS->SetStoreName( grpName );
-
-                      // Pass SMESHDS_Group to MED writer 
-                      SMESHDS_Group* aGrpDS = dynamic_cast<SMESHDS_Group*>( aGrpBaseDS );
-                      if ( aGrpDS )
-                        myWriter.AddGroup( aGrpDS );
-                      
-                      // write reference on a shape if exists
-                      SMESHDS_GroupOnGeom* aGeomGrp =
-                        dynamic_cast<SMESHDS_GroupOnGeom*>( aGrpBaseDS );
-                      if ( aGeomGrp ) {
-                        SALOMEDS::SObject_var mySubRef, myShape;
-                        if (mySObject->FindSubObject( GetRefOnShapeTag(), mySubRef ) &&
-                            mySubRef->ReferencedObject( myShape ) &&
-                            !CORBA::is_nil( myShape->GetObject() ))
-                        {
-                          string myRefOnObject = myShape->GetID();
-                          if ( myRefOnObject.length() > 0 ) {
-                            char aRefName[ 30 ];
-                            sprintf( aRefName, "Ref on shape %d", anId);
-                            aSize[ 0 ] = myRefOnObject.length() + 1;
-                            aDataset = new HDFdataset(aRefName, aGroup, HDF_STRING, aSize, 1);
-                            aDataset->CreateOnDisk();
-                            aDataset->WriteOnDisk( ( char* )( myRefOnObject.c_str() ) );
-                            aDataset->CloseOnDisk();
-                          }
-                        }
-                        else // shape ref is invalid:
-                        {
-                          // save a group on geometry as ordinary group
-                          myWriter.AddGroup( aGeomGrp );
+                    // Pass SMESHDS_Group to MED writer 
+                    SMESHDS_Group* aGrpDS = dynamic_cast<SMESHDS_Group*>( aGrpBaseDS );
+                    if ( aGrpDS )
+                      myWriter.AddGroup( aGrpDS );
+
+                    // write reference on a shape if exists
+                    SMESHDS_GroupOnGeom* aGeomGrp =
+                      dynamic_cast<SMESHDS_GroupOnGeom*>( aGrpBaseDS );
+                    if ( aGeomGrp ) {
+                      SALOMEDS::SObject_var mySubRef, myShape;
+                      if (mySObject->FindSubObject( GetRefOnShapeTag(), mySubRef ) &&
+                          mySubRef->ReferencedObject( myShape ) &&
+                          !CORBA::is_nil( myShape->GetObject() ))
+                      {
+                        string myRefOnObject = myShape->GetID();
+                        if ( myRefOnObject.length() > 0 ) {
+                          char aRefName[ 30 ];
+                          sprintf( aRefName, "Ref on shape %d", anId);
+                          aSize[ 0 ] = myRefOnObject.length() + 1;
+                          aDataset = new HDFdataset(aRefName, aGroup, HDF_STRING, aSize, 1);
+                          aDataset->CreateOnDisk();
+                          aDataset->WriteOnDisk( ( char* )( myRefOnObject.c_str() ) );
+                          aDataset->CloseOnDisk();
                         }
                       }
+                      else // shape ref is invalid:
+                      {
+                        // save a group on geometry as ordinary group
+                        myWriter.AddGroup( aGeomGrp );
+                      }
                     }
                   }
                 }
@@ -3630,6 +3659,18 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
             aDataset->CloseOnDisk();
             myNewMeshImpl->GetImpl().SetIsModified( bool(*isModified));
           }
+
+          // issue 20918. Restore Persistent Id of SMESHDS_Mesh
+          if( aTopGroup->ExistInternalObject( "meshPersistentId" ) )
+          {
+            aDataset = new HDFdataset( "meshPersistentId", aTopGroup );
+            aDataset->OpenOnDisk();
+            size = aDataset->GetSize();
+            int* meshPersistentId = new int[ size ];
+            aDataset->ReadFromDisk( meshPersistentId );
+            aDataset->CloseOnDisk();
+            myNewMeshImpl->GetImpl().GetMeshDS()->SetPersistentId( *meshPersistentId );
+          }
         }
       }
     }
@@ -3944,7 +3985,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
           aGroup = new HDFgroup( "Submeshes", aTopGroup ); 
           aGroup->OpenOnDisk();
 
-          int maxID = mySMESHDSMesh->MaxShapeIndex();
+          int maxID = Max( mySMESHDSMesh->MaxSubMeshIndex(), mySMESHDSMesh->MaxShapeIndex() );
           vector< SMESHDS_SubMesh * > subMeshes( maxID + 1, (SMESHDS_SubMesh*) 0 );
           vector< TopAbs_ShapeEnum  > smType   ( maxID + 1, TopAbs_SHAPE ); 
 
@@ -4132,20 +4173,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
         } // if ( aTopGroup->ExistInternalObject( "Node Positions" ) )
       } // if ( hasData )
 
-      // Recompute State (as computed sub-meshes are restored from MED)
-      if ( !aShapeObject->_is_nil() || !myNewMeshImpl->HasShapeToMesh()) {
-        MESSAGE("Compute State Engine ...");
-        TopoDS_Shape myLocShape;
-        if(myNewMeshImpl->HasShapeToMesh())
-          myLocShape = GeomObjectToShape( aShapeObject );
-        else
-          myLocShape = SMESH_Mesh::PseudoShape();
-        
-        myNewMeshImpl->GetImpl().GetSubMesh(myLocShape)->ComputeStateEngine
-          (SMESH_subMesh::SUBMESH_RESTORED);
-        MESSAGE("Compute State Engine finished");
-      }
-
       // try to get groups
       for ( int ii = GetNodeGroupsTag(); ii <= GetVolumeGroupsTag(); ii++ ) {
         char name_group[ 30 ];
@@ -4252,6 +4279,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
           aGroup->CloseOnDisk();
         }
       }
+
       // read submeh order if any
       if( aTopGroup->ExistInternalObject( "Mesh Order" ) ) {
         aDataset = new HDFdataset( "Mesh Order", aTopGroup );
@@ -4270,7 +4298,30 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
         
         myNewMeshImpl->GetImpl().SetMeshOrder( anOrderIds );
       }
+    } // loop on meshes
+
+    // notify algos on completed restoration
+    for ( meshi_group = meshGroupList.begin(); meshi_group != meshGroupList.end(); ++meshi_group )
+    {
+      SMESH_Mesh_i* myNewMeshImpl = meshi_group->first;
+      ::SMESH_Mesh& myLocMesh     = myNewMeshImpl->GetImpl();
+
+      TopoDS_Shape myLocShape;
+      if(myLocMesh.HasShapeToMesh())
+        myLocShape = myLocMesh.GetShapeToMesh();
+      else
+        myLocShape = SMESH_Mesh::PseudoShape();
+        
+      myLocMesh.GetSubMesh(myLocShape)->
+        ComputeStateEngine (SMESH_subMesh::SUBMESH_RESTORED);
     }
+
+    for ( hyp_data = hypDataList.begin(); hyp_data != hypDataList.end(); ++hyp_data )
+    {
+      SMESH_Hypothesis_i* hyp  = hyp_data->first;
+      hyp->UpdateAsMeshesRestored(); // for hyps needing full mesh data restored (issue 20918)
+    }
+
     // close mesh group
     if(aTopGroup)
       aTopGroup->CloseOnDisk();   
index 89cf79ca77690e5fc39133f8387eebee1f3a491e..b2c90805c642e4b8d65fdaa6413da1fb1e06ad2e 100644 (file)
@@ -223,7 +223,7 @@ public:
   SMESH::SMESH_Mesh_ptr CreateEmptyMesh()
     throw ( SALOME::SALOME_Exception );
 
-  //  Create mesh(es) and import data from UNV file
+  //  Create mesh(es) and import data from UNV fileter
   SMESH::SMESH_Mesh_ptr CreateMeshesFromUNV( const char* theFileName )
     throw ( SALOME::SALOME_Exception );
 
@@ -357,6 +357,9 @@ public:
   // Return a pattern mesher
   SMESH::SMESH_Pattern_ptr GetPattern();
 
+  // Create measurement instance
+  SMESH::Measurements_ptr  CreateMeasurements();
+
   // Clears study-connected data when it is closed
   void Close( SALOMEDS::SComponent_ptr theComponent );
   
index 19d436ff6128affb3e8641e2f6ed80c48a56353b..8875e4d1f968d176a9abe6cfdf336cab4411fadb 100644 (file)
@@ -279,4 +279,17 @@ void SMESH_Hypothesis_i::LoadFrom( const char* theStream )
   MESSAGE( "SMESH_Hypothesis_i::LoadFrom" );
   std::istringstream is( theStream );
   myBaseImpl->LoadFrom( is );
+  // let listeners know about loading (issue 0020918)
+  myBaseImpl->NotifySubMeshesHypothesisModification();
+}
+
+//================================================================================
+/*!
+ * \brief This mesthod is called after completion of loading a study 
+ */
+//================================================================================
+
+void SMESH_Hypothesis_i::UpdateAsMeshesRestored()
+{
+  // for hyps needing full data restored
 }
index 24c01d46a8c241951db83dd0685bd290c9feeada..99eba89ca6544814dd98d0129321cadc0181cec5 100644 (file)
@@ -91,7 +91,8 @@ public:
   // Persistence
   virtual char* SaveTo();
   virtual void  LoadFrom( const char* theStream );
-  
+  virtual void  UpdateAsMeshesRestored(); // for hyps needing full data restored
+
 protected:
   ::SMESH_Hypothesis* myBaseImpl;    // base hypothesis implementation
 };
diff --git a/src/SMESH_I/SMESH_Measurements_i.cxx b/src/SMESH_I/SMESH_Measurements_i.cxx
new file mode 100644 (file)
index 0000000..1397a4c
--- /dev/null
@@ -0,0 +1,259 @@
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//  File   : SMESH_Measurements_i.cxx
+//  Author : Pavel TELKOV, Open CASCADE S.A.S. (pavel.telkov@opencascade.com)
+
+#include "SMESH_Measurements_i.hxx"
+
+#include "SMESH_Gen_i.hxx"
+#include "SMESH_PythonDump.hxx"
+
+#include "SMDS_Mesh.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "SMDS_MeshElement.hxx"
+#include "SMDS_ElemIterator.hxx"
+
+#include "SMESHDS_Mesh.hxx"
+
+
+using namespace SMESH;
+
+/**
+ * this local function to avoid uninitialized fields
+ */
+static void initMeasure( SMESH::Measure& theMeasure)
+{
+
+  theMeasure.minX = theMeasure.minY = theMeasure.minZ = 0.;
+  theMeasure.maxX = theMeasure.maxY = theMeasure.maxZ = 0.;
+  theMeasure.node1 = theMeasure.node2 = -1;
+  theMeasure.elem1 = theMeasure.elem2 = -1;
+  theMeasure.value = 0.;
+}
+
+//=============================================================================
+/*!
+ *  SMESH_Gen_i::CreateMeasurements
+ *
+ *  Create measurement instance
+ */
+//=============================================================================
+
+SMESH::Measurements_ptr SMESH_Gen_i::CreateMeasurements()
+{
+  SMESH::Measurements_i* aMeasure = new SMESH::Measurements_i();
+  SMESH::Measurements_var anObj = aMeasure->_this();
+  return anObj._retn();
+}
+
+  
+/*
+  Class       : Measurements
+  Description : make measure of mesh qunatities
+*/
+
+//=======================================================================
+// name    : Measurements_i
+// Purpose : Constructor
+//=======================================================================
+Measurements_i::Measurements_i()
+: SALOME::GenericObj_i( SMESH_Gen_i::GetPOA() )
+{
+  //Base class Salome_GenericObject do it inmplicitly by overriding PortableServer::POA_ptr _default_POA() method
+  //PortableServer::ObjectId_var anObjectId =
+  //  SMESH_Gen_i::GetPOA()->activate_object( this );
+}
+
+//=======================================================================
+// name    : ~Measurements_i
+// Purpose : Destructor
+//=======================================================================
+Measurements_i::~Measurements_i()
+{
+  //TPythonDump()<<this<<".Destroy()";
+}
+
+static bool getNodeNodeDistance (SMESH::Measure& theMeasure,
+                                const SMDS_MeshNode* theNode1,
+                                const SMDS_MeshNode* theNode2 = 0)
+{
+  double dist = 0., dd = 0.;
+
+  if (!theNode1)
+    return false;
+
+  dd = theNode1->X(); if (theNode2) dd -= theNode2->X(); theMeasure.minX = dd; dd *= dd; dist += dd;
+  dd = theNode1->Y(); if (theNode2) dd -= theNode2->Y(); theMeasure.minY = dd; dd *= dd; dist += dd;
+  dd = theNode1->Z(); if (theNode2) dd -= theNode2->Z(); theMeasure.minZ = dd; dd *= dd; dist += dd;
+
+  if (dist < 0)
+    return false;
+  
+  theMeasure.value = sqrt(dist);
+  theMeasure.node1 = theNode1->GetID();
+  theMeasure.node2 = theNode2 ? theNode2->GetID() : 0;
+
+  return true;
+}
+
+static SMESHDS_Mesh* getMesh(SMESH::SMESH_IDSource_ptr theSource)
+{
+  if (!CORBA::is_nil( theSource ))
+  {
+    SMESH_Mesh_i* anImplPtr = DownCast<SMESH_Mesh_i*>(theSource->GetMesh());
+    if (anImplPtr)
+      return anImplPtr->GetImpl().GetMeshDS();
+  }
+  return 0;
+}
+
+static bool isNodeType (SMESH::array_of_ElementType_var theTypes)
+{
+  return theTypes->length() > 0 && theTypes[0] == SMESH::NODE;
+}
+
+//=======================================================================
+// name    : MinDistance
+// Purpose : minimal distance between two given entities
+//=======================================================================
+SMESH::Measure Measurements_i::MinDistance
+ (SMESH::SMESH_IDSource_ptr theSource1,
+  SMESH::SMESH_IDSource_ptr theSource2)
+{
+  SMESH::Measure aMeasure;
+  initMeasure(aMeasure);
+
+  if (CORBA::is_nil( theSource1 ))
+    return aMeasure;
+  
+  // if second source is null, min distance from theSource1 to the origin is calculated
+  bool isOrigin =  CORBA::is_nil( theSource2 );
+
+  // calculate minimal distance between two mesh entities
+  SMESH::array_of_ElementType_var types1 = theSource1->GetTypes();
+  SMESH::array_of_ElementType_var types2;
+  if ( !isOrigin ) types2 = theSource2->GetTypes();
+
+  // here we assume that type of all IDs defined by first type in array
+  bool isNode1 = isNodeType(types1);
+  bool isNode2 = isOrigin || isNodeType(types2);
+
+  SMESH::long_array_var aElementsId1 = theSource1->GetIDs();
+  SMESH::long_array_var aElementsId2;
+  if ( !isOrigin ) aElementsId2 = theSource2->GetIDs();
+
+  // compute distance between two entities
+  /* NOTE: currently only node-to-node case is implemented
+   * all other cases will be implemented later
+   * below IF should be replaced by complete switch
+   * on mesh entities types
+   */
+  if (isNode1 && isNode2)
+  {
+    // node - node
+    const SMESHDS_Mesh* aMesh1 = getMesh( theSource1 );
+    const SMESHDS_Mesh* aMesh2 = isOrigin ? 0 : getMesh( theSource2 );
+    const SMDS_MeshNode* theNode1 = aMesh1 ? aMesh1->FindNode( aElementsId1[0] ) : 0;
+    const SMDS_MeshNode* theNode2 = aMesh2 ? aMesh2->FindNode( aElementsId2[0] ) : 0;
+    getNodeNodeDistance( aMeasure, theNode1, theNode2 );
+  }
+  else
+  {
+    // NOT_IMPLEMENTED
+  }
+
+  return aMeasure;
+}
+
+//=======================================================================
+// name    : enlargeBoundingBox
+// Purpose : 
+//=======================================================================
+static void enlargeBoundingBox(const SMDS_MeshNode* theNode,
+                               SMESH::Measure&      theMeasure)
+{
+  if (!theNode)
+    return;
+  if ( theMeasure.node1 == -1 ) {
+    // we use this attribute as a flag that it is the first node added to the bnd box 
+    theMeasure.minX = theMeasure.maxX = theNode->X();
+    theMeasure.minY = theMeasure.maxY = theNode->Y();
+    theMeasure.minZ = theMeasure.maxZ = theNode->Z();
+    theMeasure.node1 = theNode->GetID();
+  }
+  else {
+    theMeasure.minX = min( theMeasure.minX, theNode->X() );
+    theMeasure.maxX = max( theMeasure.maxX, theNode->X() );
+    theMeasure.minY = min( theMeasure.minY, theNode->Y() );
+    theMeasure.maxY = max( theMeasure.maxY, theNode->Y() );
+    theMeasure.minZ = min( theMeasure.minZ, theNode->Z() );
+    theMeasure.maxZ = max( theMeasure.maxZ, theNode->Z() );
+  }
+}
+
+//=======================================================================
+// name    : enlargeBoundingBox
+// Purpose : 
+//=======================================================================
+static void enlargeBoundingBox(const SMESH::SMESH_IDSource_ptr theObject,
+                               SMESH::Measure&                 theMeasure)
+{
+  if ( CORBA::is_nil( theObject ) )
+    return;
+  const SMESHDS_Mesh* aMesh = getMesh( theObject );
+  if ( !aMesh )
+    return;
+  SMESH::array_of_ElementType_var types = theObject->GetTypes();
+  SMESH::long_array_var     aElementsId = theObject->GetIDs();
+  // here we assume that type of all IDs defined by first type in array
+  const bool isNode = isNodeType( types );
+  for(int i = 0, n = aElementsId->length(); i < n; i++)
+  {
+    if (isNode)
+      enlargeBoundingBox( aMesh->FindNode( aElementsId[i] ), theMeasure);
+    else
+    {
+      const SMDS_MeshElement* elem = aMesh->FindElement( aElementsId[i] );
+      if (!elem)
+        continue;
+      SMDS_ElemIteratorPtr aNodeIter = elem->nodesIterator();
+      while( aNodeIter->more() )
+        enlargeBoundingBox( dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() ), theMeasure);
+    }
+  }
+}
+                               
+//=======================================================================
+// name    : BoundingBox
+// Purpose : compute common bounding box of entities
+//=======================================================================
+SMESH::Measure Measurements_i::BoundingBox (const SMESH::ListOfIDSources& theSources)
+{
+  SMESH::Measure aMeasure;
+  initMeasure(aMeasure);
+
+  // calculate bounding box on sources
+  for ( int i = 0, n = theSources.length(); i < n ; ++i )
+    enlargeBoundingBox( theSources[i], aMeasure );
+
+  return aMeasure;
+}
diff --git a/src/SMESH_I/SMESH_Measurements_i.hxx b/src/SMESH_I/SMESH_Measurements_i.hxx
new file mode 100644 (file)
index 0000000..0e1d77d
--- /dev/null
@@ -0,0 +1,63 @@
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//  File   : SMESH_Measurements_i.hxx
+//  Author : Pavel TELKOV, Open CASCADE S.A.S. (pavel.telkov@opencascade.com)
+
+#ifndef _SMESH_MEASUREMENTS_I_HXX_
+#define _SMESH_MEASUREMENTS_I_HXX_
+
+#include "SMESH.hxx"
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Measurements)
+
+#include "SALOME_GenericObj_i.hh"
+
+class SMESHDS_Mesh;
+
+namespace SMESH
+{
+
+  /*
+    Measurements
+  */
+  class SMESH_I_EXPORT Measurements_i: public virtual POA_SMESH::Measurements,
+                                       public virtual SALOME::GenericObj_i
+  {
+  public:
+    Measurements_i();
+    ~Measurements_i();
+
+    /*!
+     * minimal distance between two given entities
+     */
+    SMESH::Measure MinDistance(SMESH::SMESH_IDSource_ptr theSource1,
+                               SMESH::SMESH_IDSource_ptr theSource2);
+
+    /*!
+     * common bounding box of entities
+     */
+    SMESH::Measure BoundingBox(const SMESH::ListOfIDSources& theSources);
+  };
+}
+
+#endif
index 5da4f5cebf84549a7f8dfcf361ffd89957f9787e..d442601d597f747ae8c01a51930eba581c1825e6 100644 (file)
@@ -369,10 +369,12 @@ void SMESH_MeshEditor_i::initData(bool deleteSearchers)
 
 struct _IDSource : public POA_SMESH::SMESH_IDSource
 {
-  SMESH::long_array _ids;
-  SMESH::ElementType _type;
+  SMESH::long_array     _ids;
+  SMESH::ElementType    _type;
+  SMESH::SMESH_Mesh_ptr _mesh;
   SMESH::long_array* GetIDs()      { return new SMESH::long_array( _ids ); }
   SMESH::long_array* GetMeshInfo() { return 0; }
+  SMESH::SMESH_Mesh_ptr GetMesh()  { return SMESH::SMESH_Mesh::_duplicate( _mesh ); }
   SMESH::array_of_ElementType* GetTypes()
   {
     SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
@@ -388,6 +390,7 @@ SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_arr
   _IDSource* anIDSource = new _IDSource;
   anIDSource->_ids = ids;
   anIDSource->_type = type;
+  anIDSource->_mesh = myMesh_i->_this();
   SMESH::SMESH_IDSource_var anIDSourceVar = anIDSource->_this();
 
   return anIDSourceVar._retn();
index de07a09f7e89aa40c746e7bebefaa99e9853e59e..c3be622ae71d0608e1796a3b5957f6c297dd7667 100644 (file)
@@ -858,8 +858,7 @@ void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup
   SMESH::long_array_var anIds = aGroup->GetListOfID();
   SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
 
-  // Update Python script
-  TPythonDump() << _this() << ".RemoveGroupWithContents( " << theGroup << " )";
+  TPythonDump pyDump; // Supress dump from RemoveNodes/Elements() and RemoveGroup()
 
   // Remove contents
   if ( aGroup->GetType() == SMESH::NODE )
@@ -870,12 +869,10 @@ void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup
   // Remove group
   RemoveGroup( theGroup );
 
-  // Clear python lines, created by RemoveNodes/Elements() and RemoveGroup()
-  _gen_i->RemoveLastFromPythonScript(_gen_i->GetCurrentStudy()->StudyId());
-  _gen_i->RemoveLastFromPythonScript(_gen_i->GetCurrentStudy()->StudyId());
+  // Update Python script
+  pyDump << _this() << ".RemoveGroupWithContents( " << theGroup << " )";
 }
 
-
 //================================================================================
 /*!
  * \brief Get the list of groups existing in the mesh
@@ -918,6 +915,7 @@ SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
 
   return aList._retn();
 }
+
 //=============================================================================
 /*!
  *  Get number of groups existing in the mesh
@@ -2110,13 +2108,17 @@ void SMESH_Mesh_i::removeGroup( const int theId )
 {
   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
   if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
-    removeGeomGroupData( _mapGroups[theId] );
+    SMESH::SMESH_GroupBase_ptr group = _mapGroups[theId];
     _mapGroups.erase( theId );
-    _impl->RemoveGroup( theId );
+    removeGeomGroupData( group );
+    if (! _impl->RemoveGroup( theId ))
+    {
+      // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
+      RemoveGroup( group );
+    }
   }
 }
 
-
 //=============================================================================
 /*!
  *
@@ -2213,6 +2215,19 @@ CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
   return _studyId;
 }
 
+//=============================================================================
+namespace
+{
+  //!< implementation of struct used to call SMESH_Mesh_i::removeGroup() from
+  // SMESH_Mesh::RemoveGroup() (issue 0020918)
+  struct TRmGroupCallUp_i : public SMESH_Mesh::TRmGroupCallUp
+  {
+    SMESH_Mesh_i* _mesh;
+    TRmGroupCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
+    virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
+  };
+}
+
 //=============================================================================
 /*!
  *
@@ -2223,6 +2238,8 @@ void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
 {
   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
   _impl = impl;
+  if ( _impl )
+    _impl->SetRemoveGroupCallUp( new TRmGroupCallUp_i(this));
 }
 
 //=============================================================================
@@ -3390,6 +3407,7 @@ void SMESH_Mesh_i::CreateGroupServants()
 {
   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
 
+  set<int> addedIDs;
   ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
   while ( groupIt->more() )
   {
@@ -3399,6 +3417,7 @@ void SMESH_Mesh_i::CreateGroupServants()
     map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
     if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
       continue;
+    addedIDs.insert( anId );
 
     SMESH_GroupBase_i* aGroupImpl;
     TopoDS_Shape       shape;
@@ -3424,12 +3443,23 @@ void SMESH_Mesh_i::CreateGroupServants()
     int nextId = _gen_i->RegisterObject( groupVar );
     if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
 
-    // publishing of the groups in the study
+    // publishing the groups in the study
     if ( !aStudy->_is_nil() ) {
       GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
       _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName());
     }
   }
+  if ( !addedIDs.empty() )
+  {
+    // python dump
+    set<int>::iterator id = addedIDs.begin();
+    for ( ; id != addedIDs.end(); ++id )
+    {
+      map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
+      int i = std::distance( _mapGroups.begin(), it );
+      TPythonDump() << it->second << " = " << _this() << ".GetGroups()[ "<< i << " ]";
+    }
+  }
 }
 
 //=============================================================================
@@ -3581,6 +3611,16 @@ SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
   return types._retn();
 }
 
+//=======================================================================
+//function : GetMesh
+//purpose  : Returns self
+//=======================================================================
+
+SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
+{
+  return SMESH::SMESH_Mesh::_duplicate( _this() );
+}
+
 //=============================================================================
 /*!
  * \brief Returns statistic of mesh elements
@@ -3925,10 +3965,9 @@ SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
  */
 //=============================================================================
 
-static void findCommonSubMesh
- (list<const SMESH_subMesh*>& theSubMeshList,
-  const SMESH_subMesh*             theSubMesh,
-  set<const SMESH_subMesh*>&  theCommon )
+static void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
+                               const SMESH_subMesh*        theSubMesh,
+                               set<const SMESH_subMesh*>&  theCommon )
 {
   if ( !theSubMesh )
     return;
index d3f550ecdae29dd71f1e457bc7c6d7e7b722f10b..ea33ec9fa2ca04710e2c6d13fc9e9defce10080b 100644 (file)
@@ -521,18 +521,20 @@ public:
   // =========================
 
   virtual SMESH::long_array* GetIDs();
-
   /*!
    * Returns statistic of mesh elements
    * Result array of number enityties
    * Inherited from SMESH_IDSource
    */
   virtual SMESH::long_array* GetMeshInfo();
-
   /*!
    * Returns types of elements it contains
    */
   virtual SMESH::array_of_ElementType* GetTypes();
+  /*!
+   * Returns self
+   */
+  virtual SMESH::SMESH_Mesh_ptr GetMesh();
 
 
   std::map<int, SMESH_subMesh_i*> _mapSubMesh_i; //NRI
index 031b3c4156b789ff0e5ddf2fc8c17076b5722e8c..f1ee2658182007e1182ec2f02be0d5711d7f659b 100644 (file)
@@ -73,6 +73,7 @@ namespace SMESH
   class FilterManager_i;
   class Filter_i;
   class Functor_i;
+  class Measurements_i;
 
 // ===========================================================================================
 /*!
@@ -142,6 +143,9 @@ namespace SMESH
     TPythonDump& 
     operator<<(SMESH::Functor_i* theArg);
 
+    TPythonDump& 
+    operator<<(SMESH::Measurements_i* theArg);
+
     TPythonDump& 
     operator<<(SMESH_Gen_i* theArg);
 
index faa7aa1ca5230a80dce400abbf675ab7bb246ec0..45d4867334c685132298fa237d33fe6b865ae729 100644 (file)
@@ -578,3 +578,13 @@ SMESH::array_of_ElementType* SMESH_subMesh_i::GetTypes()
   }
   return types._retn();
 }
+
+//=======================================================================
+//function : GetMesh
+//purpose  : interface SMESH_IDSource
+//=======================================================================
+
+SMESH::SMESH_Mesh_ptr SMESH_subMesh_i::GetMesh()
+{
+  return GetFather();
+}
index 3f90a8cb818294d7f443646352405e181532e1db..f5fd559d404dc692d65f4f7ed3d4376455e61464 100644 (file)
@@ -85,19 +85,28 @@ public:
   SALOME_MED::FAMILY_ptr GetFamily()
     throw (SALOME::SALOME_Exception);
 
-  virtual SMESH::long_array* GetIDs();
 
+  // =========================
+  // interface SMESH_IDSource
+  // =========================
+  /*!
+   * Returns a sequence of all element IDs
+   */
+  virtual SMESH::long_array* GetIDs();
   /*!
    * Returns statistic of mesh elements
    * Result array of number enityties
    * Inherited from SMESH_IDSource
    */
   virtual SMESH::long_array* GetMeshInfo();
-
   /*!
    * Returns types of elements it contains
    */
   virtual SMESH::array_of_ElementType* GetTypes();
+  /*!
+   * Returns the mesh
+   */
+  SMESH::SMESH_Mesh_ptr GetMesh();
 
 
   SMESH_Mesh_i* _mesh_i; //NRI
index 02047a1cf648158016f833022995e13d43b4eed8..af6c984205dd2ab4d32c67c415f979045f06d3d0 100644 (file)
@@ -40,6 +40,7 @@ def CheckBelongToGeomFilterOld(theMeshGen, theMesh, theShape, theSubShape, theEl
     aBelongToGeom.SetElementType(theElemType)
     
     aFilter.SetPredicate(aBelongToGeom)
+    aFilterMgr.Destroy()
     return aFilter.GetElementsId(theMesh)
 
 ## Current style
index e0cbb6404ca0a6eec48c0c7b08a96e105e1722ba..c90a3bd8979996f94d85151fca90e4fa058ef8c4 100644 (file)
@@ -36,6 +36,7 @@ def BuildGroupLyingOn(theMesh, theElemType, theName, theShape):
     
     aFilter.SetPredicate(aLyingOnGeom)
     anIds = aFilter.GetElementsId(theMesh)
+    aFilterMgr.Destroy()
 
     aGroup = theMesh.CreateGroup(theElemType, theName)
     aGroup.Add(anIds)
index 43c1b5874d4917ff8a7a58eb0925031d6a43c08a..8cde5ac61bbe8c79a0dd385ca87f18815ffa7f5d 100644 (file)
@@ -128,4 +128,16 @@ print "Criterion: Borders at multi-connections = 2 Nb = ", len( anIds )
   #print anIds[ i ]
 
 
+# Criterion : Max Element Length 2D > 10
+
+# create group
+aGroup = mesh.MakeGroup("Max Element Length 2D > 10", smesh.FACE, smesh.FT_MaxElementLength2D, smesh.FT_MoreThan, 10 )
+
+# print result
+anIds = aGroup.GetIDs()
+print "Criterion: Max Element Length 2D > 10 Nb = ", len( anIds )
+#for i in range( len( anIds ) ):
+  #print anIds[ i ]
+
+
 salome.sg.updateObjBrowser(1)
index 1e01d2ac014ea7f315723b319311921343f5106a..2ea857466cc38dd41840ae3ba9cdb6c43e81dd8f 100644 (file)
@@ -88,6 +88,7 @@
 ##   @defgroup l2_modif_tofromqu Convert to/from Quadratic Mesh
 
 ## @}
+## @defgroup l1_measurements Measurements
 
 import salome
 import geompyDC
@@ -857,6 +858,7 @@ class smeshDC(SMESH._objref_SMESH_Gen):
         aCriteria = []
         aCriteria.append(aCriterion)
         aFilter.SetCriteria(aCriteria)
+        aFilterMgr.Destroy()
         return aFilter
 
     ## Creates a numerical functor by its type
@@ -881,6 +883,10 @@ class smeshDC(SMESH._objref_SMESH_Gen):
             return aFilterMgr.CreateArea()
         elif theCriterion == FT_Volume3D:
             return aFilterMgr.CreateVolume3D()
+        elif theCriterion == FT_MaxElementLength2D:
+            return aFilterMgr.CreateMaxElementLength2D()
+        elif theCriterion == FT_MaxElementLength3D:
+            return aFilterMgr.CreateMaxElementLength3D()
         elif theCriterion == FT_MultiConnection:
             return aFilterMgr.CreateMultiConnection()
         elif theCriterion == FT_MultiConnection2D:
@@ -913,6 +919,110 @@ class smeshDC(SMESH._objref_SMESH_Gen):
             pass
         return d
 
+    ## Get minimum distance between two objects
+    #
+    #  If @a src2 is None, and @a id2 = 0, distance from @a src1 / @a id1 to the origin is computed.
+    #  If @a src2 is None, and @a id2 != 0, it is assumed that both @a id1 and @a id2 belong to @a src1.
+    #
+    #  @param src1 first source object 
+    #  @param src2 second source object
+    #  @param id1 node/element id from the first source
+    #  @param id2 node/element id from the second (or first) source
+    #  @param isElem1 @c True if @a id1 is element id, @c False if it is node id
+    #  @param isElem2 @c True if @a id2 is element id, @c False if it is node id
+    #  @return minimum distance value
+    #  @sa GetMinDistance()
+    #  @ingroup l1_measurements
+    def MinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
+        result = self.GetMinDistance(src1, src2, id1, id2, isElem1, isElem2)
+        if result is None:
+            result = 0.0
+        else:
+            result = result.value
+        return result
+    
+    ## Get measure structure specifying minimum distance data between two objects
+    #
+    #  If @a src2 is None, and @a id2 = 0, distance from @a src1 / @a id1 to the origin is computed.
+    #  If @a src2 is None, and @a id2 != 0, it is assumed that both @a id1 and @a id2 belong to @a src1.
+    #
+    #  @param src1 first source object 
+    #  @param src2 second source object
+    #  @param id1 node/element id from the first source
+    #  @param id2 node/element id from the second (or first) source
+    #  @param isElem1 @c True if @a id1 is element id, @c False if it is node id
+    #  @param isElem2 @c True if @a id2 is element id, @c False if it is node id
+    #  @return Measure structure or None if input data is invalid
+    #  @sa MinDistance()
+    #  @ingroup l1_measurements
+    def GetMinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
+        if isinstance(src1, Mesh): src1 = src1.mesh
+        if isinstance(src2, Mesh): src2 = src2.mesh
+        if src2 is None and id2 != 0: src2 = src1
+        if not hasattr(src1, "_narrow"): return None
+        src1 = src1._narrow(SMESH.SMESH_IDSource)
+        if not src1: return None
+        if id1 != 0:
+            m = src1.GetMesh()
+            e = m.GetMeshEditor()
+            if isElem1:
+                src1 = e.MakeIDSource([id1], SMESH.FACE)
+            else:
+                src1 = e.MakeIDSource([id1], SMESH.NODE)
+            pass
+        if hasattr(src2, "_narrow"):
+            src2 = src2._narrow(SMESH.SMESH_IDSource)
+            if src2 and id2 != 0:
+                m = src2.GetMesh()
+                e = m.GetMeshEditor()
+                if isElem2:
+                    src2 = e.MakeIDSource([id2], SMESH.FACE)
+                else:
+                    src2 = e.MakeIDSource([id2], SMESH.NODE)
+                pass
+            pass
+        aMeasurements = self.CreateMeasurements()
+        result = aMeasurements.MinDistance(src1, src2)
+        aMeasurements.Destroy()
+        return result
+    
+    ## Get bounding box of the specified object(s)
+    #  @param objects single source object or list of source objects
+    #  @return tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
+    #  @sa GetBoundingBox()
+    #  @ingroup l1_measurements
+    def BoundingBox(self, objects):
+        result = self.GetBoundingBox(objects)
+        if result is None:
+            result = (0.0,)*6
+        else:
+            result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
+        return result
+
+    ## Get measure structure specifying bounding box data of the specified object(s)
+    #  @param objects single source object or list of source objects
+    #  @return Measure structure
+    #  @sa BoundingBox()
+    #  @ingroup l1_measurements
+    def GetBoundingBox(self, objects):
+        if isinstance(objects, tuple):
+            objects = list(objects)
+        if not isinstance(objects, list):
+            objects = [objects]
+        srclist = []
+        for o in objects:
+            if isinstance(o, Mesh):
+                srclist.append(o.mesh)
+            elif hasattr(o, "_narrow"):
+                src = o._narrow(SMESH.SMESH_IDSource)
+                if src: srclist.append(src)
+                pass
+            pass
+        aMeasurements = self.CreateMeasurements()
+        result = aMeasurements.BoundingBox(srclist)
+        aMeasurements.Destroy()
+        return result
+
 import omniORB
 #Registering the new proxy for SMESH_Gen
 omniORB.registerObjref(SMESH._objref_SMESH_Gen._NP_RepositoryId, smeshDC)
@@ -1078,6 +1188,24 @@ class Mesh:
         else:
             return Mesh_Segment(self, geom)
 
+    ## Creates 1D algorithm importing segments conatined in groups of other mesh.
+    #  If the optional \a geom parameter is not set, this algorithm is global.
+    #  Otherwise, this algorithm defines a submesh based on \a geom subshape.
+    #  @param geom If defined the subshape is to be meshed
+    #  @return an instance of Mesh_UseExistingElements class
+    #  @ingroup l3_algos_basic
+    def UseExisting1DElements(self, geom=0):
+        return Mesh_UseExistingElements(1,self, geom)
+
+    ## Creates 2D algorithm importing faces conatined in groups of other mesh.
+    #  If the optional \a geom parameter is not set, this algorithm is global.
+    #  Otherwise, this algorithm defines a submesh based on \a geom subshape.
+    #  @param geom If defined the subshape is to be meshed
+    #  @return an instance of Mesh_UseExistingElements class
+    #  @ingroup l3_algos_basic
+    def UseExisting2DElements(self, geom=0):
+        return Mesh_UseExistingElements(2,self, geom)
+
     ## Enables creation of nodes and segments usable by 2D algoritms.
     #  The added nodes and segments must be bound to edges and vertices by
     #  SetNodeOnVertex(), SetNodeOnEdge() and SetMeshElementOnShape()
@@ -1209,7 +1337,9 @@ class Mesh:
         return Mesh_RadialPrism3D(self,  geom)
 
     ## Evaluates size of prospective mesh on a shape
-    #  @return True or False
+    #  @return a list where i-th element is a number of elements of i-th SMESH.EntityType
+    #  To know predicted number of e.g. edges, inquire it this way
+    #  Evaluate()[ EnumToLong( Entity_Edge )]
     def Evaluate(self, geom=0):
         if geom == 0 or not isinstance(geom, geompyDC.GEOM._objref_GEOM_Object):
             if self.geom == 0:
@@ -1639,6 +1769,7 @@ class Mesh:
         aCriteria.append(Criterion)
         aFilter.SetCriteria(aCriteria)
         group = self.MakeGroupByFilter(groupName, aFilter)
+        aFilterMgr.Destroy()
         return group
 
     ## Creates a mesh group by the given criteria (list of criteria)
@@ -1651,6 +1782,7 @@ class Mesh:
         aFilter = aFilterMgr.CreateFilter()
         aFilter.SetCriteria(theCriteria)
         group = self.MakeGroupByFilter(groupName, aFilter)
+        aFilterMgr.Destroy()
         return group
 
     ## Creates a mesh group by the given filter
@@ -1681,6 +1813,7 @@ class Mesh:
         aPredicate = aFilterMgr.CreateFreeEdges()
         aPredicate.SetMesh(self.mesh)
         aBorders = aPredicate.GetBorders()
+        aFilterMgr.Destroy()
         return aBorders
 
     ## Removes a group
@@ -2200,6 +2333,95 @@ class Mesh:
         return self.mesh.BaryCenter(id)
 
 
+    # Get mesh measurements information:
+    # ------------------------------------
+
+    ## Get minimum distance between two nodes, elements or distance to the origin
+    #  @param id1 first node/element id
+    #  @param id2 second node/element id (if 0, distance from @a id1 to the origin is computed)
+    #  @param isElem1 @c True if @a id1 is element id, @c False if it is node id
+    #  @param isElem2 @c True if @a id2 is element id, @c False if it is node id
+    #  @return minimum distance value
+    #  @sa GetMinDistance()
+    def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
+        aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
+        return aMeasure.value
+    
+    ## Get measure structure specifying minimum distance data between two objects
+    #  @param id1 first node/element id
+    #  @param id2 second node/element id (if 0, distance from @a id1 to the origin is computed)
+    #  @param isElem1 @c True if @a id1 is element id, @c False if it is node id
+    #  @param isElem2 @c True if @a id2 is element id, @c False if it is node id
+    #  @return Measure structure
+    #  @sa MinDistance()
+    def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
+        if isElem1:
+            id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
+        else:
+            id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
+        if id2 != 0:
+            if isElem2:
+                id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
+            else:
+                id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
+            pass
+        else:
+            id2 = None
+        
+        aMeasurements = self.smeshpyD.CreateMeasurements()
+        aMeasure = aMeasurements.MinDistance(id1, id2)
+        aMeasurements.Destroy()
+        return aMeasure
+    
+    ## Get bounding box of the specified object(s)
+    #  @param objects single source object or list of source objects or list of nodes/elements IDs
+    #  @param isElem if @a objects is a list of IDs, @c True value in this parameters specifies that @a objects are elements,
+    #  @c False specifies that @a objects are nodes
+    #  @return tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
+    #  @sa GetBoundingBox()
+    def BoundingBox(self, objects=None, isElem=False):
+        result = self.GetBoundingBox(objects, isElem)
+        if result is None:
+            result = (0.0,)*6
+        else:
+            result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
+        return result
+
+    ## Get measure structure specifying bounding box data of the specified object(s)
+    #  @param objects single source object or list of source objects or list of nodes/elements IDs
+    #  @param isElem if @a objects is a list of IDs, @c True value in this parameters specifies that @a objects are elements,
+    #  @c False specifies that @a objects are nodes
+    #  @return Measure structure
+    #  @sa BoundingBox()
+    def GetBoundingBox(self, IDs=None, isElem=False):
+        if IDs is None:
+            IDs = [self.mesh]
+        elif isinstance(IDs, tuple):
+            IDs = list(IDs)
+        if not isinstance(IDs, list):
+            IDs = [IDs]
+        if len(IDs) > 0 and isinstance(IDs[0], int):
+            IDs = [IDs]
+        srclist = []
+        for o in IDs:
+            if isinstance(o, Mesh):
+                srclist.append(o.mesh)
+            elif hasattr(o, "_narrow"):
+                src = o._narrow(SMESH.SMESH_IDSource)
+                if src: srclist.append(src)
+                pass
+            elif isinstance(o, list):
+                if isElem:
+                    srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
+                else:
+                    srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
+                pass
+            pass
+        aMeasurements = self.smeshpyD.CreateMeasurements()
+        aMeasure = aMeasurements.BoundingBox(srclist)
+        aMeasurements.Destroy()
+        return aMeasure
+    
     # Mesh edition (SMESH_MeshEditor functionality):
     # ---------------------------------------------
 
@@ -3838,6 +4060,86 @@ class Mesh:
     def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
         return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
 
+    def _valueFromFunctor(self, funcType, elemId):
+        fn = self.smeshpyD.GetFunctor(funcType)
+        fn.SetMesh(self.mesh)
+        if fn.GetElementType() == self.GetElementType(elemId, True):
+            val = fn.GetValue(elemId)
+        else:
+            val = 0
+        return val
+        
+    ## Get length of 1D element.
+    #  @param elemId mesh element ID
+    #  @return element's length value
+    #  @ingroup l1_measurements
+    def GetLength(self, elemId):
+        return self._valueFromFunctor(SMESH.FT_Length, elemId)    
+
+    ## Get area of 2D element.
+    #  @param elemId mesh element ID
+    #  @return element's area value
+    #  @ingroup l1_measurements
+    def GetArea(self, elemId):
+        return self._valueFromFunctor(SMESH.FT_Area, elemId)    
+
+    ## Get volume of 3D element.
+    #  @param elemId mesh element ID
+    #  @return element's volume value
+    #  @ingroup l1_measurements
+    def GetVolume(self, elemId):
+        return self._valueFromFunctor(SMESH.FT_Volume3D, elemId)    
+
+    ## Get maximum element length.
+    #  @param elemId mesh element ID
+    #  @return element's maximum length value
+    #  @ingroup l1_measurements
+    def GetMaxElementLength(self, elemId):
+        if self.GetElementType(elemId, True) == SMESH.VOLUME:
+            ftype = SMESH.FT_MaxElementLength3D
+        else:
+            ftype = SMESH.FT_MaxElementLength2D
+        return self._valueFromFunctor(ftype, elemId)    
+
+    ## Get aspect ratio of 2D or 3D element.
+    #  @param elemId mesh element ID
+    #  @return element's aspect ratio value
+    #  @ingroup l1_measurements
+    def GetAspectRatio(self, elemId):
+        if self.GetElementType(elemId, True) == SMESH.VOLUME:
+            ftype = SMESH.FT_AspectRatio3D
+        else:
+            ftype = SMESH.FT_AspectRatio
+        return self._valueFromFunctor(ftype, elemId)    
+
+    ## Get warping angle of 2D element.
+    #  @param elemId mesh element ID
+    #  @return element's warping angle value
+    #  @ingroup l1_measurements
+    def GetWarping(self, elemId):
+        return self._valueFromFunctor(SMESH.FT_Warping, elemId)
+
+    ## Get minimum angle of 2D element.
+    #  @param elemId mesh element ID
+    #  @return element's minimum angle value
+    #  @ingroup l1_measurements
+    def GetMinimumAngle(self, elemId):
+        return self._valueFromFunctor(SMESH.FT_MinimumAngle, elemId)
+
+    ## Get taper of 2D element.
+    #  @param elemId mesh element ID
+    #  @return element's taper value
+    #  @ingroup l1_measurements
+    def GetTaper(self, elemId):
+        return self._valueFromFunctor(SMESH.FT_Taper, elemId)
+
+    ## Get skew of 2D element.
+    #  @param elemId mesh element ID
+    #  @return element's skew value
+    #  @ingroup l1_measurements
+    def GetSkew(self, elemId):
+        return self._valueFromFunctor(SMESH.FT_Skew, elemId)
+
 ## The mother class to define algorithm, it is not recommended to use it directly.
 #
 #  More details.
@@ -5462,6 +5764,73 @@ class Mesh_RadialQuadrangle1D2D(Mesh_Algorithm):
         return hyp
 
 
+# Public class: Mesh_UseExistingElements
+# --------------------------------------
+## Defines a Radial Quadrangle 1D2D algorithm
+#  @ingroup l3_algos_basic
+#
+class Mesh_UseExistingElements(Mesh_Algorithm):
+
+    def __init__(self, dim, mesh, geom=0):
+        if dim == 1:
+            self.Create(mesh, geom, "Import_1D")
+        else:
+            self.Create(mesh, geom, "Import_1D2D")
+        return
+
+    ## Defines "Source edges" hypothesis, specifying groups of edges to import
+    #  @param groups list of groups of edges
+    #  @param toCopyMesh if True, the whole mesh \a groups belong to is imported
+    #  @param toCopyGroups if True, all groups of the mesh \a groups belong to are imported
+    #  @param UseExisting if ==true - searches for the existing hypothesis created with
+    #                     the same parameters, else (default) - creates a new one
+    def SourceEdges(self, groups, toCopyMesh=False, toCopyGroups=False, UseExisting=False):
+        if self.algo.GetName() == "Import_2D":
+            raise ValueError, "algoritm dimension mismatch"
+        hyp = self.Hypothesis("ImportSource1D", [groups, toCopyMesh, toCopyGroups],
+                              UseExisting=UseExisting, CompareMethod=self._compareHyp)
+        hyp.SetSourceEdges(groups)
+        hyp.SetCopySourceMesh(toCopyMesh, toCopyGroups)
+        return hyp
+
+    ## Defines "Source faces" hypothesis, specifying groups of faces to import
+    #  @param groups list of groups of faces
+    #  @param toCopyMesh if True, the whole mesh \a groups belong to is imported
+    #  @param toCopyGroups if True, all groups of the mesh \a groups belong to are imported
+    #  @param UseExisting if ==true - searches for the existing hypothesis created with
+    #                     the same parameters, else (default) - creates a new one
+    def SourceFaces(self, groups, toCopyMesh=False, toCopyGroups=False, UseExisting=False):
+        if self.algo.GetName() == "Import_1D":
+            raise ValueError, "algoritm dimension mismatch"
+        hyp = self.Hypothesis("ImportSource2D", [groups, toCopyMesh, toCopyGroups],
+                              UseExisting=UseExisting, CompareMethod=self._compareHyp)
+        hyp.SetSourceFaces(groups)
+        hyp.SetCopySourceMesh(toCopyMesh, toCopyGroups)
+        return hyp
+
+    def _compareHyp(self,hyp,args):
+        if hasattr( hyp, "GetSourceEdges"):
+            entries = hyp.GetSourceEdges()
+        else:
+            entries = hyp.GetSourceFaces()
+        groups = args[0]
+        toCopyMesh,toCopyGroups = hyp.GetCopySourceMesh()
+        if len(entries)==len(groups) and toCopyMesh==args[1] and toCopyGroups==args[2]:
+            entries2 = []
+            study = self.mesh.smeshpyD.GetCurrentStudy()
+            if study:
+                for g in groups:
+                    ior  = salome.orb.object_to_string(g)
+                    sobj = study.FindObjectIOR(ior)
+                    if sobj: entries2.append( sobj.GetID() )
+                    pass
+                pass
+            entries.sort()
+            entries2.sort()
+            return entries == entries2
+        return False
+
+
 # Private class: Mesh_UseExisting
 # -------------------------------
 class Mesh_UseExisting(Mesh_Algorithm):
index 0312e1f78cd0dbb8971dbefdd2c3fc8ad7b9115d..08c312ead58d3e1f86cb6626e3b6cddc4a4d44a0 100644 (file)
@@ -72,7 +72,10 @@ salomeinclude_HEADERS = \
        StdMeshers_MaxLength.hxx \
        StdMeshers_QuadrangleParams.hxx \
        StdMeshers_RadialQuadrangle_1D2D.hxx \
-       StdMeshers_HexaFromSkin_3D.hxx
+       StdMeshers_HexaFromSkin_3D.hxx \
+       StdMeshers_ImportSource.hxx \
+       StdMeshers_Import_1D.hxx \
+       StdMeshers_Import_1D2D.hxx
 
 # Libraries targets
 
@@ -123,7 +126,10 @@ dist_libStdMeshers_la_SOURCES = \
        StdMeshers_MaxLength.cxx \
        StdMeshers_QuadrangleParams.cxx \
        StdMeshers_RadialQuadrangle_1D2D.cxx \
-       StdMeshers_HexaFromSkin_3D.cxx
+       StdMeshers_HexaFromSkin_3D.cxx \
+       StdMeshers_ImportSource.cxx \
+       StdMeshers_Import_1D.cxx \
+       StdMeshers_Import_1D2D.cxx
 
 
 # additionnal information to compil and link file
index 7f003f4ae787118f12f976fb1e461992d1f5a651..4812b423594b6747ea72ee983e5ac6220eb73622 100644 (file)
@@ -23,7 +23,6 @@
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_CompositeSegment_1D.hxx
 //  Module : SMESH
-//  $Header$
 //
 #ifndef _SMESH_CompositeSegment_1D_HXX_
 #define _SMESH_CompositeSegment_1D_HXX_
diff --git a/src/StdMeshers/StdMeshers_ImportSource.cxx b/src/StdMeshers/StdMeshers_ImportSource.cxx
new file mode 100644 (file)
index 0000000..1ba39ea
--- /dev/null
@@ -0,0 +1,443 @@
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+//  SMESH StdMeshers_ImportSource1D : implementaion of SMESH idl descriptions
+//  File   : StdMeshers_ImportSource1D.cxx
+//  Module : SMESH
+//
+#include "StdMeshers_ImportSource.hxx"
+
+#include "SMESHDS_GroupBase.hxx"
+#include "SMESHDS_Mesh.hxx"
+#include "SMESH_Algo.hxx"
+#include "SMESH_Gen.hxx"
+#include "SMESH_Group.hxx"
+#include "SMESH_Mesh.hxx"
+#include "SMESH_subMeshEventListener.hxx"
+
+#include "utilities.h"
+
+#include <Standard_ErrorHandler.hxx>
+
+#include <boost/shared_ptr.hpp>
+
+using namespace std;
+
+//=============================================================================
+/*!
+ * Creates StdMeshers_ImportSource1D
+ */
+//=============================================================================
+
+StdMeshers_ImportSource1D::StdMeshers_ImportSource1D(int         hypId,
+                                                     int         studyId,
+                                                     SMESH_Gen * gen)
+  :SMESH_Hypothesis(hypId, studyId, gen),
+   _toCopyMesh(false),
+   _toCopyGroups(false)
+{
+  _name = "ImportSource1D";
+  _param_algo_dim = 1; // is used by StdMeshers_Import_1D;
+}
+
+//=============================================================================
+/*!
+ * Creates StdMeshers_ImportSource2D
+ */
+//=============================================================================
+
+StdMeshers_ImportSource2D::StdMeshers_ImportSource2D(int         hypId,
+                                                     int         studyId,
+                                                     SMESH_Gen * gen)
+  :StdMeshers_ImportSource1D(hypId, studyId, gen)
+{
+  _name = "ImportSource2D";
+  _param_algo_dim = 2; // is used by StdMeshers_Import_2D;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+StdMeshers_ImportSource1D::~StdMeshers_ImportSource1D()
+{
+}
+//=============================================================================
+/*!
+ *  Sets groups to import elements from
+ */
+//=============================================================================
+
+void StdMeshers_ImportSource1D::SetGroups(const std::vector<SMESH_Group*>& groups)
+{
+  if (_groups != groups)
+  {
+    _groups = groups;
+    NotifySubMeshesHypothesisModification();
+  }
+}
+
+void StdMeshers_ImportSource1D::SetCopySourceMesh(bool toCopyMesh, bool toCopyGroups)
+{
+  if ( !toCopyMesh ) toCopyGroups = false;
+  if ( _toCopyMesh != toCopyMesh || _toCopyGroups != toCopyGroups )
+  {
+    _toCopyMesh = toCopyMesh; _toCopyGroups = toCopyGroups;
+    NotifySubMeshesHypothesisModification();
+  }
+}
+void StdMeshers_ImportSource1D::GetCopySourceMesh(bool& toCopyMesh, bool& toCopyGroups) const
+{
+  toCopyMesh = _toCopyMesh; toCopyGroups = _toCopyGroups;
+}
+  
+namespace
+{
+  //================================================================================
+  /*!
+   * \brief Return only alive groups
+   */
+  //================================================================================
+
+  vector<SMESH_Group*> getValidGroups(const vector<SMESH_Group*>& groups,
+                                      StudyContextStruct*         studyContext)
+  {
+    vector<SMESH_Group*> okGroups;
+    for ( int i = 0; i < groups.size(); ++i )
+    {
+      try
+      {
+        // we expect SIGSEGV on a dead group
+        OCC_CATCH_SIGNALS;
+        SMESH_Group* okGroup = 0;
+        map<int, SMESH_Mesh*>::iterator itm = itm = studyContext->mapMesh.begin();
+        for ( ; !okGroup && itm != studyContext->mapMesh.end(); itm++)
+        {
+          SMESH_Mesh::GroupIteratorPtr gIt = itm->second->GetGroups();
+          while ( gIt->more() && !okGroup )
+            if ( gIt->next() == groups[i] )
+              okGroup = groups[i];
+        }
+        if ( okGroup )
+          okGroups.push_back( okGroup );
+      }
+      catch(...)
+      {
+      }
+    }
+    return okGroups;
+  }
+  //================================================================================
+  /*!
+   * \brief Pack meshes into a pair of ints
+   */
+  //================================================================================
+
+  pair<int, int> getResMapKey(const SMESHDS_Mesh& srcMesh, const SMESHDS_Mesh& tgtMesh)
+  {
+    return make_pair( srcMesh.GetPersistentId() , tgtMesh.GetPersistentId() );
+  }
+  //================================================================================
+  /*!
+   * \brief Return a target mesh by a pair of ints
+   */
+  //================================================================================
+
+  SMESH_Mesh* getTgtMeshByKey( const pair<int, int> & resMapKey,
+                               StudyContextStruct*    studyContext)
+  {
+    int tgtID = resMapKey.second;
+    SMESH_Mesh* tgtMesh = 0;
+    map<int, SMESH_Mesh*>::iterator itm = itm = studyContext->mapMesh.begin();
+    for ( ; !tgtMesh && itm != studyContext->mapMesh.end(); itm++)
+    {
+      tgtMesh = (*itm).second;
+      if ( tgtMesh->GetMeshDS()->GetPersistentId() != tgtID )
+        tgtMesh = 0;
+    }
+    return tgtMesh;
+  }
+  //================================================================================
+  /*!
+   * \brief Return a target mesh by a pair of ints
+   */
+  //================================================================================
+
+  int getSrcMeshID( const pair<int, int> & resMapKey )
+  {
+    return resMapKey.first;
+  }
+}
+
+//=============================================================================
+/*!
+ *  Returns groups to import elements from
+ */
+//=============================================================================
+
+const std::vector<SMESH_Group*>&  StdMeshers_ImportSource1D::GetGroups() const
+{
+  // filter off deleted groups
+  vector<SMESH_Group*> okGroups = getValidGroups( _groups,
+                                                  _gen->GetStudyContext(_studyId) );
+  if ( okGroups.size() != _groups.size() )
+    ((StdMeshers_ImportSource1D*)this)->_groups = okGroups;
+
+  return _groups;
+}
+
+//================================================================================
+/*!
+ * \brief Return source meshes
+ */
+//================================================================================
+
+std::vector<SMESH_Mesh*> StdMeshers_ImportSource1D::GetSourceMeshes() const
+{
+  // GetPersistentId()'s of meshes
+  set<int> meshIDs;
+  const vector<SMESH_Group*>& groups = GetGroups();
+  if ( !groups.empty() )
+  {
+    for ( unsigned i = 0; i < groups.size(); ++i )
+    {
+      const SMESHDS_GroupBase* gDS = groups[i]->GetGroupDS();
+      int id = gDS->GetMesh()->GetPersistentId();
+      meshIDs.insert( id );
+    }
+  }
+  else
+  {
+    if ( _resultGroups.empty() )
+      ((StdMeshers_ImportSource1D*)this)->RestoreGroups(_groups);
+    TResGroupMap::const_iterator key_groups = _resultGroups.begin();
+    for ( ; key_groups != _resultGroups.end(); ++key_groups )
+      meshIDs.insert( getSrcMeshID( key_groups->first ));
+  }
+
+  // Find corresponding meshes
+  vector<SMESH_Mesh*> meshes;
+  if ( !meshIDs.empty() )
+  {
+    StudyContextStruct* studyContext = _gen->GetStudyContext(_studyId);
+    for ( set<int>::iterator id = meshIDs.begin(); id != meshIDs.end(); ++id )
+    {
+      map<int, SMESH_Mesh*>::iterator itm = itm = studyContext->mapMesh.begin();
+      for ( ; itm != studyContext->mapMesh.end(); itm++)
+      {
+        SMESH_Mesh* mesh = (*itm).second;
+        if ( mesh->GetMeshDS()->GetPersistentId() == *id )
+        {
+          meshes.push_back( mesh );
+          break;
+        }
+      }
+    }
+  }
+  return meshes;
+}
+
+//=============================================================================
+/*!
+ * Save _toCopyMesh and _toCopyGroups to a stream
+ */
+//=============================================================================
+
+ostream & StdMeshers_ImportSource1D::SaveTo(ostream & save)
+{
+  resultGroupsToIntVec();
+
+  save << " " << _toCopyMesh << " " << _toCopyGroups;
+  save << " " << _resultGroupsStorage.size();
+  for ( unsigned i = 0; i < _resultGroupsStorage.size(); ++i )
+    save << " " << _resultGroupsStorage[i];
+
+  return save;
+}
+
+//=============================================================================
+/*!
+ * Load _toCopyMesh and _toCopyGroups from a stream
+ */
+//=============================================================================
+
+istream & StdMeshers_ImportSource1D::LoadFrom(istream & load)
+{
+  load >> _toCopyMesh >> _toCopyGroups;
+
+  _resultGroupsStorage.clear();
+  int val;
+  if ( load >> val )
+  {
+    _resultGroupsStorage.reserve(val);
+    while ( _resultGroupsStorage.size() < _resultGroupsStorage.capacity() && load >> val )
+      _resultGroupsStorage.push_back( val );
+  }
+  return load;
+}
+
+//================================================================================
+/*!
+ * \brief Convert result groups into _resultGroupsStorage
+ */
+//================================================================================
+
+void StdMeshers_ImportSource1D::resultGroupsToIntVec()
+{
+  _resultGroupsStorage.clear();
+  
+  // store result groups
+  TResGroupMap::iterator key2groups = _resultGroups.begin();
+  for ( ; key2groups != _resultGroups.end(); ++key2groups )
+  {
+    const pair<int, int>&          key = key2groups->first;
+    const vector<SMESH_Group*>& groups = key2groups->second;
+    // mesh ids, nb groups
+    _resultGroupsStorage.push_back( key.first );
+    _resultGroupsStorage.push_back( key.second );
+    _resultGroupsStorage.push_back( groups.size() );
+    for ( unsigned i = 0; i < groups.size(); ++i )
+    {
+      // store group names as sequence of ints each standing for a char
+      // of a name; that is to avoid pb with names containing white spaces
+      string name = groups[i]->GetGroupDS()->GetStoreName();
+      _resultGroupsStorage.push_back( name.size() );
+      for ( unsigned j = 0; j < name.size(); ++j )
+        _resultGroupsStorage.push_back( name[j] );
+    }
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Restore source groups and result groups by _resultGroupsStorage
+ */
+//================================================================================
+
+void StdMeshers_ImportSource1D::RestoreGroups(const std::vector<SMESH_Group*>& groups)
+{
+  _groups = groups;
+
+  _resultGroups.clear();
+  int i = 0;
+  while ( i < _resultGroupsStorage.size() )
+  {
+    int key1 = _resultGroupsStorage[i++];
+    int key2 = _resultGroupsStorage[i++];
+    pair<int, int> resMapKey( key1, key2 );
+    SMESH_Mesh* mesh = getTgtMeshByKey( resMapKey, _gen->GetStudyContext(_studyId));
+    // restore mesh ids at least
+    _resultGroups.insert( make_pair (resMapKey,vector<SMESH_Group*>() )); 
+
+    int nbGroups = _resultGroupsStorage[i++];
+    for ( int j = 0; j < nbGroups; ++j )
+    {
+      string::size_type nameSize = _resultGroupsStorage[i++];
+      string groupName(nameSize, '\0');
+      for ( unsigned k = 0; k < nameSize; ++k )
+        groupName[k] = (char) _resultGroupsStorage[i++];
+
+      // find a group by name
+      if ( mesh )
+      {
+        SMESH_Group* group = 0;
+        SMESH_Mesh::GroupIteratorPtr gIt = mesh->GetGroups();
+        while ( !group && gIt->more() )
+        {
+          group = gIt->next();
+          if ( !group->GetGroupDS() || groupName != group->GetGroupDS()->GetStoreName() )
+            group = 0;
+        }
+        if ( group )
+          _resultGroups[ resMapKey ].push_back( group );
+      }
+    }
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Remember groups imported from other mesh
+ *  \param groups - result groups
+ *  \param srcMesh - source mesh
+ *  \param tgtMesh - destination mesh
+ */
+//================================================================================
+
+void StdMeshers_ImportSource1D::StoreResultGroups(const std::vector<SMESH_Group*>& groups,
+                                                  const SMESHDS_Mesh&              srcMesh,
+                                                  const SMESHDS_Mesh&              tgtMesh)
+{
+  _resultGroups[ getResMapKey(srcMesh,tgtMesh) ] = groups;
+}
+
+//================================================================================
+/*!
+ * \brief Return groups imported from other mesh
+ *  \param srcMesh - source mesh
+ *  \param tgtMesh - destination mesh
+ *  \retval const std::vector<SMESH_Group*>& - groups
+ */
+//================================================================================
+
+std::vector<SMESH_Group*>*
+StdMeshers_ImportSource1D::GetResultGroups(const SMESHDS_Mesh& srcMesh,
+                                           const SMESHDS_Mesh& tgtMesh) 
+{
+  TResGroupMap::iterator key2groups = _resultGroups.find( getResMapKey(srcMesh,tgtMesh ));
+  if ( key2groups == _resultGroups.end() )
+    return 0;
+  vector<SMESH_Group*> vec = getValidGroups((*key2groups).second,
+                                            _gen->GetStudyContext(_studyId) );
+  if ( vec.size() != key2groups->second.size())
+    key2groups->second = vec;
+
+  return & key2groups->second;
+}
+
+//================================================================================
+/*!
+ * \brief Initialize ImportSource value by the mesh built on the geometry
+ * \param theMesh - the built mesh
+ * \param theShape - the geometry of interest
+ * \retval bool - true if parameter values have been successfully defined
+ */
+//================================================================================
+
+bool StdMeshers_ImportSource1D::SetParametersByMesh(const SMESH_Mesh*, const TopoDS_Shape&)
+{
+  return false;
+}
+
+//================================================================================
+/*!
+ * \brief Initialize my parameter values by default parameters.
+ *  \retval bool - true if parameter values have been successfully defined
+ */
+//================================================================================
+
+bool StdMeshers_ImportSource1D::SetParametersByDefaults(const TDefaults&, const SMESH_Mesh* )
+{
+  return false;
+}
diff --git a/src/StdMeshers/StdMeshers_ImportSource.hxx b/src/StdMeshers/StdMeshers_ImportSource.hxx
new file mode 100644 (file)
index 0000000..13287cb
--- /dev/null
@@ -0,0 +1,97 @@
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+//  SMESH StdMeshers : implementaion of SMESH idl descriptions
+//  File   : StdMeshers_ImportSource1D.hxx
+//  Module : SMESH
+//
+#ifndef _StdMeshers_ImportSource_HXX_
+#define _StdMeshers_ImportSource_HXX_
+
+#include "SMESH_StdMeshers.hxx"
+
+#include "SMESH_Hypothesis.hxx"
+#include "Utils_SALOME_Exception.hxx"
+
+#include <vector>
+#include <map>
+
+class SMESH_Group;
+class SMESHDS_Mesh;
+
+//==============================================================================
+/*!
+ * \brief Stores groups to import elements from
+ */
+//==============================================================================
+
+class STDMESHERS_EXPORT StdMeshers_ImportSource1D : public SMESH_Hypothesis
+{
+ public:
+  StdMeshers_ImportSource1D(int hypId, int studyId, SMESH_Gen * gen);
+  virtual ~ StdMeshers_ImportSource1D();
+
+  void SetGroups(const std::vector<SMESH_Group*>& groups);
+  const std::vector<SMESH_Group*>& GetGroups() const;
+
+  void SetCopySourceMesh(bool toCopyMesh, bool toCopyGroups);
+  void GetCopySourceMesh(bool& toCopyMesh, bool& toCopyGroups) const;
+  
+  virtual std::ostream & SaveTo(std::ostream & save);
+  virtual std::istream & LoadFrom(std::istream & load);
+  virtual bool SetParametersByMesh(const SMESH_Mesh* theMesh, const TopoDS_Shape& theShape);
+  virtual bool SetParametersByDefaults(const TDefaults& dflts, const SMESH_Mesh* theMesh=0);
+  void RestoreGroups(const std::vector<SMESH_Group*>& groups);
+
+  void StoreResultGroups(const std::vector<SMESH_Group*>& groups,
+                         const SMESHDS_Mesh&              srcMesh,
+                         const SMESHDS_Mesh&              tgtMesh);
+  std::vector<SMESH_Group*>* GetResultGroups(const SMESHDS_Mesh& srcMesh,
+                                             const SMESHDS_Mesh& tgtMesh);
+
+  std::vector<SMESH_Mesh*> GetSourceMeshes() const;
+
+private:
+
+  std::vector<SMESH_Group*> _groups;
+  bool _toCopyMesh, _toCopyGroups;
+
+  // groups imported using this hypothesis
+  typedef std::map< std::pair<int, int>, std::vector<SMESH_Group*> > TResGroupMap;
+  TResGroupMap      _resultGroups;
+  std::vector<int>  _resultGroupsStorage; // persistent representation of _resultGroups
+
+  void resultGroupsToIntVec();
+};
+
+//==============================================================================
+/*!
+ * \brief Redefines name and dimension of inherited StdMeshers_ImportSource1D
+ */
+//==============================================================================
+
+class STDMESHERS_EXPORT StdMeshers_ImportSource2D : public StdMeshers_ImportSource1D
+{
+ public:
+  StdMeshers_ImportSource2D(int hypId, int studyId, SMESH_Gen * gen);
+};
+#endif
diff --git a/src/StdMeshers/StdMeshers_Import_1D.cxx b/src/StdMeshers/StdMeshers_Import_1D.cxx
new file mode 100644 (file)
index 0000000..fe0f054
--- /dev/null
@@ -0,0 +1,959 @@
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+//  SMESH SMESH : implementaion of SMESH idl descriptions
+//  File   : StdMeshers_Import_1D.cxx
+//  Module : SMESH
+//
+#include "StdMeshers_Import_1D.hxx"
+#include "StdMeshers_ImportSource.hxx"
+
+#include "SMDS_MeshElement.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "SMESHDS_Group.hxx"
+#include "SMESHDS_Mesh.hxx"
+#include "SMESH_Comment.hxx"
+#include "SMESH_Gen.hxx"
+#include "SMESH_Group.hxx"
+#include "SMESH_HypoFilter.hxx"
+#include "SMESH_Mesh.hxx"
+#include "SMESH_MesherHelper.hxx"
+#include "SMESH_subMesh.hxx"
+#include "SMESH_subMeshEventListener.hxx"
+
+#include "Utils_SALOME_Exception.hxx"
+#include "utilities.h"
+
+#include <BRep_Builder.hxx>
+#include <BRep_Tool.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Compound.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Vertex.hxx>
+
+using namespace std;
+
+//=============================================================================
+/*!
+ * Creates StdMeshers_Import_1D
+ */
+//=============================================================================
+
+StdMeshers_Import_1D::StdMeshers_Import_1D(int hypId, int studyId, SMESH_Gen * gen)
+  :SMESH_1D_Algo(hypId, studyId, gen), _sourceHyp(0)
+{
+  MESSAGE("StdMeshers_Import_1D::StdMeshers_Import_1D");
+  _name = "Import_1D";
+  _shapeType = (1 << TopAbs_EDGE);
+
+  _compatibleHypothesis.push_back("ImportSource1D");
+}
+
+//=============================================================================
+/*!
+ * Check presence of a hypothesis
+ */
+//=============================================================================
+
+bool StdMeshers_Import_1D::CheckHypothesis
+                         (SMESH_Mesh&                          aMesh,
+                          const TopoDS_Shape&                  aShape,
+                          SMESH_Hypothesis::Hypothesis_Status& aStatus)
+{
+  _sourceHyp = 0;
+
+  const list <const SMESHDS_Hypothesis * >&hyps = GetUsedHypothesis(aMesh, aShape);
+  if ( hyps.size() == 0 )
+  {
+    aStatus = SMESH_Hypothesis::HYP_MISSING;
+    return false;  // can't work with no hypothesis
+  }
+
+  if ( hyps.size() > 1 )
+  {
+    aStatus = SMESH_Hypothesis::HYP_ALREADY_EXIST;
+    return false;
+  }
+
+  const SMESHDS_Hypothesis *theHyp = hyps.front();
+
+  string hypName = theHyp->GetName();
+
+  if (hypName == _compatibleHypothesis.front())
+  {
+    _sourceHyp = (StdMeshers_ImportSource1D *)theHyp;
+    aStatus = SMESH_Hypothesis::HYP_OK;
+    return true;
+  }
+
+  aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE;
+  return true;
+}
+
+//================================================================================
+namespace // INTERNAL STUFF
+//================================================================================
+{
+  int getSubmeshIDForCopiedMesh(const SMESHDS_Mesh* srcMeshDS, SMESH_Mesh* tgtMesh);
+
+  enum _ListenerDataType
+    {
+      WAIT_HYP_MODIF=1, // data indicating awaiting for valid parameters of src hyp
+      SRC_HYP // data storing ImportSource hyp
+    };
+  //================================================================================
+  /*!
+   * \brief _ListenerData holding ImportSource hyp holding in its turn
+   *  imported groups
+   */
+  struct _ListenerData : public SMESH_subMeshEventListenerData
+  {
+    const StdMeshers_ImportSource1D* _srcHyp;
+    _ListenerData(const StdMeshers_ImportSource1D* h):
+      SMESH_subMeshEventListenerData(/*isDeletable=*/true), _srcHyp(h)
+    {
+      myType = SRC_HYP; 
+    }
+  };
+  //================================================================================
+  /*!
+   * \brief Container of data dedicated to one source mesh
+   */
+  struct _ImportData
+  {
+    const SMESH_Mesh* _srcMesh;
+    StdMeshers_Import_1D::TNodeNodeMap _n2n;
+    StdMeshers_Import_1D::TElemElemMap _e2e;
+
+    set< SMESH_subMesh*> _subM; // submeshes relating to this srcMesh
+    set< SMESH_subMesh*> _copyMeshSubM; // submeshes requesting mesh copying
+    set< SMESH_subMesh*> _copyGroupSubM; // submeshes requesting mesh copying
+    set< SMESH_subMesh*> _computedSubM;
+
+    SMESHDS_SubMesh*     _importMeshSubDS; // submesh storing a copy of _srcMesh
+    int                  _importMeshSubID; // id of _importMeshSubDS
+
+    _ImportData(const SMESH_Mesh* srcMesh=0):
+      _srcMesh(srcMesh), _importMeshSubDS(0),_importMeshSubID(-1) {}
+
+    void removeImportedMesh( SMESHDS_Mesh* meshDS )
+    {
+      if ( !_importMeshSubDS ) return;
+      SMDS_ElemIteratorPtr eIt = _importMeshSubDS->GetElements();
+      while ( eIt->more() )
+        meshDS->RemoveFreeElement( eIt->next(), _importMeshSubDS, /*fromGroups=*/false );
+      SMDS_NodeIteratorPtr nIt = _importMeshSubDS->GetNodes();
+      while ( nIt->more() )
+        meshDS->RemoveFreeNode( nIt->next(), _importMeshSubDS, /*fromGroups=*/false );
+      _n2n.clear();
+      _e2e.clear();
+    }
+    void removeGroups( SMESH_subMesh* subM, const StdMeshers_ImportSource1D* srcHyp )
+    {
+      if ( !srcHyp ) return;
+      SMESH_Mesh*           tgtMesh = subM->GetFather();
+      const SMESHDS_Mesh* tgtMeshDS = tgtMesh->GetMeshDS();
+      const SMESHDS_Mesh* srcMeshDS = _srcMesh->GetMeshDS();
+      vector<SMESH_Group*>*  groups =
+        const_cast<StdMeshers_ImportSource1D*>(srcHyp)->GetResultGroups(*srcMeshDS,*tgtMeshDS);
+      if ( groups )
+      {
+        for ( unsigned i = 0; i < groups->size(); ++i )
+          tgtMesh->RemoveGroup( groups->at(i)->GetGroupDS()->GetID() );
+        groups->clear();
+      }
+    }
+    void trackHypParams( SMESH_subMesh* sm, const StdMeshers_ImportSource1D* srcHyp )
+    {
+      if ( !srcHyp ) return;
+      bool toCopyMesh, toCopyGroups;
+      srcHyp->GetCopySourceMesh(toCopyMesh, toCopyGroups);
+
+      if ( toCopyMesh )_copyMeshSubM.insert( sm );
+      else             _copyMeshSubM.erase( sm );
+
+      if ( toCopyGroups ) _copyGroupSubM.insert( sm );
+      else                _copyGroupSubM.erase( sm );
+    }
+  };
+  //================================================================================
+  /*!
+   * Listener notified on events of an imported submesh
+   */
+  class _Listener : public SMESH_subMeshEventListener
+  {
+    typedef map< SMESH_Mesh*, list< _ImportData > > TMesh2ImpData;
+    TMesh2ImpData _tgtMesh2ImportData;
+
+    _Listener():SMESH_subMeshEventListener(/*isDeletable=*/false){}
+
+  public:
+    // return poiter to a static listener
+    static _Listener* get() { static _Listener theListener; return &theListener; }
+
+    //--------------------------------------------------------------------------------
+    /*!
+     * \brief Find or create ImportData for given meshes
+     */
+    static _ImportData* getImportData(const SMESH_Mesh* srcMesh,
+                                       SMESH_Mesh*       tgtMesh)
+    {
+      list< _ImportData >& dList = get()->_tgtMesh2ImportData[tgtMesh];
+      list< _ImportData >::iterator d = dList.begin();
+      for ( ; d != dList.end(); ++d )
+        if ( d->_srcMesh == srcMesh )
+          return &*d;
+      dList.push_back(_ImportData(srcMesh));
+      return &dList.back();
+    }
+
+    //--------------------------------------------------------------------------------
+    /*!
+     * \brief Remember an imported mesh and groups 
+     *  \param smDS - submesh DS holding the imported mesh
+     *  \param sm - submesh computed by Import algo
+     *  \param srcMeshDS - source mesh
+     *  \param srcHyp - ImportSource hypothesis
+     */
+    static _ImportData* storeImportSubmesh(SMESH_subMesh*                   importSub,
+                                           const SMESH_Mesh*                srcMesh,
+                                           const StdMeshers_ImportSource1D* srcHyp)
+    {
+      // set listener to hear events of the submesh computed by "Import" algo
+      importSub->SetEventListener( get(), new _ListenerData(srcHyp), importSub );
+
+      // set a listener to hear events of the source mesh
+      SMESH_subMesh* smToNotify = importSub;
+      SMESH_subMesh* smToListen = srcMesh->GetSubMeshContaining(1);
+      importSub->SetEventListener
+        ( new SMESH_subMeshEventListener(/*isDeletable=*/true),
+          SMESH_subMeshEventListenerData::MakeData( smToNotify ),
+          smToListen );
+
+      // remeber the submesh
+      _ImportData* iData = _Listener::getImportData( srcMesh, importSub->GetFather());
+      iData->_subM.insert( importSub );
+      iData->trackHypParams( importSub, srcHyp );
+      if ( !importSub->IsEmpty() )
+        iData->_computedSubM.insert( importSub );
+      if ( !iData->_copyMeshSubM.empty() && iData->_importMeshSubID < 1 )
+      {
+        SMESH_Mesh* tgtMesh = importSub->GetFather();
+        iData->_importMeshSubID = getSubmeshIDForCopiedMesh( srcMesh->GetMeshDS(),tgtMesh);
+        iData->_importMeshSubDS = tgtMesh->GetMeshDS()->NewSubMesh( iData->_importMeshSubID );
+      }
+      if ( !importSub->IsEmpty() )
+        iData->_computedSubM.insert( importSub );
+
+      return iData;
+    }
+    //--------------------------------------------------------------------------------
+    /*!
+     * \brief mark sm as missing src hyp with valid groups
+     */
+    static void waitHypModification(SMESH_subMesh* sm)
+    {
+      sm->SetEventListener
+        (get(), SMESH_subMeshEventListenerData::MakeData( sm, WAIT_HYP_MODIF ), sm);
+    }
+
+    //--------------------------------------------------------------------------------
+    /*!
+     * \brief Remove imported mesh and/or groups as soon as no more imported submeshes
+     *               remain computed
+     *  \param sm - submesh loosing Import algo
+     *  \param data - data holding imported groups
+     */
+    void removeSubmesh( SMESH_subMesh* sm, _ListenerData* data )
+    {
+      list< _ImportData > &  dList = _tgtMesh2ImportData[ sm->GetFather() ];
+      list< _ImportData >::iterator d = dList.begin();
+      for ( ; d != dList.end(); ++d )
+        if ( (*d)._subM.erase( sm ))
+        {
+          d->_computedSubM.erase( sm );
+          bool rmMesh   = d->_copyMeshSubM.erase( sm ) && d->_copyMeshSubM.empty();
+          bool rmGroups = (d->_copyGroupSubM.erase( sm ) && d->_copyGroupSubM.empty()) || rmMesh;
+          if ( rmMesh )
+            d->removeImportedMesh( sm->GetFather()->GetMeshDS() );
+          if ( rmGroups && data )
+            d->removeGroups( sm, data->_srcHyp );
+        }
+    }
+    //--------------------------------------------------------------------------------
+    /*!
+     * \brief Remove imported mesh and/or groups and
+     * clear all submeshes with common source mesh
+     *  \param sm - cleared submesh
+     *  \param data - data holding imported groups
+     */
+    void clearSubmesh( SMESH_subMesh* sm, _ListenerData* data )
+    {
+      list< _ImportData > &  dList = _tgtMesh2ImportData[ sm->GetFather() ];
+      list< _ImportData >::iterator d = dList.begin();
+      for ( ; d != dList.end(); ++d )
+      {
+        if ( !d->_subM.count( sm )) continue;
+        if ( (*d)._computedSubM.erase( sm ) )
+        {
+          bool copyMesh = !d->_copyMeshSubM.empty();
+          if ( copyMesh )
+          {
+            // clear submeshes
+            if ( !d->_computedSubM.empty() )
+            {
+              set< SMESH_subMesh*> subs;
+              subs.swap( d->_computedSubM ); // avoid recursion via events
+              while ( !subs.empty() )
+              {
+                SMESH_subMesh* subM = *subs.begin(); subs.erase( subs.begin() );
+                _ListenerData* hypData = (_ListenerData*) subM->GetEventListenerData( get() );
+                if ( hypData )
+                  d->removeGroups( sm, hypData->_srcHyp );
+                
+                subM->ComputeStateEngine( SMESH_subMesh::CLEAN );
+              }
+            }
+            // remove imported mesh and groups
+            d->removeImportedMesh( sm->GetFather()->GetMeshDS() );
+
+            if ( data )
+              d->removeGroups( sm, data->_srcHyp );
+          }
+        }
+        if ( data )
+          d->trackHypParams( sm, data->_srcHyp );
+        d->_n2n.clear();
+        d->_e2e.clear();
+      }
+    }
+    //--------------------------------------------------------------------------------
+    /*!
+     * \brief Remove imported mesh and/or groups
+     */
+    virtual void ProcessEvent(const int                       event,
+                              const int                       eventType,
+                              SMESH_subMesh*                  subMesh,
+                              SMESH_subMeshEventListenerData* data,
+                              const SMESH_Hypothesis*         /*hyp*/)
+    {
+      if ( data && data->myType == WAIT_HYP_MODIF )
+      {
+        if ( SMESH_subMesh::MODIF_HYP  == event &&
+             SMESH_subMesh::ALGO_EVENT == eventType )
+        {
+          SMESH_Gen* gen = subMesh->GetFather()->GetGen();
+          if ( SMESH_Algo* algo = gen->GetAlgo(*subMesh->GetFather(), subMesh->GetSubShape()))
+            algo->SetEventListener( subMesh );
+        }
+      }
+      else
+      {
+        SMESH_Gen* gen = subMesh->GetFather()->GetGen();
+        SMESH_Algo* algo = gen->GetAlgo(*subMesh->GetFather(),subMesh->GetSubShape() );
+
+        if ( subMesh->GetAlgoState() != SMESH_subMesh::HYP_OK ||
+             strncmp( "Import", algo->GetName(), 6 ) != 0 )
+        {
+          // treate removal of Import algo from subMesh
+          removeSubmesh( subMesh, (_ListenerData*) data );
+        }
+        else if ( subMesh->IsEmpty() )
+        {
+          // treate modification of ImportSource hypothesis
+          clearSubmesh( subMesh, (_ListenerData*) data );
+        }
+        else if ( SMESH_subMesh::CHECK_COMPUTE_STATE == event &&
+                  SMESH_subMesh::COMPUTE_EVENT       == eventType )
+        {
+          // check compute state of all submeshes impoting from same src mesh;
+          // this is to take into account 1D computed submeshes hidden by 2D import algo;
+          // else source mesh is not copied as _subM.size != _computedSubM.size()
+          list< _ImportData > &  dList = _tgtMesh2ImportData[ subMesh->GetFather() ];
+          list< _ImportData >::iterator d = dList.begin();
+          for ( ; d != dList.end(); ++d )
+            if ( d->_subM.count( subMesh ))
+            {
+              set<SMESH_subMesh*>::iterator smIt = d->_subM.begin();
+              for( ; smIt != d->_subM.end(); ++smIt )
+                if ( (*smIt)->IsMeshComputed() )
+                  d->_computedSubM.insert( *smIt);
+            }
+        }
+      }
+    }
+  }; // class _Listener
+
+  //================================================================================
+  /*!
+   * \brief Return an ID of submesh to store nodes and elements of a copied mesh
+   */
+  //================================================================================
+
+  int getSubmeshIDForCopiedMesh(const SMESHDS_Mesh* srcMeshDS,
+                                SMESH_Mesh*         tgtMesh)
+  {
+    // To get SMESH_subMesh corresponding to srcMeshDS we need to have a shape
+    // for which SMESHDS_Mesh::IsGroupOfSubShapes() returns true.
+    // And this shape must be different from subshapes of the main shape.
+    // So we create a compound containing
+    // 1) some sub-shapes of SMESH_Mesh::PseudoShape() corresponding to
+    //    srcMeshDS->GetPersistentId()
+    // 2) the 1-st vertex of the main shape to assure
+    //    SMESHDS_Mesh::IsGroupOfSubShapes(shape)==true
+    TopoDS_Shape shapeForSrcMesh;
+    TopTools_IndexedMapOfShape pseudoSubShapes;
+    TopExp::MapShapes( SMESH_Mesh::PseudoShape(), pseudoSubShapes );
+
+    // index of pseudoSubShapes corresponding to srcMeshDS
+    int subIndex = srcMeshDS->GetPersistentId() % pseudoSubShapes.Extent();
+    int nbSubShapes = 1 + srcMeshDS->GetPersistentId() / pseudoSubShapes.Extent();
+
+    // try to find already present shapeForSrcMesh
+    SMESHDS_Mesh* tgtMeshDS = tgtMesh->GetMeshDS();
+    for ( int i = tgtMeshDS->MaxShapeIndex(); i > 0 && shapeForSrcMesh.IsNull(); --i )
+    {
+      const TopoDS_Shape& s = tgtMeshDS->IndexToShape(i);
+      if ( s.ShapeType() != TopAbs_COMPOUND ) break;
+      TopoDS_Iterator sSubIt( s );
+      for ( int iSub = 0; iSub < nbSubShapes && sSubIt.More(); ++iSub, sSubIt.Next() )
+        if ( pseudoSubShapes( subIndex+iSub ).IsSame( sSubIt.Value()))
+          if ( iSub+1 == nbSubShapes )
+          {
+            shapeForSrcMesh = s;
+            break;
+          }
+    }
+    if ( shapeForSrcMesh.IsNull() )
+    {
+      // make a new shapeForSrcMesh
+      BRep_Builder aBuilder;
+      TopoDS_Compound comp;
+      aBuilder.MakeCompound( comp );
+      shapeForSrcMesh = comp;
+      for ( int iSub = 0; iSub < nbSubShapes; ++iSub )
+        aBuilder.Add( comp, pseudoSubShapes( subIndex+iSub ));
+      TopExp_Explorer vExp( tgtMeshDS->ShapeToMesh(), TopAbs_VERTEX );
+      aBuilder.Add( comp, vExp.Current() );
+    }
+    SMESH_subMesh* sm = tgtMesh->GetSubMesh( shapeForSrcMesh );
+    SMESHDS_SubMesh* smDS = sm->GetSubMeshDS();
+    if ( !smDS )
+      smDS = tgtMeshDS->NewSubMesh( sm->GetId() );
+
+    // make ordinary submesh from a complex one
+    if ( smDS->IsComplexSubmesh() )
+    {
+      list< const SMESHDS_SubMesh* > subSM;
+      SMESHDS_SubMeshIteratorPtr smIt = smDS->GetSubMeshIterator();
+      while ( smIt->more() ) subSM.push_back( smIt->next() );
+      list< const SMESHDS_SubMesh* >::iterator sub = subSM.begin();
+      for ( ; sub != subSM.end(); ++sub)
+        smDS->RemoveSubMesh( *sub );
+    }
+    return sm->GetId();
+  }
+
+  //================================================================================
+  /*!
+   * \brief Return a submesh to store nodes and elements of a copied mesh
+   * and set event listeners in order to clear
+   * imported mesh and groups as soon as submesh state requires it
+   */
+  //================================================================================
+
+  SMESHDS_SubMesh* getSubmeshForCopiedMesh(const SMESH_Mesh*                    srcMesh,
+                                           SMESH_Mesh*                          tgtMesh,
+                                           const TopoDS_Shape&                  tgtShape,
+                                           StdMeshers_Import_1D::TNodeNodeMap*& n2n,
+                                           StdMeshers_Import_1D::TElemElemMap*& e2e,
+                                           bool &                               toCopyGroups)
+  {
+    StdMeshers_Import_1D::getMaps( srcMesh, tgtMesh, n2n,e2e );
+
+    _ImportData* iData = _Listener::getImportData(srcMesh,tgtMesh);
+
+    SMESH_subMesh* importedSM = tgtMesh->GetSubMesh( tgtShape );
+    iData->_computedSubM.insert( importedSM );
+    if ( iData->_computedSubM.size() != iData->_subM.size() )
+      return 0; // not all submeshes computed yet
+
+    toCopyGroups = !iData->_copyGroupSubM.empty();
+
+    if ( !iData->_copyMeshSubM.empty())
+    {
+      // make submesh to store a copied mesh
+      int smID = getSubmeshIDForCopiedMesh( srcMesh->GetMeshDS(), tgtMesh );
+      SMESHDS_SubMesh* subDS = tgtMesh->GetMeshDS()->NewSubMesh( smID );
+
+      iData->_importMeshSubID = smID;
+      iData->_importMeshSubDS = subDS;
+      return subDS;
+    }
+    return 0;
+  }
+
+} // namespace
+
+
+//=============================================================================
+/*!
+ * Import elements from the other mesh 
+ */
+//=============================================================================
+
+bool StdMeshers_Import_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & theShape)
+{
+  if ( !_sourceHyp ) return false;
+
+  const vector<SMESH_Group*>& srcGroups = _sourceHyp->GetGroups();
+  if ( srcGroups.empty() )
+    return error("Invalid source groups");
+
+  SMESH_MesherHelper helper(theMesh);
+  helper.SetSubShape(theShape);
+  SMESHDS_Mesh* tgtMesh = theMesh.GetMeshDS();
+
+  const TopoDS_Edge& geomEdge = TopoDS::Edge( theShape );
+  const double edgeTol = BRep_Tool::Tolerance( geomEdge );
+  const int shapeID = tgtMesh->ShapeToIndex( geomEdge );
+
+  set<int> subShapeIDs;
+  subShapeIDs.insert( shapeID );
+
+  // get nodes on vertices
+  list < SMESH_MeshEditor::TNodeXYZ > vertexNodes;
+  list < SMESH_MeshEditor::TNodeXYZ >::iterator vNIt;
+  TopExp_Explorer vExp( theShape, TopAbs_VERTEX );
+  for ( ; vExp.More(); vExp.Next() )
+  {
+    const TopoDS_Vertex& v = TopoDS::Vertex( vExp.Current() );
+    if ( !subShapeIDs.insert( tgtMesh->ShapeToIndex( v )).second )
+      continue; // closed edge
+    const SMDS_MeshNode* n = SMESH_Algo::VertexNode( v, tgtMesh );
+    if ( !n )
+    {
+      _gen->Compute(theMesh,v,/*anUpward=*/true);
+      n = SMESH_Algo::VertexNode( v, tgtMesh );
+      if ( !n ) return false; // very strange
+    }
+    vertexNodes.push_back( SMESH_MeshEditor::TNodeXYZ( n ));
+  }
+
+  // import edges from groups
+  TNodeNodeMap* n2n;
+  TElemElemMap* e2e;
+  for ( int iG = 0; iG < srcGroups.size(); ++iG )
+  {
+    const SMESHDS_GroupBase* srcGroup = srcGroups[iG]->GetGroupDS();
+
+    const int meshID = srcGroup->GetMesh()->GetPersistentId();
+    const SMESH_Mesh* srcMesh = GetMeshByPersistentID( meshID );
+    if ( !srcMesh ) continue;
+    getMaps( srcMesh, &theMesh, n2n, e2e );
+
+    SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements();
+    vector<const SMDS_MeshNode*> newNodes;
+    SMDS_MeshNode tmpNode(0,0,0);
+    double u;
+    while ( srcElems->more() ) // loop on group contents
+    {
+      const SMDS_MeshElement* edge = srcElems->next();
+      // find or create nodes of a new edge
+      newNodes.resize( edge->NbNodes() );
+      newNodes.back() = 0;
+      SMDS_MeshElement::iterator node = edge->begin_nodes();
+      for ( unsigned i = 0; i < newNodes.size(); ++i, ++node )
+      {
+        TNodeNodeMap::iterator n2nIt = n2n->insert( make_pair( *node, (SMDS_MeshNode*)0 )).first;
+        if ( n2nIt->second )
+        {
+          if ( !subShapeIDs.count( n2nIt->second->GetPosition()->GetShapeId() ))
+            break;
+        }
+        else
+        {
+          // find an existing vertex node
+          for ( vNIt = vertexNodes.begin(); vNIt != vertexNodes.end(); ++vNIt)
+            if ( vNIt->SquareDistance( *node ) < 10 * edgeTol * edgeTol)
+            {
+              (*n2nIt).second = vNIt->_node;
+              vertexNodes.erase( vNIt );
+              break;
+            }
+        }
+        if ( !n2nIt->second )
+        {
+          // find out if node lies on theShape
+          tmpNode.setXYZ( (*node)->X(), (*node)->Y(), (*node)->Z());
+          if ( helper.CheckNodeU( geomEdge, &tmpNode, u, 10 * edgeTol, /*force=*/true ))
+          {
+            SMDS_MeshNode* newNode = tgtMesh->AddNode( (*node)->X(), (*node)->Y(), (*node)->Z());
+            n2nIt->second = newNode;
+            tgtMesh->SetNodeOnEdge( newNode, shapeID, u );
+          }
+        }
+        if ( !(newNodes[i] = n2nIt->second ))
+          break;
+      }
+      if ( !newNodes.back() )
+        continue; // not all nodes of edge lie on theShape
+
+      // make a new edge
+      SMDS_MeshElement * newEdge;
+      if ( newNodes.size() == 3 )
+        newEdge = tgtMesh->AddEdge( newNodes[0], newNodes[1], newNodes[2] );
+      else
+        newEdge = tgtMesh->AddEdge( newNodes[0], newNodes[1]);
+      tgtMesh->SetMeshElementOnShape( newEdge, shapeID );
+      e2e->insert( make_pair( edge, newEdge ));
+    }
+  }
+  if ( n2n->empty())
+    return error("Empty source groups");
+
+  // check if the whole geom edge is covered by imported segments;
+  // the check consist in passing by segments from one vetrex node to another
+  bool isEdgeMeshed = false;
+  if ( SMESHDS_SubMesh* tgtSM = tgtMesh->MeshElements( theShape ))
+  {
+    const TopoDS_Vertex& v = ( vExp.ReInit(), TopoDS::Vertex( vExp.Current() ));
+    const SMDS_MeshNode* n = SMESH_Algo::VertexNode( v, tgtMesh );
+    const SMDS_MeshElement* seg = 0;
+    SMDS_ElemIteratorPtr segIt = n->GetInverseElementIterator(SMDSAbs_Edge);
+    while ( segIt->more() && !seg )
+      if ( !tgtSM->Contains( seg = segIt->next()))
+        seg = 0;
+    int nbPassedSegs = 0;
+    while ( seg )
+    {
+      ++nbPassedSegs;
+      const SMDS_MeshNode* n2 = seg->GetNode(0);
+      n = ( n2 == n ? seg->GetNode(1) : n2 );
+      if ( n->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX )
+        break;
+      const SMDS_MeshElement* seg2 = 0;
+      segIt = n->GetInverseElementIterator(SMDSAbs_Edge);
+      while ( segIt->more() && !seg2 )
+        if ( seg == ( seg2 = segIt->next()))
+          seg2 = 0;
+      seg = seg2;
+    }
+    if (nbPassedSegs > 0 && tgtSM->NbElements() > nbPassedSegs )
+      return error( "Source elements overlap one another");
+
+    isEdgeMeshed = ( tgtSM->NbElements() == nbPassedSegs &&
+                     n->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX );
+  }
+  if ( !isEdgeMeshed )
+    return error( "Source elements don't cover totally the geometrical edge" );
+
+  // copy meshes
+  vector<SMESH_Mesh*> srcMeshes = _sourceHyp->GetSourceMeshes();
+  for ( unsigned i = 0; i < srcMeshes.size(); ++i )
+    importMesh( srcMeshes[i], theMesh, _sourceHyp, theShape );
+
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief Copy mesh and groups
+ */
+//================================================================================
+
+void StdMeshers_Import_1D::importMesh(const SMESH_Mesh*          srcMesh,
+                                      SMESH_Mesh &               tgtMesh,
+                                      StdMeshers_ImportSource1D* srcHyp,
+                                      const TopoDS_Shape&        tgtShape)
+{
+  // get submesh to store the imported mesh
+  TNodeNodeMap* n2n;
+  TElemElemMap* e2e;
+  bool toCopyGroups;
+  SMESHDS_SubMesh* tgtSubMesh =
+    getSubmeshForCopiedMesh( srcMesh, &tgtMesh, tgtShape, n2n, e2e, toCopyGroups );
+  if ( !tgtSubMesh || tgtSubMesh->NbNodes() + tgtSubMesh->NbElements() > 0 )
+    return; // not to copy srcMeshDS twice
+
+  SMESHDS_Mesh* tgtMeshDS = tgtMesh.GetMeshDS();
+  SMESH_MeshEditor additor( &tgtMesh );
+
+  // 1. Copy mesh
+
+  vector<const SMDS_MeshNode*> newNodes;
+  const SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
+  SMDS_ElemIteratorPtr eIt = srcMeshDS->elementsIterator();
+  while ( eIt->more() )
+  {
+    const SMDS_MeshElement* elem = eIt->next();
+    TElemElemMap::iterator e2eIt = e2e->insert( make_pair( elem, (SMDS_MeshElement*)0 )).first;
+    if ( e2eIt->second ) continue; // already copied by Compute()
+    newNodes.resize( elem->NbNodes() );
+    SMDS_MeshElement::iterator node = elem->begin_nodes();
+    for ( unsigned i = 0; i < newNodes.size(); ++i, ++node )
+    {
+      TNodeNodeMap::iterator n2nIt = n2n->insert( make_pair( *node, (SMDS_MeshNode*)0 )).first;
+      if ( !n2nIt->second )
+      {
+        (*n2nIt).second = tgtMeshDS->AddNode( (*node)->X(), (*node)->Y(), (*node)->Z());
+        tgtSubMesh->AddNode( n2nIt->second );
+      }
+      newNodes[i] = n2nIt->second;
+    }
+    const SMDS_MeshElement* newElem =
+      tgtMeshDS->FindElement( newNodes, elem->GetType(), /*noMedium=*/false );
+    if ( !newElem )
+    {
+      newElem = additor.AddElement( newNodes, elem->GetType(), elem->IsPoly());
+      tgtSubMesh->AddElement( newElem );
+    }
+    if ( toCopyGroups )
+      (*e2eIt).second = newElem;
+  }
+  // copy free nodes
+  if ( srcMeshDS->NbNodes() > n2n->size() )
+  {
+    SMDS_NodeIteratorPtr nIt = srcMeshDS->nodesIterator();
+    while( nIt->more() )
+    {
+      const SMDS_MeshNode* node = nIt->next();
+      if ( node->NbInverseElements() == 0 )
+      {
+        const SMDS_MeshNode* newNode = tgtMeshDS->AddNode( node->X(), node->Y(), node->Z());
+        n2n->insert( make_pair( node, newNode ));
+        tgtSubMesh->AddNode( newNode );
+      }
+    }
+  }
+
+  // 2. Copy groups
+
+  vector<SMESH_Group*> resultGroups;
+  if ( toCopyGroups )
+  {
+    // collect names of existing groups to assure uniqueness of group names within a type
+    map< SMDSAbs_ElementType, set<string> > namesByType;
+    SMESH_Mesh::GroupIteratorPtr groupIt = tgtMesh.GetGroups();
+    while ( groupIt->more() )
+    {
+      SMESH_Group* tgtGroup = groupIt->next();
+      namesByType[ tgtGroup->GetGroupDS()->GetType() ].insert( tgtGroup->GetName() );
+    }
+    if (srcMesh)
+    {
+      SMESH_Mesh::GroupIteratorPtr groupIt = srcMesh->GetGroups();
+      while ( groupIt->more() )
+      {
+        SMESH_Group* srcGroup = groupIt->next();
+        SMESHDS_GroupBase* srcGroupDS = srcGroup->GetGroupDS();
+        string name = srcGroup->GetName();
+        int nb = 1;
+        while ( !namesByType[ srcGroupDS->GetType() ].insert( name ).second )
+          name = SMESH_Comment(srcGroup->GetName()) << "_imported_" << nb++;
+        SMESH_Group* newGroup = tgtMesh.AddGroup( srcGroupDS->GetType(), name.c_str(), nb );
+        SMESHDS_Group* newGroupDS = (SMESHDS_Group*)newGroup->GetGroupDS();
+        resultGroups.push_back( newGroup );
+
+        eIt = srcGroupDS->GetElements();
+        if ( srcGroupDS->GetType() == SMDSAbs_Node )
+          while (eIt->more())
+          {
+            TNodeNodeMap::iterator n2nIt = n2n->find((const SMDS_MeshNode*) eIt->next() );
+            if ( n2nIt != n2n->end() && n2nIt->second )
+              newGroupDS->SMDSGroup().Add((*n2nIt).second );
+          }
+        else
+          while (eIt->more())
+          {
+            TElemElemMap::iterator e2eIt = e2e->find( eIt->next() );
+            if ( e2eIt != e2e->end() && e2eIt->second )
+              newGroupDS->SMDSGroup().Add((*e2eIt).second );
+          }
+      }
+    }
+  }
+  n2n->clear();
+  e2e->clear();
+
+  // Remember created groups in order to remove them as soon as the srcHyp is
+  // modified or something other similar happens. Store them in a hypothesis
+  // as it stores its values anyway
+  srcHyp->StoreResultGroups( resultGroups, *srcMeshDS, *tgtMeshDS );
+}
+
+//=============================================================================
+/*!
+ * \brief Set needed event listeners and create a submesh for a copied mesh
+ *
+ * This method is called only if a submesh has HYP_OK algo_state.
+ */
+//=============================================================================
+
+void StdMeshers_Import_1D::setEventListener(SMESH_subMesh*             subMesh, 
+                                            StdMeshers_ImportSource1D* sourceHyp)
+{
+  if ( sourceHyp )
+  {
+    vector<SMESH_Mesh*> srcMeshes = sourceHyp->GetSourceMeshes();
+    if ( srcMeshes.empty() )
+      _Listener::waitHypModification( subMesh );
+    for ( unsigned i = 0; i < srcMeshes.size(); ++i )
+      // set a listener to remove the imported mesh and groups
+      _Listener::storeImportSubmesh( subMesh, srcMeshes[i], sourceHyp );
+  }
+}
+void StdMeshers_Import_1D::SetEventListener(SMESH_subMesh* subMesh)
+{
+  if ( !_sourceHyp )
+  {
+    const TopoDS_Shape& tgtShape = subMesh->GetSubShape();
+    SMESH_Mesh*         tgtMesh  = subMesh->GetFather();
+    Hypothesis_Status aStatus;
+    CheckHypothesis( *tgtMesh, tgtShape, aStatus );
+  }
+  setEventListener( subMesh, _sourceHyp );
+}
+
+void StdMeshers_Import_1D::SubmeshRestored(SMESH_subMesh* subMesh)
+{
+  SetEventListener(subMesh);
+}
+
+//=============================================================================
+/*!
+ * Predict nb of mesh entities created by Compute()
+ */
+//=============================================================================
+
+bool StdMeshers_Import_1D::Evaluate(SMESH_Mesh &         theMesh,
+                                    const TopoDS_Shape & theShape,
+                                    MapShapeNbElems&     aResMap)
+{
+  if ( !_sourceHyp ) return false;
+
+  const vector<SMESH_Group*>& srcGroups = _sourceHyp->GetGroups();
+  if ( srcGroups.empty() )
+    return error("Invalid source groups");
+
+  vector<int> aVec(SMDSEntity_Last,0);
+
+  bool toCopyMesh, toCopyGroups;
+  _sourceHyp->GetCopySourceMesh(toCopyMesh, toCopyGroups);
+  if ( toCopyMesh ) // the whole mesh is copied
+  {
+    vector<SMESH_Mesh*> srcMeshes = _sourceHyp->GetSourceMeshes();
+    for ( unsigned i = 0; i < srcMeshes.size(); ++i )
+    {
+      SMESH_subMesh* sm = getSubMeshOfCopiedMesh( theMesh, *srcMeshes[i]);
+      if ( !sm || aResMap.count( sm )) continue; // already counted
+      aVec.assign( SMDSEntity_Last, 0);
+      const SMDS_MeshInfo& aMeshInfo = srcMeshes[i]->GetMeshDS()->GetMeshInfo();
+      for (int i = 0; i < SMDSEntity_Last; i++)
+        aVec[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
+    }
+  }
+  else
+  {
+    SMESH_MesherHelper helper(theMesh);
+
+    const TopoDS_Edge& geomEdge = TopoDS::Edge( theShape );
+    const double edgeTol = helper.MaxTolerance( geomEdge );
+
+    // take into account nodes on vertices
+    TopExp_Explorer vExp( theShape, TopAbs_VERTEX );
+    for ( ; vExp.More(); vExp.Next() )
+      theMesh.GetSubMesh( vExp.Current())->Evaluate( aResMap );
+
+    // count edges imported from groups
+    int nbEdges = 0, nbQuadEdges = 0;
+    for ( int iG = 0; iG < srcGroups.size(); ++iG )
+    {
+      const SMESHDS_GroupBase* srcGroup = srcGroups[iG]->GetGroupDS();
+      SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements();
+      SMDS_MeshNode tmpNode(0,0,0);
+      while ( srcElems->more() ) // loop on group contents
+      {
+        const SMDS_MeshElement* edge = srcElems->next();
+        // find out if edge is located on geomEdge by projecting
+        // a middle of edge to geomEdge
+        SMESH_MeshEditor::TNodeXYZ p1( edge->GetNode(0));
+        SMESH_MeshEditor::TNodeXYZ p2( edge->GetNode(1));
+        gp_XYZ middle = ( p1 + p2 ) / 2.;
+        tmpNode.setXYZ( middle.X(), middle.Y(), middle.Z());
+        double u = 0;
+        if ( helper.CheckNodeU( geomEdge, &tmpNode, u, 10 * edgeTol, /*force=*/true ))
+          ++( edge->IsQuadratic() ? nbQuadEdges : nbEdges);
+      }
+    }
+
+    int nbNodes = nbEdges + 2 * nbQuadEdges - 1;
+
+    aVec[SMDSEntity_Node     ] = nbNodes;
+    aVec[SMDSEntity_Edge     ] = nbEdges;
+    aVec[SMDSEntity_Quad_Edge] = nbQuadEdges;
+  }
+
+  SMESH_subMesh * sm = theMesh.GetSubMesh(theShape);
+  aResMap.insert(make_pair(sm,aVec));
+
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief Return node-node and element-element maps for import of geiven source mesh
+ */
+//================================================================================
+
+void StdMeshers_Import_1D::getMaps(const SMESH_Mesh* srcMesh,
+                                   SMESH_Mesh*       tgtMesh,
+                                   TNodeNodeMap*&    n2n,
+                                   TElemElemMap*&    e2e)
+{
+  _ImportData* iData = _Listener::getImportData(srcMesh,tgtMesh);
+  n2n = &iData->_n2n;
+  e2e = &iData->_e2e;
+  if ( iData->_copyMeshSubM.empty() )
+  {
+    n2n->clear();
+    e2e->clear();
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Return submesh corresponding to the copied mesh
+ */
+//================================================================================
+
+SMESH_subMesh* StdMeshers_Import_1D::getSubMeshOfCopiedMesh( SMESH_Mesh& tgtMesh,
+                                                             SMESH_Mesh& srcMesh )
+{
+  _ImportData* iData = _Listener::getImportData(&srcMesh,&tgtMesh);
+  if ( iData->_copyMeshSubM.empty() ) return 0;
+  SMESH_subMesh* sm = tgtMesh.GetSubMeshContaining( iData->_importMeshSubID );
+  return sm;
+}
+
diff --git a/src/StdMeshers/StdMeshers_Import_1D.hxx b/src/StdMeshers/StdMeshers_Import_1D.hxx
new file mode 100644 (file)
index 0000000..a3ab382
--- /dev/null
@@ -0,0 +1,81 @@
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+//  SMESH SMESH : implementaion of SMESH idl descriptions
+//  Module : SMESH
+//
+#ifndef _SMESH_Import_1D_HXX_
+#define _SMESH_Import_1D_HXX_
+
+#include "SMESH_StdMeshers.hxx"
+
+#include "SMESH_1D_Algo.hxx"
+#include "SMDS_MeshElement.hxx"
+
+class StdMeshers_ImportSource1D;
+
+/*!
+ * \brief Copy elements from other the mesh
+ */
+class STDMESHERS_EXPORT StdMeshers_Import_1D: public SMESH_1D_Algo
+{
+public:
+  StdMeshers_Import_1D(int hypId, int studyId, SMESH_Gen* gen);
+
+  virtual bool CheckHypothesis(SMESH_Mesh& aMesh,
+                               const TopoDS_Shape& aShape,
+                               SMESH_Hypothesis::Hypothesis_Status& aStatus);
+
+  virtual bool Compute (SMESH_Mesh & aMesh, const TopoDS_Shape & aShape);
+  virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+                        MapShapeNbElems& aResMap);
+
+  virtual void SetEventListener(SMESH_subMesh* subMesh);
+  virtual void SubmeshRestored(SMESH_subMesh* subMesh);
+
+  // internal utilities
+
+  typedef std::map<const SMDS_MeshNode*,   const SMDS_MeshNode*,   TIDCompare> TNodeNodeMap;
+  typedef std::map<const SMDS_MeshElement*,const SMDS_MeshElement*,TIDCompare> TElemElemMap;
+
+  static void getMaps(const SMESH_Mesh* srcMesh,
+                      SMESH_Mesh*       tgtMesh,
+                      TNodeNodeMap*&    n2n,
+                      TElemElemMap*&    e2e);
+
+  static void importMesh(const SMESH_Mesh*          srcMesh,
+                         SMESH_Mesh &               tgtMesh,
+                         StdMeshers_ImportSource1D* srcHyp,
+                         const TopoDS_Shape&        tgtShape);
+
+  static void setEventListener( SMESH_subMesh*             subMesh,
+                                StdMeshers_ImportSource1D* sourceHyp );
+
+  static SMESH_subMesh* getSubMeshOfCopiedMesh( SMESH_Mesh& tgtMesh,
+                                                SMESH_Mesh& srcMesh );
+
+ private:
+  
+  StdMeshers_ImportSource1D* _sourceHyp;
+};
+
+#endif
diff --git a/src/StdMeshers/StdMeshers_Import_1D2D.cxx b/src/StdMeshers/StdMeshers_Import_1D2D.cxx
new file mode 100644 (file)
index 0000000..0062de3
--- /dev/null
@@ -0,0 +1,642 @@
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+//  SMESH SMESH : implementaion of SMESH idl descriptions
+//  File   : StdMeshers_Import_1D2D.cxx
+//  Module : SMESH
+//
+#include "StdMeshers_Import_1D2D.hxx"
+
+#include "StdMeshers_Import_1D.hxx"
+#include "StdMeshers_ImportSource.hxx"
+
+#include "SMDS_MeshElement.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "SMESHDS_Group.hxx"
+#include "SMESHDS_Mesh.hxx"
+#include "SMESH_Comment.hxx"
+#include "SMESH_Gen.hxx"
+#include "SMESH_Group.hxx"
+#include "SMESH_Mesh.hxx"
+#include "SMESH_MesherHelper.hxx"
+#include "SMESH_subMesh.hxx"
+
+#include "Utils_SALOME_Exception.hxx"
+#include "utilities.h"
+
+#include <BRep_Builder.hxx>
+#include <BRep_Tool.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Compound.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Vertex.hxx>
+
+#include <numeric>
+
+using namespace std;
+
+//=============================================================================
+/*!
+ * Creates StdMeshers_Import_1D2D
+ */
+//=============================================================================
+
+StdMeshers_Import_1D2D::StdMeshers_Import_1D2D(int hypId, int studyId, SMESH_Gen * gen)
+  :SMESH_2D_Algo(hypId, studyId, gen), _sourceHyp(0)
+{
+  MESSAGE("StdMeshers_Import_1D2D::StdMeshers_Import_1D2D");
+  _name = "Import_1D2D";
+  _shapeType = (1 << TopAbs_FACE);
+
+  _compatibleHypothesis.push_back("ImportSource2D");
+  _requireDescretBoundary = false;
+}
+
+//=============================================================================
+/*!
+ * Check presence of a hypothesis
+ */
+//=============================================================================
+
+bool StdMeshers_Import_1D2D::CheckHypothesis
+                         (SMESH_Mesh&                          aMesh,
+                          const TopoDS_Shape&                  aShape,
+                          SMESH_Hypothesis::Hypothesis_Status& aStatus)
+{
+  _sourceHyp = 0;
+
+  const list <const SMESHDS_Hypothesis * >&hyps = GetUsedHypothesis(aMesh, aShape);
+  if ( hyps.size() == 0 )
+  {
+    aStatus = SMESH_Hypothesis::HYP_MISSING;
+    return false;  // can't work with no hypothesis
+  }
+
+  if ( hyps.size() > 1 )
+  {
+    aStatus = SMESH_Hypothesis::HYP_ALREADY_EXIST;
+    return false;
+  }
+
+  const SMESHDS_Hypothesis *theHyp = hyps.front();
+
+  string hypName = theHyp->GetName();
+
+  if (hypName == _compatibleHypothesis.front())
+  {
+    _sourceHyp = (StdMeshers_ImportSource1D *)theHyp;
+    aStatus = SMESH_Hypothesis::HYP_OK;
+    return true;
+  }
+
+  aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE;
+  return true;
+}
+
+namespace
+{
+  /*!
+   * \brief OrientedLink additionally storing a medium node
+   */
+  struct TLink : public SMESH_OrientedLink
+  {
+    const SMDS_MeshNode* _medium;
+    TLink( const SMDS_MeshNode* n1,
+           const SMDS_MeshNode* n2,
+           const SMDS_MeshNode* medium=0)
+      : SMESH_OrientedLink( n1,n2 ), _medium( medium ) {}
+  };
+}
+
+//=============================================================================
+/*!
+ * Import elements from the other mesh 
+ */
+//=============================================================================
+
+bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & theShape)
+{
+  if ( !_sourceHyp ) return false;
+
+  const vector<SMESH_Group*>& srcGroups = _sourceHyp->GetGroups();
+  if ( srcGroups.empty() )
+    return error("Invalid source groups");
+
+  SMESH_MesherHelper helper(theMesh);
+  helper.SetSubShape(theShape);
+  SMESHDS_Mesh* tgtMesh = theMesh.GetMeshDS();
+
+  const TopoDS_Face& geomFace = TopoDS::Face( theShape );
+  const double faceTol = helper.MaxTolerance( geomFace );
+  const int shapeID = tgtMesh->ShapeToIndex( geomFace );
+  const bool toCheckOri = (helper.NbAncestors( geomFace, theMesh, TopAbs_SOLID ) == 1 );
+
+  Handle(Geom_Surface) surface = BRep_Tool::Surface( geomFace );
+  if ( helper.GetSubShapeOri( tgtMesh->ShapeToMesh(), geomFace) == TopAbs_REVERSED )
+    surface->UReverse();
+  gp_Pnt p; gp_Vec du, dv;
+
+  set<int> subShapeIDs;
+  subShapeIDs.insert( shapeID );
+
+  // get nodes on vertices
+  list < SMESH_MeshEditor::TNodeXYZ > vertexNodes;
+  list < SMESH_MeshEditor::TNodeXYZ >::iterator vNIt;
+  TopExp_Explorer exp( theShape, TopAbs_VERTEX );
+  for ( ; exp.More(); exp.Next() )
+  {
+    const TopoDS_Vertex& v = TopoDS::Vertex( exp.Current() );
+    if ( !subShapeIDs.insert( tgtMesh->ShapeToIndex( v )).second )
+      continue;
+    const SMDS_MeshNode* n = SMESH_Algo::VertexNode( v, tgtMesh );
+    if ( !n )
+    {
+      _gen->Compute(theMesh,v,/*anUpward=*/true);
+      n = SMESH_Algo::VertexNode( v, tgtMesh );
+      if ( !n ) return false; // very strange
+    }
+    vertexNodes.push_back( SMESH_MeshEditor::TNodeXYZ( n ));
+  }
+
+  // to count now many times a link between nodes encounters
+  map<TLink, int> linkCount;
+  map<TLink, int>::iterator link2Nb;
+
+  // =========================
+  // Import faces from groups
+  // =========================
+
+  StdMeshers_Import_1D::TNodeNodeMap* n2n;
+  StdMeshers_Import_1D::TElemElemMap* e2e;
+  vector<const SMDS_MeshNode*> newNodes;
+  for ( int iG = 0; iG < srcGroups.size(); ++iG )
+  {
+    const SMESHDS_GroupBase* srcGroup = srcGroups[iG]->GetGroupDS();
+
+    const int meshID = srcGroup->GetMesh()->GetPersistentId();
+    const SMESH_Mesh* srcMesh = GetMeshByPersistentID( meshID );
+    if ( !srcMesh ) continue;
+    StdMeshers_Import_1D::getMaps( srcMesh, &theMesh, n2n, e2e );
+
+    SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements();
+    SMDS_MeshNode tmpNode(0,0,0);
+    gp_XY uv;
+    while ( srcElems->more() ) // loop on group contents
+    {
+      const SMDS_MeshElement* face = srcElems->next();
+      // find or create nodes of a new face
+      newNodes.resize( face->NbNodes() );
+      newNodes.back() = 0;
+      int nbCreatedNodes = 0;
+      SMDS_MeshElement::iterator node = face->begin_nodes();
+      for ( unsigned i = 0; i < newNodes.size(); ++i, ++node )
+      {
+        TNodeNodeMap::iterator n2nIt = n2n->insert( make_pair( *node, (SMDS_MeshNode*)0 )).first;
+        if ( n2nIt->second )
+        {
+          if ( !subShapeIDs.count( n2nIt->second->GetPosition()->GetShapeId() ))
+            break;
+        }
+        else
+        {
+          // find an existing vertex node
+          for ( vNIt = vertexNodes.begin(); vNIt != vertexNodes.end(); ++vNIt)
+            if ( vNIt->SquareDistance( *node ) < 10 * faceTol * faceTol)
+            {
+              (*n2nIt).second = vNIt->_node;
+              vertexNodes.erase( vNIt );
+              break;
+            }
+        }
+        if ( !n2nIt->second )
+        {
+          // find out if node lies on theShape
+          tmpNode.setXYZ( (*node)->X(), (*node)->Y(), (*node)->Z());
+          if ( helper.CheckNodeUV( geomFace, &tmpNode, uv, 10 * faceTol, /*force=*/true ))
+          {
+            SMDS_MeshNode* newNode = tgtMesh->AddNode( (*node)->X(), (*node)->Y(), (*node)->Z());
+            n2nIt->second = newNode;
+            tgtMesh->SetNodeOnFace( newNode, shapeID, uv.X(), uv.Y() );
+            nbCreatedNodes++;
+          }
+        }
+        if ( !(newNodes[i] = n2nIt->second ))
+          break;
+      }
+      if ( !newNodes.back() )
+        continue; // not all nodes of the face lie on theShape
+
+      // try to find already created face
+      SMDS_MeshElement * newFace = 0;
+      if ( nbCreatedNodes == 0 &&
+           tgtMesh->FindElement(newNodes, SMDSAbs_Face, /*noMedium=*/false))
+        continue; // repeated face in source groups already created 
+
+      // check future face orientation
+      if ( toCheckOri )
+      {
+        int iNode = -1;
+        gp_Vec geomNorm;
+        do
+        {
+          uv = helper.GetNodeUV( geomFace, newNodes[++iNode] );
+          surface->D1( uv.X(),uv.Y(), p, du,dv );
+          geomNorm = du ^ dv;
+        }
+        while ( geomNorm.SquareMagnitude() < 1e-6 && iNode+1 < face->NbCornerNodes());
+
+        int iNext = helper.WrapIndex( iNode+1, face->NbCornerNodes() );
+        int iPrev = helper.WrapIndex( iNode-1, face->NbCornerNodes() );
+
+        gp_Vec n1n0( SMESH_MeshEditor::TNodeXYZ( newNodes[iPrev] ) -
+                     SMESH_MeshEditor::TNodeXYZ( newNodes[iNode] ));
+        gp_Vec n1n2( SMESH_MeshEditor::TNodeXYZ( newNodes[iNext] ) -
+                     SMESH_MeshEditor::TNodeXYZ( newNodes[iNode] ));
+        gp_Vec meshNorm = n1n2 ^ n1n0;
+
+        if ( geomNorm * meshNorm < 0 )
+          std::reverse( newNodes.begin(), newNodes.end() );
+      }
+
+      // make a new face
+      switch ( newNodes.size() )
+      {
+      case 3:
+        newFace = tgtMesh->AddFace( newNodes[0], newNodes[1], newNodes[2] );
+        break;
+      case 4:
+        newFace = tgtMesh->AddFace( newNodes[0], newNodes[1], newNodes[2], newNodes[3] );
+        break;
+      case 6:
+        newFace = tgtMesh->AddFace( newNodes[0], newNodes[1], newNodes[2],
+                                    newNodes[3], newNodes[4], newNodes[5]);
+        break;
+      case 8:
+        newFace = tgtMesh->AddFace( newNodes[0], newNodes[1], newNodes[2], newNodes[3],
+                                    newNodes[4], newNodes[5], newNodes[6], newNodes[7]);
+        break;
+      default: continue;
+      }
+      tgtMesh->SetMeshElementOnShape( newFace, shapeID );
+      e2e->insert( make_pair( face, newFace ));
+
+      // collect links
+      int nbNodes = face->NbCornerNodes();
+      const SMDS_MeshNode* medium = 0;
+      for ( int i = 0; i < nbNodes; ++i )
+      {
+        const SMDS_MeshNode* n1 = newNodes[i];
+        const SMDS_MeshNode* n2 = newNodes[ (i+1)%nbNodes ];
+        if ( newFace->IsQuadratic() )
+          medium = newNodes[i+nbNodes];
+        link2Nb = linkCount.insert( make_pair( TLink( n1, n2, medium ), 0)).first;
+        ++link2Nb->second;
+      }
+    }
+  }
+
+  // ==========================================================
+  // Put nodes on geom edges and create edges on them;
+  // check if the whole geom face is covered by imported faces
+  // ==========================================================
+
+  vector< TopoDS_Edge > edges;
+  for ( exp.Init( theShape, TopAbs_EDGE ); exp.More(); exp.Next() )
+    if ( subShapeIDs.insert( tgtMesh->ShapeToIndex( exp.Current() )).second )
+      edges.push_back( TopoDS::Edge( exp.Current() ));
+
+  bool isFaceMeshed = false;
+  if ( SMESHDS_SubMesh* tgtSM = tgtMesh->MeshElements( theShape ))
+  {
+    // the imported mesh is valid if all external links (encountered once)
+    // lie on geom edges
+    subShapeIDs.erase( shapeID ); // to contain edges and vertices only
+    double u, f, l;
+    for ( link2Nb = linkCount.begin(); link2Nb != linkCount.end(); ++link2Nb)
+    {
+      const TLink& link = (*link2Nb).first;
+      int nbFaces = link2Nb->second;
+      if ( nbFaces == 1 )
+      {
+        // check if the link lie on face boundary
+        bool nodesOnBoundary = true;
+        list< TopoDS_Shape > bndShapes;
+        for ( int is1stN = 0; is1stN < 2 && nodesOnBoundary; ++is1stN )
+        {
+          const SMDS_MeshNode* n = is1stN ? link.node1() : link.node2();
+          if ( !subShapeIDs.count( n->GetPosition()->GetShapeId() ))
+          {
+            for ( unsigned iE = 0; iE < edges.size(); ++iE )
+              if ( helper.CheckNodeU( edges[iE], n, u, 10 * faceTol, /*force=*/true ))
+              {
+                BRep_Tool::Range(edges[iE],f,l);
+                if ( Abs(u-f) < 2 * faceTol || Abs(u-l) < 2 * faceTol )
+                  // duplicated node on vertex
+                  return error("Source elements overlap one another");
+                tgtMesh->SetNodeOnEdge( (SMDS_MeshNode*)n, edges[iE], u );
+                break;
+              }
+            nodesOnBoundary = subShapeIDs.count( n->GetPosition()->GetShapeId());
+          }
+          if ( nodesOnBoundary )
+          {
+            TopoDS_Shape s = helper.GetSubShapeByNode( n, tgtMesh );
+            if ( s.ShapeType() == TopAbs_VERTEX )
+              bndShapes.push_front( s ); // vertex first
+            else
+              bndShapes.push_back( s ); // edges last
+          }
+        }
+        if ( !nodesOnBoundary )
+          break; // free internal link
+        if ( bndShapes.front().ShapeType() == TopAbs_EDGE &&
+             bndShapes.front() != bndShapes.back() )
+          break; // link nodes on different geom edges
+
+        // find geom edge the link is on
+        if ( bndShapes.back().ShapeType() != TopAbs_EDGE )
+        {
+          // find geom edge by two vertices
+          TopoDS_Shape geomEdge;
+          PShapeIteratorPtr edgeIt = helper.GetAncestors( bndShapes.back(), theMesh, TopAbs_EDGE );
+          while ( edgeIt->more() )
+          {
+            geomEdge = *(edgeIt->next());
+            if ( !helper.IsSubShape( bndShapes.front(), geomEdge ))
+              geomEdge.Nullify();
+          }
+          if ( geomEdge.IsNull() )
+            break; // vertices belong to different edges -> free internal link
+          bndShapes.push_back( geomEdge );
+        }
+
+        // create an edge if not yet exists
+        newNodes.resize(2);
+        newNodes[0] = link.node1(), newNodes[1] = link.node2();
+        const SMDS_MeshElement* edge = tgtMesh->FindElement( newNodes, SMDSAbs_Edge );
+        if ( edge ) continue;
+
+        if ( link._reversed ) std::swap( newNodes[0], newNodes[1] );
+        if ( link._medium )
+        {
+          newNodes.push_back( link._medium );
+          edge = tgtMesh->AddEdge( newNodes[0], newNodes[1], newNodes[2] );
+
+          TopoDS_Edge geomEdge = TopoDS::Edge(bndShapes.back());
+          helper.CheckNodeU( geomEdge, link._medium, u, 10*faceTol, /*force=*/true );
+          tgtMesh->SetNodeOnEdge( (SMDS_MeshNode*)link._medium, geomEdge, u );
+        }
+        else
+        {
+          edge = tgtMesh->AddEdge( newNodes[0], newNodes[1]);
+        }
+        // remove nodes from submesh of theShape
+        for ( unsigned i = 0; i < newNodes.size(); ++i )
+          tgtSM->RemoveNode( newNodes[i], /*isNodeDeleted=*/false );
+        if ( !edge )
+          return false;
+
+        tgtMesh->SetMeshElementOnShape( edge, bndShapes.back() );
+      }
+      else if ( nbFaces > 2 )
+      {
+        return error( "Non-manifold source mesh");
+      }
+    }
+    isFaceMeshed = ( link2Nb == linkCount.end() && !linkCount.empty());
+    if ( isFaceMeshed )
+    {
+      // check that source faces do not overlap:
+      // there must be only two edges sharing each vertex and bound to sub-edges of theShape
+      SMESH_MeshEditor editor( &theMesh );
+      set<int>::iterator subID = subShapeIDs.begin();
+      for ( ; subID != subShapeIDs.end(); ++subID )
+      {
+        const TopoDS_Shape& s = tgtMesh->IndexToShape( *subID );
+        if ( s.ShapeType() != TopAbs_VERTEX ) continue;
+        const SMDS_MeshNode* n = SMESH_Algo::VertexNode( TopoDS::Vertex(s), tgtMesh );
+        SMDS_ElemIteratorPtr eIt = n->GetInverseElementIterator(SMDSAbs_Edge);
+        int nbEdges = 0;
+        while ( eIt->more() )
+        {
+          const SMDS_MeshElement* edge = eIt->next();
+          int sId = editor.FindShape( edge );
+          nbEdges += subShapeIDs.count( sId );
+        }
+        if ( nbEdges < 2 )
+          return false; // weird
+        if ( nbEdges > 2 )
+          return error( "Source elements overlap one another");
+      }
+    }
+  }
+  if ( !isFaceMeshed )
+    return error( "Source elements don't cover totally the geometrical face" );
+
+  // notify sub-meshes of edges on computation
+  for ( unsigned iE = 0; iE < edges.size(); ++iE )
+    theMesh.GetSubMesh( edges[iE] )->ComputeStateEngine(SMESH_subMesh::CHECK_COMPUTE_STATE);
+
+  // ============
+  // Copy meshes
+  // ============
+
+  vector<SMESH_Mesh*> srcMeshes = _sourceHyp->GetSourceMeshes();
+  for ( unsigned i = 0; i < srcMeshes.size(); ++i )
+    StdMeshers_Import_1D::importMesh( srcMeshes[i], theMesh, _sourceHyp, theShape );
+
+  return true;
+}
+
+//=============================================================================
+/*!
+ * \brief Set needed event listeners and create a submesh for a copied mesh
+ *
+ * This method is called only if a submesh has HYP_OK algo_state.
+ */
+//=============================================================================
+
+void StdMeshers_Import_1D2D::SetEventListener(SMESH_subMesh* subMesh)
+{
+  if ( !_sourceHyp )
+  {
+    const TopoDS_Shape& tgtShape = subMesh->GetSubShape();
+    SMESH_Mesh*         tgtMesh  = subMesh->GetFather();
+    Hypothesis_Status aStatus;
+    CheckHypothesis( *tgtMesh, tgtShape, aStatus );
+  }
+  StdMeshers_Import_1D::setEventListener( subMesh, _sourceHyp );
+}
+void StdMeshers_Import_1D2D::SubmeshRestored(SMESH_subMesh* subMesh)
+{
+  SetEventListener(subMesh);
+}
+
+//=============================================================================
+/*!
+ * Predict nb of mesh entities created by Compute()
+ */
+//=============================================================================
+
+bool StdMeshers_Import_1D2D::Evaluate(SMESH_Mesh &         theMesh,
+                                      const TopoDS_Shape & theShape,
+                                      MapShapeNbElems&     aResMap)
+{
+  if ( !_sourceHyp ) return false;
+
+  const vector<SMESH_Group*>& srcGroups = _sourceHyp->GetGroups();
+  if ( srcGroups.empty() )
+    return error("Invalid source groups");
+
+  vector<int> aVec(SMDSEntity_Last,0);
+
+  bool toCopyMesh, toCopyGroups;
+  _sourceHyp->GetCopySourceMesh(toCopyMesh, toCopyGroups);
+  if ( toCopyMesh ) // the whole mesh is copied
+  {
+    vector<SMESH_Mesh*> srcMeshes = _sourceHyp->GetSourceMeshes();
+    for ( unsigned i = 0; i < srcMeshes.size(); ++i )
+    {
+      SMESH_subMesh* sm = StdMeshers_Import_1D::getSubMeshOfCopiedMesh( theMesh, *srcMeshes[i]);
+      if ( !sm || aResMap.count( sm )) continue; // already counted
+      const SMDS_MeshInfo& aMeshInfo = srcMeshes[i]->GetMeshDS()->GetMeshInfo();
+      for (int i = 0; i < SMDSEntity_Last; i++)
+        aVec[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
+    }
+  }
+  else
+  {
+    // std-like iterator used to get coordinates of nodes of mesh element
+    typedef SMDS_StdIterator< SMESH_MeshEditor::TNodeXYZ, SMDS_ElemIteratorPtr > TXyzIterator;
+
+    SMESH_MesherHelper helper(theMesh);
+    helper.SetSubShape(theShape);
+
+    const TopoDS_Face& geomFace = TopoDS::Face( theShape );
+    const double faceTol = helper.MaxTolerance( geomFace );
+
+    // take into account nodes on vertices
+    TopExp_Explorer exp( theShape, TopAbs_VERTEX );
+    for ( ; exp.More(); exp.Next() )
+      theMesh.GetSubMesh( exp.Current())->Evaluate( aResMap );
+
+    // to count now many times a link between nodes encounters,
+    // negative nb additionally means that a link is quadratic
+    map<SMESH_TLink, int> linkCount;
+    map<SMESH_TLink, int>::iterator link2Nb;
+
+    // count faces and nodes imported from groups
+    set<const SMDS_MeshNode* > allNodes;
+    gp_XY uv;
+    for ( int iG = 0; iG < srcGroups.size(); ++iG )
+    {
+      const SMESHDS_GroupBase* srcGroup = srcGroups[iG]->GetGroupDS();
+      SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements();
+      SMDS_MeshNode tmpNode(0,0,0);
+      while ( srcElems->more() ) // loop on group contents
+      {
+        const SMDS_MeshElement* face = srcElems->next();
+        // find out if face is located on geomEdge by projecting
+        // a gravity center of face to geomFace
+        gp_XYZ gc(0,0,0);
+        gc = accumulate( TXyzIterator(face->nodesIterator()), TXyzIterator(), gc)/face->NbNodes();
+        tmpNode.setXYZ( gc.X(), gc.Y(), gc.Z());
+        if ( helper.CheckNodeUV( geomFace, &tmpNode, uv, 10 * faceTol, /*force=*/true ))
+        {
+          ++aVec[ face->GetEntityType() ];
+
+          // collect links
+          int nbConers = face->NbCornerNodes();
+          for ( int i = 0; i < face->NbNodes(); ++i )
+          {
+            const SMDS_MeshNode* n1 = face->GetNode(i);
+            allNodes.insert( n1 );
+            if ( i < nbConers )
+            {
+              const SMDS_MeshNode* n2 = face->GetNode( (i+1)%nbConers );
+              link2Nb = linkCount.insert( make_pair( SMESH_TLink( n1, n2 ), 0)).first;
+              if ( (*link2Nb).second )
+                link2Nb->second += (link2Nb->second < 0 ) ? -1 : 1;
+              else
+                link2Nb->second += ( face->IsQuadratic() ) ? -1 : 1;
+            }
+          }
+        }
+      }
+    }
+
+    int nbNodes = allNodes.size();
+    allNodes.clear();
+
+    // count nodes and edges on geom edges
+
+    double u;
+    for ( exp.Init(theShape, TopAbs_EDGE); exp.More(); exp.Next() )
+    {
+      TopoDS_Edge geomEdge = TopoDS::Edge( exp.Current() );
+      SMESH_subMesh* sm = theMesh.GetSubMesh( geomEdge );
+      vector<int>& edgeVec = aResMap[sm];
+      if ( edgeVec.empty() )
+      {
+        edgeVec.resize(SMDSEntity_Last,0);
+        for ( link2Nb = linkCount.begin(); link2Nb != linkCount.end(); )
+        {
+          const SMESH_TLink& link = (*link2Nb).first;
+          int nbFacesOfLink = Abs( link2Nb->second );
+          bool eraseLink = ( nbFacesOfLink != 1 );
+          if ( nbFacesOfLink == 1 )
+          {
+            if ( helper.CheckNodeU( geomEdge, link.node1(), u, 10*faceTol, /*force=*/true )&&
+                 helper.CheckNodeU( geomEdge, link.node2(), u, 10*faceTol, /*force=*/true ))
+            {
+              bool isQuadratic = ( link2Nb->second < 0 );
+              ++edgeVec[ isQuadratic ? SMDSEntity_Quad_Edge : SMDSEntity_Edge ];
+              ++edgeVec[ SMDSEntity_Node ];
+              --nbNodes;
+              eraseLink = true;
+            }
+          }
+          if ( eraseLink )
+            linkCount.erase(link2Nb++);
+          else
+            link2Nb++;
+        }
+        if ( edgeVec[ SMDSEntity_Node] > 0 )
+          --edgeVec[ SMDSEntity_Node ]; // for one node on vertex
+      }
+      else if ( !helper.IsSeamShape( geomEdge ) ||
+                geomEdge.Orientation() == TopAbs_FORWARD )
+      {
+        nbNodes -= 1+edgeVec[ SMDSEntity_Node ];
+      }
+    }
+
+    aVec[SMDSEntity_Node] = nbNodes;
+  }
+
+  SMESH_subMesh * sm = theMesh.GetSubMesh(theShape);
+  aResMap.insert(make_pair(sm,aVec));
+
+  return true;
+}
diff --git a/src/StdMeshers/StdMeshers_Import_1D2D.hxx b/src/StdMeshers/StdMeshers_Import_1D2D.hxx
new file mode 100644 (file)
index 0000000..5733c2f
--- /dev/null
@@ -0,0 +1,60 @@
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+//  SMESH SMESH : implementaion of SMESH idl descriptions
+//  Module : SMESH
+//
+#ifndef _SMESH_Import_2D_HXX_
+#define _SMESH_Import_2D_HXX_
+
+#include "SMESH_StdMeshers.hxx"
+
+#include "SMESH_2D_Algo.hxx"
+#include "SMDS_MeshElement.hxx"
+
+class StdMeshers_ImportSource1D;
+
+/*!
+ * \brief Copy elements from other the mesh
+ */
+class STDMESHERS_EXPORT StdMeshers_Import_1D2D: public SMESH_2D_Algo
+{
+public:
+  StdMeshers_Import_1D2D(int hypId, int studyId, SMESH_Gen* gen);
+
+  virtual bool CheckHypothesis(SMESH_Mesh& aMesh,
+                               const TopoDS_Shape& aShape,
+                               SMESH_Hypothesis::Hypothesis_Status& aStatus);
+
+  virtual bool Compute (SMESH_Mesh & aMesh, const TopoDS_Shape & aShape);
+  virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+                        MapShapeNbElems& aResMap);
+
+  virtual void SetEventListener(SMESH_subMesh* subMesh);
+  virtual void SubmeshRestored(SMESH_subMesh* subMesh);
+
+ private:
+  
+  StdMeshers_ImportSource1D* _sourceHyp;
+};
+
+#endif
index 39dfd2e13f8bccd02922c79ef64e94c97e820676..8e2718dd0a40a36830a1898621c158b64edf9b4f 100644 (file)
@@ -46,7 +46,7 @@ using namespace std;
 
 enum EQuadNature { NOT_QUAD, QUAD, DEGEN_QUAD };
 
-  // std-like iterator used to get coordinates of nodes of mesh element
+// std-like iterator used to get coordinates of nodes of mesh element
 typedef SMDS_StdIterator< SMESH_MeshEditor::TNodeXYZ, SMDS_ElemIteratorPtr > TXyzIterator;
 
 namespace
@@ -183,7 +183,7 @@ namespace
   //================================================================================
   /*!
    * \brief Return true if two adjacent pyramids are too close one to another
-   * so that a tetrahedron to built between them whoul have too poor quality
+   * so that a tetrahedron to built between them would have too poor quality
    */
   //================================================================================
 
@@ -333,7 +333,7 @@ namespace
 //================================================================================
 
 StdMeshers_QuadToTriaAdaptor::StdMeshers_QuadToTriaAdaptor():
-  myElemSearcher(0)
+  myElemSearcher(0), myNbTriangles(0)
 {
 }
 
@@ -580,9 +580,11 @@ int StdMeshers_QuadToTriaAdaptor::Preparation(const SMDS_MeshElement*       face
                                               gp_Vec&                       VNorm,
                                               const SMDS_MeshElement**      volumes)
 {
-  if( face->NbNodes() != ( face->IsQuadratic() ? 8 : 4 ))
-    if( face->NbNodes() != 4 )
-      return NOT_QUAD;
+  if( face->NbCornerNodes() != 4 )
+  {
+    myNbTriangles += int( face->NbCornerNodes() == 3 );
+    return NOT_QUAD;
+  }
 
   int i = 0;
   gp_XYZ xyzC(0., 0., 0.);
@@ -696,6 +698,8 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape
 {
   myResMap.clear();
   myPyramids.clear();
+  myNbTriangles = 0;
+  myShape = aShape;
 
   SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
   SMESH_MesherHelper helper(aMesh);
@@ -1144,6 +1148,10 @@ bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh& aMesh)
             nodesToMove.insert( aNode1 );
             nodesToMove.insert( aNode2 );
           }
+          // fix intersections that could appear after apex movement
+          MergeAdjacent( PrmI, aMesh, nodesToMove );
+          MergeAdjacent( PrmJ, aMesh, nodesToMove );
+
         } // end if(hasInt)
       } // loop on suspectPyrams
     }  // loop on 4 base nodes of PrmI
@@ -1165,7 +1173,7 @@ bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh& aMesh)
     if ( q2t->first == q2tPrev->first )
       q2tPrev->second.splice( q2tPrev->second.end(), q2t->second );
   }
-  // delete removed triangles
+  // delete removed triangles and count resulting nb of triangles
   for ( q2t = myResMap.begin(); q2t != myResMap.end(); ++q2t )
   {
     TTriaList & trias = q2t->second;
@@ -1173,7 +1181,7 @@ bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh& aMesh)
       if ( ((const Q2TAdaptor_Triangle*) *tri)->IsRemoved() )
         delete *tri, trias.erase( tri++ );
       else
-        tri++;
+        tri++, myNbTriangles++;
   }
 
   myPyramids.clear(); // no more needed
index 874fdc6a94da089a2c17b3e16d921c88b3f4ce5c..ceccb2542a4e98184bc9bc0af760bbaccb8f738c 100644 (file)
@@ -33,7 +33,6 @@ class SMDS_MeshNode;
 class SMDS_MeshFace;
 class Handle_TColgp_HArray1OfPnt;
 class Handle_TColgp_HArray1OfVec;
-class TopoDS_Shape;
 class gp_Pnt;
 class gp_Vec;
 
@@ -42,6 +41,8 @@ class gp_Vec;
 #include <list>
 #include <vector>
 
+#include <TopoDS_Shape.hxx>
+
 /*!
  * \brief "Transforms" quadrilateral faces into triangular ones by creation of pyramids
  */
@@ -58,6 +59,13 @@ public:
 
   const std::list<const SMDS_MeshFace*>* GetTriangles(const SMDS_MeshElement* aFace);
 
+  /*!
+   * \brief Return sum of generated and already present triangles
+   */
+  int TotalNbOfTriangles() const { return myNbTriangles; }
+
+  TopoDS_Shape GetShape() const { return myShape; }
+
 protected:
 
   //bool CheckDegenerate(const SMDS_MeshElement* aFace);
@@ -77,17 +85,19 @@ protected:
   bool Compute2ndPart(SMESH_Mesh& aMesh);
 
 
-  typedef std::list<const SMDS_MeshFace* >                           TTriaList;
-  typedef std::multimap<const SMDS_MeshElement*, TTriaList >         TQuad2Trias;
-  //typedef std::map<const SMDS_MeshElement*, TTriaList *, TIDCompare> TPyram2Trias;
+  typedef std::list<const SMDS_MeshFace* >                   TTriaList;
+  typedef std::multimap<const SMDS_MeshElement*, TTriaList > TQuad2Trias;
 
   TQuad2Trias  myResMap;
-  //TPyram2Trias myPyram2Trias;
   std::vector<const SMDS_MeshElement*> myPyramids;
 
   std::list< const SMDS_MeshNode* > myDegNodes;
 
   const SMESH_ElementSearcher* myElemSearcher;
+
+  int myNbTriangles;
+
+  TopoDS_Shape myShape;
 };
 
 #endif
index 06f2431eca8ce45ea55b924d1833517269a5b29b..e69489aeb33c3c3fa9ac4786b610383e95e82d5b 100644 (file)
 #include <LightApp_SelectionMgr.h>
 #include <SVTK_ViewWindow.h>
 #include <SALOME_ListIO.hxx>
+#include <SALOME_ListIteratorOfListIO.hxx>
 
 // SALOME KERNEL incldues
 #include <SALOMEDSClient_SObject.hxx>
+#include <SALOMEDSClient_Study.hxx>
 
 // Qt includes
 #include <QPushButton>
@@ -54,8 +56,8 @@
 //================================================================================
 
 StdMeshersGUI_ObjectReferenceParamWdg::StdMeshersGUI_ObjectReferenceParamWdg
-( SUIT_SelectionFilter* f, QWidget* parent)
-  : QWidget( parent )
+( SUIT_SelectionFilter* f, QWidget* parent, bool multiSelection)
+  : QWidget( parent ), myMultiSelection( multiSelection )
 {
   myFilter = f;
   init();
@@ -69,8 +71,8 @@ StdMeshersGUI_ObjectReferenceParamWdg::StdMeshersGUI_ObjectReferenceParamWdg
 //================================================================================
 
 StdMeshersGUI_ObjectReferenceParamWdg::StdMeshersGUI_ObjectReferenceParamWdg
-( MeshObjectType objType, QWidget* parent )
-  : QWidget( parent )
+( MeshObjectType objType, QWidget* parent, bool multiSelection )
+  : QWidget( parent ), myMultiSelection( multiSelection )
 {
   myFilter = new SMESH_TypeFilter( objType );
   init();
@@ -84,7 +86,10 @@ StdMeshersGUI_ObjectReferenceParamWdg::StdMeshersGUI_ObjectReferenceParamWdg
 StdMeshersGUI_ObjectReferenceParamWdg::~StdMeshersGUI_ObjectReferenceParamWdg()
 {
   if ( myFilter )
+  {
+    mySelectionMgr->removeFilter( myFilter );
     delete myFilter;
+  }
 }
 
 
@@ -184,7 +189,7 @@ void StdMeshersGUI_ObjectReferenceParamWdg::AvoidSimultaneousSelection
 
 void StdMeshersGUI_ObjectReferenceParamWdg::SetObject(CORBA::Object_ptr obj)
 {
-  myObject = CORBA::Object::_nil();
+  myObjects.clear();
   myObjNameLineEdit->setText( "" );
   myParamValue = "";
 
@@ -194,11 +199,43 @@ void StdMeshersGUI_ObjectReferenceParamWdg::SetObject(CORBA::Object_ptr obj)
   if ( sobj ) {
     std::string name = sobj->GetName();
     myObjNameLineEdit->setText( name.c_str() );
-    myObject = CORBA::Object::_duplicate( obj );
+    myObjects.push_back( CORBA::Object::_duplicate( obj ));
     myParamValue = sobj->GetID().c_str();
   }
 }
 
+//================================================================================
+/*!
+ * \brief Initialize selected objects
+ * \param objects - entries of objects
+ */
+//================================================================================
+
+void StdMeshersGUI_ObjectReferenceParamWdg::SetObjects(SMESH::string_array_var& objects)
+{
+  myObjects.clear();
+  myObjNameLineEdit->setText( "" );
+  myParamValue = "";
+
+  for ( unsigned i = 0; i < objects->length(); ++i )
+  {
+    _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
+    _PTR(SObject) aSObj = aStudy->FindObjectID(objects[i].in());
+    CORBA::Object_var anObj = SMESH::SObjectToObject(aSObj,aStudy);
+    if ( !CORBA::is_nil( anObj )) {
+      std::string name = aSObj->GetName();
+      QString text = myObjNameLineEdit->text();
+      if ( !text.isEmpty() )
+        text += " ";
+      text += name.c_str();
+      myObjNameLineEdit->setText( text );
+      myObjects.push_back( anObj );
+      myParamValue += " ";
+      myParamValue += objects[i];
+    }
+  }
+}
+
 //================================================================================
 /*!
  * \brief Takes selected object
@@ -212,7 +249,26 @@ void StdMeshersGUI_ObjectReferenceParamWdg::onSelectionDone()
     SALOME_ListIO aList;
     mySelectionMgr->selectedObjects(aList);
     if (aList.Extent() == 1)
+    {
       obj = SMESH::IObjectToObject( aList.First() );
-    SetObject( obj.in() );
+      SetObject( obj.in() );
+    }
+    else if (myMultiSelection)
+    {
+      SMESH::string_array_var objIds = new SMESH::string_array;
+      objIds->length( aList.Extent());
+      SALOME_ListIteratorOfListIO io( aList );
+      int i = 0;
+      for ( ; io.More(); io.Next(), ++i )
+      {
+        Handle(SALOME_InteractiveObject) anIO = io.Value();
+        if ( anIO->hasEntry() )
+          objIds[i] = anIO->getEntry();
+        else
+          i--;
+      }
+      objIds->length(i);
+      SetObjects( objIds );
+    }
   }
 }
index c5fabc25e741af1fa2efac0114a97ac90e2c3f98..e8c3871945955be5b755b0ae4bfbc7584c33c988 100644 (file)
@@ -37,6 +37,8 @@
 // CORBA includes
 #include <CORBA.h>
 
+#include CORBA_SERVER_HEADER(SMESH_Mesh)
+
 class SUIT_SelectionFilter;
 class SMESHGUI;
 class LightApp_SelectionMgr;
@@ -52,22 +54,29 @@ class STDMESHERSGUI_EXPORT StdMeshersGUI_ObjectReferenceParamWdg : public QWidge
 
 public:
   StdMeshersGUI_ObjectReferenceParamWdg( SUIT_SelectionFilter* filter, 
-                                         QWidget*              parent);
+                                         QWidget*              parent,
+                                         bool                  multiSelection=false);
   StdMeshersGUI_ObjectReferenceParamWdg( MeshObjectType objType,
-                                         QWidget*       parent);
+                                         QWidget*       parent,
+                                         bool           multiSelection=false);
   ~StdMeshersGUI_ObjectReferenceParamWdg();
 
   void SetObject(CORBA::Object_ptr obj);
 
+  void SetObjects(SMESH::string_array_var& objEntries);
+
   template<class TInterface> 
-    typename TInterface::_var_type GetObject() const {
-    if ( IsObjectSelected() ) return TInterface::_narrow(myObject);
+    typename TInterface::_var_type GetObject(unsigned i=0) const {
+    if ( IsObjectSelected(i) ) return TInterface::_narrow(myObjects[i]);
     return TInterface::_nil();
   }
 
+  int NbObjects() const { return myObjects.size(); }
+
   QString GetValue() const { return myParamValue; }
 
-  bool IsObjectSelected() const { return !CORBA::is_nil(myObject); }
+  bool IsObjectSelected(unsigned i=0) const
+  { return i < myObjects.size() && !CORBA::is_nil(myObjects[i]); }
 
   void AvoidSimultaneousSelection( StdMeshersGUI_ObjectReferenceParamWdg* other);
 
@@ -97,7 +106,10 @@ private:
   void init();
   
 private:
- CORBA::Object_var      myObject;
+
+  bool                                myMultiSelection;
+  std::vector<CORBA::Object_var>      myObjects;
+
  SUIT_SelectionFilter*  myFilter;
  bool                   mySelectionActivated;
 
index 3e8d13ee2d34aced898364f3030df63b56c1a9b4..9595e67a0084357e32d576c2984d5bbd1caed484 100644 (file)
@@ -48,6 +48,7 @@
 #include <SALOMEconfig.h>
 #include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
 #include CORBA_SERVER_HEADER(SMESH_Mesh)
+#include CORBA_SERVER_HEADER(SMESH_Group)
 
 // Qt includes
 #include <QHBoxLayout>
@@ -261,6 +262,25 @@ namespace {
     return SMESH::SMESH_Mesh::_nil();
   }
   //================================================================================
+  /*!
+   * \brief Retrieve SMESH_Mesh held by widget
+   */
+  //================================================================================
+
+  inline SMESH::ListOfGroups_var groupsFromWdg(const QWidget* wdg)
+  {
+    SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
+    const StdMeshersGUI_ObjectReferenceParamWdg * objRefWdg =
+      dynamic_cast<const StdMeshersGUI_ObjectReferenceParamWdg*>( wdg );
+    if ( objRefWdg )
+    {
+      groups->length( objRefWdg->NbObjects() );
+      for ( unsigned i = 0; i < groups->length(); ++i )
+        groups[i] = objRefWdg->GetObject< SMESH::SMESH_GroupBase >(i);
+    }
+    return groups;
+  }
+  //================================================================================
   /*!
    * \brief creates a filter for selection of shapes of given dimension
     * \param dim - dimension
@@ -317,6 +337,15 @@ namespace {
     w->SetObject( object.in() );
     return w;
   }
+  QWidget* newObjRefParamWdg( SUIT_SelectionFilter*    filter,
+                              SMESH::string_array_var& objEntries)
+  {
+    StdMeshersGUI_ObjectReferenceParamWdg* w =
+      new StdMeshersGUI_ObjectReferenceParamWdg( filter, 0, /*multiSel=*/true);
+    w->SetObjects( objEntries );
+    w->activateSelection();
+    return w;
+  }
 
   //================================================================================
   /*!
@@ -382,6 +411,12 @@ bool StdMeshersGUI_StdHypothesisCreator::checkParams( QString& msg ) const
     if ( ok )
       deactivateObjRefParamWdg( customWidgets() );
   }
+  else if ( hypType().startsWith("ImportSource" ))
+  {
+    StdMeshersGUI_ObjectReferenceParamWdg* w =
+      widget< StdMeshersGUI_ObjectReferenceParamWdg >( 0 );
+    ok = ( w->IsObjectSelected() );
+  }
   else if ( hypType() == "LayerDistribution" || hypType() == "LayerDistribution2D" )
   {
     StdMeshersGUI_LayerDistributionParamWdg* w = 
@@ -609,6 +644,28 @@ QString StdMeshersGUI_StdHypothesisCreator::storeParams() const
                                geomFromWdg ( getWidgetForParam( 3 )), // tgt1
                                geomFromWdg ( getWidgetForParam( 5 ))); // tgt2
     }
+    else if( hypType()=="ImportSource1D" )
+    {
+      StdMeshers::StdMeshers_ImportSource1D_var h =
+        StdMeshers::StdMeshers_ImportSource1D::_narrow( hypothesis() );
+
+      SMESH::ListOfGroups_var groups = groupsFromWdg( getWidgetForParam( 0 ));
+      h->SetSourceEdges( groups.in() );
+      QCheckBox* toCopyMesh   = widget< QCheckBox >( 1 );
+      QCheckBox* toCopyGroups = widget< QCheckBox >( 2 );
+      h->SetCopySourceMesh( toCopyMesh->isChecked(), toCopyGroups->isChecked());
+    }
+    else if( hypType()=="ImportSource2D" )
+    {
+      StdMeshers::StdMeshers_ImportSource2D_var h =
+        StdMeshers::StdMeshers_ImportSource2D::_narrow( hypothesis() );
+
+      SMESH::ListOfGroups_var groups = groupsFromWdg( getWidgetForParam( 0 ));
+      h->SetSourceFaces( groups.in() );
+      QCheckBox* toCopyMesh   = widget< QCheckBox >( 1 );
+      QCheckBox* toCopyGroups = widget< QCheckBox >( 2 );
+      h->SetCopySourceMesh( toCopyMesh->isChecked(), toCopyGroups->isChecked());
+    }
     else if( hypType()=="QuadrangleParams" )
     {
       StdMeshers::StdMeshers_QuadrangleParams_var h =
@@ -992,6 +1049,56 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const
     customWidgets()->append( newObjRefParamWdg( filterForShapeOfDim( 0 ),
                                                h->GetTargetVertex( 2 )));
   }
+  else if( hypType()=="ImportSource1D" )
+  {
+    StdMeshers::StdMeshers_ImportSource1D_var h =
+      StdMeshers::StdMeshers_ImportSource1D::_narrow( hyp );
+
+    SMESH::string_array_var groupEntries = h->GetSourceEdges();
+    CORBA::Boolean toCopyMesh, toCopyGroups;
+    h->GetCopySourceMesh(toCopyMesh, toCopyGroups);
+
+    item.myName = tr( "SMESH_SOURCE_EDGES" ); p.append( item );
+    customWidgets()->append( newObjRefParamWdg( new SMESH_TypeFilter( GROUP_EDGE ), 
+                                                groupEntries));
+
+    item.myName = tr( "SMESH_COPY_MESH" ); p.append( item );
+    QCheckBox* aQCheckBox = new QCheckBox(dlg());
+    aQCheckBox->setChecked( toCopyMesh );
+    connect( aQCheckBox, SIGNAL(  stateChanged(int) ), this, SLOT( onValueChanged() ));
+    customWidgets()->append( aQCheckBox );
+
+    item.myName = tr( "SMESH_TO_COPY_GROUPS" ); p.append( item );
+    aQCheckBox = new QCheckBox(dlg());
+    aQCheckBox->setChecked( toCopyGroups );
+    aQCheckBox->setEnabled( toCopyMesh );
+    customWidgets()->append( aQCheckBox );
+  }
+  else if( hypType()=="ImportSource2D" )
+  {
+    StdMeshers::StdMeshers_ImportSource2D_var h =
+      StdMeshers::StdMeshers_ImportSource2D::_narrow( hyp );
+
+    SMESH::string_array_var groupEntries = h->GetSourceFaces();
+    CORBA::Boolean toCopyMesh, toCopyGroups;
+    h->GetCopySourceMesh(toCopyMesh, toCopyGroups);
+
+    item.myName = tr( "SMESH_SOURCE_FACES" ); p.append( item );
+    customWidgets()->append( newObjRefParamWdg( new SMESH_TypeFilter( GROUP_FACE ), 
+                                                groupEntries));
+
+    item.myName = tr( "SMESH_COPY_MESH" ); p.append( item );
+    QCheckBox* aQCheckBox = new QCheckBox(dlg());
+    aQCheckBox->setChecked( toCopyMesh );
+    connect( aQCheckBox, SIGNAL(  stateChanged(int) ), this, SLOT( onValueChanged() ));
+    customWidgets()->append( aQCheckBox );
+
+    item.myName = tr( "SMESH_COPY_GROUPS" ); p.append( item );
+    aQCheckBox = new QCheckBox(dlg());
+    aQCheckBox->setChecked( toCopyGroups );
+    aQCheckBox->setEnabled( toCopyMesh );
+    customWidgets()->append( aQCheckBox );
+  }
   else if (hypType() == "QuadrangleParams")
   {
     StdMeshers::StdMeshers_QuadrangleParams_var h =
@@ -1150,6 +1257,8 @@ QString StdMeshersGUI_StdHypothesisCreator::hypTypeName( const QString& t ) cons
     types.insert( "ProjectionSource1D", "PROJECTION_SOURCE_1D" );
     types.insert( "ProjectionSource2D", "PROJECTION_SOURCE_2D" );
     types.insert( "ProjectionSource3D", "PROJECTION_SOURCE_3D" );
+    types.insert( "ImportSource1D", "IMPORT_SOURCE_1D" );
+    types.insert( "ImportSource2D", "IMPORT_SOURCE_2D" );
     types.insert( "NumberOfLayers", "NUMBER_OF_LAYERS" );
     types.insert( "LayerDistribution", "LAYER_DISTRIBUTION" );
     types.insert( "NumberOfLayers2D", "NUMBER_OF_LAYERS_2D" );
@@ -1250,6 +1359,12 @@ bool StdMeshersGUI_StdHypothesisCreator::getParamFromCustomWidget( StdParam & pa
     param.myValue = w->GetValue();
     return true;
   }
+  if ( widget->inherits( "QCheckBox" ))
+  {
+    //const QCheckBox * w = static_cast<const QCheckBox*>( widget );
+    //param.myValue = w->isChecked();
+    return true;
+  }
   return false;
 }
 
@@ -1261,7 +1376,8 @@ bool StdMeshersGUI_StdHypothesisCreator::getParamFromCustomWidget( StdParam & pa
 
 void StdMeshersGUI_StdHypothesisCreator::onReject()
 {
-  if ( hypType().startsWith("ProjectionSource" ))
+  if ( hypType().startsWith("ProjectionSource" ) ||
+       hypType().startsWith("ImportSource" ))
   {
     // Uninstall filters of StdMeshersGUI_ObjectReferenceParamWdg
     deactivateObjRefParamWdg( customWidgets() );
@@ -1270,13 +1386,14 @@ void StdMeshersGUI_StdHypothesisCreator::onReject()
 
 //================================================================================
 /*!
- * \brief 
+ * \brief Update widgets dependent on paramWidget
  */
 //================================================================================
 
 void StdMeshersGUI_StdHypothesisCreator::valueChanged( QWidget* paramWidget)
 {
-  if ( hypType() == "MaxLength" && paramWidget == getWidgetForParam(1) ) {
+  if ( hypType() == "MaxLength" && paramWidget == getWidgetForParam(1) )
+  {
     getWidgetForParam(0)->setEnabled( !widget< QCheckBox >( 1 )->isChecked() );
     if ( !getWidgetForParam(0)->isEnabled() ) {
       StdMeshers::StdMeshers_MaxLength_var h =
@@ -1284,6 +1401,20 @@ void StdMeshersGUI_StdHypothesisCreator::valueChanged( QWidget* paramWidget)
       widget< QtxDoubleSpinBox >( 0 )->setValue( h->GetPreestimatedLength() );
     }
   }
+  else if ( hypType().startsWith("ImportSource") && paramWidget == getWidgetForParam(1) )
+  {
+    QCheckBox* toCopyMesh   = (QCheckBox*) paramWidget;
+    QCheckBox* toCopyGroups = widget< QCheckBox >( 2 );
+    if ( !toCopyMesh->isChecked() )
+    {
+      toCopyGroups->setChecked( false );
+      toCopyGroups->setEnabled( false );
+    }
+    else
+    {
+      toCopyGroups->setEnabled( true );
+    }
+  }
 }
 
 //================================================================================
index 927a4c09bb48a0363cafed5185084f61186d028c..87444b56a3b3c47e78b41eecf108d8862c08dff8 100644 (file)
             <source>ICON_DLG_QUADRANGLE_PARAMS</source>
             <translation>mesh_hypo_length.png</translation>
         </message>
+        <message>
+            <source>ICON_DLG_IMPORT_SOURCE_1D</source>
+            <translation>mesh_hypo_source_edge.png</translation>
+        </message>
+        <message>
+            <source>ICON_DLG_IMPORT_SOURCE_2D</source>
+            <translation>mesh_hypo_source_face.png</translation>
+        </message>
         <message>
             <source>ICON_DLG_SEGMENT_LENGTH_AROUND_VERTEX</source>
             <translation>mesh_hypo_length.png</translation>
index c04916750f3d1a12bf4d4d23cf1320948fc717a8..75888dfa36a0efa6ee3021ecad9a1b3881b24900 100644 (file)
         <source>SMESH_PROJECTION_SOURCE_3D_TITLE</source>
         <translation>Hypothesis Construction</translation>
     </message>
+    <message>
+        <source>SMESH_IMPORT_SOURCE_1D_HYPOTHESIS</source>
+        <translation>Source edges</translation>
+    </message>
+    <message>
+        <source>SMESH_IMPORT_SOURCE_1D_TITLE</source>
+        <translation>Hypothesis Construction</translation>
+    </message>
+    <message>
+        <source>SMESH_IMPORT_SOURCE_2D_HYPOTHESIS</source>
+        <translation>Source faces</translation>
+    </message>
+    <message>
+        <source>SMESH_IMPORT_SOURCE_2D_TITLE</source>
+        <translation>Hypothesis Construction</translation>
+    </message>
     <message>
         <source>SMESH_REMOVE_ROW</source>
         <translation>Remove row</translation>
         <source>SMESH_SOURCE_EDGE</source>
         <translation>Edge</translation>
     </message>
+    <message>
+        <source>SMESH_SOURCE_EDGES</source>
+        <translation>Groups of Edges</translation>
+    </message>
     <message>
         <source>SMESH_SOURCE_FACE</source>
         <translation>Face</translation>
     </message>
+    <message>
+        <source>SMESH_SOURCE_FACES</source>
+        <translation>Groups of Faces</translation>
+    </message>
     <message>
         <source>SMESH_SOURCE_MESH</source>
         <translation>Mesh</translation>
     </message>
+    <message>
+        <source>SMESH_COPY_MESH</source>
+        <translation>To copy mesh</translation>
+    </message>
+    <message>
+        <source>SMESH_TO_COPY_GROUPS</source>
+        <translation>To copy groups</translation>
+    </message>
     <message>
         <source>SMESH_SOURCE_VERTEX</source>
         <translation>Source Vertex</translation>
index 3331c0b368f61d1445a8e998f4cf97b73bd41d92..17d7c9f6fafbd543c9473629162f8cb6e81b1e2d 100644 (file)
@@ -63,7 +63,11 @@ salomeinclude_HEADERS = \
        StdMeshers_MaxLength_i.hxx \
        StdMeshers_QuadrangleParams_i.hxx \
        StdMeshers_RadialQuadrangle_1D2D_i.hxx \
-       SMESH_StdMeshers_I.hxx
+       SMESH_StdMeshers_I.hxx \
+       StdMeshers_ImportSource1D_i.hxx \
+       StdMeshers_ImportSource2D_i.hxx \
+       StdMeshers_Import_1D_i.hxx \
+       StdMeshers_Import_1D2D_i.hxx
 
 # Libraries targets
 lib_LTLIBRARIES = libStdMeshersEngine.la
@@ -105,7 +109,11 @@ dist_libStdMeshersEngine_la_SOURCES = \
        StdMeshers_TrianglePreference_i.cxx \
        StdMeshers_MaxLength_i.cxx \
        StdMeshers_QuadrangleParams_i.cxx \
-       StdMeshers_RadialQuadrangle_1D2D_i.cxx
+       StdMeshers_RadialQuadrangle_1D2D_i.cxx \
+       StdMeshers_ImportSource1D_i.cxx \
+       StdMeshers_ImportSource2D_i.cxx \
+       StdMeshers_Import_1D_i.cxx \
+       StdMeshers_Import_1D2D_i.cxx
 
 # additionnal information to compil and link file
 libStdMeshersEngine_la_CPPFLAGS = \
index 3c0859e23cabe3aded7083b820bdc18afd81dc69..61416d23cf94f6660736ca1bb5123126555db7af 100644 (file)
@@ -25,7 +25,6 @@
 //           Moved here from SMESH_LocalLength_i.cxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
-//  $Header$
 //
 #include "StdMeshers_Deflection1D_i.hxx"
 #include "SMESH_Gen_i.hxx"
diff --git a/src/StdMeshers_I/StdMeshers_ImportSource1D_i.cxx b/src/StdMeshers_I/StdMeshers_ImportSource1D_i.cxx
new file mode 100644 (file)
index 0000000..4d33ec8
--- /dev/null
@@ -0,0 +1,280 @@
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//  File   : StdMeshers_ImportSource1D_i.cxx
+//  Module : SMESH
+//
+#include "StdMeshers_ImportSource1D_i.hxx"
+
+#include "SMESH_Gen.hxx"
+#include "SMESH_Gen_i.hxx"
+#include "SMESH_Group_i.hxx"
+#include "SMESH_PythonDump.hxx"
+#include "StdMeshers_ObjRefUlils.hxx"
+
+#include "Utils_CorbaException.hxx"
+#include "utilities.h"
+
+#include <TCollection_AsciiString.hxx>
+
+#include CORBA_SERVER_HEADER(SMESH_Group)
+
+using namespace std;
+
+//=============================================================================
+/*!
+ *  StdMeshers_ImportSource1D_i::StdMeshers_ImportSource1D_i
+ *
+ *  Constructor
+ */
+//=============================================================================
+
+StdMeshers_ImportSource1D_i::StdMeshers_ImportSource1D_i( PortableServer::POA_ptr thePOA,
+                                                          int                     theStudyId,
+                                                          ::SMESH_Gen*            theGenImpl )
+  : SALOME::GenericObj_i( thePOA ), 
+    SMESH_Hypothesis_i( thePOA )
+{
+  MESSAGE( "StdMeshers_ImportSource1D_i::StdMeshers_ImportSource1D_i" );
+  myBaseImpl = new ::StdMeshers_ImportSource1D( theGenImpl->GetANewId(),
+                                                theStudyId,
+                                                theGenImpl );
+  _groupEntries = new SMESH::string_array();
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_ImportSource1D_i::~StdMeshers_ImportSource1D_i
+ *
+ *  Destructor
+ */
+//=============================================================================
+
+StdMeshers_ImportSource1D_i::~StdMeshers_ImportSource1D_i()
+{
+  MESSAGE( "StdMeshers_ImportSource1D_i::~StdMeshers_ImportSource1D_i" );
+}
+
+//=============================================================================
+/*!
+ *  SetSourceEdges
+ */
+//=============================================================================
+
+void StdMeshers_ImportSource1D_i::SetSourceEdges(const SMESH::ListOfGroups& groups)
+{
+  MESSAGE( "StdMeshers_ImportSource1D_i::SetSourceEdges" );
+  ASSERT( myBaseImpl );
+  try
+  {
+    std::vector<SMESH_Group*> smesh_groups;
+    std::vector<string> entries;
+    SALOMEDS::Study_var study = SMESH_Gen_i::GetSMESHGen()->GetCurrentStudy();
+    for ( int i = 0; i < groups.length(); ++i )
+      if ( SMESH_GroupBase_i* gp_i = SMESH::DownCast<SMESH_GroupBase_i*>( groups[i] ))
+      {
+        if ( gp_i->GetType() != SMESH::EDGE )
+          THROW_SALOME_CORBA_EXCEPTION("Wrong group type", SALOME::BAD_PARAM);
+        smesh_groups.push_back( gp_i->GetSmeshGroup() );
+
+        SALOMEDS::SObject_var so = SMESH_Gen_i::GetSMESHGen()->ObjectToSObject(study, groups[i]);
+        if ( !so->_is_nil())
+        {
+          CORBA::String_var entry = so->GetID();
+          entries.push_back( entry.in() );
+        }
+      }
+    this->GetImpl()->SetGroups( smesh_groups );
+
+    _groupEntries = new SMESH::string_array;
+    _groupEntries->length( entries.size ());
+    for ( int i = 0; i < entries.size(); ++i )
+      _groupEntries[i] = entries[i].c_str();
+  }
+  catch ( SALOME_Exception& S_ex )
+  {
+    THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM );
+  }
+
+  // Update Python script
+  SMESH::TPythonDump() << _this() << ".SetSourceEdges( " << groups << " )";
+}
+
+//=============================================================================
+/*!
+ * Return entries of groups
+ */
+//=============================================================================
+
+SMESH::string_array*  StdMeshers_ImportSource1D_i::GetSourceEdges()
+{
+  MESSAGE( "StdMeshers_ImportSource1D_i::GetImportSource" );
+  SMESH::string_array_var res = new SMESH::string_array( _groupEntries );
+  return res._retn();
+}
+
+//================================================================================
+/*!
+ * \brief Set to copy mesh and groups
+ */
+//================================================================================
+
+void StdMeshers_ImportSource1D_i::SetCopySourceMesh(CORBA::Boolean toCopyMesh,
+                                                    CORBA::Boolean toCopyGroups)
+{
+  GetImpl()->SetCopySourceMesh(toCopyMesh,toCopyGroups);
+  SMESH::TPythonDump() << _this() << ".SetCopySourceMesh( "
+                       << toCopyMesh << ", " << toCopyGroups << " )";
+}
+
+//================================================================================
+/*!
+ * \brief Return "to copy mesh and groups"
+ */
+//================================================================================
+
+void StdMeshers_ImportSource1D_i::GetCopySourceMesh(CORBA::Boolean& toCopyMesh,
+                                                    CORBA::Boolean& toCopyGroups)
+{
+  GetImpl()->GetCopySourceMesh(toCopyMesh,toCopyGroups);
+}
+
+//================================================================================
+/*!
+ * \brief Write parameters in a string
+  * \retval char* - resulting string
+ */
+//================================================================================
+
+char* StdMeshers_ImportSource1D_i::SaveTo()
+{
+  std::ostringstream os;
+  os << " " << _groupEntries->length();
+
+  SALOMEDS::Study_var study = SMESH_Gen_i::GetSMESHGen()->GetCurrentStudy();
+  for ( int i = 0; i < _groupEntries->length(); ++i )
+  {
+    // entry
+    os << " " << _groupEntries[i];
+
+    // id
+    SALOMEDS::SObject_var groupSO = study->FindObjectID( _groupEntries[i] );
+    CORBA::Object_var groupObj;
+    if ( !groupSO->_is_nil() )
+      groupObj = groupSO->GetObject();
+    StdMeshers_ObjRefUlils::SaveToStream( groupObj, os );
+  }
+
+  myBaseImpl->SaveTo( os );
+
+  return CORBA::string_dup( os.str().c_str() );
+}
+
+//================================================================================
+/*!
+ * \brief Retrieve parameters from the string
+  * \param theStream - the input string
+ */
+//================================================================================
+
+void StdMeshers_ImportSource1D_i::LoadFrom( const char* theStream )
+{
+  std::istringstream is( theStream );
+
+  int nbGroups;
+  is >> nbGroups;
+
+  _groupEntries = new SMESH::string_array;
+  _groupEntries->length( nbGroups );
+  std::string id, entry;
+  for ( int i = 0; i < _groupEntries->length(); ++i )
+  {
+    if ( is >> entry )
+      _groupEntries[i] = entry.c_str();
+    else
+    {
+      _groupEntries->length( i );
+      is.clear(ios::badbit | is.rdstate());
+      break;
+    }
+    if ( is >> id )
+      _groupIDs.push_back( id );
+    else
+    {
+      is.clear(ios::badbit | is.rdstate());
+      break;
+    }
+  }
+
+  myBaseImpl->LoadFrom( is );
+}
+
+//================================================================================
+/*!
+ * \brief Retrieve groups by their ids loaded by LoadFrom()
+ * This is possible only when all meshes are fully loaded
+ */
+//================================================================================
+
+void StdMeshers_ImportSource1D_i::UpdateAsMeshesRestored()
+{
+  std::vector<SMESH_Group*> smesh_groups;
+  for ( unsigned i = 0; i < _groupIDs.size(); ++i )
+  {
+    std::istringstream is( _groupIDs[i].c_str() );
+    SMESH::SMESH_GroupBase_var group =
+      StdMeshers_ObjRefUlils::LoadObjectFromStream<SMESH::SMESH_GroupBase>( is );
+    if ( SMESH_GroupBase_i* gp_i = SMESH::DownCast<SMESH_GroupBase_i*>( group ))
+      smesh_groups.push_back( gp_i->GetSmeshGroup() );
+  }
+  GetImpl()->RestoreGroups(smesh_groups);
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_ImportSource1D_i::GetImpl
+ *
+ *  Get implementation
+ */
+//=============================================================================
+
+::StdMeshers_ImportSource1D* StdMeshers_ImportSource1D_i::GetImpl()
+{
+  MESSAGE( "StdMeshers_ImportSource1D_i::GetImpl" );
+  return ( ::StdMeshers_ImportSource1D* )myBaseImpl;
+}
+
+//================================================================================
+/*!
+ * \brief Verify whether hypothesis supports given entity type 
+  * \param type - dimension (see SMESH::Dimension enumeration)
+  * \retval CORBA::Boolean - TRUE if dimension is supported, FALSE otherwise
+ * 
+ * Verify whether hypothesis supports given entity type (see SMESH::Dimension enumeration)
+ */
+//================================================================================  
+CORBA::Boolean StdMeshers_ImportSource1D_i::IsDimSupported( SMESH::Dimension type )
+{
+  return type == SMESH::DIM_1D;
+}
+
diff --git a/src/StdMeshers_I/StdMeshers_ImportSource1D_i.hxx b/src/StdMeshers_I/StdMeshers_ImportSource1D_i.hxx
new file mode 100644 (file)
index 0000000..216244a
--- /dev/null
@@ -0,0 +1,74 @@
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//  File   : StdMeshers_ImportSource1D_i.hxx
+//  Module : SMESH
+//
+#ifndef _SMESH_ImportSource1D_I_HXX_
+#define _SMESH_ImportSource1D_I_HXX_
+
+#include "SMESH_StdMeshers_I.hxx"
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "SMESH_Hypothesis_i.hxx"
+#include "StdMeshers_ImportSource.hxx"
+
+class SMESH_Gen;
+
+class STDMESHERS_I_EXPORT StdMeshers_ImportSource1D_i:
+  public virtual POA_StdMeshers::StdMeshers_ImportSource1D,
+  public virtual SMESH_Hypothesis_i
+{
+ public:
+  // Constructor
+  StdMeshers_ImportSource1D_i( PortableServer::POA_ptr thePOA,
+                               int                     theStudyId,
+                               ::SMESH_Gen*            theGenImpl );
+  // Destructor
+  virtual ~StdMeshers_ImportSource1D_i();
+
+  void SetSourceEdges(const ::SMESH::ListOfGroups& groups);
+  SMESH::string_array* GetSourceEdges();
+  void SetCopySourceMesh(::CORBA::Boolean toCopyMesh, ::CORBA::Boolean toCopyGroups);
+  void GetCopySourceMesh(::CORBA::Boolean& toCopyMesh, ::CORBA::Boolean& toCopyGroups);
+
+  // Get implementation
+  ::StdMeshers_ImportSource1D* GetImpl();
+
+  // Verify whether hypothesis supports given entity type 
+  CORBA::Boolean IsDimSupported( SMESH::Dimension type );
+
+  // Redefined Persistence
+  virtual char* SaveTo();
+  virtual void  LoadFrom( const char* theStream );
+  virtual void  UpdateAsMeshesRestored();
+
+ private:
+  SMESH::string_array_var _groupEntries;
+  std::vector< std::string > _groupIDs;
+};
+
+#endif
+
diff --git a/src/StdMeshers_I/StdMeshers_ImportSource2D_i.cxx b/src/StdMeshers_I/StdMeshers_ImportSource2D_i.cxx
new file mode 100644 (file)
index 0000000..b2221a4
--- /dev/null
@@ -0,0 +1,280 @@
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//  File   : StdMeshers_ImportSource2D_i.cxx
+//  Module : SMESH
+//
+#include "StdMeshers_ImportSource2D_i.hxx"
+
+#include "SMESH_Gen.hxx"
+#include "SMESH_Gen_i.hxx"
+#include "SMESH_Group_i.hxx"
+#include "SMESH_PythonDump.hxx"
+#include "StdMeshers_ObjRefUlils.hxx"
+
+#include "Utils_CorbaException.hxx"
+#include "utilities.h"
+
+#include <TCollection_AsciiString.hxx>
+
+#include CORBA_SERVER_HEADER(SMESH_Group)
+
+using namespace std;
+
+//=============================================================================
+/*!
+ *  StdMeshers_ImportSource2D_i::StdMeshers_ImportSource2D_i
+ *
+ *  Constructor
+ */
+//=============================================================================
+
+StdMeshers_ImportSource2D_i::StdMeshers_ImportSource2D_i( PortableServer::POA_ptr thePOA,
+                                                          int                     theStudyId,
+                                                          ::SMESH_Gen*            theGenImpl )
+  : SALOME::GenericObj_i( thePOA ), 
+    SMESH_Hypothesis_i( thePOA )
+{
+  MESSAGE( "StdMeshers_ImportSource2D_i::StdMeshers_ImportSource2D_i" );
+  myBaseImpl = new ::StdMeshers_ImportSource2D( theGenImpl->GetANewId(),
+                                                theStudyId,
+                                                theGenImpl );
+  _groupEntries = new SMESH::string_array();
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_ImportSource2D_i::~StdMeshers_ImportSource2D_i
+ *
+ *  Destructor
+ */
+//=============================================================================
+
+StdMeshers_ImportSource2D_i::~StdMeshers_ImportSource2D_i()
+{
+  MESSAGE( "StdMeshers_ImportSource2D_i::~StdMeshers_ImportSource2D_i" );
+}
+
+//=============================================================================
+/*!
+ *  SetSourceFaces
+ */
+//=============================================================================
+
+void StdMeshers_ImportSource2D_i::SetSourceFaces(const SMESH::ListOfGroups& groups)
+{
+  MESSAGE( "StdMeshers_ImportSource2D_i::SetSourceFaces" );
+  ASSERT( myBaseImpl );
+  try
+  {
+    std::vector<SMESH_Group*> smesh_groups;
+    std::vector<string> entries;
+    SALOMEDS::Study_var study = SMESH_Gen_i::GetSMESHGen()->GetCurrentStudy();
+    for ( int i = 0; i < groups.length(); ++i )
+      if ( SMESH_GroupBase_i* gp_i = SMESH::DownCast<SMESH_GroupBase_i*>( groups[i] ))
+      {
+        if ( gp_i->GetType() != SMESH::FACE )
+          THROW_SALOME_CORBA_EXCEPTION("Wrong group type", SALOME::BAD_PARAM);
+        smesh_groups.push_back( gp_i->GetSmeshGroup() );
+
+        SALOMEDS::SObject_var so = SMESH_Gen_i::GetSMESHGen()->ObjectToSObject(study, groups[i]);
+        if ( !so->_is_nil())
+        {
+          CORBA::String_var entry = so->GetID();
+          entries.push_back( entry.in() );
+        }
+      }
+    this->GetImpl()->SetGroups( smesh_groups );
+
+    _groupEntries = new SMESH::string_array;
+    _groupEntries->length( entries.size ());
+    for ( int i = 0; i < entries.size(); ++i )
+      _groupEntries[i] = entries[i].c_str();
+  }
+  catch ( SALOME_Exception& S_ex )
+  {
+    THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM );
+  }
+
+  // Update Python script
+  SMESH::TPythonDump() << _this() << ".SetSourceFaces( " << groups << " )";
+}
+
+//=============================================================================
+/*!
+ * Return entries of groups
+ */
+//=============================================================================
+
+SMESH::string_array*  StdMeshers_ImportSource2D_i::GetSourceFaces()
+{
+  MESSAGE( "StdMeshers_ImportSource2D_i::GetImportSource" );
+  SMESH::string_array_var res = new SMESH::string_array( _groupEntries );
+  return res._retn();
+}
+
+//================================================================================
+/*!
+ * \brief Set to copy mesh and groups
+ */
+//================================================================================
+
+void StdMeshers_ImportSource2D_i::SetCopySourceMesh(CORBA::Boolean toCopyMesh,
+                                                    CORBA::Boolean toCopyGroups)
+{
+  GetImpl()->SetCopySourceMesh(toCopyMesh,toCopyGroups);
+  SMESH::TPythonDump() << _this() << ".SetCopySourceMesh( "
+                       << toCopyMesh << ", " << toCopyGroups << " )";
+}
+
+//================================================================================
+/*!
+ * \brief Return "to copy mesh and groups"
+ */
+//================================================================================
+
+void StdMeshers_ImportSource2D_i::GetCopySourceMesh(CORBA::Boolean& toCopyMesh,
+                                                    CORBA::Boolean& toCopyGroups)
+{
+  GetImpl()->GetCopySourceMesh(toCopyMesh,toCopyGroups);
+}
+
+//================================================================================
+/*!
+ * \brief Write parameters in a string
+  * \retval char* - resulting string
+ */
+//================================================================================
+
+char* StdMeshers_ImportSource2D_i::SaveTo()
+{
+  std::ostringstream os;
+  os << " " << _groupEntries->length();
+
+  SALOMEDS::Study_var study = SMESH_Gen_i::GetSMESHGen()->GetCurrentStudy();
+  for ( int i = 0; i < _groupEntries->length(); ++i )
+  {
+    // entry
+    os << " " << _groupEntries[i];
+
+    // id
+    SALOMEDS::SObject_var groupSO = study->FindObjectID( _groupEntries[i] );
+    CORBA::Object_var groupObj;
+    if ( !groupSO->_is_nil() )
+      groupObj = groupSO->GetObject();
+    StdMeshers_ObjRefUlils::SaveToStream( groupObj, os );
+  }
+
+  myBaseImpl->SaveTo( os );
+
+  return CORBA::string_dup( os.str().c_str() );
+}
+
+//================================================================================
+/*!
+ * \brief Retrieve parameters from the string
+  * \param theStream - the input string
+ */
+//================================================================================
+
+void StdMeshers_ImportSource2D_i::LoadFrom( const char* theStream )
+{
+  std::istringstream is( theStream );
+
+  int nbGroups;
+  is >> nbGroups;
+
+  _groupEntries = new SMESH::string_array;
+  _groupEntries->length( nbGroups );
+  std::string id, entry;
+  for ( int i = 0; i < _groupEntries->length(); ++i )
+  {
+    if ( is >> entry )
+      _groupEntries[i] = entry.c_str();
+    else
+    {
+      _groupEntries->length( i );
+      is.clear(ios::badbit | is.rdstate());
+      break;
+    }
+    if ( is >> id )
+      _groupIDs.push_back( id );
+    else
+    {
+      is.clear(ios::badbit | is.rdstate());
+      break;
+    }
+  }
+
+  myBaseImpl->LoadFrom( is );
+}
+
+//================================================================================
+/*!
+ * \brief Retrieve groups by their ids loaded by LoadFrom()
+ * This is possible only when all meshes are fully loaded
+ */
+//================================================================================
+
+void StdMeshers_ImportSource2D_i::UpdateAsMeshesRestored()
+{
+  std::vector<SMESH_Group*> smesh_groups;
+  for ( unsigned i = 0; i < _groupIDs.size(); ++i )
+  {
+    std::istringstream is( _groupIDs[i].c_str() );
+    SMESH::SMESH_GroupBase_var group =
+      StdMeshers_ObjRefUlils::LoadObjectFromStream<SMESH::SMESH_GroupBase>( is );
+    if ( SMESH_GroupBase_i* gp_i = SMESH::DownCast<SMESH_GroupBase_i*>( group ))
+      smesh_groups.push_back( gp_i->GetSmeshGroup() );
+  }
+  GetImpl()->RestoreGroups(smesh_groups);
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_ImportSource2D_i::GetImpl
+ *
+ *  Get implementation
+ */
+//=============================================================================
+
+::StdMeshers_ImportSource2D* StdMeshers_ImportSource2D_i::GetImpl()
+{
+  MESSAGE( "StdMeshers_ImportSource2D_i::GetImpl" );
+  return ( ::StdMeshers_ImportSource2D* )myBaseImpl;
+}
+
+//================================================================================
+/*!
+ * \brief Verify whether hypothesis supports given entity type 
+  * \param type - dimension (see SMESH::Dimension enumeration)
+  * \retval CORBA::Boolean - TRUE if dimension is supported, FALSE otherwise
+ * 
+ * Verify whether hypothesis supports given entity type (see SMESH::Dimension enumeration)
+ */
+//================================================================================  
+CORBA::Boolean StdMeshers_ImportSource2D_i::IsDimSupported( SMESH::Dimension type )
+{
+  return type == SMESH::DIM_2D;
+}
+
diff --git a/src/StdMeshers_I/StdMeshers_ImportSource2D_i.hxx b/src/StdMeshers_I/StdMeshers_ImportSource2D_i.hxx
new file mode 100644 (file)
index 0000000..7f2d712
--- /dev/null
@@ -0,0 +1,74 @@
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//  File   : StdMeshers_ImportSource2D_i.hxx
+//  Module : SMESH
+//
+#ifndef _SMESH_ImportSource2D_I_HXX_
+#define _SMESH_ImportSource2D_I_HXX_
+
+#include "SMESH_StdMeshers_I.hxx"
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "SMESH_Hypothesis_i.hxx"
+#include "StdMeshers_ImportSource.hxx"
+
+class SMESH_Gen;
+
+class STDMESHERS_I_EXPORT StdMeshers_ImportSource2D_i:
+  public virtual POA_StdMeshers::StdMeshers_ImportSource2D,
+  public virtual SMESH_Hypothesis_i
+{
+ public:
+  // Constructor
+  StdMeshers_ImportSource2D_i( PortableServer::POA_ptr thePOA,
+                               int                     theStudyId,
+                               ::SMESH_Gen*            theGenImpl );
+  // Destructor
+  virtual ~StdMeshers_ImportSource2D_i();
+
+  void SetSourceFaces(const ::SMESH::ListOfGroups& groups);
+  SMESH::string_array*  GetSourceFaces();
+  void SetCopySourceMesh(::CORBA::Boolean toCopyMesh, ::CORBA::Boolean toCopyGroups);
+  void GetCopySourceMesh(::CORBA::Boolean& toCopyMesh, ::CORBA::Boolean& toCopyGroups);
+
+  // Get implementation
+  ::StdMeshers_ImportSource2D* GetImpl();
+
+  // Verify whether hypothesis supports given entity type 
+  CORBA::Boolean IsDimSupported( SMESH::Dimension type );
+
+  // Redefined Persistence
+  virtual char* SaveTo();
+  virtual void  LoadFrom( const char* theStream );
+  virtual void  UpdateAsMeshesRestored();
+
+ private:
+  SMESH::string_array_var _groupEntries;
+  std::vector< std::string > _groupIDs;
+};
+
+#endif
+
diff --git a/src/StdMeshers_I/StdMeshers_Import_1D2D_i.cxx b/src/StdMeshers_I/StdMeshers_Import_1D2D_i.cxx
new file mode 100644 (file)
index 0000000..e2489e5
--- /dev/null
@@ -0,0 +1,67 @@
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//  File   : StdMeshers_Import_1D2D_i.cxx
+//  Module : SMESH
+//
+#include "StdMeshers_Import_1D2D_i.hxx"
+#include "SMESH_Gen.hxx"
+
+#include "Utils_CorbaException.hxx"
+#include "utilities.h"
+
+using namespace std;
+
+
+//=============================================================================
+/*!
+ *  StdMeshers_Import_1D2D_i::StdMeshers_Import_1D2D_i
+ */
+//=============================================================================
+
+StdMeshers_Import_1D2D_i::StdMeshers_Import_1D2D_i (PortableServer::POA_ptr thePOA,
+                                                    int                     theStudyId,
+                                                    ::SMESH_Gen*            theGenImpl)
+  : SALOME::GenericObj_i( thePOA ), 
+    SMESH_Hypothesis_i( thePOA ), 
+    SMESH_Algo_i( thePOA ),
+    SMESH_2D_Algo_i( thePOA )
+{
+  MESSAGE( "StdMeshers_Import_1D2D_i::StdMeshers_Import_1D2D_i" );
+  myBaseImpl = new ::StdMeshers_Import_1D2D(theGenImpl->GetANewId(),
+                                            theStudyId,
+                                            theGenImpl );
+}
+
+//-----------------------------------------------------------------------------
+
+StdMeshers_Import_1D2D_i::~StdMeshers_Import_1D2D_i()
+{
+  MESSAGE( "StdMeshers_Import_1D2D_i::~StdMeshers_Import_1D2D_i" );
+}
+
+//-----------------------------------------------------------------------------
+
+::StdMeshers_Import_1D2D* StdMeshers_Import_1D2D_i::GetImpl()
+{
+  MESSAGE( "StdMeshers_Import_1D2D_i::GetImpl" );
+  return ( ::StdMeshers_Import_1D2D* )myBaseImpl;
+}
+
diff --git a/src/StdMeshers_I/StdMeshers_Import_1D2D_i.hxx b/src/StdMeshers_I/StdMeshers_Import_1D2D_i.hxx
new file mode 100644 (file)
index 0000000..8e56966
--- /dev/null
@@ -0,0 +1,53 @@
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//  File   : StdMeshers_Import_1D2D_i.hxx
+//  Module : SMESH
+//
+#ifndef _SMESH_Import_1D2D_I_HXX_
+#define _SMESH_Import_1D2D_I_HXX_
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "SMESH_2D_Algo_i.hxx"
+#include "StdMeshers_Import_1D2D.hxx"
+
+class SMESH_Gen;
+
+class StdMeshers_Import_1D2D_i:
+  public virtual POA_StdMeshers::StdMeshers_Import_1D2D,
+  public virtual SMESH_2D_Algo_i
+{
+public:
+  // Constructor
+  StdMeshers_Import_1D2D_i( PortableServer::POA_ptr thePOA,
+                            int                     theStudyId,
+                            ::SMESH_Gen*            theGenImpl );
+
+  // Destructor
+  virtual ~StdMeshers_Import_1D2D_i();
+
+  // Get implementation
+  ::StdMeshers_Import_1D2D* GetImpl();
+};
+
+
+#endif
diff --git a/src/StdMeshers_I/StdMeshers_Import_1D_i.cxx b/src/StdMeshers_I/StdMeshers_Import_1D_i.cxx
new file mode 100644 (file)
index 0000000..02b3e29
--- /dev/null
@@ -0,0 +1,85 @@
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//  File   : StdMeshers_Import_1D_i.cxx
+//           Moved here from SMESH_Import_1D_i.cxx
+//  Author : Paul RASCLE, EDF
+//  Module : SMESH
+//
+#include "StdMeshers_Import_1D_i.hxx"
+#include "SMESH_Gen.hxx"
+
+#include "Utils_CorbaException.hxx"
+#include "utilities.h"
+
+using namespace std;
+
+//=============================================================================
+/*!
+ *  StdMeshers_Import_1D_i::StdMeshers_Import_1D_i
+ *
+ *  Constructor
+ */
+//=============================================================================
+
+StdMeshers_Import_1D_i::StdMeshers_Import_1D_i( PortableServer::POA_ptr thePOA,
+                                                int                     theStudyId,
+                                                ::SMESH_Gen*            theGenImpl )
+  : SALOME::GenericObj_i( thePOA ), 
+    SMESH_Hypothesis_i( thePOA ), 
+    SMESH_Algo_i( thePOA ),
+    SMESH_1D_Algo_i( thePOA )
+{
+  MESSAGE( "StdMeshers_Import_1D_i::StdMeshers_Import_1D_i" );
+  myBaseImpl = new ::StdMeshers_Import_1D( theGenImpl->GetANewId(),
+                                           theStudyId,
+                                           theGenImpl );
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_Import_1D_i::~StdMeshers_Import_1D_i
+ *
+ *  Destructor
+ */
+//=============================================================================
+
+StdMeshers_Import_1D_i::~StdMeshers_Import_1D_i()
+{
+  MESSAGE( "StdMeshers_Import_1D_i::~StdMeshers_Import_1D_i" );
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_Import_1D_i::GetImpl
+ *
+ *  Get implementation
+ */
+//=============================================================================
+
+::StdMeshers_Import_1D* StdMeshers_Import_1D_i::GetImpl()
+{
+  MESSAGE( "StdMeshers_Import_1D_i::GetImpl" );
+  return ( ::StdMeshers_Import_1D* )myBaseImpl;
+}
+
diff --git a/src/StdMeshers_I/StdMeshers_Import_1D_i.hxx b/src/StdMeshers_I/StdMeshers_Import_1D_i.hxx
new file mode 100644 (file)
index 0000000..d0e1d97
--- /dev/null
@@ -0,0 +1,54 @@
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//  File   : StdMeshers_Import_1D_i.hxx
+//  Module : SMESH
+//
+#ifndef _SMESH_Import_1D_I_HXX_
+#define _SMESH_Import_1D_I_HXX_
+
+#include "SMESH_StdMeshers_I.hxx"
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "SMESH_1D_Algo_i.hxx"
+#include "StdMeshers_Import_1D.hxx"
+
+class STDMESHERS_I_EXPORT StdMeshers_Import_1D_i:
+  public virtual POA_StdMeshers::StdMeshers_Import_1D,
+  public virtual SMESH_1D_Algo_i
+{
+ public:
+  // Constructor
+  StdMeshers_Import_1D_i( PortableServer::POA_ptr thePOA,
+                          int                     theStudyId,
+                          ::SMESH_Gen*            theGenImpl );
+  // Destructor
+  virtual ~StdMeshers_Import_1D_i();
+
+  // Get implementation
+  ::StdMeshers_Import_1D* GetImpl();
+};
+
+#endif
index d416a578744845a4e16601b6d96b4c547ab1b6ab..fbd8b189852702f93d307ccd25dd53193b9e775d 100644 (file)
@@ -24,7 +24,6 @@
 //  File   : StdMeshers_ProjectionSource1D_i.hxx
 //  Author : Edward AGAPOV
 //  Module : SMESH
-//  $Header$
 //
 #ifndef _SMESH_ProjectionSource1D_I_HXX_
 #define _SMESH_ProjectionSource1D_I_HXX_
index 090e00ee9172a5a090af9fce374ba59186dfb264..b58d9cbd5938535a57e62bc29e0fa2afa91c9588 100644 (file)
@@ -19,7 +19,6 @@
 
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_RadialQuadrangle_1D2D_i.cxx
-//  Author : Paul RASCLE, EDF
 //  Module : SMESH
 //
 #include "StdMeshers_RadialQuadrangle_1D2D_i.hxx"
index 85a6e3ae05f0b69f6d4ac8bebf982bb5ab944d64..1a9fb637c90294c58209db466e63d2b77cb8e30a 100644 (file)
@@ -19,9 +19,7 @@
 
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_RadialQuadrangle_1D2D_i.hxx
-//  Author : Paul RASCLE, EDF
 //  Module : SMESH
-//  $Header$
 //
 #ifndef _SMESH_RadialQuadrangle_1D2D_I_HXX_
 #define _SMESH_RadialQuadrangle_1D2D_I_HXX_
index 2b75cdc8a769e52f9e785ce52864e53a50e1524a..d6fd3cf4500c240ebb8d4905f93e9aa2e95f6f3f 100644 (file)
@@ -25,7 +25,6 @@
 //           Moved here from SMESH_Regular_1D_i.cxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
-//  $Header$
 //
 #include "StdMeshers_Regular_1D_i.hxx"
 #include "SMESH_Gen.hxx"
index bfc463de51da897fcacd0496e3889778e588b944..02006c455e3ec19692b32c6ccd3632d41407b2e5 100644 (file)
@@ -25,7 +25,6 @@
 //           Moved here from SMESH_Regular_1D_i.hxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
-//  $Header$
 //
 #ifndef _SMESH_REGULAR_1D_I_HXX_
 #define _SMESH_REGULAR_1D_I_HXX_
index f50fae594d4c96aa2f8fe37fd0530a5e448dc22c..a8f6a9824f19d2fa46cf8bb0d67375b3c7d1f6e6 100644 (file)
@@ -56,6 +56,8 @@
 #include "StdMeshers_SegmentLengthAroundVertex_i.hxx"
 #include "StdMeshers_MaxLength_i.hxx"
 #include "StdMeshers_QuadrangleParams_i.hxx"
+#include "StdMeshers_ImportSource1D_i.hxx"
+#include "StdMeshers_ImportSource2D_i.hxx"
 
 #include "StdMeshers_Regular_1D_i.hxx"
 #include "StdMeshers_MEFISTO_2D_i.hxx"
@@ -67,6 +69,8 @@
 #include "StdMeshers_CompositeSegment_1D_i.hxx"
 #include "StdMeshers_UseExisting_1D2D_i.hxx"
 #include "StdMeshers_RadialQuadrangle_1D2D_i.hxx"
+#include "StdMeshers_Import_1D_i.hxx"
+#include "StdMeshers_Import_1D2D_i.hxx"
 
 
 template <class T> class StdHypothesisCreator_i:public HypothesisCreator_i<T>
@@ -141,6 +145,10 @@ STDMESHERS_I_EXPORT
       aCreator = new StdHypothesisCreator_i<StdMeshers_SegmentLengthAroundVertex_i>;
     else if (strcmp(aHypName, "QuadrangleParams") == 0)
       aCreator = new StdHypothesisCreator_i<StdMeshers_QuadrangleParams_i>;
+    else if (strcmp(aHypName, "ImportSource1D") == 0)
+      aCreator = new StdHypothesisCreator_i<StdMeshers_ImportSource1D_i>;
+    else if (strcmp(aHypName, "ImportSource2D") == 0)
+      aCreator = new StdHypothesisCreator_i<StdMeshers_ImportSource2D_i>;
 
     // Algorithms
     else if (strcmp(aHypName, "Regular_1D") == 0)
@@ -171,6 +179,10 @@ STDMESHERS_I_EXPORT
       aCreator = new StdHypothesisCreator_i<StdMeshers_UseExisting_2D_i>;
     else if (strcmp(aHypName, "RadialQuadrangle_1D2D") == 0)
       aCreator = new StdHypothesisCreator_i<StdMeshers_RadialQuadrangle_1D2D_i>;
+    else if (strcmp(aHypName, "Import_1D") == 0)
+      aCreator = new StdHypothesisCreator_i<StdMeshers_Import_1D_i>;
+    else if (strcmp(aHypName, "Import_1D2D") == 0)
+      aCreator = new StdHypothesisCreator_i<StdMeshers_Import_1D2D_i>;
     else ;
 
     return aCreator;