Salome HOME
22806: EDF SMESH: Regression: Prism_3D error
[modules/smesh.git] / src / SMESH / SMESH_MesherHelper.cxx
index 4449efbce31db19f2ce544689a35d68281427b22..329c17e62402040814231a790de0a462215c5bc5 100644 (file)
@@ -254,25 +254,49 @@ void SMESH_MesherHelper::SetSubShape(const TopoDS_Shape& aSh)
       myPar2[1] = surf.LastVParameter();
     }
 
+    gp_Pnt2d uv1, uv2;
     for (TopExp_Explorer exp( face, TopAbs_EDGE ); exp.More(); exp.Next())
     {
-      // look for a "seam" edge, actually an edge on period boundary
-      const TopoDS_Edge& edge = TopoDS::Edge( exp.Current() );
+      // look for a "seam" edge, a real seam or an edge on period boundary
+      TopoDS_Edge edge = TopoDS::Edge( exp.Current() );
       if ( myParIndex )
       {
+        BRep_Tool::UVPoints( edge, face, uv1, uv2 );
+        const double du = Abs( uv1.Coord(1) - uv2.Coord(1) );
+        const double dv = Abs( uv1.Coord(2) - uv2.Coord(2) );
+
         bool isSeam = BRep_Tool::IsClosed( edge, face );
-        if ( !isSeam )
+        if ( isSeam ) // real seam - having two pcurves on face
+        {
+          // pcurve can lie not on pediod boundary (22582, mesh_Quadratic_01/C9)
+          if ( du < dv )
+          {
+            double u1 = uv1.Coord(1);
+            edge.Reverse();
+            BRep_Tool::UVPoints( edge, face, uv1, uv2 );
+            double u2 = uv1.Coord(1);
+            myPar1[0] = Min( u1, u2 );
+            myPar2[0] = Max( u1, u2 );
+          }
+          else
+          {
+            double v1 = uv1.Coord(2);
+            edge.Reverse();
+            BRep_Tool::UVPoints( edge, face, uv1, uv2 );
+            double v2 = uv1.Coord(2);
+            myPar1[1] = Min( v1, v2 );
+            myPar2[1] = Max( v1, v2 );
+          }
+        }
+        else //if ( !isSeam )
         {
-          gp_Pnt2d uv1, uv2;
-          BRep_Tool::UVPoints( edge, face, uv1, uv2 );
-          const double du = Abs( uv1.Coord(1) - uv2.Coord(1) );
-          const double dv = Abs( uv1.Coord(2) - uv2.Coord(2) );
-          if      ( du < Precision::PConfusion() )
+          // one pcurve but on period boundary (22772, mesh_Quadratic_01/D1)
+          if      (( myParIndex & U_periodic ) && du < Precision::PConfusion() )
           {
             isSeam = ( Abs( uv1.Coord(1) - myPar1[0] ) < Precision::PConfusion() ||
                        Abs( uv1.Coord(1) - myPar2[0] ) < Precision::PConfusion() );
           }
-          else if ( dv < Precision::PConfusion() )
+          else if (( myParIndex & V_periodic ) && dv < Precision::PConfusion() )
           {
             isSeam = ( Abs( uv1.Coord(2) - myPar1[1] ) < Precision::PConfusion() ||
                        Abs( uv1.Coord(2) - myPar2[1] ) < Precision::PConfusion() );
@@ -917,7 +941,7 @@ bool SMESH_MesherHelper::CheckNodeU(const TopoDS_Edge&   E,
   int  shapeID = n->getshapeId();
   bool infinit = Precision::IsInfinite( u );
   bool zero    = ( u == 0. );
-  if ( force || toCheckPosOnShape( shapeID ) || infinit || zero )
+  if ( force || infinit || zero || toCheckPosOnShape( shapeID ))
   {
     TopLoc_Location loc; double f,l;
     Handle(Geom_Curve) curve = BRep_Tool::Curve( E,loc,f,l );
@@ -934,7 +958,7 @@ bool SMESH_MesherHelper::CheckNodeU(const TopoDS_Edge&   E,
       gp_Pnt nodePnt = SMESH_TNodeXYZ( n );
       if ( !loc.IsIdentity() ) nodePnt.Transform( loc.Transformation().Inverted() );
       gp_Pnt curvPnt;
-      double dist = u;
+      double dist = 2*tol;
       if ( !infinit )
       {
         curvPnt = curve->Value( u );
@@ -2440,7 +2464,7 @@ namespace
 
 //=======================================================================
 //function : IsStructured
-//purpose  : Return true if 2D mesh on FACE is structured
+//purpose  : Return true if 2D mesh on FACE is a structured rectangle
 //=======================================================================
 
 bool SMESH_MesherHelper::IsStructured( SMESH_subMesh* faceSM )
@@ -2535,7 +2559,8 @@ bool SMESH_MesherHelper::IsStructured( SMESH_subMesh* faceSM )
 //purpose  : Return true if 2D mesh on FACE is ditorted
 //=======================================================================
 
-bool SMESH_MesherHelper::IsDistorted2D( SMESH_subMesh* faceSM )
+bool SMESH_MesherHelper::IsDistorted2D( SMESH_subMesh* faceSM,
+                                        bool           checkUV)
 {
   if ( !faceSM || faceSM->GetSubShape().ShapeType() != TopAbs_FACE )
     return false;
@@ -2553,6 +2578,7 @@ bool SMESH_MesherHelper::IsDistorted2D( SMESH_subMesh* faceSM )
   double prevArea2D = 0;
   vector< const SMDS_MeshNode* > nodes;
   vector< gp_XY >                uv;
+  bool* toCheckUV = checkUV ? & checkUV : 0;
   while ( faceIt->more() && !haveBadFaces )
   {
     const SMDS_MeshElement* face = faceIt->next();
@@ -2574,15 +2600,17 @@ bool SMESH_MesherHelper::IsDistorted2D( SMESH_subMesh* faceSM )
     }
     // prepare to getting UVs
     const SMDS_MeshNode* inFaceNode = 0;
-    if ( helper.HasSeam() )
+    if ( helper.HasSeam() ) {
       for ( size_t i = 0; ( i < nodes.size() && !inFaceNode ); ++i )
         if ( !helper.IsSeamShape( nodes[ i ]->getshapeId() ))
           inFaceNode = nodes[ i ];
-
+      if ( !inFaceNode )
+        continue;
+    }
     // get UVs
     uv.resize( nodes.size() );
     for ( size_t i = 0; i < nodes.size(); ++i )
-      uv[ i ] = helper.GetNodeUV( F, nodes[ i ], inFaceNode );
+      uv[ i ] = helper.GetNodeUV( F, nodes[ i ], inFaceNode, toCheckUV );
 
     // compare orientation of triangles
     for ( int iT = 0, nbT = nodes.size()-2; iT < nbT; ++iT )
@@ -2778,6 +2806,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