Salome HOME
0020809: [CEA 400] ParaMEDSPLITTER failure on blade.med
authoreap <eap@opencascade.com>
Wed, 19 May 2010 09:38:12 +0000 (09:38 +0000)
committereap <eap@opencascade.com>
Wed, 19 May 2010 09:38:12 +0000 (09:38 +0000)
 * Fix SMESH_MesherHelper::GetNodeU() for a node on vertex of a closed geom edge

   double GetNodeU(const TopoDS_Edge&   theEdge,
                   const SMDS_MeshNode* theNode,
+                  const SMDS_MeshNode* inEdgeNode=0,
                   bool*                check=0);

src/SMESH/SMESH_MesherHelper.cxx
src/SMESH/SMESH_MesherHelper.hxx
src/StdMeshers/StdMeshers_FaceSide.cxx

index 13b06a3965960dc8f883e8f0f3f48ab8f360bca5..ac0de4e39d935f1b8ac8cd6d66f89c1db9065947 100644 (file)
@@ -597,20 +597,33 @@ gp_XY SMESH_MesherHelper::GetMiddleUV(const Handle(Geom_Surface)& surface,
 
 double SMESH_MesherHelper::GetNodeU(const TopoDS_Edge&   E,
                                     const SMDS_MeshNode* n,
+                                    const SMDS_MeshNode* inEdgeNode,
                                     bool*                check)
 {
   double param = 0;
   const SMDS_PositionPtr Pos = n->GetPosition();
-  if(Pos->GetTypeOfPosition()==SMDS_TOP_EDGE) {
+  if ( Pos->GetTypeOfPosition()==SMDS_TOP_EDGE )
+  {
     const SMDS_EdgePosition* epos =
       static_cast<const SMDS_EdgePosition*>(n->GetPosition().get());
     param =  epos->GetUParameter();
   }
-  else if(Pos->GetTypeOfPosition()==SMDS_TOP_VERTEX) {
-    SMESHDS_Mesh * meshDS = GetMeshDS();
-    int vertexID = n->GetPosition()->GetShapeId();
-    const TopoDS_Vertex& V = TopoDS::Vertex(meshDS->IndexToShape(vertexID));
-    param =  BRep_Tool::Parameter( V, E );
+  else if( Pos->GetTypeOfPosition() == SMDS_TOP_VERTEX )
+  {
+    if ( inEdgeNode && TopExp::FirstVertex( E ).IsSame( TopExp::LastVertex( E ))) // issue 0020809
+    {
+      Standard_Real f,l;
+      BRep_Tool::Range( E, f,l );
+      double uInEdge = GetNodeU( E, inEdgeNode );
+      param = ( fabs( uInEdge - f ) < fabs( l - uInEdge )) ? f : l;
+    }
+    else
+    {
+      SMESHDS_Mesh * meshDS = GetMeshDS();
+      int vertexID = n->GetPosition()->GetShapeId();
+      const TopoDS_Vertex& V = TopoDS::Vertex(meshDS->IndexToShape(vertexID));
+      param =  BRep_Tool::Parameter( V, E );
+    }
   }
   if ( check )
     *check = CheckNodeU( E, n, param, BRep_Tool::Tolerance( E ));
@@ -739,8 +752,8 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetMediumNode(const SMDS_MeshNode* n1,
       E = TopoDS::Edge(myShape);
       edgeID = myShapeID;
     }
-    u[0] = GetNodeU(E,n1, force3d ? 0 : &uvOK[0]);
-    u[1] = GetNodeU(E,n2, force3d ? 0 : &uvOK[1]);
+    u[0] = GetNodeU(E,n1,n2, force3d ? 0 : &uvOK[0]);
+    u[1] = GetNodeU(E,n2,n1, force3d ? 0 : &uvOK[1]);
   }
   if(!force3d)
   {
index f26ed4f6f2a55eaa04cc4f005a51242dbc882694..3fece8a8264aabfc4289f8873b54ccc6d3d3e74f 100644 (file)
@@ -269,6 +269,7 @@ public:
    */
   double GetNodeU(const TopoDS_Edge&   theEdge,
                   const SMDS_MeshNode* theNode,
+                  const SMDS_MeshNode* inEdgeNode=0,
                   bool*                check=0);
   /*!
    * \brief Return node UV on face
index c0cef600d0d97a5eb6b05dcc61fc3ba5223ee4a0..19859a2b3c283f67aeb4d5a80b9adf8172491750 100644 (file)
@@ -270,7 +270,7 @@ const vector<UVPtStruct>& StdMeshers_FaceSide::GetUVPtStruct(bool   isXConst,
           const SMDS_MeshNode* node = nItr->next();
           if ( myIgnoreMediumNodes && SMESH_MeshEditor::IsMedium( node, SMDSAbs_Edge ))
             continue;
-          double u = helper.GetNodeU( myEdge[i], node, &paramOK );
+          double u = helper.GetNodeU( myEdge[i], node, 0, &paramOK );
           double aLenU = GCPnts_AbscissaPoint::Length
             ( const_cast<GeomAdaptor_Curve&>( myC3dAdaptor[i]), myFirst[i], u );
           if ( myEdgeLength[i] < aLenU ) // nonregression test "3D_mesh_NETGEN/G6"
@@ -288,7 +288,7 @@ const vector<UVPtStruct>& StdMeshers_FaceSide::GetUVPtStruct(bool   isXConst,
           const SMDS_MeshNode* node = nItr->next();
           if ( myIgnoreMediumNodes && SMESH_MeshEditor::IsMedium( node, SMDSAbs_Edge ))
             continue;
-          double u = helper.GetNodeU( myEdge[i], node, &paramOK );
+          double u = helper.GetNodeU( myEdge[i], node, 0, &paramOK );
 
           // paramSize is signed so orientation is taken into account
           double normPar = prevNormPar + r * ( u - myFirst[i] ) / paramSize;