X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FStdMeshers%2FStdMeshers_Projection_2D.cxx;h=64ce054c5d9d6a2385c97e980f0d8e6de654156e;hp=31db57e967fd3f2702c6bd6fbf8d17131acccf48;hb=30ce546b0c5099ad1112929e2db94810e683e54b;hpb=7ea81bbe6e068500dbaf7ff693dd05f33b974c53 diff --git a/src/StdMeshers/StdMeshers_Projection_2D.cxx b/src/StdMeshers/StdMeshers_Projection_2D.cxx index 31db57e96..64ce054c5 100644 --- a/src/StdMeshers/StdMeshers_Projection_2D.cxx +++ b/src/StdMeshers/StdMeshers_Projection_2D.cxx @@ -72,6 +72,10 @@ using namespace std; #define RETURN_BAD_RESULT(msg) { MESSAGE(")-: Error: " << msg); return false; } +#ifdef _DEBUG_ +// enable printing algo + projection shapes while meshing +//#define PRINT_WHO_COMPUTE_WHAT +#endif namespace TAssocTool = StdMeshers_ProjectionUtils; //typedef StdMeshers_ProjectionUtils TAssocTool; @@ -422,6 +426,7 @@ namespace { const TopoDS_Face& srcFace, SMESH_Mesh * tgtMesh, SMESH_Mesh * srcMesh, + SMESH_MesherHelper* tgtHelper, const TAssocTool::TShapeShapeMap& shape2ShapeMap, TSideVector& srcWires, TSideVector& tgtWires, @@ -432,13 +437,15 @@ namespace { // get ordered src EDGEs TError err; - srcWires = StdMeshers_FaceSide::GetFaceWires( srcFace, *srcMesh,/*skipMediumNodes=*/0, err); + srcWires = StdMeshers_FaceSide::GetFaceWires( srcFace, *srcMesh,/*skipMediumNodes=*/0, err ); if (( err && !err->IsOK() ) || ( srcWires.empty() )) return err; - - SMESH_MesherHelper srcHelper( *srcMesh ); - srcHelper.SetSubShape( srcFace ); +#ifdef PRINT_WHO_COMPUTE_WHAT + cout << "Projection_2D" << " F " + << tgtMesh->GetMeshDS()->ShapeToIndex( tgtFace ) << " <- " + << srcMesh->GetMeshDS()->ShapeToIndex( srcFace ) << endl; +#endif // make corresponding sequence of tgt EDGEs tgtWires.resize( srcWires.size() ); @@ -485,13 +492,19 @@ namespace { tgtWires[ iW ].reset( new StdMeshers_FaceSide( tgtFace, tgtEdges, tgtMesh, /*theIsForward = */ true, - /*theIgnoreMediumNodes = */false)); + /*theIgnoreMediumNodes = */false, + tgtHelper )); StdMeshers_FaceSidePtr tgtWire = tgtWires[ iW ]; // Fill map of src to tgt nodes with nodes on edges for ( int iE = 0; iE < srcWire->NbEdges(); ++iE ) { +#ifdef PRINT_WHO_COMPUTE_WHAT + if ( tgtMesh->GetSubMesh( tgtWire->Edge(iE) )->IsEmpty() ) + cout << "Projection_2D" << " E " + << tgtWire->EdgeID(iE) << " <- " << srcWire->EdgeID(iE) << endl; +#endif if ( srcMesh->GetSubMesh( srcWire->Edge(iE) )->IsEmpty() || tgtMesh->GetSubMesh( tgtWire->Edge(iE) )->IsEmpty() ) { @@ -504,9 +517,11 @@ namespace { else { const bool skipMedium = true, isFwd = true; - StdMeshers_FaceSide srcEdge( srcFace, srcWire->Edge(iE), srcMesh, isFwd, skipMedium); - StdMeshers_FaceSide tgtEdge( tgtFace, tgtWire->Edge(iE), tgtMesh, isFwd, skipMedium); - + StdMeshers_FaceSide srcEdge( srcFace, srcWire->Edge(iE), + srcMesh, isFwd, skipMedium, srcWires[0]->FaceHelper() ); + StdMeshers_FaceSide tgtEdge( tgtFace, tgtWire->Edge(iE), + tgtMesh, isFwd, skipMedium, tgtHelper); + vector< const SMDS_MeshNode* > srcNodes = srcEdge.GetOrderedNodes(); vector< const SMDS_MeshNode* > tgtNodes = tgtEdge.GetOrderedNodes(); @@ -540,7 +555,7 @@ namespace { //================================================================================ /*! - * \brief Preform projection in case if tgtFace.IsPartner( srcFace ) and in case + * \brief Perform projection in case if tgtFace.IsPartner( srcFace ) and in case * if projection by 3D transformation is possible */ //================================================================================ @@ -553,11 +568,11 @@ namespace { TAssocTool::TNodeNodeMap& src2tgtNodes, const bool is1DComputed) { - SMESH_Mesh * tgtMesh = tgtWires[0]->GetMesh(); - SMESH_Mesh * srcMesh = srcWires[0]->GetMesh(); - SMESHDS_Mesh* tgtMeshDS = tgtMesh->GetMeshDS(); - SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS(); - SMESH_MesherHelper helper( *tgtMesh ); + SMESH_Mesh * tgtMesh = tgtWires[0]->GetMesh(); + SMESH_Mesh * srcMesh = srcWires[0]->GetMesh(); + SMESHDS_Mesh* tgtMeshDS = tgtMesh->GetMeshDS(); + SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS(); + SMESH_MesherHelper* helper = tgtWires[0]->FaceHelper(); const double tol = 1.e-7 * srcMeshDS->getMaxDim(); @@ -634,7 +649,7 @@ namespace { 0.123 * ( srcSurf.FirstVParameter() + srcSurf.LastVParameter() )); gp_Pnt tgtTrsfP = trsf.Transform( srcP ); TopLoc_Location loc; - GeomAPI_ProjectPointOnSurf& proj = helper.GetProjector( tgtFace, loc, 0.1*tol ); + GeomAPI_ProjectPointOnSurf& proj = helper->GetProjector( tgtFace, loc, 0.1*tol ); if ( !loc.IsIdentity() ) tgtTrsfP.Transform( loc.Transformation().Inverted() ); proj.Perform( tgtTrsfP ); @@ -649,16 +664,14 @@ namespace { // Make new faces // prepare the helper to adding quadratic elements if necessary - //helper.SetSubShape( tgtFace ); - helper.IsQuadraticSubMesh( tgtFace ); + helper->IsQuadraticSubMesh( tgtFace ); SMESHDS_SubMesh* srcSubDS = srcMeshDS->MeshElements( srcFace ); if ( !is1DComputed && srcSubDS->NbElements() ) - helper.SetIsQuadratic( srcSubDS->GetElements()->next()->IsQuadratic() ); + helper->SetIsQuadratic( srcSubDS->GetElements()->next()->IsQuadratic() ); - SMESH_MesherHelper srcHelper( *srcMesh ); - srcHelper.SetSubShape( srcFace ); - SMESH_MesherHelper edgeHelper( *tgtMesh ); + SMESH_MesherHelper* srcHelper = srcWires[0]->FaceHelper(); + SMESH_MesherHelper edgeHelper( *tgtMesh ); edgeHelper.ToFixNodeParameters( true ); const SMDS_MeshNode* nullNode = 0; @@ -677,7 +690,7 @@ namespace { const SMDS_MeshElement* elem = elemIt->next(); const int nbN = elem->NbCornerNodes(); tgtNodes.resize( nbN ); - helper.SetElementsOnShape( false ); + helper->SetElementsOnShape( false ); for ( int i = 0; i < nbN; ++i ) // loop on nodes of the source element { const SMDS_MeshNode* srcNode = elem->GetNode(i); @@ -686,27 +699,27 @@ namespace { { // create a new node gp_Pnt tgtP = trsf.Transform( SMESH_TNodeXYZ( srcNode )); - SMDS_MeshNode* n = helper.AddNode( tgtP.X(), tgtP.Y(), tgtP.Z() ); + SMDS_MeshNode* n = helper->AddNode( tgtP.X(), tgtP.Y(), tgtP.Z() ); srcN_tgtN->second = n; switch ( srcNode->GetPosition()->GetTypeOfPosition() ) { case SMDS_TOP_FACE: { - gp_Pnt2d srcUV = srcHelper.GetNodeUV( srcFace, srcNode ); - tgtMeshDS->SetNodeOnFace( n, helper.GetSubShapeID(), srcUV.X(), srcUV.Y() ); + gp_Pnt2d srcUV = srcHelper->GetNodeUV( srcFace, srcNode ); + tgtMeshDS->SetNodeOnFace( n, helper->GetSubShapeID(), srcUV.X(), srcUV.Y() ); break; } case SMDS_TOP_EDGE: { const TopoDS_Edge& srcE = TopoDS::Edge( srcMeshDS->IndexToShape( srcNode->getshapeId())); const TopoDS_Edge& tgtE = TopoDS::Edge( shape2ShapeMap( srcE, /*isSrc=*/true )); - double srcU = srcHelper.GetNodeU( srcE, srcNode ); + double srcU = srcHelper->GetNodeU( srcE, srcNode ); tgtMeshDS->SetNodeOnEdge( n, tgtE, srcU ); if ( !tgtFace.IsPartner( srcFace )) { - bool isOk = true; edgeHelper.SetSubShape( tgtE ); - edgeHelper.GetNodeU( tgtE, n, 0, &isOk ); + double tol = BRep_Tool::Tolerance( tgtE ); + bool isOk = edgeHelper.CheckNodeU( tgtE, n, srcU, 2 * tol, /*force=*/true ); if ( !isOk ) // projection of n to tgtE failed (23395) { double sF, sL, tF, tL; @@ -717,7 +730,6 @@ namespace { tgtMeshDS->SetNodeOnEdge( n, tgtE, tgtU ); gp_Pnt newP = BRepAdaptor_Curve( tgtE ).Value( tgtU ); double dist = newP.Distance( tgtP ); - double tol = BRep_Tool::Tolerance( tgtE ); if ( tol < dist && dist < 1000*tol ) tgtMeshDS->MoveNode( n, newP.X(), newP.Y(), newP.Z() ); } @@ -737,14 +749,14 @@ namespace { tgtNodes[i] = srcN_tgtN->second; } // create a new face - helper.SetElementsOnShape( true ); + helper->SetElementsOnShape( true ); switch ( nbN ) { - case 3: helper.AddFace(tgtNodes[0], tgtNodes[tri1], tgtNodes[tri2]); break; - case 4: helper.AddFace(tgtNodes[0], tgtNodes[quad1], tgtNodes[2], tgtNodes[quad3]); break; + case 3: helper->AddFace(tgtNodes[0], tgtNodes[tri1], tgtNodes[tri2]); break; + case 4: helper->AddFace(tgtNodes[0], tgtNodes[quad1], tgtNodes[2], tgtNodes[quad3]); break; default: if ( isReverse ) std::reverse( tgtNodes.begin(), tgtNodes.end() ); - helper.AddPolygonalFace( tgtNodes ); + helper->AddPolygonalFace( tgtNodes ); } } @@ -752,7 +764,7 @@ namespace { if ( !tgtFace.IsPartner( srcFace ) ) { - helper.ToFixNodeParameters( true ); + helper->ToFixNodeParameters( true ); int nbOkPos = 0; const double tol2d = 1e-12; @@ -765,8 +777,8 @@ namespace { case SMDS_TOP_FACE: { if ( nbOkPos > 10 ) break; - gp_XY uv = helper.GetNodeUV( tgtFace, n ), uvBis = uv; - if (( helper.CheckNodeUV( tgtFace, n, uv, tol )) && + gp_XY uv = helper->GetNodeUV( tgtFace, n ), uvBis = uv; + if (( helper->CheckNodeUV( tgtFace, n, uv, tol )) && (( uv - uvBis ).SquareModulus() < tol2d )) ++nbOkPos; else @@ -791,7 +803,7 @@ namespace { //================================================================================ /*! - * \brief Preform projection in case if the faces are similar in 2D space + * \brief Perform projection in case if the faces are similar in 2D space */ //================================================================================ @@ -886,18 +898,16 @@ namespace { SMESHDS_SubMesh* srcSubDS = srcMesh->GetMeshDS()->MeshElements( srcFace ); - SMESH_MesherHelper helper( *tgtMesh ); - helper.SetSubShape( tgtFace ); + SMESH_MesherHelper* helper = tgtWires[0]->FaceHelper(); if ( is1DComputed ) - helper.IsQuadraticSubMesh( tgtFace ); + helper->IsQuadraticSubMesh( tgtFace ); else - helper.SetIsQuadratic( srcSubDS->GetElements()->next()->IsQuadratic() ); - helper.SetElementsOnShape( true ); + helper->SetIsQuadratic( srcSubDS->GetElements()->next()->IsQuadratic() ); + helper->SetElementsOnShape( true ); Handle(Geom_Surface) tgtSurface = BRep_Tool::Surface( tgtFace ); SMESHDS_Mesh* tgtMeshDS = tgtMesh->GetMeshDS(); - SMESH_MesherHelper srcHelper( *srcMesh ); - srcHelper.SetSubShape( srcFace ); + SMESH_MesherHelper* srcHelper = srcWires[0]->FaceHelper(); const SMDS_MeshNode* nullNode = 0; TAssocTool::TNodeNodeMap::iterator srcN_tgtN; @@ -908,7 +918,7 @@ namespace { while ( elemIt->more() ) // loop on all mesh faces on srcFace { const SMDS_MeshElement* elem = elemIt->next(); - const int nbN = elem->NbCornerNodes(); + const int nbN = elem->NbCornerNodes(); tgtNodes.resize( nbN ); for ( int i = 0; i < nbN; ++i ) // loop on nodes of the source element { @@ -917,27 +927,27 @@ namespace { if ( srcN_tgtN->second == nullNode ) { // create a new node - gp_Pnt2d srcUV = srcHelper.GetNodeUV( srcFace, srcNode, - elem->GetNode( helper.WrapIndex(i+1,nbN)), &uvOK); + gp_Pnt2d srcUV = srcHelper->GetNodeUV( srcFace, srcNode, + elem->GetNode( helper->WrapIndex(i+1,nbN)), &uvOK); gp_Pnt2d tgtUV = trsf.Transform( srcUV ); gp_Pnt tgtP = tgtSurface->Value( tgtUV.X(), tgtUV.Y() ); SMDS_MeshNode* n = tgtMeshDS->AddNode( tgtP.X(), tgtP.Y(), tgtP.Z() ); switch ( srcNode->GetPosition()->GetTypeOfPosition() ) { case SMDS_TOP_FACE: { - tgtMeshDS->SetNodeOnFace( n, helper.GetSubShapeID(), tgtUV.X(), tgtUV.Y() ); + tgtMeshDS->SetNodeOnFace( n, helper->GetSubShapeID(), tgtUV.X(), tgtUV.Y() ); break; } case SMDS_TOP_EDGE: { - TopoDS_Shape srcEdge = srcHelper.GetSubShapeByNode( srcNode, srcHelper.GetMeshDS() ); + TopoDS_Shape srcEdge = srcHelper->GetSubShapeByNode( srcNode, srcHelper->GetMeshDS() ); TopoDS_Edge tgtEdge = TopoDS::Edge( shape2ShapeMap( srcEdge, /*isSrc=*/true )); double U = Precision::Infinite(); - helper.CheckNodeU( tgtEdge, n, U, Precision::PConfusion()); + helper->CheckNodeU( tgtEdge, n, U, Precision::PConfusion()); tgtMeshDS->SetNodeOnEdge( n, TopoDS::Edge( tgtEdge ), U ); break; } case SMDS_TOP_VERTEX: { - TopoDS_Shape srcV = srcHelper.GetSubShapeByNode( srcNode, srcHelper.GetMeshDS() ); + TopoDS_Shape srcV = srcHelper->GetSubShapeByNode( srcNode, srcHelper->GetMeshDS() ); TopoDS_Shape tgtV = shape2ShapeMap( srcV, /*isSrc=*/true ); tgtMeshDS->SetNodeOnVertex( n, TopoDS::Vertex( tgtV )); break; @@ -951,8 +961,8 @@ namespace { // create a new face (with reversed orientation) switch ( nbN ) { - case 3: helper.AddFace(tgtNodes[0], tgtNodes[2], tgtNodes[1]); break; - case 4: helper.AddFace(tgtNodes[0], tgtNodes[3], tgtNodes[2], tgtNodes[1]); break; + case 3: helper->AddFace(tgtNodes[0], tgtNodes[2], tgtNodes[1]); break; + case 4: helper->AddFace(tgtNodes[0], tgtNodes[3], tgtNodes[2], tgtNodes[1]); break; } } // loop on all mesh faces on srcFace @@ -961,7 +971,7 @@ namespace { //================================================================================ /*! - * \brief Preform projection in case of quadrilateral faces + * \brief Perform projection in case of quadrilateral faces */ //================================================================================ @@ -1058,7 +1068,7 @@ namespace { // } // else // { - // // find XY of src node withing the quadrilateral srcFace + // // find XY of src node within the quadrilateral srcFace // if ( !block.ComputeParameters( SMESH_TNodeXYZ( srcNode ), // tgtNodeOrXY.second, srcFaceBID )) // return false; @@ -1070,8 +1080,7 @@ namespace { // // as all XY are computed, create tgt nodes and faces - // SMESH_MesherHelper helper( *tgtMesh ); - // helper.SetSubShape( tgtFace ); + // SMESH_MesherHelper helper = *tgtWires[0]->FaceHelper(); // if ( is1DComputed ) // helper.IsQuadraticSubMesh( tgtFace ); // else @@ -1079,8 +1088,7 @@ namespace { // helper.SetElementsOnShape( true ); // Handle(Geom_Surface) tgtSurface = BRep_Tool::Surface( tgtFace ); - // SMESH_MesherHelper srcHelper( *srcMesh ); - // srcHelper.SetSubShape( srcFace ); + // SMESH_MesherHelper srcHelper = *srcWires[0]->FaceHelper(); // vector< const SMDS_MeshNode* > tgtNodes; // gp_XY uv; @@ -1125,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(); @@ -1171,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 @@ -1529,7 +1303,7 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& // get ordered src and tgt EDGEs TSideVector srcWires, tgtWires; bool is1DComputed = false; // if any tgt EDGE is meshed - TError err = getWires( tgtFace, srcFace, tgtMesh, srcMesh, + TError err = getWires( tgtFace, srcFace, tgtMesh, srcMesh, &helper, shape2ShapeMap, srcWires, tgtWires, _src2tgtNodes, is1DComputed ); if ( err && !err->IsOK() ) return error( err ); @@ -1606,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 @@ -1923,9 +1698,11 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& // boundary, also bad face can be created if EDGEs already discretized // --> fix bad faces by smoothing // ---------------------------------------------------------------- - if ( helper.IsDistorted2D( tgtSubMesh, /*checkUV=*/false )) + 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");