Salome HOME
Merge remote branch 'origin/Doc_update_ver741' into V7_5_BR
authorvsr <vsr@opencascade.com>
Mon, 10 Nov 2014 11:21:42 +0000 (14:21 +0300)
committervsr <vsr@opencascade.com>
Mon, 10 Nov 2014 12:09:13 +0000 (15:09 +0300)
40 files changed:
CMakeLists.txt
doc/salome/examples/CMakeLists.txt
doc/salome/examples/a3DmeshOnModified2Dmesh.py [new file with mode: 0644]
doc/salome/examples/prism_3d_algo.py
doc/salome/gui/SMESH/input/2d_meshing_hypo.doc
doc/salome/gui/SMESH/input/about_meshes.doc
doc/salome/gui/SMESH/input/basic_meshing_algos.doc
doc/salome/gui/SMESH/input/constructing_meshes.doc
doc/salome/gui/SMESH/input/modifying_meshes.doc
doc/salome/gui/SMESH/input/pattern_mapping.doc
doc/salome/gui/SMESH/input/reorient_faces.doc
doc/salome/gui/SMESH/input/tui_creating_meshes.doc
src/Controls/SMESH_Controls.cxx
src/SMESH/CMakeLists.txt
src/SMESH/SMESH_Mesh.cxx
src/SMESH/SMESH_MesherHelper.cxx
src/SMESH/SMESH_MesherHelper.hxx
src/SMESHGUI/SMESHGUI.cxx
src/SMESHGUI/SMESHGUI_Add0DElemsOnAllNodesDlg.cxx
src/SMESHGUI/SMESHGUI_AddMeshElementDlg.cxx
src/SMESHGUI/SMESHGUI_FilterDlg.cxx
src/SMESHGUI/SMESHGUI_GEOMGenUtils.cxx
src/SMESHGUI/SMESHGUI_GEOMGenUtils.h
src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx
src/SMESHGUI/SMESHGUI_HypothesesUtils.h
src/SMESHGUI/SMESHGUI_MakeNodeAtPointDlg.cxx
src/SMESHGUI/SMESHGUI_MeshEditPreview.cxx
src/SMESHGUI/SMESHGUI_MeshInfo.cxx
src/SMESHGUI/SMESHGUI_MeshOp.cxx
src/SMESHGUI/SMESHGUI_SelectionOp.cxx
src/SMESH_I/SMESH_2smeshpy.cxx
src/SMESH_I/SMESH_2smeshpy.hxx
src/SMESH_I/SMESH_Filter_i.cxx
src/SMESH_I/SMESH_Gen_i_1.cxx
src/StdMeshers/StdMeshers_Prism_3D.cxx
src/StdMeshers/StdMeshers_ProjectionUtils.cxx
src/StdMeshers/StdMeshers_Projection_2D.cxx
src/StdMeshers/StdMeshers_Quadrangle_2D.cxx
src/StdMeshers/StdMeshers_RadialPrism_3D.cxx
src/StdMeshers/StdMeshers_ViscousLayers.cxx

index a88f8c23a473c4e13cefb8f8d2bbec713a5608b0..0eb2d62516d56e07c957101e65d8d55e9fd11903 100755 (executable)
@@ -28,11 +28,11 @@ CMAKE_POLICY(SET CMP0003 NEW)
 STRING(TOUPPER ${PROJECT_NAME} PROJECT_NAME_UC)
 
 SET(${PROJECT_NAME_UC}_MAJOR_VERSION 7)
-SET(${PROJECT_NAME_UC}_MINOR_VERSION 4)
-SET(${PROJECT_NAME_UC}_PATCH_VERSION 1)
+SET(${PROJECT_NAME_UC}_MINOR_VERSION 5)
+SET(${PROJECT_NAME_UC}_PATCH_VERSION 0)
 SET(${PROJECT_NAME_UC}_VERSION
   ${${PROJECT_NAME_UC}_MAJOR_VERSION}.${${PROJECT_NAME_UC}_MINOR_VERSION}.${${PROJECT_NAME_UC}_PATCH_VERSION})
-SET(${PROJECT_NAME_UC}_VERSION_DEV 1)
+SET(${PROJECT_NAME_UC}_VERSION_DEV 0)
 
 # Find KERNEL
 # ===========
index 227764998bb0c1281ab364df15d4bbc745604b8b..7aa0636896d74818d7515d8e56d0f36ad144f9e8 100644 (file)
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 
+# examples that cant be used for testing because they use external mesher plug-ins
 SET(BAD_TESTS
   3dmesh.py
+  a3DmeshOnModified2Dmesh.py
   creating_meshes_ex01.py
   creating_meshes_ex03.py
   creating_meshes_ex05.py
@@ -39,14 +41,14 @@ SET(BAD_TESTS
   quality_controls_ex20.py
   quality_controls_ex21.py
   quality_controls_ex22.py
-  viewing_meshes_ex01.py 
-)
+  viewing_meshes_ex01.py
+  )
 
 SET(GOOD_TESTS
-  cartesian_algo.py 
-  creating_meshes_ex02.py 
-  creating_meshes_ex04.py 
-  creating_meshes_ex06.py 
+  cartesian_algo.py
+  creating_meshes_ex02.py
+  creating_meshes_ex04.py
+  creating_meshes_ex06.py
   creating_meshes_ex07.py 
   creating_meshes_ex08.py 
   defining_hypotheses_ex01.py 
diff --git a/doc/salome/examples/a3DmeshOnModified2Dmesh.py b/doc/salome/examples/a3DmeshOnModified2Dmesh.py
new file mode 100644 (file)
index 0000000..7fcdcac
--- /dev/null
@@ -0,0 +1,62 @@
+import salome
+salome.salome_init()
+
+from salome.geom import geomBuilder
+geompy = geomBuilder.New(salome.myStudy)
+
+# This script demonstrates generation of 3D mesh basing on a modified 2D mesh
+#
+# Purpose is to get a tetrahedral mesh in a sphere cut by a cube.
+# The requirement is to have a surface mesh on the cube comprised of
+# triangles of exactly the same size arranged in a grid pattern.
+#
+# To fulfill this requirement we mesh the box using Quadrangle (Mapping)
+# meshing algorithm, split quadrangles into triangles and then generate
+# tetrahedrons.
+
+
+# Make the geometry
+
+Box_1    = geompy.MakeBox(-100,-100,-100, 100, 100, 100)
+Sphere_1 = geompy.MakeSphereR( 300 )
+Cut_1    = geompy.MakeCut(Sphere_1, Box_1, theName="Cut_1")
+# get a spherical face
+Sph_Face = geompy.ExtractShapes( Sphere_1, geompy.ShapeType["FACE"] )[0]
+
+# get the shape Sph_Face turned into during MakeCut()
+Sph_Face = geompy.GetInPlace(Cut_1, Sph_Face, isNewImplementation=True, theName="Sphere_1")
+
+
+# 1) Define a mesh with 1D and 2D meshers
+
+import  SMESH
+from salome.smesh import smeshBuilder
+smesh = smeshBuilder.New(salome.myStudy)
+
+Mesh_1 = smesh.Mesh(Cut_1)
+
+# "global" meshers (assigned to Cut_1) that will be used for the box
+Regular_1D = Mesh_1.Segment()
+Local_Length_1 = Regular_1D.LocalLength(20)
+Quadrangle_2D = Mesh_1.Quadrangle()
+
+# a "local" mesher (assigned to a sub-mesh on Sphere_1) to mesh the sphere
+algo_2D = Mesh_1.Triangle( smeshBuilder.NETGEN_1D2D, Sph_Face )
+algo_2D.SetMaxSize( 70. )
+algo_2D.SetFineness( smeshBuilder.Moderate )
+algo_2D.SetMinSize( 7. )
+
+# 2) Compute 2D mesh
+isDone = Mesh_1.Compute()
+
+# 3) Split quadrangles into triangles
+isDone = Mesh_1.SplitQuadObject( Mesh_1, Diag13=True )
+
+# 4) Define a 3D mesher
+Mesh_1.Tetrahedron()
+
+# 5) Compute 3D mesh
+Mesh_1.Compute()
+
+if salome.sg.hasDesktop():
+  salome.sg.updateObjBrowser(1)
index df18d0fcb511a98627d2294bfc85ae2af6ae8a65..7be0a29d3ddabad9cebf570f5da15e9166d06087 100644 (file)
@@ -1,9 +1,14 @@
 # Use 3D extrusion meshing algorithm
 
-import salome, smesh, SMESH, geompy
-
+import salome
 salome.salome_init()
-smesh.SetCurrentStudy( salome.myStudy )
+
+from salome.geom import geomBuilder
+geompy = geomBuilder.New(salome.myStudy)
+
+import SMESH
+from salome.smesh import smeshBuilder
+smesh =  smeshBuilder.New(salome.myStudy)
 
 OX = geompy.MakeVectorDXDYDZ(1,0,0)
 OY = geompy.MakeVectorDXDYDZ(0,1,0)
index 0ccb902e0025d7266fde1d8fc95b8901a9ad9458..05b8d5a39eaff5d547459f907681d5b0b398834f 100644 (file)
@@ -113,10 +113,9 @@ of the enforced nodes.
     projected to the meshed face and located close enough to the
     meshed face will be used to create the enforced nodes.</li>
 </ul>
+\note <b>Enforced nodes</b> can't be created at \b Reduced transition type.
 
 Let us see how the algorithm works:
-
-
 <ul>
   <li> Initially positions of nodes are computed without taking into
   account the enforced vertex (yellow point).</li> 
index 870e5c1825cdffb4185235ec4db026777ccf522a..65201ac6422e54c9a72469a622bcd5f3f6d8dc6a 100644 (file)
@@ -7,10 +7,12 @@ a set of entities with a simple topology.
 
 It is possible to \subpage constructing_meshes_page "construct meshes" 
 on the basis of geometrical shapes produced in the GEOM module.
-It is also possible to 
-\subpage constructing_submeshes_page "construct mesh on a part of the geometrical object", 
-for example, a face, with different meshing parameters or using
-another meshing algorithm.
+Construction of \subpage constructing_submeshes_page "sub-meshes"
+allows to mesh parts of the geometrical object, for example a face,
+with different meshing parameters or using another meshing algorithm
+than other parts.
+
+3D mesh can be generated basing on a 2D closed mesh.
 
 Several created meshes can be \subpage building_compounds_page "combined into another mesh".
 
@@ -62,44 +64,4 @@ described in the following way:
   coordinates of the corresponding vertex.</li>
 </ul>
 
-<br><h2>Connections</h2>
-
-Each mesh entity bounds 0 or more mesh entities of higher
-dimension. In the same way each mesh entity is bounded by 0 or more
-mesh entities of lower dimension:
-
-<ul>
-<li>A node bounds edges, faces and volumes</li>
-<li>An edge bounds faces, and volumes</li>
-<li>A face bounds volumes</li>
-<li>A volume is bounded by faces, edges and nodes</li>
-<li>A face is bounded by edges, and nodes</li>
-<li>An edge is bounded by nodes</li>
-</ul>
-
-You can notice that there are two types of connections: \b inverse and
-\b direct connections.
-
-<br><h2>Inverse connections</h2>
-
-This relationship has a particularity that the order of bounded
-entities has not a direct meaning. Also the number of bounded entities
-is not fixed.
-
-\b Example: The edges surrounding a node. The 3rd edge has no more
-sense that the 5th one.
-
-<br><h2>Direct connections</h2>
-
-This relationship has a particularity that the order of bounding
-entities is meaningful. The number of bounding entities is fixed and
-depends on the type of the entity (hexahedron, tetrahedron,?).
-
-\b Example: An edge is composed of two nodes. A face is composed of 3
-or 4 edges depending if we are dealing with triangles or quadrangles.
-
-The connections are not only restricted to entities of one dimension
-higher or lower. For example some algorithms may be interested to
-retrieve all the faces surrounding a node.
-
 */
index ee632b282113eb56970641ada4fda99b01a9a1ec..977b505dbad674d72220d8e33e9aaf5a4363c7bb 100644 (file)
@@ -52,15 +52,15 @@ geometrical objects.
 
 There is also a number of more specific algorithms:
 <ul>
+<li>\subpage prism_3d_algo_page "for meshing prismatic shapes"</li>
 <li>\subpage projection_algos_page "for meshing by projection of another mesh"</li>
 <li>\subpage import_algos_page "for meshing by importing elements from another mesh"</li>
 <li>\subpage radial_prism_algo_page "for meshing geometrical objects with cavities"</li>
-<li>\subpage segments_around_vertex_algo_page "for defining the local size of elements around a certain node"</li>
-<li>\subpage prism_3d_algo_page "for meshing prismatic shapes"</li>
 <li>\subpage radial_quadrangle_1D2D_algo_page "for meshing special 2d faces (circles and part of circles)"</li>
 <li>\subpage use_existing_page "Use Edges to be Created Manually" and 
 \ref use_existing_page "Use Faces to be Created Manually" algorithms can be
 used to create a 1D or a 2D mesh in a python script.</li>
+<li>\subpage segments_around_vertex_algo_page "for defining the local size of elements around a certain node"</li>
 </ul>
 
 \ref constructing_meshes_page "Constructing meshes" page describes in
index 05d8c663efa8644e942dbf52e5511026a2307b6e..2a1a0c3aab8bfc97a6f5eb63e17565d687988838 100644 (file)
@@ -9,6 +9,7 @@
   <li> \ref preview_anchor "Previewing the mesh" (optional)</li>
   <li> \ref submesh_order_anchor "Changing sub-mesh priority" (optional)</li>
   <li> \ref compute_anchor "Computing the mesh"</li>
+  <li> \ref edit_anchor "Editing the mesh" (optional)</li>
 </ul>
 
 \anchor create_mesh_anchor
       List of sets of hypotheses. Tag <em>[custom]</em> is
       automatically added to the sets defined by the user.
       
-      \note \a Automatic in the names of predefined sets of
-      hypotheses means only that \ref automatic_length_anchor "Automatic Length" hypothesis 
-         is included in these sets, and not that these sets are suitable for
+      \note \a "Automatic" in the names of predefined sets of
+      hypotheses came from previous versions of SALOME where
+      \ref automatic_length_anchor "Automatic Length" hypothesis 
+      was included in these sets, and not that these sets are suitable for
       meshing any geometry.
   </li>
 </ol>
@@ -356,8 +358,29 @@ computation reporting. There are the following possibilities: always
 show the information box, show only if an error occurs or never. 
 By default, the information box is always shown after mesh computation operation.
 
-<br><br>
-
-
+<p><p>
+\anchor edit_anchor
+<h2>Editing the mesh</h2>
+
+It is possible to \ref modifying_meshes_page "edit the mesh" of
+lower dimension before generation of mesh of higher dimension.
+
+For example you can generate 2D mesh, modify it using e.g. 
+\ref pattern_mapping_page, and then generate 3D mesh basing on the
+modified 2D mesh. The workflow is following:
+- Define 1D and 2D meshing algorithms.
+- Compute the mesh. 2D mesh is generated.
+- Apply \ref pattern_mapping_page.
+- Define 3D meshing algorithms without modifying 1D and 2D algorithms
+and hypotheses.
+- Compute the mesh. 3D mesh is generated.
+
+\note Nodes and elements added \ref adding_nodes_and_elements_page
+"manually" can't be used in this workflow because the manually created
+entities are not attached to any geometry and thus (usually) can't be
+found by a mesher paving some geometry.
+
+<b>See Also</b> a sample TUI Script demonstrates the possibility of 
+\ref tui_editing_while_meshing "Intermediate edition while meshing"
 
 */
index 1bd0cc919b62f0b86a3c5ffee38822b0fa856ee8..f09ab21d47d03e7477f85efc37c810c38226a16b 100755 (executable)
@@ -51,6 +51,11 @@ or vice versa.</li>
 <li>\subpage cut_mesh_by_plane_page "Cut a tetrahedron mesh by a plane".</li>
 </ul>
 
+It is possible to \ref edit_anchor "modify the mesh" of lower
+dimension before generation of mesh of higher dimension.
+
+<p><br></p>
+
 \note It is possible to use the variables defined in the SALOME \b NoteBook
  to specify the numerical parameters used for modification of any object.
 
index ef7f8ba66a704be2910dfba199764ad1a3e4665f..969b9fc5e066a39b75acea62020432974a51864c 100644 (file)
@@ -14,7 +14,7 @@ The smp file contains 4 sections:
 
 -# The first line indicates the total number of pattern nodes (N).
 -# The next N lines describe nodes coordinates. Each line contains 2
-node coordinates for a 2D pattern or 3 node cordinates for a 3D pattern.
+node coordinates for a 2D pattern or 3 node coordinates for a 3D pattern.
 Note, that node coordinates of a 3D pattern can be defined only by relative values in range [0;1].
 -# The key-points line contains the indices of the nodes to be mapped on geometrical
 vertices (for a 2D pattern only). Index n refers to the node described 
@@ -89,7 +89,7 @@ An example of a simple 3D pattern smp file:
 
 <br><h2>Application of pattern mapping</h2>
 
-<em>To apply pattern mapping to a geometrical object:</em>
+<em>To apply pattern mapping to a geometrical object or mesh elements:</em>
 
 From the \b Modification menu choose the <b>Pattern Mapping</b> item or click 
 <em>"Pattern mapping"</em> button in the toolbar.
@@ -113,16 +113,17 @@ created manually or generated automatically from an existing mesh or submesh.</l
      boundaries of the pattern must also be equal to the number of vertices
      on internal boundaries of the face;</li>
 <li> \b Vertex to which the first key-point should be mapped;</li>
+</ul>
 Alternatively, it is possible to select <b>Refine selected mesh elements</b> 
-checkbox and apply the pattern to
+check-box and apply the pattern to <ul>
 <li> <b>Mesh Face</b> instead of a geometric Face</li>
 <li> and select \b Node instead of vertex.</li>
-
-Additionally it is possible to:
-<li> <b>Reverse the order of key-points</b> By default, the vertices of
-     a face are ordered counterclockwise.<li>
+</ul>
+Additionally it is possible to: <ul>
+<li> <b>Reverse the order of key-points</b>. By default, the vertices of
+     a face are ordered counterclockwise.</li>
 <li> Enable to <b> Create polygons near boundary</b> </li>
-<li> and <b>Create polyhedrons near boundary</b><li>  
+<li> and <b>Create polyhedrons near boundary</b></li>
 </ul>
 
 \n For a <b>3D pattern</b>
@@ -133,21 +134,27 @@ In this dialog you should specify:
 <ul>
 <li> \b Pattern, which can be loaded from .smp pattern file previously
 created manually or generated automatically from an existing mesh or submesh.</li>
-   <li> A 3D block (Solid) object;</li>
-   <li> Two vertices that specify the order of nodes in the resulting mesh.</li>
+<li> A 3D block (Solid) object.</li>
+<li> Two vertices that specify the order of nodes in the resulting
+  mesh.</li>
+</ul>
 Alternatively, it is possible to select <b>Refine selected mesh elements</b> 
 checkbox and apply the pattern to
+<ul>
 <li> One or several <b>Mesh volumes</b> instead of a geometric 3D
 object</li>
 <li> and select two /b Nodes instead of vertices.</li> 
+</ul>
 Additionally it is possible to:
+<ul>
 <li> Enable to <b> Create polygons near boundary</b> </li>
-<li> and <b>Create polyhedrons near boundary</b><li>
+<li> and <b>Create polyhedrons near boundary</b></li>
 </ul>
 
-\n Automatic Generation 
+<br>
+<h3> Automatic Generation </h3>
 
-To generate a pattern automatically from an existing mesh or submesh,
+To generate a pattern automatically from an existing mesh or sub-mesh,
 click \b New button.
 
 The following dialog box will appear:
index 66db5393753a0767da35f3f1e71d859a608e61bf..20346a9dc54510ae63e1972d6557928c5c2d8d5b 100644 (file)
@@ -4,15 +4,17 @@
 
 \n This operation allows changing the orientation of a set faces in the following ways:
 <ul>
-<li> The new orientation of a set of neighboring faces can be defined  
+<li>The new orientation of a set of neighboring faces can be defined  
   by a vector. <br> Since the direction of face normals in
   the set can be even opposite, it is necessary to specify a control
   face, the normal to which will be compared with the vector. This face can be
-  either: <ul>
-    <li> found by proximity to a given point, or </li> 
-    <li> specified explicitly. </li> 
-</ul> </li>
-<li> Alternatively, the faces can be oriented relatively to the adjacent volumes. </li>
+  either:
+  <ul>
+    <li>found by proximity to a given point, or</li> 
+    <li>specified explicitly.</li> 
+  </ul>
+</li>
+<li>Alternatively, the faces can be oriented relatively to the adjacent volumes.</li>
 </ul>
 
 The orientation of a face is changed by reverting the order of its nodes.
@@ -26,19 +28,17 @@ The orientation of a face is changed by reverting the order of its nodes.
 \image html reorient_faces_face.png
 <em>"Reorient faces" button</em>
 </center>
+</li>
 
-The following dialog box will appear:
+<li>In the "Reorient faces" dialog box
 
-<center>
-\image html reorient_2d_point.png "The orientation of adjacent faces is chosen according to a vector. The control face is found by point."
-<br>
-
-<li>In this dialog
 <ul>
 <li>Select the \b Object (mesh, sub-mesh or group)
   containing faces to reorient, in the Object Browser or in the 3D
   Viewer.</li>
-<li>To reorient according to vector: <ul>
+
+<li>To reorient according to vector:
+    <ul>
     <li>Specify the coordinates of the \b Point by which the control face
       will be found. You can easy specify the \b
       Point by either picking a node in the 3D Viewer or selecting a vertex
@@ -48,28 +48,41 @@ The following dialog box will appear:
       control face. If you pick a node in the 3D Viewer then the \b Direction
       vector will go from the coordinate system origin to the selected node.
       If you pick two nodes (holding Shift button) then the \b Direction vector
-      will go from the first to the second node.</li> </ul> </li>
+      will go from the first to the second node.</li>
+    </ul>
 
-
-
-\image html reorient_2d_face.png "The orientation of adjacent faces is chosen according to a vector. The control face is explicitly given."
 <br>
+<center>
+\image html reorient_2d_point.png "The orientation of adjacent faces is chosen according to a vector. The control face is found by point."
+</center>
 
-<li>In the second mode it is possible to directly input the \b Face ID in the corresponding field. </li>
+</li>
 
-\image html reorient_2d_volume.png "The orientation of faces is chosen with relation to adjacent volumes."
+<li>In the second mode it is possible to directly input the \b Face ID in the corresponding field.
+
+<center>
+\image html reorient_2d_face.png "The orientation of adjacent faces is chosen according to a vector. The control face is explicitly given."
 </center>
 
+</li>
 
-<li>In the third mode, the faces can be reoriented according to volumes: <ul>
+<li>In the third mode, the faces can be reoriented according to volumes:
+    <ul>
     <li>Select an object (mesh, sub-mesh or group) containing
       reference \b Volumes, in the Object Browser or in the 3D
       Viewer.</li>
     <li>Specify whether face normals should point outside or inside
       the reference volumes using <b>Face normal outside volume</b>
-      check-box.</li></ul> </li>
-</ul>
+      check-box.</li>
+    </ul>
+
+<br>
+<center>
+\image html reorient_2d_volume.png "The orientation of faces is chosen with relation to adjacent volumes."
+</center>
+
 </li>
+</ul>
 
 <li>Click the \b Apply or <b>Apply and Close</b> button to confirm the operation.</li>
 </ol>
index f1b12e4c41882ede90fe4b6e91c70341ba05fd58..984616457c7ff2b93f5bde86d206e9f2f0962671 100644 (file)
 <h2>Change priority of submeshes in Mesh</h2>
 \tui_script{creating_meshes_ex03.py}
 
+<br>
+\anchor tui_editing_while_meshing
+<h2>Intermediate edition while meshing</h2>
+\tui_script{a3DmeshOnModified2Dmesh.py}
+
 <br>
 \anchor tui_editing_mesh
 <h2>Editing a mesh</h2>
index dcb5d7b1a36351088d8139e80118e655925a5c71..6311da713a53cdff7413d67c76f886b75066d35a 100644 (file)
@@ -4251,11 +4251,11 @@ void BelongToGeom::init()
     myIsSubshape = IsSubShape(aMap, myShape);
   }
 
-  if (!myIsSubshape)
+  //if (!myIsSubshape) // to be always ready to check an element not bound to geometry
   {
     myElementsOnShapePtr.reset(new ElementsOnShape());
     myElementsOnShapePtr->SetTolerance(myTolerance);
-    myElementsOnShapePtr->SetAllNodes(true); // belong, while false means "lays on"
+    myElementsOnShapePtr->SetAllNodes(true); // "belong", while false means "lays on"
     myElementsOnShapePtr->SetMesh(myMeshDS);
     myElementsOnShapePtr->SetShape(myShape, myType);
   }
@@ -4296,36 +4296,43 @@ bool BelongToGeom::IsSatisfy (long theId)
   {
     if( const SMDS_MeshNode* aNode = myMeshDS->FindNode( theId ) )
     {
+      if ( aNode->getshapeId() < 1 )
+        return myElementsOnShapePtr->IsSatisfy(theId);
+
       const SMDS_PositionPtr& aPosition = aNode->GetPosition();
       SMDS_TypeOfPosition aTypeOfPosition = aPosition->GetTypeOfPosition();
       switch( aTypeOfPosition )
       {
-      case SMDS_TOP_VERTEX : return IsContains( myMeshDS,myShape,aNode,TopAbs_VERTEX );
-      case SMDS_TOP_EDGE   : return IsContains( myMeshDS,myShape,aNode,TopAbs_EDGE );
-      case SMDS_TOP_FACE   : return IsContains( myMeshDS,myShape,aNode,TopAbs_FACE );
-      case SMDS_TOP_3DSPACE: return IsContains( myMeshDS,myShape,aNode,TopAbs_SHELL );
+      case SMDS_TOP_VERTEX : return ( IsContains( myMeshDS,myShape,aNode,TopAbs_VERTEX ));
+      case SMDS_TOP_EDGE   : return ( IsContains( myMeshDS,myShape,aNode,TopAbs_EDGE ));
+      case SMDS_TOP_FACE   : return ( IsContains( myMeshDS,myShape,aNode,TopAbs_FACE ));
+      case SMDS_TOP_3DSPACE: return ( IsContains( myMeshDS,myShape,aNode,TopAbs_SOLID ) ||
+                                      IsContains( myMeshDS,myShape,aNode,TopAbs_SHELL ));
       }
     }
   }
   else
   {
-    if( const SMDS_MeshElement* anElem = myMeshDS->FindElement( theId ) )
+    if ( const SMDS_MeshElement* anElem = myMeshDS->FindElement( theId ))
     {
+      if ( anElem->getshapeId() < 1 )
+        return myElementsOnShapePtr->IsSatisfy(theId);
+
       if( myType == SMDSAbs_All )
       {
-        return IsContains( myMeshDS,myShape,anElem,TopAbs_EDGE ) ||
-               IsContains( myMeshDS,myShape,anElem,TopAbs_FACE ) ||
-               IsContains( myMeshDS,myShape,anElem,TopAbs_SHELL )||
-               IsContains( myMeshDS,myShape,anElem,TopAbs_SOLID );
+        return IsContains( myMeshDS,myShape,anElem,TopAbs_EDGE ) ||
+                 IsContains( myMeshDS,myShape,anElem,TopAbs_FACE ) ||
+                 IsContains( myMeshDS,myShape,anElem,TopAbs_SOLID )||
+                 IsContains( myMeshDS,myShape,anElem,TopAbs_SHELL ));
       }
       else if( myType == anElem->GetType() )
       {
         switch( myType )
         {
-        case SMDSAbs_Edge  : return IsContains( myMeshDS,myShape,anElem,TopAbs_EDGE );
-        case SMDSAbs_Face  : return IsContains( myMeshDS,myShape,anElem,TopAbs_FACE );
-        case SMDSAbs_Volume: return IsContains( myMeshDS,myShape,anElem,TopAbs_SHELL )||
-                                    IsContains( myMeshDS,myShape,anElem,TopAbs_SOLID );
+        case SMDSAbs_Edge  : return ( IsContains( myMeshDS,myShape,anElem,TopAbs_EDGE ));
+        case SMDSAbs_Face  : return ( IsContains( myMeshDS,myShape,anElem,TopAbs_FACE ));
+        case SMDSAbs_Volume: return ( IsContains( myMeshDS,myShape,anElem,TopAbs_SOLID )||
+                                      IsContains( myMeshDS,myShape,anElem,TopAbs_SHELL ));
         }
       }
     }
index 17e8d7b9cac767d0c5656190cfaa3c5fa6e945ae..a23c8c468a3d071107cb18d412fc9ed8ee3e8c65 100644 (file)
@@ -58,6 +58,7 @@ SET(_link_LIBRARIES
   ${CAS_TKG2d}
   ${CAS_TKCDF}
   ${GEOM_NMTTools}
+  ${GEOM_GEOMUtils}
   ${Boost_LIBRARIES}
   SMESHDS
   SMESHControls
index b0dcee9ac22247bc2be4a404f940989f404466ad..72d7ef193b7e9c3950ba27c43e99c3a6db75bfdb 100644 (file)
 #include "DriverCGNS_Write.hxx"
 #endif
 
+#include <GEOMUtils.hxx>
+
 #undef _Precision_HeaderFile
-#include <BRepBndLib.hxx>
+//#include <BRepBndLib.hxx>
 #include <BRepPrimAPI_MakeBox.hxx>
 #include <Bnd_Box.hxx>
 #include <TColStd_MapOfInteger.hxx>
@@ -327,8 +329,9 @@ double SMESH_Mesh::GetShapeDiagonalSize(const TopoDS_Shape & aShape)
 {
   if ( !aShape.IsNull() ) {
     Bnd_Box Box;
-    BRepBndLib::Add(aShape, Box);
-    return sqrt( Box.SquareExtent() );
+    GEOMUtils::PreciseBoundingBox(aShape, Box);
+    if ( !Box.IsVoid() )
+      return sqrt( Box.SquareExtent() );
   }
   return 0;
 }
index 6e5b08498b8addc06a1012b8bac388092f0612c3..0d4173c28db7da996bdd311c049c1b25ca2cfdc8 100644 (file)
@@ -2804,6 +2804,28 @@ bool SMESH_MesherHelper::IsSubShape( const TopoDS_Shape& shape, SMESH_Mesh* aMes
     (shape.ShapeType() == TopAbs_COMPOUND && aMesh->GetMeshDS()->IsGroupOfSubShapes( shape ));
 }
 
+//=======================================================================
+//function : IsBlock
+//purpose  : 
+//=======================================================================
+
+bool SMESH_MesherHelper::IsBlock( const TopoDS_Shape& shape )
+{
+  if ( shape.IsNull() )
+    return false;
+
+  TopoDS_Shell shell;
+  TopExp_Explorer exp( shape, TopAbs_SHELL );
+  if ( !exp.More() ) return false;
+  shell = TopoDS::Shell( exp.Current() );
+  if ( exp.Next(), exp.More() ) return false;
+
+  TopoDS_Vertex v;
+  TopTools_IndexedMapOfOrientedShape map;
+  return SMESH_Block::FindBlockShapes( shell, v, v, map );
+}
+
+
 //================================================================================
 /*!
  * \brief Return maximal tolerance of shape
index 430e6f374c71ee4a384073b07500d1283e6f0bbc..ae6767d309af00cb2ae5e8752a2164660f63b944 100644 (file)
@@ -221,6 +221,8 @@ class SMESH_EXPORT SMESH_MesherHelper
 
   static bool IsSubShape( const TopoDS_Shape& shape, SMESH_Mesh* aMesh );
 
+  static bool IsBlock( const TopoDS_Shape& shape );
+
   static double MaxTolerance( const TopoDS_Shape& shape );
 
   static double GetAngle( const TopoDS_Edge & E1, const TopoDS_Edge & E2,
index 0f8f8d31ebb3f26771f0cb160d36b5d2f1401401..61ff14fb5ed3a71a07d55fd5985bfe99860e2851 100644 (file)
@@ -1756,6 +1756,19 @@ namespace
     return RefType;
   }
 
+  uint randomize( uint size )
+  {
+    static bool initialized = false;
+    if ( !initialized ) {
+      qsrand( QDateTime::currentDateTime().toTime_t() );
+      initialized = true;
+    }
+    uint v = qrand();
+    v = uint( (double)( v ) / RAND_MAX * size );
+    v = qMax( uint(0), qMin ( v, size-1 ) );
+    return v;
+  }
+  
 } //namespace
 
 void SMESHGUI::OnEditDelete()
@@ -6939,7 +6952,7 @@ SALOMEDS::Color SMESHGUI::getPredefinedUniqueColor()
       }
     }
   }
-  static int currentColor = 0;
+  static int currentColor = randomize( colors.size() );
 
   SALOMEDS::Color color;
   color.R = (double)colors[currentColor].red()   / 255.0;
index 9cbad861c453b08361e8a96bc38836bd8742ff6c..b053c60998ec2d5b549fb32633f3b75cb5b23029 100644 (file)
@@ -463,9 +463,7 @@ void SMESHGUI_Add0DElemsOnAllNodesOp::onSelTypeChange(int selType)
 
 //================================================================================
 /*!
- * \brief Install 
- * 
- * 
+ * \brief Install filters
  */
 //================================================================================
 
index 79588047cb0abfb36b46746cfd9387503fc559e0..cbc584da5a2d85f976b4b9ad0188877b800dee6c 100644 (file)
@@ -586,6 +586,7 @@ void SMESHGUI_AddMeshElementDlg::ClickOnApply()
     SMESH::long_array_var anIdList = new SMESH::long_array;
     anIdList->length( 1 );
     anIdList[0] = -1;
+    const bool onlyNodesInMesh = ( myMesh->NbElements() == 0 );
 
     switch (myElementType) {
     case SMDSAbs_0DElement:
@@ -645,8 +646,10 @@ void SMESHGUI_AddMeshElementDlg::ClickOnApply()
     mySelectionMgr->setSelectedObjects( aList, false );
 
     mySimulation->SetVisibility(false);
+    if ( onlyNodesInMesh )
+      myActor->SetRepresentation( SMESH_Actor::eEdge ); // wireframe
     SMESH::UpdateView();
-    
+
     buttonOk->setEnabled(false);
     buttonApply->setEnabled(false);
 
index 4dfa5268b9de3e361e5180713fb853a541af1737..8db0a78141b2dac70528ed0d9926c16e7c5537e5 100755 (executable)
@@ -1954,7 +1954,10 @@ void SMESHGUI_FilterTable::onCriterionChanged (const int row, const int col, con
       break;
     }
     case 3: {
+      int oldValue = aCompareItem->value();
       aCompareItem->setItems(getCompare());
+      if ( oldValue >= 0 )
+        aCompareItem->setValue( oldValue );
       break;
     }
     }
index 88b1819445cb5ace027fd75faba4cb4bead9bcc2..5453a6a1b758608d71a50e4b0eca7221532432ff 100644 (file)
@@ -82,20 +82,25 @@ namespace SMESH
     return GEOM::GEOM_Object::_nil();
   }
 
-  GEOM::GEOM_Object_ptr GetGeom (_PTR(SObject) theSO)
+  GEOM::GEOM_Object_var GetGeom (_PTR(SObject) theSO)
   {
+    GEOM::GEOM_Object_var aMeshShape;
     if (!theSO)
-      return GEOM::GEOM_Object::_nil();
+      return aMeshShape;
+
+    CORBA::Object_var obj = _CAST( SObject,theSO )->GetObject();
+    aMeshShape = GEOM::GEOM_Object::_narrow( obj );
+    if ( !aMeshShape->_is_nil() )
+      return aMeshShape;
 
     _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
     if (!aStudy)
-      return GEOM::GEOM_Object::_nil();
+      return aMeshShape;
 
     _PTR(ChildIterator) anIter (aStudy->NewChildIterator(theSO));
     for ( ; anIter->More(); anIter->Next()) {
       _PTR(SObject) aSObject = anIter->Value();
       _PTR(SObject) aRefSOClient;
-      GEOM::GEOM_Object_var aMeshShape;
 
       if (aSObject->ReferencedObject(aRefSOClient)) {
         SALOMEDS_SObject* aRefSO = _CAST(SObject,aRefSOClient);
@@ -104,11 +109,10 @@ namespace SMESH
         SALOMEDS_SObject* aSO = _CAST(SObject,aSObject);
         aMeshShape = GEOM::GEOM_Object::_narrow(aSO->GetObject());
       }
-
-      if (!aMeshShape->_is_nil())
-        return aMeshShape._retn();
+      if ( !aMeshShape->_is_nil() )
+        return aMeshShape;
     }
-    return GEOM::GEOM_Object::_nil();
+    return aMeshShape;
   }
 
   SMESHGUI_EXPORT char* GetGeomName( _PTR(SObject) smeshSO )
index f9cdeafd40acc430f0a58f0b3cc8d5d48ee8492c..0aa10bd7a9bb493a9a431f867eefffab9dca2190 100644 (file)
@@ -47,7 +47,7 @@ namespace SMESH
 
   SMESHGUI_EXPORT GEOM::GEOM_Object_var GetShapeOnMeshOrSubMesh( _PTR(SObject), bool* isMesh=0 );
 
-  SMESHGUI_EXPORT GEOM::GEOM_Object_ptr GetGeom( _PTR(SObject) );
+  SMESHGUI_EXPORT GEOM::GEOM_Object_var GetGeom( _PTR(SObject) );
 
   SMESHGUI_EXPORT char* GetGeomName( _PTR(SObject) smeshSO );
 
index dc499bd7381fe9e7db3feb31fc0cad754090bebe..fa29da180e0efe8ed73680d34caa0e020d9e08f2 100644 (file)
@@ -511,10 +511,14 @@ namespace SMESH
 
     return SMESH::SMESH_Hypothesis::_nil();
   }
+
   bool IsApplicable(const QString&        aHypType,
                     GEOM::GEOM_Object_ptr theGeomObject,
                     const bool            toCheckAll)
   {
+    if ( getenv("NO_LIMIT_ALGO_BY_SHAPE")) // allow a workaround for a case if
+      return true;                         // IsApplicable() returns false due to a bug
+
     HypothesisData* aHypData = GetHypothesisData(aHypType);
     QString aServLib = aHypData->ServerLibName;
     return SMESHGUI::GetSMESHGen()->IsApplicable( aHypType.toLatin1().data(),
index 4e4f4a86857d2e40bf4e71fe95c5a900b60bb616..8768e07112e19d35bd31c137facdb367aef08e3f 100644 (file)
@@ -120,8 +120,7 @@ namespace SMESH
 
   SMESHGUI_EXPORT
   // name of proprty saving plug-in of a hypothesis
-  static const char* Plugin_Name() { return "PLUGIN_NAME"; }
-
+  inline const char* Plugin_Name() { return "PLUGIN_NAME"; }
 }
 
 #endif // SMESHGUI_HYPOTHESESUTILS_H
index 970500e69d7f60d60c8abd5e20da97d695ab7b48..2754b34a92436c064a1a15b786e5bdc3d0ac919b 100644 (file)
@@ -716,17 +716,17 @@ void SMESHGUI_MakeNodeAtPointOp::redisplayPreview()
                 myDlg->myDestinationZ->SetValue(z);
               }
               if ( myDestCoordChanged ) {
-                dx = myDlg->myDestinationX->GetValue() - myDlg->myCurrentX->GetValue();
-                dy = myDlg->myDestinationY->GetValue() - myDlg->myCurrentY->GetValue();
-                dz = myDlg->myDestinationZ->GetValue() - myDlg->myCurrentZ->GetValue();
+                dx = myDlg->myDestinationX->GetValue() - x;
+                dy = myDlg->myDestinationY->GetValue() - y;
+                dz = myDlg->myDestinationZ->GetValue() - z;
                 myDlg->myDestDX->SetValue(dx);
                 myDlg->myDestDY->SetValue(dy);
                 myDlg->myDestDZ->SetValue(dz);
               }
               else {
-                dx = myDlg->myDestDX->GetValue() + myDlg->myCurrentX->GetValue();;
-                dy = myDlg->myDestDY->GetValue() + myDlg->myCurrentY->GetValue();;
-                dz = myDlg->myDestDZ->GetValue() + myDlg->myCurrentZ->GetValue();;
+                dx = myDlg->myDestDX->GetValue() + x;
+                dy = myDlg->myDestDY->GetValue() + y;
+                dz = myDlg->myDestDZ->GetValue() + z;
                 myDlg->myDestinationX->SetValue(dx);
                 myDlg->myDestinationY->SetValue(dy);
                 myDlg->myDestinationZ->SetValue(dz);
index ef9ac22ad31e41cc782d610860acdbb2ec97c600..7f8b060c8dc934368925c38cac90ddda89c4424a 100644 (file)
@@ -126,8 +126,9 @@ vtkIdType getCellType( const SMDSAbs_ElementType theType,
 {
   switch( theType ) 
   {
+  case SMDSAbs_Ball:              return VTK_VERTEX;
   case SMDSAbs_Node:              return VTK_VERTEX;
-  case SMDSAbs_Edge: 
+  case SMDSAbs_Edge:
     if( theNbNodes == 2 )         return VTK_LINE;
     else if ( theNbNodes == 3 )   return VTK_QUADRATIC_EDGE;
     else return VTK_EMPTY_CELL;
index 2dca23bbacc452bd8c4466bf80eecfe6629d2b91..e91afa388e3d91e894bc3caf141d2a711369106e 100644 (file)
@@ -506,8 +506,9 @@ void SMESHGUI_MeshInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
     long nb2DLinear      = info[SMDSEntity_Triangle]        + info[SMDSEntity_Quadrangle] + info[SMDSEntity_Polygon];
     long nb2DQuadratic   = info[SMDSEntity_Quad_Triangle]   + info[SMDSEntity_Quad_Quadrangle];
     long nb2DBiQuadratic = info[SMDSEntity_BiQuad_Triangle] + info[SMDSEntity_BiQuad_Quadrangle];
+    long nb2DTotal       = nb2DLinear + nb2DQuadratic + nb2DBiQuadratic;
 
-    myWidgets[i2D][iTotal]                  ->setProperty( "text", QString::number( nb2DLinear + nb2DQuadratic ));
+    myWidgets[i2D][iTotal]                  ->setProperty( "text", QString::number( nb2DTotal ));
     myWidgets[i2D][iLinear]                 ->setProperty( "text", QString::number( nb2DLinear ) );
     myWidgets[i2D][iQuadratic]              ->setProperty( "text", QString::number( nb2DQuadratic ) );
     myWidgets[i2D][iBiQuadratic]            ->setProperty( "text", QString::number( nb2DBiQuadratic ) );
@@ -524,10 +525,11 @@ void SMESHGUI_MeshInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
     long nbHexahedrons   = info[SMDSEntity_Hexa]    + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_TriQuad_Hexa];
     long nbPyramids      = info[SMDSEntity_Pyramid] + info[SMDSEntity_Quad_Pyramid];
     long nbPrisms        = info[SMDSEntity_Penta]   + info[SMDSEntity_Quad_Penta];
-    long nb3DLinear      = info[SMDSEntity_Tetra]      + info[SMDSEntity_Hexa] + info[SMDSEntity_Pyramid] + info[SMDSEntity_Penta] + info[SMDSEntity_Polyhedra] + info[SMDSEntity_Hexagonal_Prism];
+    long nb3DLinear      = info[SMDSEntity_Tetra]   + info[SMDSEntity_Hexa] + info[SMDSEntity_Pyramid] + info[SMDSEntity_Penta] + info[SMDSEntity_Polyhedra] + info[SMDSEntity_Hexagonal_Prism];
     long nb3DQuadratic   = info[SMDSEntity_Quad_Tetra] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_Quad_Pyramid] + info[SMDSEntity_Quad_Penta];
     long nb3DBiQuadratic = info[SMDSEntity_TriQuad_Hexa];
-    myWidgets[i3D][iTotal]                  ->setProperty( "text", QString::number( nb3DLinear + nb3DQuadratic ) );
+    long nb3DTotal       = nb3DLinear + nb3DQuadratic + nb3DBiQuadratic;
+    myWidgets[i3D][iTotal]                  ->setProperty( "text", QString::number( nb3DTotal ) );
     myWidgets[i3D][iLinear]                 ->setProperty( "text", QString::number( nb3DLinear ) );
     myWidgets[i3D][iQuadratic]              ->setProperty( "text", QString::number( nb3DQuadratic ) );
     myWidgets[i3D][iBiQuadratic]            ->setProperty( "text", QString::number( nb3DBiQuadratic ) );
@@ -546,7 +548,7 @@ void SMESHGUI_MeshInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
     myWidgets[i3DPrisms][iQuadratic]        ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Penta] ) );
     myWidgets[i3DHexaPrisms][iTotal]        ->setProperty( "text", QString::number( info[SMDSEntity_Hexagonal_Prism] ) );
     myWidgets[i3DPolyhedrons][iTotal]       ->setProperty( "text", QString::number( info[SMDSEntity_Polyhedra] ) );
-    long nbElemTotal       = info[SMDSEntity_0D] + info[SMDSEntity_Ball] + nbEdges + nb2DLinear + nb2DQuadratic + nb2DBiQuadratic + nb3DLinear + nb3DQuadratic + nb3DBiQuadratic;
+    long nbElemTotal       = info[SMDSEntity_0D] + info[SMDSEntity_Ball] + nbEdges + nb2DTotal + nb3DTotal;
     long nbElemLinerial    = info[SMDSEntity_Edge] + nb2DLinear + nb3DLinear;
     long nbElemQuadratic   = info[SMDSEntity_Quad_Edge] + nb2DQuadratic + nb3DQuadratic;
     long nbElemBiQuadratic = nb2DBiQuadratic + nb3DBiQuadratic;
index 151328f9bc524b40fbc381f5287ba8a3076ae156..5f7f27ace455a3b5c2c4893fa5b58bab326576bb 100644 (file)
@@ -247,8 +247,9 @@ void SMESHGUI_MeshOp::startOperation()
     myDlg->activateObject( myIsMesh ? SMESHGUI_MeshDlg::Geom : SMESHGUI_MeshDlg::Mesh );
   }
   else
+  {
     myDlg->activateObject( SMESHGUI_MeshDlg::Obj );
-
+  }
   myDlg->setCurrentTab( SMESH::DIM_3D );
 
   QStringList TypeMeshList;
@@ -2614,11 +2615,11 @@ void SMESHGUI_MeshOp::setFilteredAlgoData( const int theTabIndex, const int theI
 
   bool toCheckIsApplicableToAll = !myIsMesh;
   GEOM::GEOM_Object_var aGeomVar;
-  QString anEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom );
+  QString anEntry =
+    myDlg->selectedObject( myToCreate ? SMESHGUI_MeshDlg::Geom : SMESHGUI_MeshDlg::Obj );
   if ( _PTR(SObject) so = studyDS()->FindObjectID( anEntry.toLatin1().data() ))
   {
-    CORBA::Object_var obj = _CAST( SObject,so )->GetObject();
-    aGeomVar = GEOM::GEOM_Object::_narrow( obj );
+    aGeomVar = SMESH::GetGeom( so );
     if ( !aGeomVar->_is_nil() && toCheckIsApplicableToAll )
       toCheckIsApplicableToAll = ( aGeomVar->GetType() == GEOM_GROUP );
   }
index 999951ba30e4408a69633f151887dfde9857097f..daf2bf493ff5e4a499d2e05130a58e42b61b6543 100644 (file)
@@ -427,7 +427,7 @@ void SMESHGUI_SelectionOp::selected( QStringList& names,
       {
         _PTR(SObject) obj = _study->studyDS()->FindObjectID( anIt.Value()->getEntry() );
         if( obj )
-          names.append( obj->GetName().c_str() );
+          names.append( QString( obj->GetName().c_str() ).trimmed() );
       }
     }
   }
index 564632744b8c4f7c98413b5235e91c2183c21ca2..911375f68ea1e59894eb2f13e3fe41268377d9a2 100644 (file)
@@ -1793,10 +1793,29 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand )
       list< Handle(_pyHypothesis) >::iterator hyp;
       if ( !myLastComputeCmd.IsNull() )
       {
-        for ( hyp = myHypos.begin(); hyp != myHypos.end(); ++hyp )
-          (*hyp)->ComputeDiscarded( myLastComputeCmd );
+        // check if the previously computed mesh has been edited,
+        // if so then we do not clear the previous Compute()
+        bool toClear = true;
+        if ( myLastComputeCmd->GetMethod() == "Compute" )
+        {
+          list< Handle(_pyMeshEditor)>::iterator e = myEditors.begin();
+          for ( ; e != myEditors.end() && toClear; ++e )
+          {
+            list< Handle(_pyCommand)>& cmds = (*e)->GetProcessedCmds();
+            list< Handle(_pyCommand) >::reverse_iterator cmd = cmds.rbegin();
+            if ( cmd != cmds.rend() &&
+                 (*cmd)->GetOrderNb() > myLastComputeCmd->GetOrderNb() )
+              toClear = false;
+          }
+        }
+        if ( toClear )
+        {
+          // clear hyp commands called before myLastComputeCmd
+          for ( hyp = myHypos.begin(); hyp != myHypos.end(); ++hyp )
+            (*hyp)->ComputeDiscarded( myLastComputeCmd );
 
-        myLastComputeCmd->Clear();
+          myLastComputeCmd->Clear();
+        }
       }
       myLastComputeCmd = theCommand;
 
@@ -1961,7 +1980,7 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand )
       //
       // remove "PartTo" from the method
       TCollection_AsciiString newMethod = method;
-      newMethod.Remove( 7, 6 );
+      newMethod.Remove( /*where=*/7, /*howmany=*/6 );
       theCommand->SetMethod( newMethod );
       // make the 1st arg be the last one (or last but three for ExportMED())
       _pyID partID = theCommand->GetArg( 1 );
index 4e6531ddee31c3ed6e9785afc58f6e2f9a19853d..04352f24ca3b8c8ff8cb1cb420f7da9476f853f8 100644 (file)
@@ -117,17 +117,17 @@ public:
   _pyCommand( const _AString& theString, int theNb=-1 )
     : myString( theString ), myOrderNb( theNb ) {};
   _AString & GetString() { return myString; }
-  int GetOrderNb() const { return myOrderNb; }
+  int  GetOrderNb() const { return myOrderNb; }
   void SetOrderNb( int theNb ) { myOrderNb = theNb; }
   typedef void* TAddr;
   TAddr GetAddress() const { return (void*) this; }
-  int Length() const { return myString.Length(); }
+  int  Length() const { return myString.Length(); }
   void Clear() { myString.Clear(); myBegPos.Clear(); myArgs.Clear(); }
   bool IsEmpty() const { return myString.IsEmpty(); }
   _AString GetIndentation();
   const _AString & GetResultValue();
   int GetNbResultValues();
-  const _AString& GetResultValue(int res);
+  const _AString & GetResultValue(int res);
   const _AString & GetObject();
   const _AString & GetMethod();
   const _AString & GetArg( int index );
@@ -183,11 +183,11 @@ public:
   const _pyID& GetID() { return myID.IsEmpty() ? myCreationCmd->GetResultValue() : myID; }
   static _pyID FatherID(const _pyID & childID);
   const Handle(_pyCommand)& GetCreationCmd() { return myCreationCmd; }
-  int GetNbCalls() const { return myProcessedCmds.size(); }
+  int  GetNbCalls() const { return myProcessedCmds.size(); }
   bool IsInStudy() const { return myIsPublished; }
   virtual void SetRemovedFromStudy(const bool isRemoved) { myIsPublished = !isRemoved; }
   void SetCreationCmd( Handle(_pyCommand) cmd ) { myCreationCmd = cmd; }
-  int GetCommandNb() { return myCreationCmd->GetOrderNb(); }
+  int  GetCommandNb() { return myCreationCmd->GetOrderNb(); }
   void AddProcessedCmd( const Handle(_pyCommand) & cmd )
   { if (myProcessedCmds.empty() || myProcessedCmds.back()!=cmd) myProcessedCmds.push_back( cmd );}
   std::list< Handle(_pyCommand) >& GetProcessedCmds() { return myProcessedCmds; }
index d0bb58cd26753f67b48d829fcd9bc06ddeccfea3..3d7977cb6969fd9d92e157d5836622b427d78717 100644 (file)
@@ -1550,8 +1550,8 @@ void ConnectedElements_i::SetThreshold ( const char*
       if ( sobj->_is_nil() )
         THROW_SALOME_CORBA_EXCEPTION
           ( "ConnectedElements_i::SetThreshold(): invalid vertex study entry", SALOME::BAD_PARAM );
-      CORBA::Object_var         obj = sobj->GetObject();
-      GEOM::GEOM_Object_wrap vertex = GEOM::GEOM_Object::_narrow( obj );
+      CORBA::Object_var        obj = sobj->GetObject();
+      GEOM::GEOM_Object_var vertex = GEOM::GEOM_Object::_narrow( obj );
       if ( vertex->_is_nil() )
         THROW_SALOME_CORBA_EXCEPTION
           ( "ConnectedElements_i::SetThreshold(): no GEOM_Object in SObject", SALOME::BAD_PARAM );
index 6890bcf08e1f9867328a4ba193256c9305b2a519..b59479fce561d0c5a843b181968fc5604a4b7b76 100644 (file)
@@ -43,6 +43,8 @@
 #include <TCollection_AsciiString.hxx>
 #include <TopoDS_Solid.hxx>
 
+#include <cctype>
+
 #ifdef _DEBUG_
 static int MYDEBUG = 0;
 //static int VARIABLE_DEBUG = 0;
@@ -341,9 +343,15 @@ void SMESH_Gen_i::SetName(SALOMEDS::SObject_ptr theSObject,
     SALOMEDS::GenericAttribute_wrap   anAttr =
       aStudyBuilder->FindOrCreateAttribute( theSObject, "AttributeName" );
     SALOMEDS::AttributeName_wrap aNameAttr = anAttr;
-    if ( theName && strlen( theName ) != 0 )
-      aNameAttr->SetValue( theName );
-    else {
+    if ( theName && theName[0] ) {
+      std::string name( theName ); // trim trailing white spaces
+      for ( size_t i = name.size()-1; i > 0; --i )
+        if ( isspace( name[i] )) name[i] = '\0';
+        else                     break;
+      aNameAttr->SetValue( name.c_str() );
+    }
+    else
+    {
       CORBA::String_var curName = aNameAttr->Value();
       if ( strlen( curName.in() ) == 0 ) {
         SMESH_Comment aName(theDefaultName);
@@ -355,7 +363,7 @@ void SMESH_Gen_i::SetName(SALOMEDS::SObject_ptr theSObject,
 
 //=======================================================================
 //function : SetPixMap
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 void SMESH_Gen_i::SetPixMap(SALOMEDS::SObject_ptr theSObject,
index fbc5704bd593eb2e66cc9112afab729a84c327da..62f538d84d72e927508e3add571619d4ba4d557f 100644 (file)
@@ -687,6 +687,7 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
 
   TopTools_MapOfShape meshedSolids;
   list< Prism_3D::TPrismTopo > meshedPrism;
+  list< TopoDS_Face > suspectSourceFaces;
   TopTools_ListIteratorOfListOfShape solidIt;
 
   while ( meshedSolids.Extent() < nbSolids )
@@ -717,6 +718,10 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
           {
             meshedFaces.push_front( prism.myTop );
           }
+          else
+          {
+            suspectSourceFaces.push_back( prism.myTop );
+          }
           meshedPrism.push_back( prism );
         }
       }
@@ -746,6 +751,10 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
               solidList.Remove( solidIt );
               continue; // already computed prism
             }
+            if ( myHelper->IsBlock( solid )) {
+              solidIt.Next();
+              continue; // too trivial
+            }
             // find a source FACE of the SOLID: it's a FACE sharing a bottom EDGE with wFace
             const TopoDS_Edge& wEdge = (*wQuad)->side[ QUAD_TOP_SIDE ].grid->Edge(0);
             PShapeIteratorPtr faceIt = myHelper->GetAncestors( wEdge, *myHelper->GetMesh(),
@@ -760,6 +769,7 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
                    myHelper->IsSubShape( candidateF, solid ) &&
                    !myHelper->GetMesh()->GetSubMesh( candidateF )->IsMeshComputed() &&
                    initPrism( prism, solid ) &&
+                   !myHelper->GetMesh()->GetSubMesh( prism.myTop )->IsMeshComputed() &&
                    project2dMesh( prismIt->myBottom, candidateF))
               {
                 mySetErrorToSM = true;
@@ -789,31 +799,49 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
         break; // to compute prisms with avident sources
     }
 
+    if ( meshedFaces.empty() )
+    {
+      meshedFaces.splice( meshedFaces.end(), suspectSourceFaces );
+    }
+
     // find FACEs with local 1D hyps, which has to be computed by now,
     // or at least any computed FACEs
-    for ( int iF = 1; ( meshedFaces.empty() && iF < faceToSolids.Extent() ); ++iF )
+    if ( meshedFaces.empty() )
     {
-      const TopoDS_Face&               face = TopoDS::Face( faceToSolids.FindKey( iF ));
-      const TopTools_ListOfShape& solidList = faceToSolids.FindFromKey( face );
-      if ( solidList.IsEmpty() ) continue;
-      SMESH_subMesh*                 faceSM = theMesh.GetSubMesh( face );
-      if ( !faceSM->IsEmpty() )
+      int prevNbFaces = 0;
+      for ( int iF = 1; iF <= faceToSolids.Extent(); ++iF )
       {
-        meshedFaces.push_back( face ); // lower priority
-      }
-      else
-      {
-        bool allSubMeComputed = true;
-        SMESH_subMeshIteratorPtr smIt = faceSM->getDependsOnIterator(false,true);
-        while ( smIt->more() && allSubMeComputed )
-          allSubMeComputed = smIt->next()->IsMeshComputed();
-        if ( allSubMeComputed )
+        const TopoDS_Face&               face = TopoDS::Face( faceToSolids.FindKey( iF ));
+        const TopTools_ListOfShape& solidList = faceToSolids.FindFromKey( face );
+        if ( solidList.IsEmpty() ) continue;
+        SMESH_subMesh*                 faceSM = theMesh.GetSubMesh( face );
+        if ( !faceSM->IsEmpty() )
         {
-          faceSM->ComputeStateEngine( SMESH_subMesh::COMPUTE );
-          if ( !faceSM->IsEmpty() )
-            meshedFaces.push_front( face ); // higher priority
-          else
-            faceSM->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
+          int nbFaces = faceSM->GetSubMeshDS()->NbElements();
+          if ( prevNbFaces < nbFaces )
+          {
+            if ( !meshedFaces.empty() ) meshedFaces.pop_back();
+            meshedFaces.push_back( face ); // lower priority
+            prevNbFaces = nbFaces;
+          }
+        }
+        else
+        {
+          bool allSubMeComputed = true;
+          SMESH_subMeshIteratorPtr smIt = faceSM->getDependsOnIterator(false,true);
+          while ( smIt->more() && allSubMeComputed )
+            allSubMeComputed = smIt->next()->IsMeshComputed();
+          if ( allSubMeComputed )
+          {
+            faceSM->ComputeStateEngine( SMESH_subMesh::COMPUTE );
+            if ( !faceSM->IsEmpty() ) {
+              meshedFaces.push_front( face ); // higher priority
+              break;
+            }
+            else {
+              faceSM->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
+            }
+          }
         }
       }
     }
@@ -1512,6 +1540,8 @@ bool StdMeshers_Prism_3D::computeWalls(const Prism_3D::TPrismTopo& thePrism)
         SMESH_subMesh*    topSM = mesh->GetSubMesh( topE );
         SMESH_subMesh*    srcSM = botSM;
         SMESH_subMesh*    tgtSM = topSM;
+        srcSM->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
+        tgtSM->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
         if ( !srcSM->IsMeshComputed() && tgtSM->IsMeshComputed() )
           std::swap( srcSM, tgtSM );
 
@@ -1521,7 +1551,6 @@ bool StdMeshers_Prism_3D::computeWalls(const Prism_3D::TPrismTopo& thePrism)
           srcSM->ComputeSubMeshStateEngine( SMESH_subMesh::COMPUTE ); // nodes on VERTEXes
           srcSM->ComputeStateEngine( SMESH_subMesh::COMPUTE );        // segments on the EDGE
         }
-        srcSM->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
 
         if ( tgtSM->IsMeshComputed() &&
              tgtSM->GetSubMeshDS()->NbNodes() != srcSM->GetSubMeshDS()->NbNodes() )
index da476e4b46a2adbba2c1045b5b26ce5ca16c68ab..f4c233e3e43a8aadf8d4dfa604e862cbfd402469 100644 (file)
@@ -658,7 +658,6 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
       TopoDS_Shape F1, F2;
 
       // get a face sharing edge1 (F1)
-      TopoDS_Shape FF2[2];
       TopTools_ListIteratorOfListOfShape ancestIt1( edgeToFace1.FindFromKey( edge1 ));
       for ( ; F1.IsNull() && ancestIt1.More(); ancestIt1.Next() )
         if ( ancestIt1.Value().ShapeType() == TopAbs_FACE )
@@ -668,6 +667,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
         RETURN_BAD_RESULT(" Face1 not found");
 
       // get 2 faces sharing edge2 (one of them is F2)
+      TopoDS_Shape FF2[2];
       TopTools_ListIteratorOfListOfShape ancestIt2( edgeToFace2.FindFromKey( edge2 ));
       for ( int i = 0; FF2[1].IsNull() && ancestIt2.More(); ancestIt2.Next() )
         if ( ancestIt2.Value().ShapeType() == TopAbs_FACE )
index 66e7834aec0cf2846de4d283b1309f30f899284c..f8dd7501666ac0edcbb18001285b135c2e1469b3 100644 (file)
@@ -706,7 +706,12 @@ namespace {
 
     if ( !tgtFace.IsPartner( srcFace ) )
     {
+      SMESH_MesherHelper edgeHelper( *tgtMesh );
+      edgeHelper.ToFixNodeParameters( true );
+      helper.ToFixNodeParameters( true );
+
       int nbOkPos = 0;
+      bool toCheck = true;
       const double tol2d = 1e-12;
       srcN_tgtN = src2tgtNodes.begin();
       for ( ; srcN_tgtN != src2tgtNodes.end(); ++srcN_tgtN )
@@ -716,11 +721,11 @@ namespace {
         {
         case SMDS_TOP_FACE:
         {
+          if ( nbOkPos < 10 ) break;
           gp_XY uv = helper.GetNodeUV( tgtFace, n ), uvBis = uv;
           if (( helper.CheckNodeUV( tgtFace, n, uv, tol )) &&
-              (( uv - uvBis ).SquareModulus() < tol2d )    &&
-              ( ++nbOkPos > 10 ))
-            return true;
+              (( uv - uvBis ).SquareModulus() < tol2d ))
+            ++nbOkPos;
           else
             nbOkPos = 0;
           break;
@@ -728,10 +733,8 @@ namespace {
         case SMDS_TOP_EDGE:
         {
           const TopoDS_Edge & tgtE = TopoDS::Edge( tgtMeshDS->IndexToShape( n->getshapeId() ));
-          double u = helper.GetNodeU( tgtE, n ), uBis = u;
-          if (( !helper.CheckNodeU( tgtE, n, u, tol )) ||
-              (( u - uBis ) < tol2d ))
-            nbOkPos = 0;
+          edgeHelper.SetSubShape( tgtE );
+          edgeHelper.GetNodeU( tgtE, n, 0, &toCheck );
           break;
         }
         default:;
index a9990e5e7e7aaf475b764d56ac9e684aa8f92205..4d1321497a6d08eb6ad1fe25b8c4b43227dc3647 100644 (file)
@@ -4280,16 +4280,17 @@ int StdMeshers_Quadrangle_2D::getCorners(const TopoDS_Face&          theFace,
     vMap.Add( (*a2v).second );
 
   // check if there are possible variations in choosing corners
-  bool isThereVariants = false;
+  bool haveVariants = false;
   if ( vertexByAngle.size() > nbCorners )
   {
     double lostAngle = a2v->first;
     double lastAngle = ( --a2v, a2v->first );
-    isThereVariants  = ( lostAngle * 1.1 >= lastAngle );
+    haveVariants  = ( lostAngle * 1.1 >= lastAngle );
   }
 
+  const double angleTol = 5.* M_PI/180;
   myCheckOri = ( vertexByAngle.size() > nbCorners ||
-                 vertexByAngle.begin()->first < 5.* M_PI/180 );
+                 vertexByAngle.begin()->first < angleTol );
 
   // make theWire begin from a corner vertex or triaVertex
   if ( nbCorners == 3 )
@@ -4306,9 +4307,10 @@ int StdMeshers_Quadrangle_2D::getCorners(const TopoDS_Face&          theFace,
   vector< double >      angles;
   vector< TopoDS_Edge > edgeVec;
   vector< int >         cornerInd, nbSeg;
-  angles.reserve( vertexByAngle.size() );
+  int nbSegTot = 0;
+  angles .reserve( vertexByAngle.size() );
   edgeVec.reserve( vertexByAngle.size() );
-  nbSeg.reserve( vertexByAngle.size() );
+  nbSeg  .reserve( vertexByAngle.size() );
   cornerInd.reserve( nbCorners );
   for ( edge = theWire.begin(); edge != theWire.end(); ++edge )
   {
@@ -4321,105 +4323,219 @@ int StdMeshers_Quadrangle_2D::getCorners(const TopoDS_Face&          theFace,
       theVertices.push_back( v );
       cornerInd.push_back( angles.size() );
     }
-    angles.push_back( angleByVertex.IsBound( v ) ? angleByVertex( v ) : -M_PI );
+    angles .push_back( angleByVertex.IsBound( v ) ? angleByVertex( v ) : -M_PI );
     edgeVec.push_back( *edge );
-    if ( theConsiderMesh && isThereVariants )
+    if ( theConsiderMesh && haveVariants )
     {
       if ( SMESHDS_SubMesh* sm = helper.GetMeshDS()->MeshElements( *edge ))
         nbSeg.push_back( sm->NbNodes() + 1 );
       else
         nbSeg.push_back( 0 );
+      nbSegTot += nbSeg.back();
     }
   }
 
-  // refine the result vector - make sides elual by length if
+  // refine the result vector - make sides equal by length if
   // there are several equal angles
-  if ( isThereVariants )
+  if ( haveVariants )
   {
     if ( nbCorners == 3 )
       angles[0] = 2 * M_PI; // not to move the base triangle VERTEX
 
-    set< int > refinedCorners;
+    // here we refer to VERTEX'es and EDGEs by indices in angles and edgeVec vectors
+    typedef int TGeoIndex;
+
+    // for each vertex find a vertex till which there are nbSegHalf segments
+    const int nbSegHalf = ( nbSegTot % 2 || nbCorners == 3 ) ? 0 : nbSegTot / 2;
+    vector< TGeoIndex > halfDivider( angles.size(), -1 );
+    int nbHalfDividers = 0;
+    if ( nbSegHalf )
+    {
+      // get min angle of corners
+      double minAngle = 10.;
+      for ( size_t iC = 0; iC < cornerInd.size(); ++iC )
+        minAngle = Min( minAngle, angles[ cornerInd[ iC ]]);
+
+      // find halfDivider's
+      for ( TGeoIndex iV1 = 0; iV1 < TGeoIndex( angles.size() ); ++iV1 )
+      {
+        int nbSegs = 0;
+        TGeoIndex iV2 = iV1;
+        do {
+          nbSegs += nbSeg[ iV2 ];
+          iV2 = helper.WrapIndex( iV2 + 1, nbSeg.size() );
+        } while ( nbSegs < nbSegHalf );
+
+        if ( nbSegs == nbSegHalf &&
+             angles[ iV1 ] + angleTol >= minAngle &&
+             angles[ iV2 ] + angleTol >= minAngle )
+        {
+          halfDivider[ iV1 ] = iV2;
+          ++nbHalfDividers;
+        }
+      }
+    }
+
+    set< TGeoIndex > refinedCorners, treatedCorners;
     for ( size_t iC = 0; iC < cornerInd.size(); ++iC )
     {
-      int iV = cornerInd[iC];
-      if ( !refinedCorners.insert( iV ).second )
+      TGeoIndex iV = cornerInd[iC];
+      if ( !treatedCorners.insert( iV ).second )
         continue;
-      list< int > equalVertices;
-      equalVertices.push_back( iV );
+      list< TGeoIndex > equVerts; // inds of vertices that can become corners
+      equVerts.push_back( iV );
       int nbC[2] = { 0, 0 };
       // find equal angles backward and forward from the iV-th corner vertex
       for ( int isFwd = 0; isFwd < 2; ++isFwd )
       {
-        int     dV = isFwd ? +1 : -1;
-        int iCNext = helper.WrapIndex( iC + dV, cornerInd.size() );
-        int iVNext = helper.WrapIndex( iV + dV, angles.size() );
+        int           dV = isFwd ? +1 : -1;
+        int       iCNext = helper.WrapIndex( iC + dV, cornerInd.size() );
+        TGeoIndex iVNext = helper.WrapIndex( iV + dV, angles.size() );
         while ( iVNext != iV )
         {
-          bool equal = Abs( angles[iV] - angles[iVNext] ) < 0.1 * angles[iV];
+          bool equal = Abs( angles[iV] - angles[iVNext] ) < angleTol;
           if ( equal )
-            equalVertices.insert( isFwd ? equalVertices.end() : equalVertices.begin(), iVNext );
+            equVerts.insert( isFwd ? equVerts.end() : equVerts.begin(), iVNext );
           if ( iVNext == cornerInd[ iCNext ])
           {
             if ( !equal )
+            {
+              if ( angles[iV] < angles[iVNext] )
+                refinedCorners.insert( iVNext );
               break;
+            }
             nbC[ isFwd ]++;
-            refinedCorners.insert( cornerInd[ iCNext ] );
+            treatedCorners.insert( cornerInd[ iCNext ] );
             iCNext = helper.WrapIndex( iCNext + dV, cornerInd.size() );
           }
           iVNext = helper.WrapIndex( iVNext + dV, angles.size() );
         }
+        if ( iVNext == iV )
+          break; // all angles equal
       }
+
+      const bool allCornersSame = ( nbC[0] == 3 );
+      if ( allCornersSame && nbHalfDividers > 0 )
+      {
+        // select two halfDivider's as corners
+        TGeoIndex hd1, hd2 = -1;
+        int iC2;
+        for ( iC2 = 0; iC2 < cornerInd.size() && hd2 < 0; ++iC2 )
+        {
+          hd1 = cornerInd[ iC2 ];
+          hd2 = halfDivider[ hd1 ];
+          if ( std::find( equVerts.begin(), equVerts.end(), hd2 ) == equVerts.end() )
+            hd2 = -1; // hd2-th vertex can't become a corner
+          else
+            break;
+        }
+        if ( hd2 >= 0 )
+        {
+          angles[ hd1 ] = 2 * M_PI; // make hd1-th vertex no more "equal"
+          angles[ hd2 ] = 2 * M_PI;
+          refinedCorners.insert( hd1 );
+          refinedCorners.insert( hd2 );
+          treatedCorners = refinedCorners;
+          // update cornerInd
+          equVerts.push_front( equVerts.back() );
+          equVerts.push_back( equVerts.front() );
+          list< TGeoIndex >::iterator hdPos =
+            std::find( equVerts.begin(), equVerts.end(), hd2 );
+          if ( hdPos == equVerts.end() ) break;
+          cornerInd[ helper.WrapIndex( iC2 + 0, cornerInd.size()) ] = hd1;
+          cornerInd[ helper.WrapIndex( iC2 + 1, cornerInd.size()) ] = *( --hdPos );
+          cornerInd[ helper.WrapIndex( iC2 + 2, cornerInd.size()) ] = hd2;
+          cornerInd[ helper.WrapIndex( iC2 + 3, cornerInd.size()) ] = *( ++hdPos, ++hdPos );
+
+          theVertices[ 0 ] = helper.IthVertex( 0, edgeVec[ cornerInd[0] ]);
+          theVertices[ 1 ] = helper.IthVertex( 0, edgeVec[ cornerInd[1] ]);
+          theVertices[ 2 ] = helper.IthVertex( 0, edgeVec[ cornerInd[2] ]);
+          theVertices[ 3 ] = helper.IthVertex( 0, edgeVec[ cornerInd[3] ]);
+          iC = -1;
+          continue;
+        }
+      }
+
       // move corners to make sides equal by length
-      int nbEqualV  = equalVertices.size();
+      int nbEqualV  = equVerts.size();
       int nbExcessV = nbEqualV - ( 1 + nbC[0] + nbC[1] );
-      if ( nbExcessV > 0 )
+      if ( nbExcessV > 0 ) // there is nbExcessV vertices that can become corners
       {
-        // calculate normalized length of each side enclosed between neighbor equalVertices
-        vector< double > curLengths;
+        // calculate normalized length of each "side" enclosed between neighbor equVerts
+        vector< double > accuLength;
         double totalLen = 0;
-        vector< int > evVec( equalVertices.begin(), equalVertices.end() );
-        int   iEV = 0;
-        int    iE = cornerInd[ helper.WrapIndex( iC - nbC[0] - 1, cornerInd.size() )];
-        int iEEnd = cornerInd[ helper.WrapIndex( iC + nbC[1] + 1, cornerInd.size() )];
-        while ( curLengths.size() < nbEqualV + 1 )
+        vector< TGeoIndex > evVec( equVerts.begin(), equVerts.end() );
+        int          iEV = 0;
+        TGeoIndex    iE = cornerInd[ helper.WrapIndex( iC - nbC[0] - 1, cornerInd.size() )];
+        TGeoIndex iEEnd = cornerInd[ helper.WrapIndex( iC + nbC[1] + 1, cornerInd.size() )];
+        while ( accuLength.size() < nbEqualV + int( !allCornersSame ) )
         {
-          curLengths.push_back( totalLen );
+          // accumulate length of edges before iEV-th equal vertex
+          accuLength.push_back( totalLen );
           do {
-            curLengths.back() += SMESH_Algo::EdgeLength( edgeVec[ iE ]);
+            accuLength.back() += SMESH_Algo::EdgeLength( edgeVec[ iE ]);
             iE = helper.WrapIndex( iE + 1, edgeVec.size());
-            if ( iEV < evVec.size() && iE == evVec[ iEV++ ] )
-              break;
+            if ( iEV < evVec.size() && iE == evVec[ iEV ] ) {
+              iEV++;
+              break; // equal vertex reached
+            }
           }
           while( iE != iEEnd );
-          totalLen = curLengths.back();
+          totalLen = accuLength.back();
         }
-        curLengths.resize( equalVertices.size() );
-        for ( size_t iS = 0; iS < curLengths.size(); ++iS )
-          curLengths[ iS ] /= totalLen;
+        accuLength.resize( equVerts.size() );
+        for ( size_t iS = 0; iS < accuLength.size(); ++iS )
+          accuLength[ iS ] /= totalLen;
 
-        // find equalVertices most close to the ideal sub-division of all sides
+        // find equVerts most close to the ideal sub-division of all sides
         int iBestEV = 0;
         int iCorner = helper.WrapIndex( iC - nbC[0], cornerInd.size() );
-        int nbSides = 2 + nbC[0] + nbC[1];
+        int nbSides = Min( nbCorners, 2 + nbC[0] + nbC[1] );
         for ( int iS = 1; iS < nbSides; ++iS, ++iBestEV )
         {
           double idealLen = iS / double( nbSides );
-          double d, bestDist = 1.;
-          for ( iEV = iBestEV; iEV < curLengths.size(); ++iEV )
-            if (( d = Abs( idealLen - curLengths[ iEV ])) < bestDist )
+          double d, bestDist = 2.;
+          for ( iEV = iBestEV; iEV < accuLength.size(); ++iEV )
+          {
+            d = Abs( idealLen - accuLength[ iEV ]);
+
+            // take into account presence of a coresponding halfDivider
+            const double cornerWgt = 0.5  / nbSides;
+            const double vertexWgt = 0.25 / nbSides;
+            TGeoIndex hd = halfDivider[ evVec[ iEV ]];
+            if ( hd < 0 )
+              d += vertexWgt;
+            else if( refinedCorners.count( hd ))
+              d -= cornerWgt;
+            else
+              d -= vertexWgt;
+
+            // choose vertex with the best d
+            if ( d < bestDist )
             {
               bestDist = d;
               iBestEV  = iEV;
             }
+          }
           if ( iBestEV > iS-1 + nbExcessV )
             iBestEV = iS-1 + nbExcessV;
           theVertices[ iCorner ] = helper.IthVertex( 0, edgeVec[ evVec[ iBestEV ]]);
+          refinedCorners.insert( evVec[ iBestEV ]);
           iCorner = helper.WrapIndex( iCorner + 1, cornerInd.size() );
         }
+
+      } // if ( nbExcessV > 0 )
+      else
+      {
+        refinedCorners.insert( cornerInd[ iC ]);
       }
-    }
-  }
+    } // loop on cornerInd
+
+    // make theWire begin from the cornerInd[0]-th EDGE
+    while ( !theWire.front().IsSame( edgeVec[ cornerInd[0] ]))
+      theWire.splice( theWire.begin(), theWire, --theWire.end() );
+
+  } // if ( haveVariants )
 
   return nbCorners;
 }
index 3b36e0058a9c20103606b4f621589cabe9f2b5b4..5ef61aab9cdfc9fb6404afb92aa86410db218f8b 100644 (file)
@@ -179,13 +179,13 @@ bool StdMeshers_RadialPrism_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& a
   // ----------------------------------
 
   ProjectionUtils::TShapeShapeMap shape2ShapeMaps[2];
-  if ( !ProjectionUtils::FindSubShapeAssociation( innerShell, &aMesh,
-                                                  outerShell, &aMesh,
-                                                  shape2ShapeMaps[0])
-       &&
-       !ProjectionUtils::FindSubShapeAssociation( innerShell.Reversed(), &aMesh,
-                                                  outerShell, &aMesh,
-                                                  shape2ShapeMaps[1]))
+  bool mapOk1 = ProjectionUtils::FindSubShapeAssociation( innerShell, &aMesh,
+                                                          outerShell, &aMesh,
+                                                          shape2ShapeMaps[0]);
+  bool mapOk2 = ProjectionUtils::FindSubShapeAssociation( innerShell.Reversed(), &aMesh,
+                                                          outerShell, &aMesh,
+                                                          shape2ShapeMaps[1]);
+  if ( !mapOk1 && !mapOk2 )
     return error(COMPERR_BAD_SHAPE,"Topology of inner and outer shells seems different" );
 
   int iMap;
index 49d0e09af1c496bf37b4c9ef70f1bada6d8cd240..704144d7a6d3a5c74f9315050c0640226ff920a7 100644 (file)
@@ -5386,7 +5386,7 @@ int _LayerEdge::Smooth(const int step, const bool isConcaveFace, const bool find
     // get worse?
     if ( nbOkAfter < nbOkBefore )
       continue;
-    if (( isConcaveFace ) &&
+    if (( isConcaveFace || findBest ) &&
         ( nbOkAfter == nbOkBefore ) &&
         //( iFun > -1 || nbOkAfter < _simplices.size() ) &&
         ( minVolAfter <= minVolBefore ))