Salome HOME
23189: EDF 11603 - Dyssymetry in meshing
authoreap <eap@opencascade.com>
Tue, 27 Oct 2015 18:21:05 +0000 (21:21 +0300)
committereap <eap@opencascade.com>
Tue, 27 Oct 2015 18:21:05 +0000 (21:21 +0300)
  (fix StdMeshers_CompositeHexa_3D.cxx, StdMeshers_Hexa_3D.cxx)

+ Doc update
+ Optimize dump of NumberOfSegments

doc/salome/examples/filters_ex01.py
doc/salome/gui/SMESH/input/1d_meshing_hypo.doc
doc/salome/gui/SMESH/input/selection_filter_library.doc
doc/salome/gui/SMESH/input/tui_filters.doc
src/StdMeshers/StdMeshers_CompositeHexa_3D.cxx
src/StdMeshers/StdMeshers_Hexa_3D.cxx
src/StdMeshers/StdMeshers_NumberOfSegments.cxx
src/StdMeshersGUI/StdMeshersGUI_NbSegmentsCreator.cxx
src/StdMeshers_I/StdMeshers_NumberOfSegments_i.cxx

index 233b699a9fae0aed51653378aaed73861670cbdd..88305c97f9523b52ad8809b37456bf7bf1d031a1 100644 (file)
@@ -25,3 +25,10 @@ crit = [ smesh.GetCriterion( SMESH.FACE, SMESH.FT_AspectRatio, '<', 1.5, BinaryO
 triaGroup = mesh.MakeGroupByCriteria( "Tria AR < 1.5", crit )
 print "Number of triangles with aspect ratio < 1.5:", triaGroup.Size()
 
 triaGroup = mesh.MakeGroupByCriteria( "Tria AR < 1.5", crit )
 print "Number of triangles with aspect ratio < 1.5:", triaGroup.Size()
 
+# get range of values of Aspect Ratio of all faces in the mesh
+aspects = mesh.GetMinMax( SMESH.FT_AspectRatio )
+print "MESH: Min aspect = %s, Max aspect = %s" % ( aspects[0], aspects[1] )
+
+# get max value of Aspect Ratio of faces in triaGroup
+grAspects = mesh.GetMinMax( SMESH.FT_AspectRatio, triaGroup )
+print "GROUP: Max aspect = %s" % grAspects[1]
index a5b54c82c0422fd3d8cbd7e11db971d3edba118b..0995673b393d94a7a7b94b08a1b279c9457b160c 100644 (file)
@@ -241,7 +241,7 @@ in the plot the density function curve in red and the node
 distribution as blue crosses. The node distribution is computed in the
 same way as for 
 \ref analyticdensity_anchor "Distribution with Analytic Density". You
 distribution as blue crosses. The node distribution is computed in the
 same way as for 
 \ref analyticdensity_anchor "Distribution with Analytic Density". You
-can select the <b>Conversion mode</b> from\b Exponent and <b>Cut
+can select the <b>Conversion mode</b> from \b Exponent and <b>Cut
 negative</b>.
 
 \image html distributionwithtabledensity.png
 negative</b>.
 
 \image html distributionwithtabledensity.png
@@ -344,16 +344,24 @@ geometrical model in the 3D Viewer, which can help to understand the
 location of a set of edges within the model.
 
 <b>Propagation chains</b> group allows defining <b>Reversed Edges</b>
 location of a set of edges within the model.
 
 <b>Propagation chains</b> group allows defining <b>Reversed Edges</b>
-for splitting opposite edges of quadrilateral faces
-in a logically uniform direction. When this group is
-activated, the list is filled with propagation chains found within the
-model. When a chain is selected in the list its edges are
-shown in the Viewer with arrows, which enables choosing a common
-direction for all chain edges. \b Reverse button inverts the common
-direction of chain edges. If \b Add button is active, some
-edges of a chain have a different direction, so you can click \b Add
-button to add them to <b>Reversed Edges</b> list.
+for splitting opposite edges of quadrilateral faces in a logically
+uniform direction. When this group is activated, the list is filled
+with propagation chains found within the shape on which a hypothesis
+is assigned. When a chain is selected in the list its edges are shown
+in the Viewer with arrows, which enables choosing a common direction
+for all chain edges. \b Reverse button inverts the common direction of
+chain edges. \b Add button is active if some edges of a chain have a
+different direction, so you can click \b Add button to add them
+to <b>Reversed Edges</b> list.
 
 \image html propagation_chain.png "The whole geometry and a propagation chain"
 
 
 \image html propagation_chain.png "The whole geometry and a propagation chain"
 
+\note Alternatively, uniform direction of edges of one propagation
+chain can be achieved by 
+\ref constructing_submeshes_page "definition of a sub-mesh" on one
+edge of the chain and assigning a 
+\ref propagation_anchor "Propagation" additional hypothesis.
+Orientation of this edge (and hence of all the rest edges of the chain) can be
+controlled by using <b>Reversed Edges</b> field.
+
 */
 */
index 30870607574f58c3dc6b1b4465c452de6fc6ad2c..c73c1e42e67995a5f856fe3d7b6aa508de2b1e28 100644 (file)
@@ -20,7 +20,7 @@ filter. By default it is prefixed with the corresponding entity type.
 
 \anchor filtering_elements
 
 
 \anchor filtering_elements
 
-When we use filters during group creation or another operation (by 
+When we use filters during group creation or another operation (by 
 clicking <b>Set Filter</b> button in the corresponding dialog), the
 dialog for setting filters looks as shown below.
 
 clicking <b>Set Filter</b> button in the corresponding dialog), the
 dialog for setting filters looks as shown below.
 
@@ -29,7 +29,10 @@ dialog for setting filters looks as shown below.
 The \b Add button creates a new criterion at the end of the list of
 criteria. The \b Insert button creates a new criterion before the
 selected criterion. The \b Remove button deletes the selected
 The \b Add button creates a new criterion at the end of the list of
 criteria. The \b Insert button creates a new criterion before the
 selected criterion. The \b Remove button deletes the selected
-criterion. The \b Clear button deletes all criteria.
+criterion. The \b Clear button deletes all criteria.\n
+If there is a choice of <b>Entity type</b> in the dialog, only
+criteria of currently selected type are used to create or change a
+filter, and criteria of hidden types (if were specified) are ignored.
 \n Each <b>Entity type</b> has its specific list of criteria, however all
 filters have common syntax. The <b>Threshold Value</b> should be specified 
 for most criteria. For numerical criteria it is necessary to indicate if 
 \n Each <b>Entity type</b> has its specific list of criteria, however all
 filters have common syntax. The <b>Threshold Value</b> should be specified 
 for most criteria. For numerical criteria it is necessary to indicate if 
index bf3a1f72e23a4180e163ca9407571d6cd1dfaede..66cd3135d5ce10c463c611658713613f98a2be3e 100755 (executable)
@@ -13,7 +13,7 @@ Several filtering criteria can be combined together by using logical
 operators \a AND and \a OR. In addition, applied filter criterion can
 be reverted using logical operator \a NOT.
 
 operators \a AND and \a OR. In addition, applied filter criterion can
 be reverted using logical operator \a NOT.
 
-Mesh filters use the functionality of mesh quality controls to filter
+Mesh filters can use the functionality of mesh quality controls to filter
 mesh nodes / elements by a specific characteristic (Area, Length, etc).
 
 This page provides a short description of the existing mesh filters,
 mesh nodes / elements by a specific characteristic (Area, Length, etc).
 
 This page provides a short description of the existing mesh filters,
index cc27b86d7cef22fc9937a25764d95d2dac31e18a..07919e0ffcaef8115f50eb116d22997282bc4087 100644 (file)
@@ -62,7 +62,9 @@
 #ifdef _DEBUG_
 // #define DEB_FACES
 // #define DEB_GRID
 #ifdef _DEBUG_
 // #define DEB_FACES
 // #define DEB_GRID
-// #define DUMP_VERT(msg,V) { TopoDS_Vertex v = V; gp_Pnt p = BRep_Tool::Pnt(v); cout << msg << "( "<< p.X()<<", "<<p.Y()<<", "<<p.Z()<<" )"<<endl; }
+// #define DUMP_VERT(msg,V) \
+//   { TopoDS_Vertex v = V; gp_Pnt p = BRep_Tool::Pnt(v);                  \
+//     cout << msg << "( "<< p.X()<<", "<<p.Y()<<", "<<p.Z()<<" )"<<endl;}
 #endif
 
 #ifndef DUMP_VERT
 #endif
 
 #ifndef DUMP_VERT
@@ -78,6 +80,8 @@ enum EQuadSides{ Q_BOTTOM=0, Q_RIGHT, Q_TOP, Q_LEFT,   Q_CHILD, Q_PARENT };
 
 enum EBoxSides{ B_BOTTOM=0, B_RIGHT, B_TOP, B_LEFT, B_FRONT, B_BACK, B_UNDEFINED };
 
 
 enum EBoxSides{ B_BOTTOM=0, B_RIGHT, B_TOP, B_LEFT, B_FRONT, B_BACK, B_UNDEFINED };
 
+enum EAxes{ COO_X=1, COO_Y, COO_Z };
+
 //================================================================================
 /*!
  * \brief Convertor of a pair of integers to a sole index
 //================================================================================
 /*!
  * \brief Convertor of a pair of integers to a sole index
@@ -157,7 +161,7 @@ public: //** Methods to find and orient faces of 6 sides of the box **//
   _QuadFaceGrid* FindAdjacentForSide(int i, list<_QuadFaceGrid>& faces, EBoxSides id) const;
 
   //!< Reverse edges in order to have the bottom edge going along axes of the unit box
   _QuadFaceGrid* FindAdjacentForSide(int i, list<_QuadFaceGrid>& faces, EBoxSides id) const;
 
   //!< Reverse edges in order to have the bottom edge going along axes of the unit box
-  void ReverseEdges(/*int e1, int e2*/);
+  void ReverseEdges();
 
   bool IsComplex() const { return !myChildren.empty(); }
 
 
   bool IsComplex() const { return !myChildren.empty(); }
 
@@ -177,6 +181,9 @@ public: //** Loading and access to mesh **//
   //!< Load nodes of a mesh
   bool LoadGrid( SMESH_Mesh& mesh );
 
   //!< Load nodes of a mesh
   bool LoadGrid( SMESH_Mesh& mesh );
 
+  //!< Computes normalized parameters of nodes of myGrid
+  void ComputeIJK( int i1, int i2, double v3 );
+
   //!< Return number of segments on the hirizontal sides
   int GetNbHoriSegments(SMESH_Mesh& mesh, bool withBrothers=false) const;
 
   //!< Return number of segments on the hirizontal sides
   int GetNbHoriSegments(SMESH_Mesh& mesh, bool withBrothers=false) const;
 
@@ -192,6 +199,9 @@ public: //** Loading and access to mesh **//
   //!< Return node coordinates by its position
   gp_XYZ GetXYZ(int iHori, int iVert) const;
 
   //!< Return node coordinates by its position
   gp_XYZ GetXYZ(int iHori, int iVert) const;
 
+  //!< Return normalized parameters of nodes within the unitary cube
+  gp_XYZ& GetIJK(int iCol, int iRow) { return myIJK[ myIndexer( iCol, iRow )]; }
+
 public: //** Access to member fields **//
 
   //!< Return i-th face side (0<i<4)
 public: //** Access to member fields **//
 
   //!< Return i-th face side (0<i<4)
@@ -241,8 +251,9 @@ private:
   _QuadFaceGrid* myRightBrother;
   _QuadFaceGrid* myUpBrother;
 
   _QuadFaceGrid* myRightBrother;
   _QuadFaceGrid* myUpBrother;
 
-  _Indexer    myIndexer;
+  _Indexer                      myIndexer;
   vector<const SMDS_MeshNode*>  myGrid;
   vector<const SMDS_MeshNode*>  myGrid;
+  vector<gp_XYZ>                myIJK; // normalized parameters of nodes
 
   SMESH_ComputeErrorPtr         myError;
 
 
   SMESH_ComputeErrorPtr         myError;
 
@@ -590,6 +601,14 @@ bool StdMeshers_CompositeHexa_3D::Compute(SMESH_Mesh&         theMesh,
   if ( !fRight ->LoadGrid( theMesh )) return error( fRight ->GetError() );
   if ( !fTop   ->LoadGrid( theMesh )) return error( fTop   ->GetError() );
 
   if ( !fRight ->LoadGrid( theMesh )) return error( fRight ->GetError() );
   if ( !fTop   ->LoadGrid( theMesh )) return error( fTop   ->GetError() );
 
+  // compute normalized parameters of nodes on sides (PAL23189)
+  fBottom->ComputeIJK( COO_X, COO_Y, /*z=*/0. );
+  fBack  ->ComputeIJK( COO_X, COO_Z, /*y=*/1. );
+  fLeft  ->ComputeIJK( COO_Y, COO_Z, /*x=*/0. );
+  fFront ->ComputeIJK( COO_X, COO_Z, /*y=*/0. );
+  fRight ->ComputeIJK( COO_Y, COO_Z, /*x=*/1. );
+  fTop   ->ComputeIJK( COO_X, COO_Y, /*z=*/1. );
+
   int x, xSize = fBottom->GetNbHoriSegments(theMesh) + 1, X = xSize - 1;
   int y, ySize = fBottom->GetNbVertSegments(theMesh) + 1, Y = ySize - 1;
   int z, zSize = fFront ->GetNbVertSegments(theMesh) + 1, Z = zSize - 1;
   int x, xSize = fBottom->GetNbHoriSegments(theMesh) + 1, X = xSize - 1;
   int y, ySize = fBottom->GetNbVertSegments(theMesh) + 1, Y = ySize - 1;
   int z, zSize = fFront ->GetNbVertSegments(theMesh) + 1, Z = zSize - 1;
@@ -645,13 +664,14 @@ bool StdMeshers_CompositeHexa_3D::Compute(SMESH_Mesh&         theMesh,
   pointsOnShapes[ SMESH_Block::ID_V011 ] = fTop->GetXYZ( 0, Y );
   pointsOnShapes[ SMESH_Block::ID_V111 ] = fTop->GetXYZ( X, Y );
 
   pointsOnShapes[ SMESH_Block::ID_V011 ] = fTop->GetXYZ( 0, Y );
   pointsOnShapes[ SMESH_Block::ID_V111 ] = fTop->GetXYZ( X, Y );
 
+  gp_XYZ params; // normalized parameters of an internal node within the unit box
+
   for ( x = 1; x < xSize-1; ++x )
   {
   for ( x = 1; x < xSize-1; ++x )
   {
-    gp_XYZ params; // normalized parameters of internal node within a unit box
-    params.SetCoord( 1, x / double(X) );
+    const double rX = x / double(X);
     for ( y = 1; y < ySize-1; ++y )
     {
     for ( y = 1; y < ySize-1; ++y )
     {
-      params.SetCoord( 2, y / double(Y) );
+      const double rY = y / double(Y);
       // column to fill during z loop
       vector< const SMDS_MeshNode* >& column = columns[ colIndex( x, y )];
       // points projections on horizontal edges
       // column to fill during z loop
       vector< const SMDS_MeshNode* >& column = columns[ colIndex( x, y )];
       // points projections on horizontal edges
@@ -668,14 +688,28 @@ bool StdMeshers_CompositeHexa_3D::Compute(SMESH_Mesh&         theMesh,
       pointsOnShapes[ SMESH_Block::ID_Fxy1 ] = fTop   ->GetXYZ( x, y );
       for ( z = 1; z < zSize-1; ++z ) // z loop
       {
       pointsOnShapes[ SMESH_Block::ID_Fxy1 ] = fTop   ->GetXYZ( x, y );
       for ( z = 1; z < zSize-1; ++z ) // z loop
       {
-        params.SetCoord( 3, z / double(Z) );
+        // compute normalized parameters of an internal node within the unit box
+        const double   rZ = z / double(Z);
+        const gp_XYZ& pBo = fBottom->GetIJK( x, y );
+        const gp_XYZ& pTo = fTop   ->GetIJK( x, y );
+        const gp_XYZ& pFr = fFront ->GetIJK( x, z );
+        const gp_XYZ& pBa = fBack  ->GetIJK( x, z );
+        const gp_XYZ& pLe = fLeft  ->GetIJK( y, z );
+        const gp_XYZ& pRi = fRight ->GetIJK( y, z );
+        params.SetCoord( 1, 0.5 * ( pBo.X() * ( 1. - rZ ) + pTo.X() * rZ  +
+                                    pFr.X() * ( 1. - rY ) + pBa.X() * rY ));
+        params.SetCoord( 2, 0.5 * ( pBo.Y() * ( 1. - rZ ) + pTo.Y() * rZ  +
+                                    pLe.Y() * ( 1. - rX ) + pRi.Y() * rX ));
+        params.SetCoord( 3, 0.5 * ( pFr.Z() * ( 1. - rY ) + pBa.Z() * rY  +
+                                    pLe.Z() * ( 1. - rX ) + pRi.Z() * rX ));
+
         // point projections on vertical edges
         // point projections on vertical edges
-        pointsOnShapes[ SMESH_Block::ID_E00z ] = fFront->GetXYZ( 0, z );    
-        pointsOnShapes[ SMESH_Block::ID_E10z ] = fFront->GetXYZ( X, z );    
-        pointsOnShapes[ SMESH_Block::ID_E01z ] = fBack->GetXYZ( 0, z );    
+        pointsOnShapes[ SMESH_Block::ID_E00z ] = fFront->GetXYZ( 0, z );
+        pointsOnShapes[ SMESH_Block::ID_E10z ] = fFront->GetXYZ( X, z );
+        pointsOnShapes[ SMESH_Block::ID_E01z ] = fBack->GetXYZ( 0, z );
         pointsOnShapes[ SMESH_Block::ID_E11z ] = fBack->GetXYZ( X, z );
         // point projections on vertical faces
         pointsOnShapes[ SMESH_Block::ID_E11z ] = fBack->GetXYZ( X, z );
         // point projections on vertical faces
-        pointsOnShapes[ SMESH_Block::ID_Fx0z ] = fFront->GetXYZ( x, z );    
+        pointsOnShapes[ SMESH_Block::ID_Fx0z ] = fFront->GetXYZ( x, z );
         pointsOnShapes[ SMESH_Block::ID_Fx1z ] = fBack ->GetXYZ( x, z );    
         pointsOnShapes[ SMESH_Block::ID_F0yz ] = fLeft ->GetXYZ( y, z );    
         pointsOnShapes[ SMESH_Block::ID_F1yz ] = fRight->GetXYZ( y, z );
         pointsOnShapes[ SMESH_Block::ID_Fx1z ] = fBack ->GetXYZ( x, z );    
         pointsOnShapes[ SMESH_Block::ID_F0yz ] = fLeft ->GetXYZ( y, z );    
         pointsOnShapes[ SMESH_Block::ID_F1yz ] = fRight->GetXYZ( y, z );
@@ -1117,7 +1151,7 @@ bool _QuadFaceGrid::LoadGrid( SMESH_Mesh& mesh )
   const SMDS_MeshElement* firstQuad = 0; // most left face above the last row of found nodes
 
   int nbFoundNodes = myIndexer._xSize;
   const SMDS_MeshElement* firstQuad = 0; // most left face above the last row of found nodes
 
   int nbFoundNodes = myIndexer._xSize;
-  while ( nbFoundNodes != (int) myGrid.size() )
+  while ( nbFoundNodes != myGrid.size() )
   {
     // first and last nodes of the last filled row of nodes
     const SMDS_MeshNode* n1down = myGrid[ nbFoundNodes - myIndexer._xSize ];
   {
     // first and last nodes of the last filled row of nodes
     const SMDS_MeshNode* n1down = myGrid[ nbFoundNodes - myIndexer._xSize ];
@@ -1185,6 +1219,53 @@ bool _QuadFaceGrid::LoadGrid( SMESH_Mesh& mesh )
   return true;
 }
 
   return true;
 }
 
+//================================================================================
+/*!
+ * \brief Fill myIJK with normalized parameters of nodes in myGrid
+ *  \param [in] i1 - coordinate index along rows of myGrid
+ *  \param [in] i2 - coordinate index along columns of myGrid
+ *  \param [in] v3 - value of the constant parameter
+ */
+//================================================================================
+
+void _QuadFaceGrid::ComputeIJK( int i1, int i2, double v3 )
+{
+  gp_XYZ ijk( v3, v3, v3 );
+  myIJK.resize( myIndexer.size(), ijk );
+
+  const size_t nbCol = myIndexer._xSize;
+  const size_t nbRow = myIndexer._ySize;
+
+  vector< double > len( nbRow );
+  len[0] = 0;
+  for ( size_t i = 0; i < nbCol; ++i )
+  {
+    gp_Pnt pPrev = GetXYZ( i, 0 );
+    for ( size_t j = 1; j < nbRow; ++j )
+    {
+      gp_Pnt p = GetXYZ( i, j );
+      len[ j ] = len[ j-1 ] + p.Distance( pPrev );
+      pPrev = p;
+    }
+    for ( size_t j = 0; j < nbRow; ++j )
+      GetIJK( i, j ).SetCoord( i2, len[ j ]/len.back() );
+  }
+
+  len.resize( nbCol );
+  for ( size_t j = 0; j < nbRow; ++j )
+  {
+    gp_Pnt pPrev = GetXYZ( 0, j );
+    for ( size_t i = 1; i < nbCol; ++i )
+    {
+      gp_Pnt p = GetXYZ( i, j );
+      len[ i ] = len[ i-1 ] + p.Distance( pPrev );
+      pPrev = p;
+    }
+    for ( size_t i = 0; i < nbCol; ++i )
+      GetIJK( i, j ).SetCoord( i1, len[ i ]/len.back() );
+  }
+}
+
 //================================================================================
 /*!
  * \brief Find out mutual location of children: find their right and up brothers
 //================================================================================
 /*!
  * \brief Find out mutual location of children: find their right and up brothers
@@ -1441,8 +1522,8 @@ const SMDS_MeshNode* _QuadFaceGrid::GetNode(int iHori, int iVert) const
 
 gp_XYZ _QuadFaceGrid::GetXYZ(int iHori, int iVert) const
 {
 
 gp_XYZ _QuadFaceGrid::GetXYZ(int iHori, int iVert) const
 {
-  const SMDS_MeshNode* n = myGrid[ myIndexer( iHori, iVert )];
-  return gp_XYZ( n->X(), n->Y(), n->Z() );
+  SMESH_TNodeXYZ xyz = myGrid[ myIndexer( iHori, iVert )];
+  return xyz;
 }
 
 //================================================================================
 }
 
 //================================================================================
index 87f1aa8d78b0bd57baab08faf4903342a9c08ef5..c8d4c7a727adc886a38abfae2ec8218484b273d8 100644 (file)
@@ -144,6 +144,7 @@ namespace
   //=============================================================================
 
   typedef boost::shared_ptr< FaceQuadStruct > FaceQuadStructPtr;
   //=============================================================================
 
   typedef boost::shared_ptr< FaceQuadStruct > FaceQuadStructPtr;
+  typedef std::vector<gp_XYZ>                 TXYZColumn;
 
   // symbolic names of box sides
   enum EBoxSides{ B_BOTTOM=0, B_RIGHT, B_TOP, B_LEFT, B_FRONT, B_BACK, B_NB_SIDES };
 
   // symbolic names of box sides
   enum EBoxSides{ B_BOTTOM=0, B_RIGHT, B_TOP, B_LEFT, B_FRONT, B_BACK, B_NB_SIDES };
@@ -151,6 +152,8 @@ namespace
   // symbolic names of sides of quadrangle
   enum EQuadSides{ Q_BOTTOM=0, Q_RIGHT, Q_TOP, Q_LEFT, Q_NB_SIDES };
 
   // symbolic names of sides of quadrangle
   enum EQuadSides{ Q_BOTTOM=0, Q_RIGHT, Q_TOP, Q_LEFT, Q_NB_SIDES };
 
+  enum EAxes{ COO_X=1, COO_Y, COO_Z };
+
   //=============================================================================
   /*!
    * \brief Container of nodes of structured mesh on a qudrangular geom FACE
   //=============================================================================
   /*!
    * \brief Container of nodes of structured mesh on a qudrangular geom FACE
@@ -166,6 +169,9 @@ namespace
     // node column's taken form _u2nodesMap taking into account sub-shape orientation
     vector<TNodeColumn> _columns;
 
     // node column's taken form _u2nodesMap taking into account sub-shape orientation
     vector<TNodeColumn> _columns;
 
+    // columns of normalized parameters of nodes within the unitary cube
+    vector<TXYZColumn> _ijkColumns;
+
     // geometry of a cube side
     TopoDS_Face _sideF;
 
     // geometry of a cube side
     TopoDS_Face _sideF;
 
@@ -177,6 +183,10 @@ namespace
     {
       return SMESH_TNodeXYZ( GetNode( iCol, iRow ));
     }
     {
       return SMESH_TNodeXYZ( GetNode( iCol, iRow ));
     }
+    gp_XYZ& GetIJK(int iCol, int iRow)
+    {
+      return _ijkColumns[iCol][iRow];
+    }
   };
 
   //================================================================================
   };
 
   //================================================================================
@@ -276,6 +286,56 @@ namespace
     }
     return ( n == n00 || n == n01 || n == n10 || n == n11 );
   }
     }
     return ( n == n00 || n == n01 || n == n10 || n == n11 );
   }
+
+  //================================================================================
+  /*!
+   * \brief Fill in _FaceGrid::_ijkColumns
+   *  \param [in,out] fg - a _FaceGrid
+   *  \param [in] i1 - coordinate index along _columns
+   *  \param [in] i2 - coordinate index along _columns[i]
+   *  \param [in] v3 - value of the constant parameter
+   */
+  //================================================================================
+
+  void computeIJK( _FaceGrid& fg, int i1, int i2, double v3 )
+  {
+    gp_XYZ ijk( v3, v3, v3 );
+    const size_t nbCol = fg._columns.size();
+    const size_t nbRow = fg._columns[0].size();
+
+    fg._ijkColumns.resize( nbCol );
+    for ( size_t i = 0; i < nbCol; ++i )
+      fg._ijkColumns[ i ].resize( nbRow, ijk );
+
+    vector< double > len( nbRow );
+    len[0] = 0;
+    for ( size_t i = 0; i < nbCol; ++i )
+    {
+      gp_Pnt pPrev = fg.GetXYZ( i, 0 );
+      for ( size_t j = 1; j < nbRow; ++j )
+      {
+        gp_Pnt p = fg.GetXYZ( i, j );
+        len[ j ] = len[ j-1 ] + p.Distance( pPrev );
+        pPrev = p;
+      }
+      for ( size_t j = 0; j < nbRow; ++j )
+        fg.GetIJK( i, j ).SetCoord( i2, len[ j ]/len.back() );
+    }
+
+    len.resize( nbCol );
+    for ( size_t j = 0; j < nbRow; ++j )
+    {
+      gp_Pnt pPrev = fg.GetXYZ( 0, j );
+      for ( size_t i = 1; i < nbCol; ++i )
+      {
+        gp_Pnt p = fg.GetXYZ( i, j );
+        len[ i ] = len[ i-1 ] + p.Distance( pPrev );
+        pPrev = p;
+      }
+      for ( size_t i = 0; i < nbCol; ++i )
+        fg.GetIJK( i, j ).SetCoord( i1, len[ i ]/len.back() );
+    }
+  }
 }
 
 //=============================================================================
 }
 
 //=============================================================================
@@ -444,15 +504,15 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh &         aMesh,
   {
     aCubeSide[i]._columns.resize( aCubeSide[i]._u2nodesMap.size() );
 
   {
     aCubeSide[i]._columns.resize( aCubeSide[i]._u2nodesMap.size() );
 
-    size_t iFwd = 0, iRev = aCubeSide[i]._columns.size()-1;
-    size_t*  pi = isReverse[i] ? &iRev : &iFwd;
+    int iFwd = 0, iRev = aCubeSide[i]._columns.size()-1;
+    int* pi = isReverse[i] ? &iRev : &iFwd;
     TParam2ColumnMap::iterator u2nn = aCubeSide[i]._u2nodesMap.begin();
     for ( ; iFwd < aCubeSide[i]._columns.size(); --iRev, ++iFwd, ++u2nn )
       aCubeSide[i]._columns[ *pi ].swap( u2nn->second );
 
     aCubeSide[i]._u2nodesMap.clear();
   }
     TParam2ColumnMap::iterator u2nn = aCubeSide[i]._u2nodesMap.begin();
     for ( ; iFwd < aCubeSide[i]._columns.size(); --iRev, ++iFwd, ++u2nn )
       aCubeSide[i]._columns[ *pi ].swap( u2nn->second );
 
     aCubeSide[i]._u2nodesMap.clear();
   }
-  
+
   if ( proxymesh )
     for ( int i = 0; i < 6; ++i )
       for ( unsigned j = 0; j < aCubeSide[i]._columns.size(); ++j)
   if ( proxymesh )
     for ( int i = 0; i < 6; ++i )
       for ( unsigned j = 0; j < aCubeSide[i]._columns.size(); ++j)
@@ -476,6 +536,14 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh &         aMesh,
   _FaceGrid* fFront  = & aCubeSide[ B_FRONT  ];
   _FaceGrid* fBack   = & aCubeSide[ B_BACK   ];
 
   _FaceGrid* fFront  = & aCubeSide[ B_FRONT  ];
   _FaceGrid* fBack   = & aCubeSide[ B_BACK   ];
 
+  // compute normalized parameters of nodes on sides (PAL23189)
+  computeIJK( *fBottom, COO_X, COO_Y, /*z=*/0. );
+  computeIJK( *fRight,  COO_Y, COO_Z, /*x=*/1. );
+  computeIJK( *fTop,    COO_X, COO_Y, /*z=*/1. );
+  computeIJK( *fLeft,   COO_Y, COO_Z, /*x=*/0. );
+  computeIJK( *fFront,  COO_X, COO_Z, /*y=*/0. );
+  computeIJK( *fBack,   COO_X, COO_Z, /*y=*/1. );
+
   // cube size measured in nb of nodes
   int x, xSize = fBottom->_columns.size() , X = xSize - 1;
   int y, ySize = fLeft->_columns.size()   , Y = ySize - 1;
   // cube size measured in nb of nodes
   int x, xSize = fBottom->_columns.size() , X = xSize - 1;
   int y, ySize = fLeft->_columns.size()   , Y = ySize - 1;
@@ -531,13 +599,14 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh &         aMesh,
   pointsOnShapes[ SMESH_Block::ID_V011 ] = fTop->GetXYZ( 0, Y );
   pointsOnShapes[ SMESH_Block::ID_V111 ] = fTop->GetXYZ( X, Y );
 
   pointsOnShapes[ SMESH_Block::ID_V011 ] = fTop->GetXYZ( 0, Y );
   pointsOnShapes[ SMESH_Block::ID_V111 ] = fTop->GetXYZ( X, Y );
 
+  gp_XYZ params; // normalized parameters of an internal node within the unit box
   for ( x = 1; x < xSize-1; ++x )
   {
   for ( x = 1; x < xSize-1; ++x )
   {
-    gp_XYZ params; // normalized parameters of internal node within a unit box
-    params.SetCoord( 1, x / double(X) );
+    const double rX = x / double(X);
     for ( y = 1; y < ySize-1; ++y )
     {
     for ( y = 1; y < ySize-1; ++y )
     {
-      params.SetCoord( 2, y / double(Y) );
+      const double rY = y / double(Y);
+
       // a column to fill in during z loop
       vector< const SMDS_MeshNode* >& column = columns[ colIndex( x, y )];
       // projection points on horizontal edges
       // a column to fill in during z loop
       vector< const SMDS_MeshNode* >& column = columns[ colIndex( x, y )];
       // projection points on horizontal edges
@@ -554,23 +623,36 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh &         aMesh,
       pointsOnShapes[ SMESH_Block::ID_Fxy1 ] = fTop   ->GetXYZ( x, y );
       for ( z = 1; z < zSize-1; ++z ) // z loop
       {
       pointsOnShapes[ SMESH_Block::ID_Fxy1 ] = fTop   ->GetXYZ( x, y );
       for ( z = 1; z < zSize-1; ++z ) // z loop
       {
-        params.SetCoord( 3, z / double(Z) );
+        const double rZ = z / double(Z);
+
+        const gp_XYZ& pBo = fBottom->GetIJK( x, y );
+        const gp_XYZ& pTo = fTop   ->GetIJK( x, y );
+        const gp_XYZ& pFr = fFront ->GetIJK( x, z );
+        const gp_XYZ& pBa = fBack  ->GetIJK( x, z );
+        const gp_XYZ& pLe = fLeft  ->GetIJK( y, z );
+        const gp_XYZ& pRi = fRight ->GetIJK( y, z );
+        params.SetCoord( 1, 0.5 * ( pBo.X() * ( 1. - rZ ) + pTo.X() * rZ  +
+                                    pFr.X() * ( 1. - rY ) + pBa.X() * rY ));
+        params.SetCoord( 2, 0.5 * ( pBo.Y() * ( 1. - rZ ) + pTo.Y() * rZ  +
+                                    pLe.Y() * ( 1. - rX ) + pRi.Y() * rX ));
+        params.SetCoord( 3, 0.5 * ( pFr.Z() * ( 1. - rY ) + pBa.Z() * rY  +
+                                    pLe.Z() * ( 1. - rX ) + pRi.Z() * rX ));
+
         // projection points on vertical edges
         // projection points on vertical edges
-        pointsOnShapes[ SMESH_Block::ID_E00z ] = fFront->GetXYZ( 0, z );    
-        pointsOnShapes[ SMESH_Block::ID_E10z ] = fFront->GetXYZ( X, z );    
-        pointsOnShapes[ SMESH_Block::ID_E01z ] = fBack->GetXYZ( 0, z );    
+        pointsOnShapes[ SMESH_Block::ID_E00z ] = fFront->GetXYZ( 0, z );
+        pointsOnShapes[ SMESH_Block::ID_E10z ] = fFront->GetXYZ( X, z );
+        pointsOnShapes[ SMESH_Block::ID_E01z ] = fBack->GetXYZ( 0, z );
         pointsOnShapes[ SMESH_Block::ID_E11z ] = fBack->GetXYZ( X, z );
         // projection points on vertical faces
         pointsOnShapes[ SMESH_Block::ID_E11z ] = fBack->GetXYZ( X, z );
         // projection points on vertical faces
-        pointsOnShapes[ SMESH_Block::ID_Fx0z ] = fFront->GetXYZ( x, z );    
-        pointsOnShapes[ SMESH_Block::ID_Fx1z ] = fBack ->GetXYZ( x, z );    
-        pointsOnShapes[ SMESH_Block::ID_F0yz ] = fLeft ->GetXYZ( y, z );    
+        pointsOnShapes[ SMESH_Block::ID_Fx0z ] = fFront->GetXYZ( x, z );
+        pointsOnShapes[ SMESH_Block::ID_Fx1z ] = fBack ->GetXYZ( x, z );
+        pointsOnShapes[ SMESH_Block::ID_F0yz ] = fLeft ->GetXYZ( y, z );
         pointsOnShapes[ SMESH_Block::ID_F1yz ] = fRight->GetXYZ( y, z );
 
         // compute internal node coordinates
         gp_XYZ coords;
         SMESH_Block::ShellPoint( params, pointsOnShapes, coords );
         column[ z ] = helper.AddNode( coords.X(), coords.Y(), coords.Z() );
         pointsOnShapes[ SMESH_Block::ID_F1yz ] = fRight->GetXYZ( y, z );
 
         // compute internal node coordinates
         gp_XYZ coords;
         SMESH_Block::ShellPoint( params, pointsOnShapes, coords );
         column[ z ] = helper.AddNode( coords.X(), coords.Y(), coords.Z() );
-
       }
     }
   }
       }
     }
   }
index 2f0d05b9d75e8aee3d1c903434f830bfd71da973..29e55e4a5e983d3a0b85012c72942149bbb5fcdd 100644 (file)
@@ -180,15 +180,16 @@ StdMeshers_NumberOfSegments::DistrType StdMeshers_NumberOfSegments::GetDistrType
 void StdMeshers_NumberOfSegments::SetScaleFactor(double scaleFactor)
   throw(SALOME_Exception)
 {
 void StdMeshers_NumberOfSegments::SetScaleFactor(double scaleFactor)
   throw(SALOME_Exception)
 {
-  if (_distrType != DT_Scale)
-    _distrType = DT_Scale;
-    //throw SALOME_Exception(LOCALIZED("not a scale distribution"));
   if (scaleFactor < PRECISION)
     throw SALOME_Exception(LOCALIZED("scale factor must be positive"));
   if (scaleFactor < PRECISION)
     throw SALOME_Exception(LOCALIZED("scale factor must be positive"));
-  if (fabs(scaleFactor - 1.0) < PRECISION)
+
+  if (_distrType != DT_Scale)
+    _distrType = DT_Scale;
+
+  if ( fabs(scaleFactor - 1.0) < PRECISION )
     _distrType = DT_Regular;
 
     _distrType = DT_Regular;
 
-  if (fabs(_scaleFactor - scaleFactor) > PRECISION)
+  if ( fabs(_scaleFactor - scaleFactor) > PRECISION )
   {
     _scaleFactor = scaleFactor;
     NotifySubMeshesHypothesisModification();
   {
     _scaleFactor = scaleFactor;
     NotifySubMeshesHypothesisModification();
@@ -197,7 +198,7 @@ void StdMeshers_NumberOfSegments::SetScaleFactor(double scaleFactor)
 
 //================================================================================
 /*!
 
 //================================================================================
 /*!
- * 
+ *
  */
 //================================================================================
 
  */
 //================================================================================
 
@@ -211,7 +212,7 @@ double StdMeshers_NumberOfSegments::GetScaleFactor() const
 
 //================================================================================
 /*!
 
 //================================================================================
 /*!
- * 
+ *
  */
 //================================================================================
 
  */
 //================================================================================
 
@@ -224,12 +225,12 @@ void StdMeshers_NumberOfSegments::SetTableFunction(const vector<double>& table)
   if ( (table.size() % 2) != 0 )
     throw SALOME_Exception(LOCALIZED("odd size of vector of table function"));
 
   if ( (table.size() % 2) != 0 )
     throw SALOME_Exception(LOCALIZED("odd size of vector of table function"));
 
-  int i;
   double prev = -PRECISION;
   bool isSame = table.size() == _table.size();
 
   bool pos = false;
   double prev = -PRECISION;
   bool isSame = table.size() == _table.size();
 
   bool pos = false;
-  for (i=0; i < table.size()/2; i++) {
+  for ( size_t i = 0; i < table.size() / 2; i++ )
+  {
     double par = table[i*2];
     double val = table[i*2+1];
     if( _convMode==0 )
     double par = table[i*2];
     double val = table[i*2+1];
     if( _convMode==0 )
@@ -239,7 +240,8 @@ void StdMeshers_NumberOfSegments::SetTableFunction(const vector<double>& table)
         OCC_CATCH_SIGNALS;
 #endif
         val = pow( 10.0, val );
         OCC_CATCH_SIGNALS;
 #endif
         val = pow( 10.0, val );
-      } catch(Standard_Failure) {
+      }
+      catch(Standard_Failure) {
         Handle(Standard_Failure) aFail = Standard_Failure::Caught();
         throw SALOME_Exception( LOCALIZED( "invalid value"));
         return;
         Handle(Standard_Failure) aFail = Standard_Failure::Caught();
         throw SALOME_Exception( LOCALIZED( "invalid value"));
         return;
@@ -248,19 +250,19 @@ void StdMeshers_NumberOfSegments::SetTableFunction(const vector<double>& table)
     else if( _convMode==1 && val<0.0 )
       val = 0.0;
 
     else if( _convMode==1 && val<0.0 )
       val = 0.0;
 
-    if ( par<0 || par > 1)
+    if ( par < 0 || par > 1)
       throw SALOME_Exception(LOCALIZED("parameter of table function is out of range [0,1]"));
       throw SALOME_Exception(LOCALIZED("parameter of table function is out of range [0,1]"));
-    if ( fabs(par-prev)<PRECISION )
+    if ( fabs(par-prev) < PRECISION )
       throw SALOME_Exception(LOCALIZED("two parameters are the same"));
     if ( val < 0 )
       throw SALOME_Exception(LOCALIZED("value of table function is not positive"));
       throw SALOME_Exception(LOCALIZED("two parameters are the same"));
     if ( val < 0 )
       throw SALOME_Exception(LOCALIZED("value of table function is not positive"));
-    if( val>PRECISION )
+    if( val > PRECISION )
       pos = true;
     if (isSame)
     {
       double oldpar = _table[i*2];
       double oldval = _table[i*2+1];
       pos = true;
     if (isSame)
     {
       double oldpar = _table[i*2];
       double oldval = _table[i*2+1];
-      if (fabs(par - oldpar) > PRECISION || fabs(val - oldval) > PRECISION)
+      if ( fabs(par - oldpar) > PRECISION || fabs(val - oldval) > PRECISION )
         isSame = false;
     }
     prev = par;
         isSame = false;
     }
     prev = par;
@@ -269,7 +271,7 @@ void StdMeshers_NumberOfSegments::SetTableFunction(const vector<double>& table)
   if( !pos )
     throw SALOME_Exception(LOCALIZED("value of table function is not positive"));
 
   if( !pos )
     throw SALOME_Exception(LOCALIZED("value of table function is not positive"));
 
-  if( pos && !isSame )
+  if ( pos && !isSame )
   {
     _table = table;
     NotifySubMeshesHypothesisModification();
   {
     _table = table;
     NotifySubMeshesHypothesisModification();
@@ -278,7 +280,7 @@ void StdMeshers_NumberOfSegments::SetTableFunction(const vector<double>& table)
 
 //================================================================================
 /*!
 
 //================================================================================
 /*!
- * 
+ *
  */
 //================================================================================
 
  */
 //================================================================================
 
@@ -394,7 +396,6 @@ void StdMeshers_NumberOfSegments::SetExpressionFunction(const char* expr)
 {
   if (_distrType != DT_ExprFunc)
     _distrType = DT_ExprFunc;
 {
   if (_distrType != DT_ExprFunc)
     _distrType = DT_ExprFunc;
-    //throw SALOME_Exception(LOCALIZED("not an expression function distribution"));
 
   string func = CheckExpressionFunction( expr, _convMode );
   if( _func != func )
 
   string func = CheckExpressionFunction( expr, _convMode );
   if( _func != func )
@@ -509,9 +510,8 @@ ostream & StdMeshers_NumberOfSegments::SaveTo(ostream & save)
     save << " " << _scaleFactor;
     break;
   case DT_TabFunc:
     save << " " << _scaleFactor;
     break;
   case DT_TabFunc:
-    int i;
     save << " " << _table.size();
     save << " " << _table.size();
-    for (i=0; i < _table.size(); i++)
+    for ( size_t i = 0; i < _table.size(); i++ )
       save << " " << _table[i];
     break;
   case DT_ExprFunc:
       save << " " << _table[i];
     break;
   case DT_ExprFunc:
@@ -599,8 +599,7 @@ istream & StdMeshers_NumberOfSegments::LoadFrom(istream & load)
       if (isOK)
       {
         _table.resize(a, 0.);
       if (isOK)
       {
         _table.resize(a, 0.);
-        int i;
-        for (i=0; i < _table.size(); i++)
+        for ( size_t i=0; i < _table.size(); i++ )
         {
           isOK = (load >> b);
           if (isOK)
         {
           isOK = (load >> b);
           if (isOK)
@@ -652,7 +651,7 @@ istream & StdMeshers_NumberOfSegments::LoadFrom(istream & load)
   isOK = (load >> intVal);
   if ( isOK && _distrType != DT_Regular && intVal > 0 ) {
     _edgeIDs.reserve( intVal );
   isOK = (load >> intVal);
   if ( isOK && _distrType != DT_Regular && intVal > 0 ) {
     _edgeIDs.reserve( intVal );
-    for (int i = 0; i < _edgeIDs.capacity() && isOK; i++) {
+    for ( size_t i = 0; i < _edgeIDs.capacity() && isOK; i++) {
       isOK = (load >> intVal);
       if ( isOK ) _edgeIDs.push_back( intVal );
     }
       isOK = (load >> intVal);
       if ( isOK ) _edgeIDs.push_back( intVal );
     }
@@ -664,7 +663,7 @@ istream & StdMeshers_NumberOfSegments::LoadFrom(istream & load)
 
 //=============================================================================
 /*!
 
 //=============================================================================
 /*!
- *  
+ *
  */
 //=============================================================================
 
  */
 //=============================================================================
 
index 4450986fd396a45adda4c709facb409c4d1369c6..6749e0b9c753d5653eff3116fe0d1e0be5dd39e6 100644 (file)
@@ -94,9 +94,10 @@ bool StdMeshersGUI_NbSegmentsCreator::checkParams( QString& msg ) const
   readParamsFromHypo( data_old );
   readParamsFromWidgets( data_new );
   bool res = storeParamsToHypo( data_new );
   readParamsFromHypo( data_old );
   readParamsFromWidgets( data_new );
   bool res = storeParamsToHypo( data_new );
-  storeParamsToHypo( data_old );
   res = myNbSeg->isValid( msg, true ) && res;
   res = myScale->isValid( msg, true ) && res;
   res = myNbSeg->isValid( msg, true ) && res;
   res = myScale->isValid( msg, true ) && res;
+  if ( !res )
+    storeParamsToHypo( data_old );
   return res;
 }
 
   return res;
 }
 
@@ -300,7 +301,7 @@ QString StdMeshersGUI_NbSegmentsCreator::storeParams() const
   case TabFunc : {
     //valStr += tr("SMESH_TAB_FUNC");
     bool param = true;
   case TabFunc : {
     //valStr += tr("SMESH_TAB_FUNC");
     bool param = true;
-    for( size_t i=0; i < data.myTable.length(); i++, param = !param ) {
+    for( int i=0; i < data.myTable.length(); i++, param = !param ) {
       if ( param )
         valStr += "[";
       valStr += QString::number( data.myTable[ i ]);
       if ( param )
         valStr += "[";
       valStr += QString::number( data.myTable[ i ]);
@@ -382,9 +383,10 @@ bool StdMeshersGUI_NbSegmentsCreator::storeParamsToHypo( const NbSegmentsHypothe
 
     h->SetVarParameter( h_data.myNbSegVarName.toLatin1().constData(), "SetNumberOfSegments" );
     h->SetNumberOfSegments( h_data.myNbSeg );
 
     h->SetVarParameter( h_data.myNbSegVarName.toLatin1().constData(), "SetNumberOfSegments" );
     h->SetNumberOfSegments( h_data.myNbSeg );
-    int distr = h_data.myDistrType;
-    h->SetDistrType( distr );
     
     
+    int distr = h_data.myDistrType;
+    if ( distr == 0 )
+      h->SetDistrType( distr ); // this is actually needed at non-uniform -> uniform switch
     if( distr==1 ) {
       h->SetVarParameter( h_data.myScaleVarName.toLatin1().constData(), "SetScaleFactor" );
       h->SetScaleFactor( h_data.myScale );
     if( distr==1 ) {
       h->SetVarParameter( h_data.myScaleVarName.toLatin1().constData(), "SetScaleFactor" );
       h->SetScaleFactor( h_data.myScale );
index 0033badf7f9364cfadd1e005c0bca7df3934e67a..4e6ef16ae844e39cdfa50caf380125251db7741b 100644 (file)
@@ -267,10 +267,13 @@ void StdMeshers_NumberOfSegments_i::SetDistrType(CORBA::Long typ)
 {
   ASSERT( myBaseImpl );
   try {
 {
   ASSERT( myBaseImpl );
   try {
+    CORBA::Long oldType = (CORBA::Long) this->GetImpl()->GetDistrType();
+
     this->GetImpl()->SetDistrType( (::StdMeshers_NumberOfSegments::DistrType) typ );
 
     // Update Python script
     this->GetImpl()->SetDistrType( (::StdMeshers_NumberOfSegments::DistrType) typ );
 
     // Update Python script
-    SMESH::TPythonDump() << _this() << ".SetDistrType( " << typ << " )";
+    if ( oldType != typ )
+      SMESH::TPythonDump() << _this() << ".SetDistrType( " << typ << " )";
   }
   catch ( SALOME_Exception& S_ex ) {
     THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
   }
   catch ( SALOME_Exception& S_ex ) {
     THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
@@ -397,7 +400,8 @@ void StdMeshers_NumberOfSegments_i::SetExpressionFunction(const char* expr)
     SMESH::TPythonDump() << _this() << ".SetExpressionFunction( '" << expr << "' )";
   }
   catch ( SALOME_Exception& S_ex ) {
     SMESH::TPythonDump() << _this() << ".SetExpressionFunction( '" << expr << "' )";
   }
   catch ( SALOME_Exception& S_ex ) {
-    THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM );
+    THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
+                                  SALOME::BAD_PARAM );
   }
 }
 
   }
 }