Salome HOME
0021543: EDF 1978 SMESH: Viscous layer for 2D meshes
[modules/smesh.git] / src / StdMeshers / StdMeshers_Projection_2D.cxx
index cbffd5aac7dd5c607c78dfb6838c71da37a37389..ad6f45e572bdb05ebb40db1b893de3c05d572e1b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -72,8 +72,6 @@ StdMeshers_Projection_2D::StdMeshers_Projection_2D(int hypId, int studyId, SMESH
   :SMESH_2D_Algo(hypId, studyId, gen)
 {
   _name = "Projection_2D";
-  _shapeType = (1 << TopAbs_FACE);      // 1 bit per shape type
-
   _compatibleHypothesis.push_back("ProjectionSource2D");
   _sourceHypo = 0;
 }
@@ -428,7 +426,7 @@ namespace {
           // find corresponding point on target shape
           pOK = false;
           gp_Pnt tgtP;
-          const TopoDS_Shape& tgtShape = shape2ShapeMap( srcSM->GetSubShape() );
+          const TopoDS_Shape& tgtShape = shape2ShapeMap( srcSM->GetSubShape(), /*isSrc=*/true );
           if ( tgtShape.ShapeType() == TopAbs_VERTEX )
           {
             tgtP = BRep_Tool::Pnt( TopoDS::Vertex( tgtShape ));
@@ -480,7 +478,7 @@ namespace {
 
     for ( TopExp_Explorer srcEdge( srcFace, TopAbs_EDGE); srcEdge.More(); srcEdge.Next() )
     {
-      const TopoDS_Shape& tgtEdge = shape2ShapeMap( srcEdge.Current() );
+      const TopoDS_Shape& tgtEdge = shape2ShapeMap( srcEdge.Current(), /*isSrc=*/true );
 
       map< double, const SMDS_MeshNode* > srcNodes, tgtNodes;
       if ( !SMESH_Algo::GetSortedNodesOnEdge( srcMesh->GetMeshDS(),
@@ -611,7 +609,7 @@ namespace {
       TopTools_IndexedMapOfShape edgeMap; // to detect seam edges
       for ( int iE = 0; iE < srcWire->NbEdges(); ++iE )
       {
-        tgtEdges.push_back( TopoDS::Edge( shape2ShapeMap( srcWire->Edge( iE ))));
+        tgtEdges.push_back( TopoDS::Edge( shape2ShapeMap( srcWire->Edge( iE ), /*isSrc=*/true)));
         // reverse a seam edge encountered for the second time
         const int oldExtent = edgeMap.Extent();
         edgeMap.Add( tgtEdges.back() );
@@ -734,14 +732,16 @@ namespace {
           }
           case SMDS_TOP_EDGE: {
             TopoDS_Shape srcEdge = srcHelper.GetSubShapeByNode( srcNode, srcHelper.GetMeshDS() );
-            TopoDS_Shape tgtEdge = shape2ShapeMap( srcEdge );
+            TopoDS_Edge  tgtEdge = TopoDS::Edge( shape2ShapeMap( srcEdge, /*isSrc=*/true ));
+            tgtMeshDS->SetNodeOnEdge( n, TopoDS::Edge( tgtEdge ));
             double U = srcHelper.GetNodeU( TopoDS::Edge( srcEdge ), srcNode );
-            tgtMeshDS->SetNodeOnEdge( n, TopoDS::Edge( tgtEdge ), U);
+            helper.CheckNodeU( tgtEdge, n, U, Precision::PConfusion());
+            n->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition( U )));
             break;
           }
           case SMDS_TOP_VERTEX: {
             TopoDS_Shape srcV = srcHelper.GetSubShapeByNode( srcNode, srcHelper.GetMeshDS() );
-            TopoDS_Shape tgtV = shape2ShapeMap( srcV );
+            TopoDS_Shape tgtV = shape2ShapeMap( srcV, /*isSrc=*/true );
             tgtMeshDS->SetNodeOnVertex( n, TopoDS::Vertex( tgtV ));
             break;
           }
@@ -790,12 +790,22 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
   TopoDS_Shape srcShape = _sourceHypo->GetSourceFace().Oriented(TopAbs_FORWARD);
 
   TAssocTool::TShapeShapeMap shape2ShapeMap;
-  TAssocTool::InitVertexAssociation( _sourceHypo, shape2ShapeMap, tgtFace );
+  TAssocTool::InitVertexAssociation( _sourceHypo, shape2ShapeMap );
   if ( !TAssocTool::FindSubShapeAssociation( tgtFace, tgtMesh, srcShape, srcMesh,
                                              shape2ShapeMap)  ||
        !shape2ShapeMap.IsBound( tgtFace ))
+  {
+    if ( srcShape.ShapeType() == TopAbs_FACE )
+    {
+      int nbE1 = TAssocTool::Count( tgtFace, TopAbs_EDGE, /*ignoreSame=*/true );
+      int nbE2 = TAssocTool::Count( srcShape, TopAbs_EDGE, /*ignoreSame=*/true );
+      if ( nbE1 != nbE2 )
+        return error(COMPERR_BAD_SHAPE,
+                     SMESH_Comment("Different number of edges in source and target faces: ")
+                     << nbE2 << " and " << nbE1 );
+    }
     return error(COMPERR_BAD_SHAPE,"Topology of source and target faces seems different" );
-
+  }
   TopoDS_Face srcFace = TopoDS::Face( shape2ShapeMap( tgtFace ).Oriented(TopAbs_FORWARD));
 
   // ----------------------------------------------
@@ -806,7 +816,7 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
   SMESH_subMesh* tgtSubMesh = tgtMesh->GetSubMesh( tgtFace );
 
   if ( tgtMesh == srcMesh ) {
-    if ( !TAssocTool::MakeComputed( srcSubMesh ))
+    if ( !TAssocTool::MakeComputed( srcSubMesh ) || !srcSubMesh->IsMeshComputed() )
       return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed");
   }
   else {
@@ -881,9 +891,9 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
     TopoDS_Vertex srcV1 = TopoDS::Vertex( mapper.GetSubShape( 1 ));
     if ( srcV1.IsNull() )
       RETURN_BAD_RESULT("Mesh is not bound to the face");
-    if ( !shape2ShapeMap.IsBound( srcV1 ))
+    if ( !shape2ShapeMap.IsBound( srcV1, /*isSrc=*/true ))
       RETURN_BAD_RESULT("Not associated vertices, srcV1 " << srcV1.TShape().operator->() );
-    TopoDS_Vertex tgtV1 = TopoDS::Vertex( shape2ShapeMap( srcV1 ));
+    TopoDS_Vertex tgtV1 = TopoDS::Vertex( shape2ShapeMap( srcV1, /*isSrc=*/true ));
 
     if ( !SMESH_MesherHelper::IsSubShape( srcV1, srcFace ))
       RETURN_BAD_RESULT("Wrong srcV1 " << srcV1.TShape().operator->());
@@ -948,7 +958,7 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
     {
       SMESH_subMesh*     sm = smIt->next();
       SMESHDS_SubMesh* smDS = sm->GetSubMeshDS();
-      if ( smDS->NbNodes() == 0 )
+      if ( !smDS || smDS->NbNodes() == 0 )
         continue;
       //if ( !is1DComputed && sm->GetSubShape().ShapeType() == TopAbs_EDGE )
       //break;
@@ -1005,24 +1015,18 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
         ( u2nodesMaps[ NEW_NODES ].size() == u2nodesOnSeam.size() );
 
       if ( !mergeNewToOld )
-      {
-        // if ( u2nodesMaps[ NEW_NODES ].size() == 0         &&
-        //      sm->GetSubShape().ShapeType() == TopAbs_EDGE &&
-        //      helper.IsDegenShape( sm->GetId() )             )
-        //   // NPAL15894 (tt88bis.py) - project mesh built by NETGEN_1d_2D that
-        //   // does not make segments/nodes on degenerated edges
-        //   continue;
-
-        // if ( u2nodesMaps[ OLD_NODES ].size() == 0           &&
-        //      sm->GetSubShape().ShapeType() == TopAbs_VERTEX )
-        //   // old nodes are optional on vertices in the case of 1D-2D projection
-        //   continue;
-
-        //RETURN_BAD_RESULT
-        MESSAGE("Different nb of old and new nodes on shape #"<< sm->GetId() <<" "<<
-                u2nodesMaps[ OLD_NODES ].size() << " != " <<
-                u2nodesMaps[ NEW_NODES ].size());
-      }
+        if ( u2nodesMaps[ NEW_NODES ].size() > 0 &&
+             u2nodesMaps[ OLD_NODES ].size() > 0 )
+        {
+          u_oldNode = u2nodesMaps[ OLD_NODES ].begin(); 
+          newEnd    = u2nodesMaps[ OLD_NODES ].end();
+          for ( ; u_oldNode != newEnd; ++u_oldNode )
+            _badInputElements.push_back( u_oldNode->second );
+          return error( COMPERR_BAD_INPUT_MESH,
+                        SMESH_Comment( "Existing mesh mismatches the projected 2D mesh on " )
+                        << ( sm->GetSubShape().ShapeType() == TopAbs_EDGE ? "edge" : "vertex" )
+                        << " #" << sm->GetId() );
+        }
       if ( isSeam && !mergeSeamToNew ) {
         //RETURN_BAD_RESULT
         MESSAGE("Different nb of old and seam nodes " <<
@@ -1087,7 +1091,7 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
   // Check elements orientation
   // ---------------------------
 
-  TopoDS_Face face = tgtFace;
+  TopoDS_Face face = TopoDS::Face( theShape );
   if ( !theMesh.IsMainShape( tgtFace ))
   {
     // find the main shape
@@ -1157,7 +1161,7 @@ bool StdMeshers_Projection_2D::Evaluate(SMESH_Mesh&         theMesh,
   TopoDS_Shape srcShape = _sourceHypo->GetSourceFace().Oriented(TopAbs_FORWARD);
 
   TAssocTool::TShapeShapeMap shape2ShapeMap;
-  TAssocTool::InitVertexAssociation( _sourceHypo, shape2ShapeMap, tgtFace );
+  TAssocTool::InitVertexAssociation( _sourceHypo, shape2ShapeMap );
   if ( !TAssocTool::FindSubShapeAssociation( tgtFace, tgtMesh, srcShape, srcMesh,
                                              shape2ShapeMap)  ||
        !shape2ShapeMap.IsBound( tgtFace ))