Salome HOME
Fix typos by Kunda
[modules/smesh.git] / src / StdMeshers / StdMeshers_Projection_2D.cxx
index eeb20f00981b187845326a9f89555d493339c052..4ef3b3f671d6ed10964de5512a9f23231ff6bfe3 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2020  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
@@ -20,7 +20,7 @@
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
-//  SMESH SMESH : implementaion of SMESH idl descriptions
+//  SMESH SMESH : implementation of SMESH idl descriptions
 // File      : StdMeshers_Projection_2D.cxx
 // Module    : SMESH
 // Created   : Fri Oct 20 11:37:07 2006
@@ -42,6 +42,7 @@
 #include "SMESH_Gen.hxx"
 #include "SMESH_Mesh.hxx"
 #include "SMESH_MeshAlgos.hxx"
+#include "SMESH_MeshEditor.hxx"
 #include "SMESH_MesherHelper.hxx"
 #include "SMESH_Pattern.hxx"
 #include "SMESH_subMesh.hxx"
@@ -85,8 +86,8 @@ namespace TAssocTool = StdMeshers_ProjectionUtils;
 //purpose  : 
 //=======================================================================
 
-StdMeshers_Projection_2D::StdMeshers_Projection_2D(int hypId, int studyId, SMESH_Gen* gen)
-  :SMESH_2D_Algo(hypId, studyId, gen)
+StdMeshers_Projection_2D::StdMeshers_Projection_2D(int hypId, SMESH_Gen* gen)
+  :SMESH_2D_Algo(hypId, gen)
 {
   _name = "Projection_2D";
   _compatibleHypothesis.push_back("ProjectionSource2D");
@@ -277,7 +278,7 @@ namespace {
   //================================================================================
 
   bool getBoundaryNodes ( SMESH_subMesh*                        sm,
-                          const TopoDS_Face&                    face,
+                          const TopoDS_Face&                    /*face*/,
                           map< double, const SMDS_MeshNode* > & u2nodes,
                           set< const SMDS_MeshNode* > &         seamNodes)
   {
@@ -371,8 +372,7 @@ namespace {
         if ( node->GetPosition()->GetTypeOfPosition() != SMDS_TOP_EDGE )
           RETURN_BAD_RESULT("Bad node position type: node " << node->GetID() <<
                             " pos type " << node->GetPosition()->GetTypeOfPosition());
-        const SMDS_EdgePosition* pos =
-          static_cast<const SMDS_EdgePosition*>(node->GetPosition());
+        SMDS_EdgePositionPtr pos = node->GetPosition();
         u2nodes.insert( make_pair( pos->GetUParameter(), node ));
         seamNodes.insert( node );
       }
@@ -975,13 +975,13 @@ namespace {
    */
   //================================================================================
 
-  bool projectQuads(const TopoDS_Face&                 tgtFace,
-                    const TopoDS_Face&                 srcFace,
-                    const TSideVector&                 tgtWires,
-                    const TSideVector&                 srcWires,
-                    const TAssocTool::TShapeShapeMap&  shape2ShapeMap,
-                    TAssocTool::TNodeNodeMap&          src2tgtNodes,
-                    const bool                         is1DComputed)
+  bool projectQuads(const TopoDS_Face&                 /*tgtFace*/,
+                    const TopoDS_Face&                 /*srcFace*/,
+                    const TSideVector&                 /*tgtWires*/,
+                    const TSideVector&                 /*srcWires*/,
+                    const TAssocTool::TShapeShapeMap&  /*shape2ShapeMap*/,
+                    TAssocTool::TNodeNodeMap&          /*src2tgtNodes*/,
+                    const bool                         /*is1DComputed*/)
   {
     // SMESH_Mesh * tgtMesh = tgtWires[0]->GetMesh();
     // SMESH_Mesh * srcMesh = srcWires[0]->GetMesh();
@@ -1133,7 +1133,7 @@ namespace {
   {
     SMESH_subMesh* faceSM = helper.GetMesh()->GetSubMesh( helper.GetSubShape() );
 
-    if ( helper.IsDistorted2D( faceSM, /*checkUV=*/true ))
+    //if ( helper.IsDistorted2D( faceSM, /*checkUV=*/true ))
     {
       SMESH_MeshEditor editor( helper.GetMesh() );
       SMESHDS_SubMesh* smDS = faceSM->GetSubMeshDS();
@@ -1179,240 +1179,6 @@ namespace {
     return true;
   }
 
-  typedef list< pair< const SMDS_MeshNode*, const BRepMesh_Triangle* > > TNodeTriaList;
-
-  //================================================================================
-  /*!
-   * \brief Add in-FACE nodes surrounding a given node to a queue
-   */
-  //================================================================================
-
-  void addCloseNodes( const SMDS_MeshNode*     srcNode,
-                      const BRepMesh_Triangle* bmTria,
-                      const int                srcFaceID,
-                      TNodeTriaList &          noTriQueue )
-  {
-    // find in-FACE nodes
-    SMDS_ElemIteratorPtr elems = srcNode->GetInverseElementIterator(SMDSAbs_Face);
-    while ( elems->more() )
-    {
-      const SMDS_MeshElement* elem = elems->next();
-      if ( elem->getshapeId() == srcFaceID )
-      {
-        for ( int i = 0, nb = elem->NbNodes(); i < nb; ++i )
-        {
-          const SMDS_MeshNode* n = elem->GetNode( i );
-          if ( !n->isMarked() )
-            noTriQueue.push_back( make_pair( n, bmTria ));
-        }
-      }
-    }
-  }
-
-  //================================================================================
-  /*!
-   * \brief Find a delauney triangle containing a given 2D point and return
-   *        barycentric coordinates within the found triangle
-   */
-  //================================================================================
-
-  const BRepMesh_Triangle* findTriangle( const gp_XY&                            uv,
-                                         const BRepMesh_Triangle*                bmTria,
-                                         Handle(BRepMesh_DataStructureOfDelaun)& triaDS,
-                                         double                                  bc[3] )
-  {
-    int   nodeIDs[3];
-    gp_XY nodeUVs[3];
-    int   linkIDs[3];
-    Standard_Boolean ori[3];
-
-    while ( bmTria )
-    {
-      // check bmTria
-
-      triaDS->ElementNodes( *bmTria, nodeIDs );
-      nodeUVs[0] = triaDS->GetNode( nodeIDs[0] ).Coord();
-      nodeUVs[1] = triaDS->GetNode( nodeIDs[1] ).Coord();
-      nodeUVs[2] = triaDS->GetNode( nodeIDs[2] ).Coord();
-
-      SMESH_MeshAlgos::GetBarycentricCoords( uv,
-                                             nodeUVs[0], nodeUVs[1], nodeUVs[2],
-                                             bc[0], bc[1] );
-      if ( bc[0] >= 0 && bc[1] >= 0 && bc[0] + bc[1] <= 1 )
-      {
-        bc[2] = 1 - bc[0] - bc[1];
-        return bmTria;
-      }
-
-      // look for a neighbor triangle, which is adjacent to a link intersected
-      // by a segment( triangle center -> uv )
-
-      gp_XY gc = ( nodeUVs[0] + nodeUVs[1] + nodeUVs[2] ) / 3.;
-      gp_XY seg = uv - gc;
-
-      bmTria->Edges( linkIDs, ori );
-      int triaID = triaDS->IndexOf( *bmTria );
-      bmTria = 0;
-
-      for ( int i = 0; i < 3; ++i )
-      {
-        const BRepMesh_PairOfIndex & triIDs = triaDS->ElementsConnectedTo( linkIDs[i] );
-        if ( triIDs.Extent() < 2 )
-          continue; // no neighbor triangle
-
-        // check if a link intersects gc2uv
-        const BRepMesh_Edge & link = triaDS->GetLink( linkIDs[i] );
-        const BRepMesh_Vertex & n1 = triaDS->GetNode( link.FirstNode() );
-        const BRepMesh_Vertex & n2 = triaDS->GetNode( link.LastNode() );
-        gp_XY uv1 = n1.Coord();
-        gp_XY lin = n2.Coord() - uv1; // link direction
-
-        double crossSegLin = seg ^ lin;
-        if ( Abs( crossSegLin ) < std::numeric_limits<double>::min() )
-          continue; // parallel
-
-        double uSeg = ( uv1 - gc ) ^ lin / crossSegLin;
-        if ( 0. <= uSeg && uSeg <= 1. )
-        {
-          bmTria = & triaDS->GetElement( triIDs.Index( 1 + ( triIDs.Index(1) == triaID )));
-          break;
-        }
-      }
-    }
-    return bmTria;
-  }
-
-  //================================================================================
-  /*!
-   * \brief Morph mesh on the target face to lie within FACE boundary w/o distortion
-   *
-   * algo:
-   * - make a CDT on the src FACE
-   * - find a triangle containing a src node and get its barycentric coordinates
-   * - move the node to a point with the same barycentric coordinates in a corresponding
-   *   tgt triangle
-   */
-  //================================================================================
-
-  bool morph( SMESH_MesherHelper&             tgtHelper,
-              const TopoDS_Face&              tgtFace,
-              const TopoDS_Face&              srcFace,
-              const TSideVector&              tgtWires,
-              const TSideVector&              srcWires,
-              const TAssocTool::TNodeNodeMap& src2tgtNodes )
-  {
-    if ( srcWires.size() != tgtWires.size() ) return false;
-    if ( srcWires.size() == 1 ) return false; // tmp
-
-    // count boundary points
-    int iP = 1, nbP = 0;
-    for ( size_t iW = 0; iW < srcWires.size(); ++iW )
-      nbP += srcWires[iW]->NbPoints() - 1; // 1st and last points coincide
-
-    // fill boundary points
-    BRepMesh::Array1OfVertexOfDelaun srcVert( 1, 1 + nbP ), tgtVert( 1, 1 + nbP );
-    vector< const SMDS_MeshNode* > bndSrcNodes( nbP + 1 ); bndSrcNodes[0] = 0;
-    BRepMesh_Vertex v( 0, 0, BRepMesh_Frontier );
-    for ( size_t iW = 0; iW < srcWires.size(); ++iW )
-    {
-      const UVPtStructVec& srcPnt = srcWires[iW]->GetUVPtStruct();
-      const UVPtStructVec& tgtPnt = tgtWires[iW]->GetUVPtStruct();
-      if ( srcPnt.size() != tgtPnt.size() ) return false;
-
-      for ( int i = 0, nb = srcPnt.size() - 1;  i < nb;  ++i, ++iP )
-      {
-        bndSrcNodes[ iP ]  = srcPnt[i].node;
-        srcPnt[i].node->setIsMarked( true );
-
-        v.ChangeCoord() = srcPnt[i].UV();
-        srcVert( iP )   = v;
-        v.ChangeCoord() = tgtPnt[i].UV();
-        tgtVert( iP )   = v;
-      }
-    }
-    // triangulate the srcFace in 2D
-    BRepMesh_Delaun delauney( srcVert );
-    Handle(BRepMesh_DataStructureOfDelaun) triaDS = delauney.Result();
-
-    Handle(ShapeAnalysis_Surface) tgtSurface = tgtHelper.GetSurface( tgtFace );
-    SMESHDS_Mesh* srcMesh = srcWires[0]->GetMesh()->GetMeshDS();
-    SMESHDS_Mesh* tgtMesh = tgtHelper.GetMeshDS();
-    const SMDS_MeshNode *srcNode, *tgtNode;
-    const BRepMesh_Triangle *bmTria;
-
-    // un-mark internal src nodes; later we will mark moved nodes
-    SMDS_NodeIteratorPtr nIt = srcMesh->MeshElements( srcFace )->GetNodes();
-    if ( !nIt || !nIt->more() ) return true;
-    while ( nIt->more() )
-      ( srcNode = nIt->next() )->setIsMarked( false );
-
-    // initialize a queue of nodes with starting triangles
-    const int srcFaceID = srcNode->getshapeId();
-    TNodeTriaList noTriQueue;
-    size_t iBndSrcN = 1;
-    for ( ; iBndSrcN < bndSrcNodes.size() &&  noTriQueue.empty();  ++iBndSrcN )
-    {
-      // get a triangle
-      const BRepMesh::ListOfInteger & linkIds = triaDS->LinksConnectedTo( iBndSrcN );
-      const BRepMesh_PairOfIndex &    triaIds = triaDS->ElementsConnectedTo( linkIds.First() );
-      const BRepMesh_Triangle&           tria = triaDS->GetElement( triaIds.Index(1) );
-
-      addCloseNodes( bndSrcNodes[ iBndSrcN ], &tria, srcFaceID, noTriQueue );
-    }
-
-    // Move tgt nodes
-
-    double bc[3]; // barycentric coordinates
-    int    nodeIDs[3];
-    bool   checkUV = true;
-    const SMDS_FacePosition* pos;
-
-    while ( !noTriQueue.empty() )
-    {
-      srcNode = noTriQueue.front().first;
-      bmTria  = noTriQueue.front().second;
-      noTriQueue.pop_front();
-      if ( srcNode->isMarked() )
-        continue;
-      srcNode->setIsMarked( true );
-
-      // find a delauney triangle containing the src node
-      gp_XY uv = tgtHelper.GetNodeUV( srcFace, srcNode, NULL, &checkUV );
-      bmTria = findTriangle( uv, bmTria, triaDS, bc );
-      if ( !bmTria )
-        continue;
-
-      // compute new coordinates for a corresponding tgt node
-      gp_XY uvNew( 0., 0. ), nodeUV;
-      triaDS->ElementNodes( *bmTria, nodeIDs );
-      for ( int i = 0; i < 3; ++i )
-        uvNew += bc[i] * tgtVert( nodeIDs[i]).Coord();
-      gp_Pnt xyz = tgtSurface->Value( uvNew );
-
-      // find and move tgt node
-      TAssocTool::TNodeNodeMap::const_iterator n2n = src2tgtNodes.find( srcNode );
-      if ( n2n == src2tgtNodes.end() ) continue;
-      tgtNode = n2n->second;
-      tgtMesh->MoveNode( tgtNode, xyz.X(), xyz.Y(), xyz.Z() );
-
-      if (( pos = dynamic_cast< const SMDS_FacePosition* >( tgtNode->GetPosition() )))
-        const_cast<SMDS_FacePosition*>( pos )->SetParameters( uvNew.X(), uvNew.Y() );
-
-      addCloseNodes( srcNode, bmTria, srcFaceID, noTriQueue );
-
-      // assure that all src nodes are visited
-      for ( ; iBndSrcN < bndSrcNodes.size() &&  noTriQueue.empty();  ++iBndSrcN )
-      {
-        const BRepMesh::ListOfInteger & linkIds = triaDS->LinksConnectedTo( iBndSrcN );
-        const BRepMesh_PairOfIndex &    triaIds = triaDS->ElementsConnectedTo( linkIds.First() );
-        const BRepMesh_Triangle&           tria = triaDS->GetElement( triaIds.Index(1) );
-        addCloseNodes( bndSrcNodes[ iBndSrcN ], &tria, srcFaceID, noTriQueue );
-      }
-    }
-
-    return true;
-  }
-
   //=======================================================================
   /*
    * Set initial association of VERTEXes for the case of projection
@@ -1614,11 +1380,12 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
       TopoDS_Edge srcE1 = srcEdges.front(), tgtE1 = tgtEdges.front();
       TopoDS_Shape srcE1bis = shape2ShapeMap( tgtE1 );
       reverse = ( ! srcE1.IsSame( srcE1bis ));
-      if ( reverse &&
-           //_sourceHypo->HasVertexAssociation() &&
+      if ( ( reverse || srcE1.Orientation() != srcE1bis.Orientation() ) &&
            nbEdgesInWires.front() > 2 &&
            helper.IsRealSeam( tgtEdges.front() ))
       {
+        if ( srcE1.Orientation() != srcE1bis.Orientation() )
+          reverse = true;
         // projection to a face with seam EDGE; pb is that GetOrderedEdges()
         // always puts a seam EDGE first (if possible) and as a result
         // we can't use only theReverse flag to correctly associate source
@@ -1795,7 +1562,9 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
 
       // mapper changed, no more "mapper puts on a seam edge nodes from 2 edges"
       if ( isSeam && ! getBoundaryNodes ( sm, tgtFace, u2nodesOnSeam, seamNodes ))
-        ;//RETURN_BAD_RESULT("getBoundaryNodes() failed");
+      {
+        //RETURN_BAD_RESULT("getBoundaryNodes() failed");
+      }
 
       SMDS_NodeIteratorPtr nIt = smDS->GetNodes();
       while ( nIt->more() )
@@ -1820,8 +1589,7 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
           break;
         }
         case  SMDS_TOP_EDGE:   {
-          const SMDS_EdgePosition* pos =
-            static_cast<const SMDS_EdgePosition*>(node->GetPosition());
+          SMDS_EdgePositionPtr pos = node->GetPosition();
           pos2nodes.insert( make_pair( pos->GetUParameter(), node ));
           break;
         }
@@ -1928,12 +1696,14 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
   if ( !projDone || is1DComputed )
     // ----------------------------------------------------------------
     // The mapper can create distorted faces by placing nodes out of the FACE
-    // boundary, also bad face can be created if EDGEs already discretized
+    // boundary, also bad faces can be created if EDGEs already discretized
     // --> fix bad faces by smoothing
     // ----------------------------------------------------------------
     if ( helper.IsDistorted2D( tgtSubMesh, /*checkUV=*/false, &helper ))
     {
-      morph( helper, tgtFace, srcFace, tgtWires, srcWires, _src2tgtNodes );
+      TAssocTool::Morph morph( srcWires );
+      morph.Perform( helper, tgtWires, helper.GetSurface( tgtFace ),
+                     _src2tgtNodes, /*moveAll=*/true );
 
       if ( !fixDistortedFaces( helper, tgtWires ))
         return error("Invalid mesh generated");