Salome HOME
0020222: Quandrangle_2D meshing fail
authoreap <eap@opencascade.com>
Thu, 19 Mar 2009 07:14:16 +0000 (07:14 +0000)
committereap <eap@opencascade.com>
Thu, 19 Mar 2009 07:14:16 +0000 (07:14 +0000)
     unite only edges shared by two same faces

src/StdMeshers/StdMeshers_Quadrangle_2D.cxx

index 3a137b109cf2947d97a4c2c0d1b81fdb7d1010c7..acc8731860dbd6c0bf234d181f7b366565756d42 100644 (file)
@@ -24,7 +24,6 @@
 //           Moved here from SMESH_Quadrangle_2D.cxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
-//  $Header$
 //
 #include "StdMeshers_Quadrangle_2D.hxx"
 
@@ -42,7 +41,6 @@
 #include "SMDS_EdgePosition.hxx"
 #include "SMDS_FacePosition.hxx"
 
-#include <BRepTools.hxx>
 #include <BRepTools_WireExplorer.hxx>
 #include <BRep_Tool.hxx>
 #include <Geom_Surface.hxx>
@@ -51,6 +49,7 @@
 #include <TColStd_SequenceOfReal.hxx>
 #include <TColgp_SequenceOfXY.hxx>
 #include <TopExp.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
 #include <TopoDS.hxx>
 
 #include "utilities.h"
@@ -588,6 +587,27 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
   return isOk;
 }
 
+//================================================================================
+/*!
+ * \brief Return true if only two given edges meat at their common vertex
+ */
+//================================================================================
+
+static bool twoEdgesMeatAtVertex(const TopoDS_Edge& e1,
+                                 const TopoDS_Edge& e2,
+                                 SMESH_Mesh &       mesh)
+{
+  TopoDS_Vertex v;
+  if ( !TopExp::CommonVertex( e1, e2, v ))
+    return false;
+  TopTools_ListIteratorOfListOfShape ancestIt( mesh.GetAncestors( v ));
+  for ( ; ancestIt.More() ; ancestIt.Next() )
+    if ( ancestIt.Value().ShapeType() == TopAbs_EDGE )
+      if ( !e1.IsSame( ancestIt.Value() ) && !e2.IsSame( ancestIt.Value() ))
+        return false;
+  return true;
+}
+
 //=============================================================================
 /*!
  *  
@@ -644,6 +664,41 @@ FaceQuadStruct* StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh &         aMes
                                                     nbSides<TOP_SIDE, ignoreMediumNodes));
       ++nbSides;
     }
+    // issue 20222. Try to unite only edges shared by two same faces
+    if (nbSides < 4) {
+      // delete found sides
+      { FaceQuadStruct cleaner( *quad ); }
+      quad->side.clear();
+      quad->side.reserve(nbEdgesInWire.front());
+      nbSides = 0;
+
+      SMESH_Block::GetOrderedEdges (F, V, edges, nbEdgesInWire);
+      while ( !edges.empty()) {
+        sideEdges.clear();
+        sideEdges.splice( sideEdges.end(), edges, edges.begin());
+        bool sameSide = true;
+        while ( !edges.empty() && sameSide ) {
+          sameSide =
+            SMESH_Algo::IsContinuous( sideEdges.back(), edges.front() ) &&
+            twoEdgesMeatAtVertex( sideEdges.back(), edges.front(), aMesh );
+          if ( sameSide )
+            sideEdges.splice( sideEdges.end(), edges, edges.begin());
+        }
+        if ( nbSides == 0 ) { // go backward from the first edge
+          sameSide = true;
+          while ( !edges.empty() && sameSide ) {
+            sameSide =
+              SMESH_Algo::IsContinuous( sideEdges.front(), edges.back() ) &&
+              twoEdgesMeatAtVertex( sideEdges.front(), edges.back(), aMesh );
+            if ( sameSide )
+              sideEdges.splice( sideEdges.begin(), edges, --edges.end());
+          }
+        }
+        quad->side.push_back( new StdMeshers_FaceSide(F, sideEdges, &aMesh,
+                                                      nbSides<TOP_SIDE, ignoreMediumNodes));
+        ++nbSides;
+      }
+    }
   }
   if (nbSides != 4) {
 #ifdef _DEBUG_