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>
<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>
*/
<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>
\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
<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>
<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>
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>
\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"
<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>
<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>
--- /dev/null
+/*!
+
+\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
--- /dev/null
+/*!
+
+\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
--- /dev/null
+/*!
+
+\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".
+
+*/
/*!
-\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
+*/
+
<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>
<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
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>
\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>
<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>
- \subpage tui_modifying_meshes_page
- \subpage tui_transforming_meshes_page
- \subpage tui_notebook_smesh_page
+- \subpage tui_measurements_page
*/
<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>
\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)
# 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
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:
\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
- /*!
+/*!
\page tui_grouping_elements_page Grouping Elements
--- /dev/null
+/*!
+
+\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
+
+*/
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
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
+
*/
--- /dev/null
+/*!
+
+\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".
+
+*/
+
<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>
<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>
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)
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)
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
*/
{
};
+ /*!
+ * 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
FT_Skew,
FT_Area,
FT_Volume3D,
+ FT_MaxElementLength2D,
+ FT_MaxElementLength3D,
FT_FreeBorders,
FT_FreeEdges,
FT_FreeNodes,
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 )
*/
{
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.
interface Skew : NumericalFunctor{};
interface Area : NumericalFunctor{};
interface Volume3D : NumericalFunctor{};
+ interface MaxElementLength2D : NumericalFunctor{};
+ interface MaxElementLength3D : NumericalFunctor{};
interface Length : NumericalFunctor{};
interface Length2D : NumericalFunctor
{
Skew CreateSkew();
Area CreateArea();
Volume3D CreateVolume3D();
+ MaxElementLength2D CreateMaxElementLength2D();
+ MaxElementLength3D CreateMaxElementLength3D();
Length CreateLength();
Length2D CreateLength2D();
MultiConnection CreateMultiConnection();
interface FilterManager;
interface SMESH_Pattern;
+ interface Measurements;
/*!
* Tags definition
SMESH_Pattern GetPattern();
+ Measurements CreateMeasurements();
+
/*!
Set the current mode
*/
*/
long_array Evaluate(in SMESH_Mesh theMesh,
in GEOM::GEOM_Object theSubObject)
- //inout long_array theNbElems)
raises ( SALOME::SALOME_Exception );
/*!
*/
long_array GetListOfID();
- /*!
- * Returns the mesh object this group belongs to
- */
- SMESH_Mesh GetMesh();
-
/*!
* Sets group color
*/
--- /dev/null
+// 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
long_array elementConnectivities;
types_array elementTypes; };
+ interface SMESH_Mesh;
+
interface SMESH_IDSource
{
/*!
* Returns types of elements it contains
*/
array_of_ElementType GetTypes();
+
+ /*!
+ * Returns the mesh
+ */
+ SMESH_Mesh GetMesh();
};
interface SMESH_Group;
mesh_info.png \
advanced_mesh_info.png \
standard_mesh_info.png \
+ mesh_elem_info.png \
mesh_whatis.png \
mesh_init.png \
mesh_length.png \
mesh_free_edges.png \
mesh_free_edges_2d.png \
mesh_free_nodes.png \
+ mesh_max_element_length_2d.png \
+ mesh_max_element_length_3d.png \
mesh_multi_edges.png \
mesh_multi_edges_2d.png \
mesh_line_n.png \
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
<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"/>
<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"
new Taper();
new Skew();
new Area();
+ new MaxElementLength2D();
+ new MaxElementLength3D();
new Length();
// new Length2D();
new MultiConnection();
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 :
}
+/*
+ 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
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
*/
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
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 ));
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 ));
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;
};
+ /*
+ 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
SMESH_DeviceActor.h \
SMESH_PreviewActorsCollection.h \
SMESH_ExtractGeometry.h \
- SMESH_FaceOrientationFilter.h
+ SMESH_FaceOrientationFilter.h \
+ SMESH_ScalarBarActor.h
+
# Libraries targets
SMESH_PreviewActorsCollection.cxx \
SMESH_ExtractGeometry.cxx \
SMESH_ActorUtils.cxx \
- SMESH_FaceOrientationFilter.cxx
+ SMESH_FaceOrientationFilter.cxx \
+ SMESH_ScalarBarActor.cxx
libSMESHObject_la_CPPFLAGS = \
$(QT_INCLUDES) \
#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"
#include <vtkLabeledDataMapper.h>
#include <vtkSelectVisiblePoints.h>
-#include <vtkScalarBarActor.h>
#include <vtkLookupTable.h>
#include <vtkMath.h>
//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);
{
if(MYDEBUG) MESSAGE("~SMESH_ActorDef - "<<this);
+ // caught by SMESHGUI::ProcessEvents() static method
+ this->InvokeEvent( SMESH::DeleteActorEvent, NULL );
+
myScalarBarActor->Delete();
myLookupTable->Delete();
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;
}
{
SMESH::Controls::Taper* aControl = new SMESH::Controls::Taper();
aControl->SetPrecision( myControlsPrecision );
- aFunctor.reset( aControl );
+ myFunctor.reset( aControl );
myControlActor = my2DActor;
break;
}
{
SMESH::Controls::AspectRatio* aControl = new SMESH::Controls::AspectRatio();
aControl->SetPrecision( myControlsPrecision );
- aFunctor.reset( aControl );
+ myFunctor.reset( aControl );
myControlActor = my2DActor;
break;
}
{
SMESH::Controls::AspectRatio3D* aControl = new SMESH::Controls::AspectRatio3D();
aControl->SetPrecision( myControlsPrecision );
- aFunctor.reset( aControl );
+ myFunctor.reset( aControl );
myControlActor = my3DActor;
break;
}
{
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;
}
{
SMESH::Controls::MinimumAngle* aControl = new SMESH::Controls::MinimumAngle();
aControl->SetPrecision( myControlsPrecision );
- aFunctor.reset( aControl );
+ myFunctor.reset( aControl );
myControlActor = my2DActor;
break;
}
{
SMESH::Controls::Warping* aControl = new SMESH::Controls::Warping();
aControl->SetPrecision( myControlsPrecision );
- aFunctor.reset( aControl );
+ myFunctor.reset( aControl );
myControlActor = my2DActor;
break;
}
{
SMESH::Controls::Skew* aControl = new SMESH::Controls::Skew();
aControl->SetPrecision( myControlsPrecision );
- aFunctor.reset( aControl );
+ myFunctor.reset( aControl );
myControlActor = my2DActor;
break;
}
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);
}
}
SetEntityMode(eVolumes);
}
- }else if(theCheckEntityMode){
- myEntityMode = eAllEntity;
+ }
+ else {
+ if(theCheckEntityMode)
+ myEntityMode = eAllEntity;
+ myFunctor.reset();
}
SetRepresentation(GetRepresentation());
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();
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);
+
}
#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;}
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;
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
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();
TVisualObjPtr myVisualObj;
vtkTimeStamp* myTimeStamp;
- vtkScalarBarActor* myScalarBarActor;
+ SMESH_ScalarBarActor* myScalarBarActor;
vtkLookupTable* myLookupTable;
vtkProperty* mySurfaceProp;
SMESH_DeviceActor* myHighlitableActor;
eControl myControlMode;
+ SMESH::Controls::FunctorPtr myFunctor;
vtkProperty* my2DExtProp;
SMESH_DeviceActor* my2DActor;
SMESH_DeviceActor* my2DExtActor;
// Module : SMESH
//
#include "SMESH_DeviceActor.h"
+#include "SMESH_ScalarBarActor.h"
#include "SMESH_ExtractGeometry.h"
#include "SMESH_ControlsDef.hxx"
#include "SMESH_ActorUtils.h"
#include <vtkPolyDataMapper.h>
#include <vtkUnstructuredGrid.h>
-#include <vtkScalarBarActor.h>
#include <vtkLookupTable.h>
#include <vtkDoubleArray.h>
#include <vtkCellData.h>
void
SMESH_DeviceActor
::SetControlMode(SMESH::Controls::FunctorPtr theFunctor,
- vtkScalarBarActor* theScalarBarActor,
+ SMESH_ScalarBarActor* theScalarBarActor,
vtkLookupTable* theLookupTable)
{
bool anIsInitialized = theFunctor;
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);
void
SMESH_DeviceActor
::SetExtControlMode(SMESH::Controls::FunctorPtr theFunctor,
- vtkScalarBarActor* theScalarBarActor,
+ SMESH_ScalarBarActor* theScalarBarActor,
vtkLookupTable* theLookupTable)
{
bool anIsInitialized = theFunctor;
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);
class vtkMergeFilter;
class vtkShrinkFilter;
class vtkUnstructuredGrid;
-class vtkScalarBarActor;
class vtkLookupTable;
class vtkImplicitBoolean;
class vtkPassThroughFilter;
class SMESH_ExtractGeometry;
class SMESH_FaceOrientationFilter;
+class SMESH_ScalarBarActor;
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);
// VTK includes
#include <vtkUnstructuredGrid.h>
-#include <vtkScalarBarActor.h>
#include <vtkPlane.h>
#include <vtkRenderer.h>
#include <vtkProperty.h>
--- /dev/null
+// 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);
+}
--- /dev/null
+// 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
///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;
/*!
* \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);
*
* 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);
*/
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 )
SMESH_Group::~SMESH_Group ()
{
- delete myGroupDS;
+ delete myGroupDS; myGroupDS=0;
}
// File : SMESH_Group.hxx
// Author : Michael Sazonov (OCC)
// Module : SMESH
-// $Header$
//
#ifndef _SMESH_Group_HeaderFile
#define _SMESH_Group_HeaderFile
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
*/
_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;
+}
+
//=============================================================================
/*!
*
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;
_isAutoColor = false;
_isModified = false;
_shapeDiagonal = 0.0;
+ _rmGroupCallUp = 0;
_myMeshDS->ShapeToMesh( PseudoShape() );
}
delete aGroup;
}
_mapGroup.clear();
+
+ if ( _rmGroupCallUp) delete _rmGroupCallUp;
+ _rmGroupCallUp = 0;
}
//=============================================================================
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;
}
}
}
- HasModificationsToDiscard(); // to reset _isModified flag if mesh become empty
+ HasModificationsToDiscard(); // to reset _isModified flag if mesh becomes empty
}
//=============================================================================
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;
+}
//=============================================================================
/*!
*/
//=============================================================================
-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;
}
//=======================================================================
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);
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();
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
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&) {};
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;
+ }
}
//=======================================================================
{
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 );
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;
#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;
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,
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;
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;
}
}
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
//purpose :
//=======================================================================
-SMDS_ElemIteratorPtr SMESHDS_Group::GetElements()
+SMDS_ElemIteratorPtr SMESHDS_Group::GetElements() const
{
return SMDS_ElemIteratorPtr( new MyGroupIterator ( myGroup ));
}
virtual bool Contains (const SMDS_MeshElement* elem);
- virtual SMDS_ElemIteratorPtr GetElements();
+ virtual SMDS_ElemIteratorPtr GetElements() const;
bool Add (const int theID);
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()
//purpose :
//=======================================================================
-SMDS_ElemIteratorPtr SMESHDS_GroupOnGeom::GetElements()
+SMDS_ElemIteratorPtr SMESHDS_GroupOnGeom::GetElements() const
{
return SMDS_ElemIteratorPtr( new MyIterator ( GetType(), mySubMesh ));
}
virtual bool Contains (const SMDS_MeshElement* elem);
- virtual SMDS_ElemIteratorPtr GetElements();
+ virtual SMDS_ElemIteratorPtr GetElements() const;
private:
{
myScript = new SMESHDS_Script(theIsEmbeddedMode);
myCurSubMesh = 0;
+ SetPersistentId(theMeshID);
}
//=======================================================================
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 :
return nullShape;
}
+//================================================================================
+/*!
+ * \brief Return max index of sub-mesh
+ */
+//================================================================================
+
+int SMESHDS_Mesh::MaxSubMeshIndex() const
+{
+ return myShapeIndexToSubMesh.empty() ? 0 : myShapeIndexToSubMesh.rbegin()->first;
+}
+
//=======================================================================
//function : ShapeToIndex
//purpose :
#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"
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;
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);
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
{
ShapeToHypothesis myShapeToHypothesis;
- int myMeshID;
+ int myMeshID, myPersistentID;
TopoDS_Shape myShape;
typedef std::map<int,SMESHDS_SubMesh*> TShapeIndexToSubMesh;
SUBMESH_SOLID,
SUBMESH_COMPOUND,
GROUP,
+ GROUP_NODE,
+ GROUP_EDGE,
+ GROUP_FACE,
+ GROUP_VOLUME,
+ GROUP_0D,
COMPONENT
};
// 4 | |- Applied algorithms ( selectable in Use Case Browser )
// 5 | |- Regular 1D
// |- Group Of Nodes
+ // |- Group 1
if (aLevel <= 0)
return false;
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;
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 \
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 \
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 \
#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"
#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();
}
}
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();
{
#ifdef WITHGENERICOBJ
SMESH::GetFilterManager()->Destroy();
+ SMESH::GetMeasurements()->Destroy();
#endif
SMESH::GetFilterManager() = SMESH::FilterManager::_nil();
+ SMESH::GetMeasurements() = SMESH::Measurements::_nil();
}
//=============================================================================
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:
}
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;
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();
( new SMESHGUI_StandardMeshInfosDlg( this ) )->show();
break;
}
-
case 903: // WHAT IS
{
EmitSignalDeactivateDialog();
( new SMESHGUI_WhatIsDlg( this ) )->show();
break;
}
+ */
case 904: // FIND ELEM
{
case 6005:
case 6009:
case 6021:
+ case 6022:
+ case 6023:
if ( vtkwnd ) {
LightApp_SelectionMgr* mgr = selectionMgr();
}
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
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 );
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 );
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" );
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 ),
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 );
createMenu( 417, modifyId, -1 );
createMenu( 418, modifyId, -1 );
+ createMenu( 501, measureId, -1 );
+ createMenu( 502, measureId, -1 );
createMenu( 214, viewId, -1 );
// ----- create toolbars --------------
//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 );
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 );
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 );
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 );
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
//-------------------------------------------------
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 );
//-------------------------------------------------
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* ) ) );
}
//================================================================================
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 ------------------------------------------------------------------------
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 );
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,
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 )
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();
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 );
// 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++)
{
// 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
} // 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
*
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)
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)
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);
}
}
}
}
// 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];
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 );
}
}
}
} // 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);
#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;
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 :
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* );
private slots:
void OnGUIEvent();
void onViewManagerActivated( SUIT_ViewManager* );
+ void onViewManagerRemoved( SUIT_ViewManager* );
void onOperationCommited( SUIT_Operation* );
void onOperationAborted( SUIT_Operation* );
void onHypothesisEdit( int result );
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,
SMESHGUI_FilterLibraryDlg* myFilterLibraryDlg;
SMESHGUI_StudyId2MarkerMap myMarkerMap;
+ SMESHGUI_ClippingPlaneInfoMap myClippingPlaneInfoMap;
+
+ vtkSmartPointer<vtkCallbackCommand> myEventCallbackCommand;
+ vtkFloatingPointType myPriority;
};
#endif // SMESHGUI_H
#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;
};
// 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];
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}};
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;
}
//=================================================================================
// 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 );
// 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);
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);
SpinBoxDistance->SetValue(0.5);
- myActor = 0;
myIsSelectPlane = false;
- onSelectionChanged();
+
+ initializePlaneData();
+ synchronize();
myHelpFileName = "clipping_page.html";
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()));
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()));
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
//=======================================================================
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 );
}
}
}
}
-//=================================================================================
-// 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();
break;
}
myIsSelectPlane = false;
+
+ // Actors
+ bool anIsBlocked = ActorList->blockSignals( true );
+ updateActorList();
+ ActorList->blockSignals( anIsBlocked );
}
//=======================================================================
//=======================================================================
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 );
}
}
//=======================================================================
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();
}
//=======================================================================
}
//=======================================================================
-// function : Sinchronize()
+// function : synchronize()
// purpose :
//=======================================================================
-void SMESHGUI_ClippingDlg::Sinchronize()
+void SMESHGUI_ClippingDlg::synchronize()
{
int aNbPlanes = myPlanes.size();
ComboBoxPlanes->clear();
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);
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;
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 );
}
//=======================================================================
//=======================================================================
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 );
}
//=================================================================================
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" );
+}
// 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
Q_OBJECT
public:
- SMESHGUI_ClippingDlg( SMESHGUI* );
+ SMESHGUI_ClippingDlg( SMESHGUI*, SVTK_ViewWindow* );
~SMESHGUI_ClippingDlg();
double getDistance() const;
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;
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();
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;
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");
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;
--- /dev/null
+// 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() ) );
+}
--- /dev/null
+// 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
--- /dev/null
+// 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 );
+ }
+}
--- /dev/null
+// 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
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 ))
{
// 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();
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();
//
#include "SMESHGUI_MeshUtils.h"
+#include "SMESHGUI.h"
#include "SMESHGUI_Utils.h"
// SALOME KERNEL includes
// IDL includes
#include <SALOMEconfig.h>
#include CORBA_SERVER_HEADER(SMESH_Group)
+#include CORBA_SERVER_HEADER(SMESH_Measurements)
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
// IDL includes
#include <SALOMEconfig.h>
#include CORBA_SERVER_HEADER(SMESH_Mesh)
+#include CORBA_SERVER_HEADER(SMESH_Measurements)
class SALOMEDSClient_SObject;
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
#include "SMESHGUI_Utils.h"
#include <SMESH_Actor.h>
+#include <SMESH_ScalarBarActor.h>
+#include <SMESH_ControlsDef.hxx>
// SALOME GUI includes
#include <SUIT_Desktop.h>
// VTK includes
#include <vtkTextProperty.h>
-#include <vtkScalarBarActor.h>
#include <vtkLookupTable.h>
#define MINIMUM_WIDTH 70
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 );
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();
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";
}
//=================================================================================================
// Scalar Bar properties
if (!myActor)
return false;
- vtkScalarBarActor* myScalarBarActor = myActor->GetScalarBarActor();
+ SMESH_ScalarBarActor* myScalarBarActor = myActor->GetScalarBarActor();
vtkTextProperty* aTitleTextPrp = myScalarBarActor->GetTitleTextProperty();
QColor aTColor = myTitleColorBtn->color();
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();
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 =
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();
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 );
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
class QPushButton;
class QToolButton;
class QRadioButton;
+class QButtonGroup;
+class QLabel;
class SMESHGUI;
class SMESH_Actor;
void onSelectionChanged();
void onXYChanged();
void onOrientationChanged();
+ void onDistributionChanged( int );
private:
SMESHGUI* mySMESHGUI;
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;
#include <SMESH_Type.h>
#include <SMESH_Actor.h>
+#include <SMESH_ScalarBarActor.h>
// SALOME GUI includes
#include <SalomeApp_Study.h>
else if ( p=="shrinkMode" ) val = QVariant( shrinkMode( ind ) );
else if ( p=="entityMode" ) val = QVariant( entityMode( ind ) );
else if ( p=="controlMode" ) val = QVariant( controlMode( ind ) );
+ else if ( p=="isNumFunctor" ) val = QVariant( isNumFunctor( ind ) );
else if ( p=="displayMode" ) val = QVariant( displayMode( ind ) );
else if ( p=="isComputable" ) val = QVariant( isComputable( ind ) );
else if ( p=="isPreComputable" ) val = QVariant( isPreComputable( ind ) );
else if ( p=="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;
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'
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";
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 :
}
return type;
}
-
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;
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;
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()) {
return TInterface::_nil();
}
+SMESHGUI_EXPORT
+ _PTR(SObject) ObjectToSObject( CORBA::Object_ptr );
+
SMESHGUI_EXPORT
CORBA::Object_var IObjectToObject( const Handle(SALOME_InteractiveObject)& );
#include CORBA_CLIENT_HEADER(SMESH_Group)
// VTK includes
+#include <vtkMath.h>
#include <vtkRenderer.h>
#include <vtkActorCollection.h>
#include <vtkUnstructuredGrid.h>
}
}
}
+ if( anActor )
+ if( SMESHGUI* aSMESHGUI = SMESHGUI::GetSMESHGUI() )
+ aSMESHGUI->addActorAsObserver( anActor );
return anActor;
}
}
}
+
+ //----------------------------------------------------------------------------
+ // 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
class SMESH_Actor;
class SALOME_Actor;
+class vtkActor;
+
namespace SMESH
{
//----------------------------------------------------------------------------
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
<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>
<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>
<source>SMESH_POSITION_SIZE_SCALARBAR</source>
<translation>Origin && Size</translation>
</message>
+ <message>
+ <source>SMESH_DISTRIBUTION_SCALARBAR</source>
+ <translation>Distribution</translation>
+ </message>
+ <message>
+ <source>SMESH_SHOW_DISTRIBUTION_SCALARBAR</source>
+ <translation>Show Distribution</translation>
+ </message>
<message>
<source>SMESH_PRECISION</source>
<translation>Precision</translation>
<message>
<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>
</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>
<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>
<source>STB_RESET</source>
<translation>Reset</translation>
</message>
+ <message>
+ <source>STB_SAVE_DISTRIBUTION</source>
+ <translation>Save distribution to the file</translation>
+ </message>
+ <message>
+ <source>STB_SHOW_DISTRIBUTION</source>
+ <translation>Show Distribution</translation>
+ </message>
<message>
<source>STB_REVOLUTION</source>
<translation>Revolution</translation>
</message>
<message>
<source>STB_WHAT_IS</source>
- <translation>Mesh Element Info</translation>
+ <translation>Show information about the mesh node or element</translation>
</message>
<message>
<source>STB_WIRE</source>
</message>
<message>
<source>TOP_ADV_INFO</source>
- <translation>Advanced Mesh Infos</translation>
+ <translation>Mesh Information</translation>
</message>
<message>
<source>TOP_ALL</source>
<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>
<source>TOP_RESET</source>
<translation>Reset</translation>
</message>
+ <message>
+ <source>TOP_SAVE_DISTRIBUTION</source>
+ <translation>Export distribution</translation>
+ </message>
+ <message>
+ <source>TOP_SHOW_DISTRIBUTION</source>
+ <translation>Show Distribution</translation>
+ </message>
<message>
<source>TOP_REVOLUTION</source>
<translation>Revolution</translation>
</message>
<message>
<source>TOP_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>
<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>
<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>
<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>
<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>
<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>
<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>
SMESH_Pattern_i.hxx \
SMESH_2smeshpy.hxx \
SMESH_NoteBook.hxx \
+ SMESH_Measurements_i.hxx \
SMESH.hxx
# Scripts to be installed.
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
// Concatenate( [mesh1, ...], ... )
// CreateHypothesis( theHypType, theLibName )
// Compute( mesh, geom )
+ // Evaluate( mesh, geom )
// mesh creation
TCollection_AsciiString method = theCommand->GetMethod();
}
}
+ // 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" ) {
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;
return *this;
}
+ TPythonDump&
+ TPythonDump::
+ operator<<(SMESH::Measurements_i* theArg)
+ {
+ myStream<<"aMeasurements";
+ return *this;
+ }
+
+
TPythonDump& TPythonDump:: operator<<(SMESH_Gen_i* theArg)
{
myStream << SMESHGenName(); return *this;
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
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 );
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
}
+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();
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
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
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";
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;
{
public:
CORBA::Double GetValue( CORBA::Long theElementId );
+ SMESH::Histogram* GetHistogram(CORBA::Short nbIntervals);
void SetPrecision( CORBA::Long thePrecision );
CORBA::Long GetPrecision();
Controls::NumericalFunctorPtr GetNumericalFunctor();
};
+ /*
+ 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
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*,
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;
Skew_ptr CreateSkew();
Area_ptr CreateArea();
Volume3D_ptr CreateVolume3D();
+ MaxElementLength2D_ptr CreateMaxElementLength2D();
+ MaxElementLength3D_ptr CreateMaxElementLength3D();
Length_ptr CreateLength();
Length2D_ptr CreateLength2D();
MultiConnection_ptr CreateMultiConnection();
// Python Dump
TPythonDump aPythonDump;
aPythonDump << "([";
- //TCollection_AsciiString aStr ("([");
if (theStatus == SMESH::DRS_OK) {
SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder();
// 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
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())
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 ) {
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() );
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;
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 );
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 );
+ }
}
}
}
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 );
+ }
}
}
}
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 );
} // 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 ];
aGroup->CloseOnDisk();
}
}
+
// read submeh order if any
if( aTopGroup->ExistInternalObject( "Mesh Order" ) ) {
aDataset = new HDFdataset( "Mesh Order", aTopGroup );
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();
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 );
// 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 );
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
}
// 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
};
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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
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;
_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();
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 )
// 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
return aList._retn();
}
+
//=============================================================================
/*!
* Get number of groups existing in the mesh
{
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 );
+ }
}
}
-
//=============================================================================
/*!
*
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 ); }
+ };
+}
+
//=============================================================================
/*!
*
{
if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
_impl = impl;
+ if ( _impl )
+ _impl->SetRemoveGroupCallUp( new TRmGroupCallUp_i(this));
}
//=============================================================================
{
SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
+ set<int> addedIDs;
::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
while ( groupIt->more() )
{
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;
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 << " ]";
+ }
+ }
}
//=============================================================================
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
*/
//=============================================================================
-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;
// =========================
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
class FilterManager_i;
class Filter_i;
class Functor_i;
+ class Measurements_i;
// ===========================================================================================
/*!
TPythonDump&
operator<<(SMESH::Functor_i* theArg);
+ TPythonDump&
+ operator<<(SMESH::Measurements_i* theArg);
+
TPythonDump&
operator<<(SMESH_Gen_i* theArg);
}
return types._retn();
}
+
+//=======================================================================
+//function : GetMesh
+//purpose : interface SMESH_IDSource
+//=======================================================================
+
+SMESH::SMESH_Mesh_ptr SMESH_subMesh_i::GetMesh()
+{
+ return GetFather();
+}
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
aBelongToGeom.SetElementType(theElemType)
aFilter.SetPredicate(aBelongToGeom)
+ aFilterMgr.Destroy()
return aFilter.GetElementsId(theMesh)
## Current style
aFilter.SetPredicate(aLyingOnGeom)
anIds = aFilter.GetElementsId(theMesh)
+ aFilterMgr.Destroy()
aGroup = theMesh.CreateGroup(theElemType, theName)
aGroup.Add(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)
## @defgroup l2_modif_tofromqu Convert to/from Quadratic Mesh
## @}
+## @defgroup l1_measurements Measurements
import salome
import geompyDC
aCriteria = []
aCriteria.append(aCriterion)
aFilter.SetCriteria(aCriteria)
+ aFilterMgr.Destroy()
return aFilter
## Creates a numerical functor by its type
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:
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)
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()
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:
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)
aFilter = aFilterMgr.CreateFilter()
aFilter.SetCriteria(theCriteria)
group = self.MakeGroupByFilter(groupName, aFilter)
+ aFilterMgr.Destroy()
return group
## Creates a mesh group by the given filter
aPredicate = aFilterMgr.CreateFreeEdges()
aPredicate.SetMesh(self.mesh)
aBorders = aPredicate.GetBorders()
+ aFilterMgr.Destroy()
return aBorders
## Removes a group
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):
# ---------------------------------------------
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.
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):
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
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
// 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_
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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
--- /dev/null
+// 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;
+}
+
--- /dev/null
+// 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
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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
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
//================================================================================
/*!
* \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
*/
//================================================================================
//================================================================================
StdMeshers_QuadToTriaAdaptor::StdMeshers_QuadToTriaAdaptor():
- myElemSearcher(0)
+ myElemSearcher(0), myNbTriangles(0)
{
}
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.);
{
myResMap.clear();
myPyramids.clear();
+ myNbTriangles = 0;
+ myShape = aShape;
SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
SMESH_MesherHelper helper(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
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;
if ( ((const Q2TAdaptor_Triangle*) *tri)->IsRemoved() )
delete *tri, trias.erase( tri++ );
else
- tri++;
+ tri++, myNbTriangles++;
}
myPyramids.clear(); // no more needed
class SMDS_MeshFace;
class Handle_TColgp_HArray1OfPnt;
class Handle_TColgp_HArray1OfVec;
-class TopoDS_Shape;
class gp_Pnt;
class gp_Vec;
#include <list>
#include <vector>
+#include <TopoDS_Shape.hxx>
+
/*!
* \brief "Transforms" quadrilateral faces into triangular ones by creation of pyramids
*/
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);
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
#include <LightApp_SelectionMgr.h>
#include <SVTK_ViewWindow.h>
#include <SALOME_ListIO.hxx>
+#include <SALOME_ListIteratorOfListIO.hxx>
// SALOME KERNEL incldues
#include <SALOMEDSClient_SObject.hxx>
+#include <SALOMEDSClient_Study.hxx>
// Qt includes
#include <QPushButton>
//================================================================================
StdMeshersGUI_ObjectReferenceParamWdg::StdMeshersGUI_ObjectReferenceParamWdg
-( SUIT_SelectionFilter* f, QWidget* parent)
- : QWidget( parent )
+( SUIT_SelectionFilter* f, QWidget* parent, bool multiSelection)
+ : QWidget( parent ), myMultiSelection( multiSelection )
{
myFilter = f;
init();
//================================================================================
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();
StdMeshersGUI_ObjectReferenceParamWdg::~StdMeshersGUI_ObjectReferenceParamWdg()
{
if ( myFilter )
+ {
+ mySelectionMgr->removeFilter( myFilter );
delete myFilter;
+ }
}
void StdMeshersGUI_ObjectReferenceParamWdg::SetObject(CORBA::Object_ptr obj)
{
- myObject = CORBA::Object::_nil();
+ myObjects.clear();
myObjNameLineEdit->setText( "" );
myParamValue = "";
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
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 );
+ }
}
}
// CORBA includes
#include <CORBA.h>
+#include CORBA_SERVER_HEADER(SMESH_Mesh)
+
class SUIT_SelectionFilter;
class SMESHGUI;
class LightApp_SelectionMgr;
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);
void init();
private:
- CORBA::Object_var myObject;
+
+ bool myMultiSelection;
+ std::vector<CORBA::Object_var> myObjects;
+
SUIT_SelectionFilter* myFilter;
bool mySelectionActivated;
#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>
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
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;
+ }
//================================================================================
/*!
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 =
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 =
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 =
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" );
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;
}
void StdMeshersGUI_StdHypothesisCreator::onReject()
{
- if ( hypType().startsWith("ProjectionSource" ))
+ if ( hypType().startsWith("ProjectionSource" ) ||
+ hypType().startsWith("ImportSource" ))
{
// Uninstall filters of StdMeshersGUI_ObjectReferenceParamWdg
deactivateObjRefParamWdg( customWidgets() );
//================================================================================
/*!
- * \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 =
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 );
+ }
+ }
}
//================================================================================
<source>ICON_DLG_QUADRANGLE_PARAMS</source>
<translation>mesh_hypo_length.png</translation>
</message>
+ <message>
+ <source>ICON_DLG_IMPORT_SOURCE_1D</source>
+ <translation>mesh_hypo_source_edge.png</translation>
+ </message>
+ <message>
+ <source>ICON_DLG_IMPORT_SOURCE_2D</source>
+ <translation>mesh_hypo_source_face.png</translation>
+ </message>
<message>
<source>ICON_DLG_SEGMENT_LENGTH_AROUND_VERTEX</source>
<translation>mesh_hypo_length.png</translation>
<source>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>
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
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 = \
// Moved here from SMESH_LocalLength_i.cxx
// Author : Paul RASCLE, EDF
// Module : SMESH
-// $Header$
//
#include "StdMeshers_Deflection1D_i.hxx"
#include "SMESH_Gen_i.hxx"
--- /dev/null
+// 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;
+}
+
--- /dev/null
+// 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
+
--- /dev/null
+// 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;
+}
+
--- /dev/null
+// 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
+
--- /dev/null
+// 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;
+}
+
--- /dev/null
+// 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
--- /dev/null
+// 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;
+}
+
--- /dev/null
+// 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
// File : StdMeshers_ProjectionSource1D_i.hxx
// Author : Edward AGAPOV
// Module : SMESH
-// $Header$
//
#ifndef _SMESH_ProjectionSource1D_I_HXX_
#define _SMESH_ProjectionSource1D_I_HXX_
// 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"
// 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_
// 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"
// 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_
#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"
#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>
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)
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;