X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FStdMeshers%2FStdMeshers_Projection_2D.cxx;h=b88130cb2e948cc1823f93bf1b62214833950938;hb=847109ca105992b415893dd2ef416b45e258b537;hp=eeb20f00981b187845326a9f89555d493339c052;hpb=55290963c776b86cb15aea30629389d503c1d3b9;p=modules%2Fsmesh.git diff --git a/src/StdMeshers/StdMeshers_Projection_2D.cxx b/src/StdMeshers/StdMeshers_Projection_2D.cxx index eeb20f009..b88130cb2 100644 --- a/src/StdMeshers/StdMeshers_Projection_2D.cxx +++ b/src/StdMeshers/StdMeshers_Projection_2D.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2019 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"); @@ -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(node->GetPosition()); + SMDS_EdgePositionPtr pos = node->GetPosition(); u2nodes.insert( make_pair( pos->GetUParameter(), node )); seamNodes.insert( node ); } @@ -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::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( 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 @@ -1820,8 +1587,7 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& break; } case SMDS_TOP_EDGE: { - const SMDS_EdgePosition* pos = - static_cast(node->GetPosition()); + SMDS_EdgePositionPtr pos = node->GetPosition(); pos2nodes.insert( make_pair( pos->GetUParameter(), node )); break; } @@ -1928,12 +1694,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");