Salome HOME
23076: [CEA 1499] Get in python all sub-shapes in error after Compute
[modules/smesh.git] / src / StdMeshers / StdMeshers_Quadrangle_2D.cxx
index af3d51d7652eace82d250b955b1253bf70069160..30c91c4cdf366945808b72e67002e500b2730a92 100644 (file)
@@ -609,7 +609,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh&         aMesh,
       int g = nbhoriz - 1; // last processed node in the regular grid
 
       ilow = 0;
-      iup = nbhoriz - 1;
+      iup  = nbhoriz - 1;
 
       int stop = 0;
       if ( quad->side[3].grid->Edge(0).IsNull() ) // left side is simulated one
@@ -667,7 +667,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh&         aMesh,
       for ( ; i > stop; i--) {
         a = uv_e2[i].node;
         b = uv_e2[i - 1].node;
-        gp_Pnt pb (b->X(), b->Y(), b->Z());
+        gp_Pnt pb = SMESH_TNodeXYZ( b );
 
         // find node c in the grid, which will be linked with node b
         int near = g;
@@ -683,7 +683,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh&         aMesh,
               nk = uv_e1[nbright - 2].node;
             else
               nk = quad->uv_grid[nbhoriz*(nbvertic - 2) + k].node;
-            gp_Pnt pnk (nk->X(), nk->Y(), nk->Z());
+            gp_Pnt pnk = SMESH_TNodeXYZ( nk );
             double dist = pb.Distance(pnk);
             if (dist < mind - eps) {
               c = nk;
@@ -1599,7 +1599,7 @@ void StdMeshers_Quadrangle_2D::shiftQuad(FaceQuadStruct::Ptr& quad, const int nu
 
 //================================================================================
 /*!
- * \brief Rotate sides of a quad by given nb of quartes
+ * \brief Rotate sides of a quad CCW by given nb of quartes
  *  \param nb  - number of rotation quartes
  *  \param ori - to keep orientation of sides as in an unit quad or not
  *  \param keepGrid - if \c true Side::grid is not changed, Side::from and Side::to
@@ -1611,6 +1611,8 @@ void FaceQuadStruct::shift( size_t nb, bool ori, bool keepGrid )
 {
   if ( nb == 0 ) return;
 
+  nb = nb % NB_QUAD_SIDES;
+
   vector< Side > newSides( side.size() );
   vector< Side* > sidePtrs( side.size() );
   for (int i = QUAD_BOTTOM_SIDE; i < NB_QUAD_SIDES; ++i)
@@ -1640,7 +1642,33 @@ void FaceQuadStruct::shift( size_t nb, bool ori, bool keepGrid )
   }
   newSides.swap( side );
 
-  uv_grid.clear();
+  if ( keepGrid && !uv_grid.empty() )
+  {
+    if ( nb == 2 ) // "PI"
+    {
+      std::reverse( uv_grid.begin(), uv_grid.end() );
+    }
+    else
+    {
+      FaceQuadStruct newQuad;
+      newQuad.uv_grid.resize( uv_grid.size() );
+      newQuad.iSize = jSize;
+      newQuad.jSize = iSize;
+      int i, j, iRev, jRev;
+      int *iNew = ( nb == 1 ) ? &jRev : &j;
+      int *jNew = ( nb == 1 ) ? &i : &iRev;
+      for ( i = 0, iRev = iSize-1; i < iSize; ++i, --iRev )
+        for ( j = 0, jRev = jSize-1; j < jSize; ++j, --jRev )
+          newQuad.UVPt( *iNew, *jNew ) = UVPt( i, j );
+
+      std::swap( iSize, jSize );
+      std::swap( uv_grid, newQuad.uv_grid );
+    }
+  }
+  else
+  {
+    uv_grid.clear();
+  }
 }
 
 //=======================================================================
@@ -4199,10 +4227,11 @@ int StdMeshers_Quadrangle_2D::getCorners(const TopoDS_Face&          theFace,
   theNbDegenEdges = 0;
 
   SMESH_MesherHelper helper( theMesh );
+  StdMeshers_FaceSide faceSide( theFace, theWire, &theMesh, /*isFwd=*/true, /*skipMedium=*/true);
 
   // sort theVertices by angle
   multimap<double, TopoDS_Vertex> vertexByAngle;
-  TopTools_DataMapOfShapeReal angleByVertex;
+  TopTools_DataMapOfShapeReal     angleByVertex;
   TopoDS_Edge prevE = theWire.back();
   if ( SMESH_Algo::isDegenerated( prevE ))
   {
@@ -4214,17 +4243,17 @@ int StdMeshers_Quadrangle_2D::getCorners(const TopoDS_Face&          theFace,
     prevE = *edge;
   }
   list<TopoDS_Edge>::iterator edge = theWire.begin();
-  for ( ; edge != theWire.end(); ++edge )
+  for ( int iE = 0; edge != theWire.end(); ++edge, ++iE )
   {
     if ( SMESH_Algo::isDegenerated( *edge ))
     {
       ++theNbDegenEdges;
       continue;
     }
-    TopoDS_Vertex v = helper.IthVertex( 0, *edge );
-    if ( !theConsiderMesh || SMESH_Algo::VertexNode( v, helper.GetMeshDS() ))
+    if ( !theConsiderMesh || faceSide.VertexNode( iE ))
     {
-      double angle = SMESH_MesherHelper::GetAngle( prevE, *edge, theFace, v );
+      TopoDS_Vertex v = helper.IthVertex( 0, *edge );
+      double    angle = SMESH_MesherHelper::GetAngle( prevE, *edge, theFace, v );
       vertexByAngle.insert( make_pair( angle, v ));
       angleByVertex.Bind( v, angle );
     }
@@ -4243,6 +4272,14 @@ int StdMeshers_Quadrangle_2D::getCorners(const TopoDS_Face&          theFace,
     triaVertex.Nullify();
 
   // check nb of available corners
+  if ( faceSide.NbEdges() < nbCorners )
+    return error(COMPERR_BAD_SHAPE,
+                 TComm("Face must have 4 sides but not ") << faceSide.NbEdges() );
+
+  const int nbSegments = Max( faceSide.NbPoints()-1, faceSide.NbSegments() );
+  if ( nbSegments < nbCorners )
+    return error(COMPERR_BAD_INPUT_MESH, TComm("Too few boundary nodes: ") << nbSegments);
+
   if ( nbCorners == 3 )
   {
     if ( vertexByAngle.size() < 3 )