X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FStdMeshers%2FStdMeshers_Quadrangle_2D.cxx;h=679769a8f8e0b7c5296de4fdec4a9911df41c665;hp=989a2d50138e93d527ca830c79420a78ea5526e6;hb=04f997252152407f9180e03f0af428ab2ca6f4be;hpb=c98d9fcd7f02c1f1f5c24dd3e709ed75228d66c4 diff --git a/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx b/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx index 989a2d501..679769a8f 100644 --- a/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx +++ b/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx @@ -30,6 +30,7 @@ #include "SMDS_FacePosition.hxx" #include "SMDS_MeshElement.hxx" #include "SMDS_MeshNode.hxx" +#include "SMESHDS_Mesh.hxx" #include "SMESH_Block.hxx" #include "SMESH_Comment.hxx" #include "SMESH_Gen.hxx" @@ -50,7 +51,6 @@ #include #include #include -#include #include #include #include @@ -64,17 +64,15 @@ #include "utilities.h" #include "Utils_ExceptHandlers.hxx" -#ifndef StdMeshers_Array2OfNode_HeaderFile -#define StdMeshers_Array2OfNode_HeaderFile -typedef const SMDS_MeshNode* SMDS_MeshNodePtr; -typedef NCollection_Array2 StdMeshers_Array2OfNode; -#endif +#include -using namespace std; +typedef NCollection_Array2 StdMeshers_Array2OfNode; typedef gp_XY gp_UV; typedef SMESH_Comment TComm; +using namespace std; + //============================================================================= /*! * @@ -93,7 +91,6 @@ StdMeshers_Quadrangle_2D::StdMeshers_Quadrangle_2D (int hypId, int studyId, myQuadType(QUAD_STANDARD), myHelper( NULL ) { - MESSAGE("StdMeshers_Quadrangle_2D::StdMeshers_Quadrangle_2D"); _name = "Quadrangle_2D"; _shapeType = (1 << TopAbs_FACE); _compatibleHypothesis.push_back("QuadrangleParams"); @@ -110,7 +107,6 @@ StdMeshers_Quadrangle_2D::StdMeshers_Quadrangle_2D (int hypId, int studyId, StdMeshers_Quadrangle_2D::~StdMeshers_Quadrangle_2D() { - MESSAGE("StdMeshers_Quadrangle_2D::~StdMeshers_Quadrangle_2D"); } //============================================================================= @@ -160,7 +156,7 @@ bool StdMeshers_Quadrangle_2D::CheckHypothesis } else if (strcmp("TrianglePreference", aHyp->GetName()) == 0){ isFirstParams = false; - myTrianglePreference = true; + myTrianglePreference = true; } else { isFirstParams = false; @@ -173,18 +169,18 @@ bool StdMeshers_Quadrangle_2D::CheckHypothesis if (isFirstParams) { if (strcmp("QuadranglePreference", aHyp->GetName()) == 0) { myQuadranglePreference = true; - myTrianglePreference = false; + myTrianglePreference = false; myQuadType = QUAD_STANDARD; } else if (strcmp("TrianglePreference", aHyp->GetName()) == 0){ myQuadranglePreference = false; - myTrianglePreference = true; + myTrianglePreference = true; myQuadType = QUAD_STANDARD; } } - else { - const StdMeshers_QuadrangleParams* aHyp2 = - (const StdMeshers_QuadrangleParams*)aHyp; + else if (const StdMeshers_QuadrangleParams* aHyp2 = + dynamic_cast( aHyp )) + { myTriaVertexID = aHyp2->GetTriaVertex(); if (!myQuadranglePreference && !myTrianglePreference) { // priority of hypos @@ -205,7 +201,7 @@ bool StdMeshers_Quadrangle_2D::CheckHypothesis //============================================================================= /*! - * + * */ //============================================================================= @@ -231,7 +227,7 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, myNeedSmooth = false; myCheckOri = false; - FaceQuadStruct::Ptr quad = CheckNbEdges( aMesh, F, /*considerMesh=*/true ); + FaceQuadStruct::Ptr quad = CheckNbEdges( aMesh, F, /*considerMesh=*/true, myHelper ); if (!quad) return false; myQuadList.clear(); @@ -492,7 +488,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh& aMesh, int nbright = (int) uv_e1.size(); int nbleft = (int) uv_e3.size(); - if (quad->nbNodeOut(0) && nbvertic == 2) // this should not occure + if (quad->nbNodeOut(0) && nbvertic == 2) // this should not occur { // Down edge is out // @@ -519,7 +515,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh& aMesh, // for each node of the down edge find nearest node // in the first row of the regular grid and link them for (i = 0; i < stop; i++) { - const SMDS_MeshNode *a, *b, *c, *d; + const SMDS_MeshNode *a, *b, *c=0, *d; a = uv_e0[i].node; b = uv_e0[i + 1].node; gp_Pnt pb (b->X(), b->Y(), b->Z()); @@ -533,6 +529,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh& aMesh, } else { // find in the grid node c, nearest to the b + c = 0; double mind = RealLast(); for (int k = g; k <= iup; k++) { @@ -608,8 +605,8 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh& aMesh, int stop = 0; if ( quad->side[3].grid->Edge(0).IsNull() ) // left side is simulated one { - // quad divided at I but not at J, as nbvertic==nbright==2 - stop++; // we stop at a second node + if ( nbright == 2 ) // quad divided at I but not at J (2D_mesh_QuadranglePreference_01/B1) + stop++; // we stop at a second node } else { @@ -656,7 +653,8 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh& aMesh, } // for each node of the up edge find nearest node // in the first row of the regular grid and link them - for ( ; i > stop; i--) { + for ( ; i > stop; i--) + { a = uv_e2[i].node; b = uv_e2[i - 1].node; gp_Pnt pb = SMESH_TNodeXYZ( b ); @@ -720,7 +718,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh& aMesh, } // right or left boundary quadrangles - if (quad->nbNodeOut( QUAD_RIGHT_SIDE ) && nbhoriz == 2) // this should not occure + if (quad->nbNodeOut( QUAD_RIGHT_SIDE ) && nbhoriz == 2) // this should not occur { int g = 0; // last processed node in the grid int stop = nbright - 1; @@ -734,8 +732,9 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh& aMesh, gp_Pnt pb (b->X(), b->Y(), b->Z()); // find node c in the grid, nearest to the b + c = 0; int near = g; - if (i == stop - 1) { // up bondary reached + if (i == stop - 1) { // up boundary reached c = quad->uv_grid[nbhoriz*(jup + 1) - 2].node; near = jup; } else { @@ -789,8 +788,8 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh& aMesh, } } } else { - if (quad->nbNodeOut(3) && nbhoriz == 2) { -// MESSAGE("left edge is out"); + if (quad->nbNodeOut(3) && nbhoriz == 2) + { int g = nbvertic - 1; // last processed node in the grid int stop = 0; i = quad->side[ QUAD_LEFT_SIDE ].to-1; // nbleft - 1; @@ -835,7 +834,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadDominant(SMESH_Mesh& aMesh, // find node c in the grid, nearest to the b int near = g; - if (i == stop + 1) { // down bondary reached + if (i == stop + 1) { // down boundary reached c = quad->uv_grid[nbhoriz*jlow + 1].node; near = jlow; } @@ -1009,14 +1008,14 @@ bool StdMeshers_Quadrangle_2D::IsApplicable( const TopoDS_Shape & aShape, bool t continue; } - int nbNoDegenEdges = 0; + int nbNoDegenEdges = 0, totalNbEdges = 0; TopExp_Explorer eExp( aFace, TopAbs_EDGE ); - for ( ; eExp.More() && nbNoDegenEdges < 3; eExp.Next() ) { + for ( ; eExp.More() && nbNoDegenEdges < 3; eExp.Next(), ++totalNbEdges ) { if ( !SMESH_Algo::isDegenerated( TopoDS::Edge( eExp.Current() ))) ++nbNoDegenEdges; } - if ( toCheckAll && nbNoDegenEdges < 3 ) return false; - if ( !toCheckAll && nbNoDegenEdges >= 3 ) return true; + if ( toCheckAll && ( totalNbEdges < 4 && nbNoDegenEdges < 3 )) return false; + if ( !toCheckAll && ( totalNbEdges >= 4 || nbNoDegenEdges >= 3 )) return true; } return ( toCheckAll && nbFoundFaces != 0 ); } @@ -1050,7 +1049,8 @@ static bool twoEdgesMeatAtVertex(const TopoDS_Edge& e1, FaceQuadStruct::Ptr StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, - const bool considerMesh) + const bool considerMesh, + SMESH_MesherHelper* aFaceHelper) { if ( !myQuadList.empty() && myQuadList.front()->face.IsSame( aShape )) return myQuadList.front(); @@ -1069,6 +1069,7 @@ FaceQuadStruct::Ptr StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh & } // find corner vertices of the quad + myHelper = ( aFaceHelper && aFaceHelper->GetSubShape() == aShape ) ? aFaceHelper : NULL; vector corners; int nbDegenEdges, nbSides = getCorners( F, aMesh, edges, corners, nbDegenEdges, considerMesh ); if ( nbSides == 0 ) @@ -1094,7 +1095,7 @@ FaceQuadStruct::Ptr StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh & sideEdges.push_back( *edgeIt++ ); if ( !sideEdges.empty() ) quad->side.push_back( StdMeshers_FaceSide::New(F, sideEdges, &aMesh, iSide < QUAD_TOP_SIDE, - ignoreMediumNodes, myProxyMesh)); + ignoreMediumNodes, myHelper, myProxyMesh)); else --iSide; } @@ -1136,7 +1137,7 @@ FaceQuadStruct::Ptr StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh & } } } - else + else //if ( !myHelper || !myHelper->IsRealSeam( edge )) { sideEdges.push_back( edge ); } @@ -1148,7 +1149,7 @@ FaceQuadStruct::Ptr StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh & { quad->side.push_back ( StdMeshers_FaceSide::New( F, sideEdges, &aMesh, iSide < QUAD_TOP_SIDE, - ignoreMediumNodes, myProxyMesh )); + ignoreMediumNodes, myHelper, myProxyMesh )); ++iSide; } if ( quad->side.size() == 4 ) @@ -1572,7 +1573,7 @@ bool StdMeshers_Quadrangle_2D::setNormalizedGrid (FaceQuadStruct::Ptr quad) //======================================================================= //function : ShiftQuad -//purpose : auxilary function for computeQuadPref +//purpose : auxiliary function for computeQuadPref //======================================================================= void StdMeshers_Quadrangle_2D::shiftQuad(FaceQuadStruct::Ptr& quad, const int num ) @@ -1656,7 +1657,7 @@ void FaceQuadStruct::shift( size_t nb, bool ori, bool keepGrid ) //======================================================================= //function : calcUV -//purpose : auxilary function for computeQuadPref +//purpose : auxiliary function for computeQuadPref //======================================================================= static gp_UV calcUV(double x0, double x1, double y0, double y1, @@ -1679,7 +1680,7 @@ static gp_UV calcUV(double x0, double x1, double y0, double y1, //======================================================================= //function : calcUV2 -//purpose : auxilary function for computeQuadPref +//purpose : auxiliary function for computeQuadPref //======================================================================= static gp_UV calcUV2(double x, double y, @@ -1760,7 +1761,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadPref (SMESH_Mesh & aMesh, // | | | | // | |C | | // | L | | R | - // left | |__| | rigth + // left | |__| | right // | / \ | // | / C \ | // |/ \| @@ -1773,7 +1774,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadPref (SMESH_Mesh & aMesh, // | |__| | // | / \ | // | / C \ | - // left |/________\| rigth + // left |/________\| right // | | // | C | // | | @@ -2138,7 +2139,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadPref (SMESH_Mesh & aMesh, npl.Append(uv_el[i].normParam); } - int dl,dr; + int dl = 0, dr = 0; if (OldVersion) { // add some params to right and left after the first param // insert to right @@ -2156,7 +2157,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadPref (SMESH_Mesh & aMesh, } int nnn = Min(nr,nl); - // auxilary sequence of XY for creation nodes + // auxiliary sequence of XY for creation nodes // in the bottom part of central domain // Length of UVL and UVR must be == nbv-nnn TColgp_SequenceOfXY UVL, UVR, UVT; @@ -2380,7 +2381,7 @@ bool StdMeshers_Quadrangle_2D::computeQuadPref (SMESH_Mesh & aMesh, TColgp_SequenceOfXY UVtmp; double drparam = npr.Value(nr) - npr.Value(nnn-1); double dlparam = npl.Value(nnn) - npl.Value(nnn-1); - double y0,y1; + double y0 = 0, y1 = 0; for (i=1; i<=drl; i++) { // add existed nodes from right edge NodesC.SetValue(nb,i+1,uv_er[nnn+i-2].node); @@ -2514,7 +2515,7 @@ bool StdMeshers_Quadrangle_2D::evaluateQuadPref(SMESH_Mesh & aMesh, MapShapeNbElems& aResMap, bool IsQuadratic) { - // Auxilary key in order to keep old variant + // Auxiliary key in order to keep old variant // of meshing after implementation new variant // for bug 0016220 from Mantis. bool OldVersion = false; @@ -2996,7 +2997,7 @@ bool StdMeshers_Quadrangle_2D::computeReduced (SMESH_Mesh & aMesh, // | | | | // | | | | // | L | | R | - // left | | | | rigth + // left | | | | right // | / \ | // | / C \ | // |/ \| @@ -3023,7 +3024,7 @@ bool StdMeshers_Quadrangle_2D::computeReduced (SMESH_Mesh & aMesh, gp_XY a3 (uv_et.front().u, uv_et.front().v); int nnn = Min(nr,nl); - // auxilary sequence of XY for creation of nodes + // auxiliary sequence of XY for creation of nodes // in the bottom part of central domain // it's length must be == nbv-nnn-1 TColgp_SequenceOfXY UVL; @@ -3296,7 +3297,11 @@ bool StdMeshers_Quadrangle_2D::computeReduced (SMESH_Mesh & aMesh, vector curr_base = uv_eb, next_base; - UVPtStruct nullUVPtStruct; nullUVPtStruct.node = 0; + UVPtStruct nullUVPtStruct; + nullUVPtStruct.node = 0; + nullUVPtStruct.x = nullUVPtStruct.y = nullUVPtStruct.u = nullUVPtStruct.v = 0; + nullUVPtStruct.param = 0; + int curr_base_len = nb; int next_base_len = 0; @@ -3888,171 +3893,177 @@ void StdMeshers_Quadrangle_2D::smooth (FaceQuadStruct::Ptr quad) { // "smooth" by computing node positions using 3D TFI and further projection - int nbhoriz = quad->iSize; - int nbvertic = quad->jSize; + list< FaceQuadStruct::Ptr >::iterator q = myQuadList.begin(); + for ( ; q != myQuadList.end() ; ++q ) + { + quad = *q; + int nbhoriz = quad->iSize; + int nbvertic = quad->jSize; - SMESH_TNodeXYZ a0( quad->UVPt( 0, 0 ).node ); - SMESH_TNodeXYZ a1( quad->UVPt( nbhoriz-1, 0 ).node ); - SMESH_TNodeXYZ a2( quad->UVPt( nbhoriz-1, nbvertic-1 ).node ); - SMESH_TNodeXYZ a3( quad->UVPt( 0, nbvertic-1 ).node ); + SMESH_TNodeXYZ a0( quad->UVPt( 0, 0 ).node ); + SMESH_TNodeXYZ a1( quad->UVPt( nbhoriz-1, 0 ).node ); + SMESH_TNodeXYZ a2( quad->UVPt( nbhoriz-1, nbvertic-1 ).node ); + SMESH_TNodeXYZ a3( quad->UVPt( 0, nbvertic-1 ).node ); - for (int i = 1; i < nbhoriz-1; i++) - { - SMESH_TNodeXYZ p0( quad->UVPt( i, 0 ).node ); - SMESH_TNodeXYZ p2( quad->UVPt( i, nbvertic-1 ).node ); - for (int j = 1; j < nbvertic-1; j++) + for (int i = 1; i < nbhoriz-1; i++) { - SMESH_TNodeXYZ p1( quad->UVPt( nbhoriz-1, j ).node ); - SMESH_TNodeXYZ p3( quad->UVPt( 0, j ).node ); + SMESH_TNodeXYZ p0( quad->UVPt( i, 0 ).node ); + SMESH_TNodeXYZ p2( quad->UVPt( i, nbvertic-1 ).node ); + for (int j = 1; j < nbvertic-1; j++) + { + SMESH_TNodeXYZ p1( quad->UVPt( nbhoriz-1, j ).node ); + SMESH_TNodeXYZ p3( quad->UVPt( 0, j ).node ); - UVPtStruct& uvp = quad->UVPt( i, j ); + UVPtStruct& uvp = quad->UVPt( i, j ); - gp_Pnt p = myHelper->calcTFI(uvp.x,uvp.y, a0,a1,a2,a3, p0,p1,p2,p3); - gp_Pnt2d uv = surface->NextValueOfUV( uvp.UV(), p, 10*tol ); - gp_Pnt pnew = surface->Value( uv ); + gp_Pnt p = myHelper->calcTFI(uvp.x,uvp.y, a0,a1,a2,a3, p0,p1,p2,p3); + gp_Pnt2d uv = surface->NextValueOfUV( uvp.UV(), p, 10*tol ); + gp_Pnt pnew = surface->Value( uv ); - meshDS->MoveNode( uvp.node, pnew.X(), pnew.Y(), pnew.Z() ); - uvp.u = uv.X(); - uvp.v = uv.Y(); + meshDS->MoveNode( uvp.node, pnew.X(), pnew.Y(), pnew.Z() ); + uvp.u = uv.X(); + uvp.v = uv.Y(); + } } } - return; } + else + { + // Get nodes to smooth - // Get nodes to smooth - - typedef map< const SMDS_MeshNode*, TSmoothNode, TIDCompare > TNo2SmooNoMap; - TNo2SmooNoMap smooNoMap; + typedef map< const SMDS_MeshNode*, TSmoothNode, TIDCompare > TNo2SmooNoMap; + TNo2SmooNoMap smooNoMap; - // fixed nodes - set< const SMDS_MeshNode* > fixedNodes; - for ( size_t i = 0; i < myForcedPnts.size(); ++i ) - { - fixedNodes.insert( myForcedPnts[i].node ); - if ( myForcedPnts[i].node->getshapeId() != myHelper->GetSubShapeID() ) + // fixed nodes + boost::container::flat_set< const SMDS_MeshNode* > fixedNodes; + for ( size_t i = 0; i < myForcedPnts.size(); ++i ) { - TSmoothNode & sNode = smooNoMap[ myForcedPnts[i].node ]; - sNode._uv = myForcedPnts[i].uv; - sNode._xyz = SMESH_TNodeXYZ( myForcedPnts[i].node ); + fixedNodes.insert( myForcedPnts[i].node ); + if ( myForcedPnts[i].node->getshapeId() != myHelper->GetSubShapeID() ) + { + TSmoothNode & sNode = smooNoMap[ myForcedPnts[i].node ]; + sNode._uv = myForcedPnts[i].uv; + sNode._xyz = SMESH_TNodeXYZ( myForcedPnts[i].node ); + } } - } - SMESHDS_SubMesh* fSubMesh = meshDS->MeshElements( quad->face ); - SMDS_NodeIteratorPtr nIt = fSubMesh->GetNodes(); - while ( nIt->more() ) // loop on nodes bound to a FACE - { - const SMDS_MeshNode* node = nIt->next(); - TSmoothNode & sNode = smooNoMap[ node ]; - sNode._uv = myHelper->GetNodeUV( quad->face, node ); - sNode._xyz = SMESH_TNodeXYZ( node ); - if ( fixedNodes.count( node )) - continue; // fixed - no triangles - - // set sNode._triangles - SMDS_ElemIteratorPtr fIt = node->GetInverseElementIterator( SMDSAbs_Face ); - while ( fIt->more() ) + SMESHDS_SubMesh* fSubMesh = meshDS->MeshElements( quad->face ); + SMDS_NodeIteratorPtr nIt = fSubMesh->GetNodes(); + while ( nIt->more() ) // loop on nodes bound to a FACE { - const SMDS_MeshElement* face = fIt->next(); - const int nbN = face->NbCornerNodes(); - const int nInd = face->GetNodeIndex( node ); - const int prevInd = myHelper->WrapIndex( nInd - 1, nbN ); - const int nextInd = myHelper->WrapIndex( nInd + 1, nbN ); - const SMDS_MeshNode* prevNode = face->GetNode( prevInd ); - const SMDS_MeshNode* nextNode = face->GetNode( nextInd ); - sNode._triangles.push_back( TTriangle( & smooNoMap[ prevNode ], - & smooNoMap[ nextNode ])); - } - } - // set _uv of smooth nodes on FACE boundary - set< StdMeshers_FaceSide* > sidesOnEdge; - list< FaceQuadStruct::Ptr >::iterator q = myQuadList.begin(); - for ( ; q != myQuadList.end() ; ++q ) - for ( size_t i = 0; i < (*q)->side.size(); ++i ) - if ( ! (*q)->side[i].grid->Edge(0).IsNull() && - //(*q)->nbNodeOut( i ) == 0 && - sidesOnEdge.insert( (*q)->side[i].grid.get() ).second ) + const SMDS_MeshNode* node = nIt->next(); + TSmoothNode & sNode = smooNoMap[ node ]; + sNode._uv = myHelper->GetNodeUV( quad->face, node ); + sNode._xyz = SMESH_TNodeXYZ( node ); + if ( fixedNodes.count( node )) + continue; // fixed - no triangles + + // set sNode._triangles + SMDS_ElemIteratorPtr fIt = node->GetInverseElementIterator( SMDSAbs_Face ); + while ( fIt->more() ) { - const vector& uvVec = (*q)->side[i].grid->GetUVPtStruct(); - for ( unsigned j = 0; j < uvVec.size(); ++j ) + const SMDS_MeshElement* face = fIt->next(); + const int nbN = face->NbCornerNodes(); + const int nInd = face->GetNodeIndex( node ); + const int prevInd = myHelper->WrapIndex( nInd - 1, nbN ); + const int nextInd = myHelper->WrapIndex( nInd + 1, nbN ); + const SMDS_MeshNode* prevNode = face->GetNode( prevInd ); + const SMDS_MeshNode* nextNode = face->GetNode( nextInd ); + sNode._triangles.push_back( TTriangle( & smooNoMap[ prevNode ], + & smooNoMap[ nextNode ])); + } + } + // set _uv of smooth nodes on FACE boundary + set< StdMeshers_FaceSide* > sidesOnEdge; + list< FaceQuadStruct::Ptr >::iterator q = myQuadList.begin(); + for ( ; q != myQuadList.end() ; ++q ) + for ( size_t i = 0; i < (*q)->side.size(); ++i ) + if ( ! (*q)->side[i].grid->Edge(0).IsNull() && + //(*q)->nbNodeOut( i ) == 0 && + sidesOnEdge.insert( (*q)->side[i].grid.get() ).second ) { - TSmoothNode & sNode = smooNoMap[ uvVec[j].node ]; - sNode._uv = uvVec[j].UV(); - sNode._xyz = SMESH_TNodeXYZ( uvVec[j].node ); + const vector& uvVec = (*q)->side[i].grid->GetUVPtStruct(); + for ( unsigned j = 0; j < uvVec.size(); ++j ) + { + TSmoothNode & sNode = smooNoMap[ uvVec[j].node ]; + sNode._uv = uvVec[j].UV(); + sNode._xyz = SMESH_TNodeXYZ( uvVec[j].node ); + } } - } - // define refernce orientation in 2D - TNo2SmooNoMap::iterator n2sn = smooNoMap.begin(); - for ( ; n2sn != smooNoMap.end(); ++n2sn ) - if ( !n2sn->second._triangles.empty() ) - break; - if ( n2sn == smooNoMap.end() ) return; - const TSmoothNode & sampleNode = n2sn->second; - const bool refForward = ( sampleNode._triangles[0].IsForward( sampleNode._uv )); + // define reference orientation in 2D + TNo2SmooNoMap::iterator n2sn = smooNoMap.begin(); + for ( ; n2sn != smooNoMap.end(); ++n2sn ) + if ( !n2sn->second._triangles.empty() ) + break; + if ( n2sn == smooNoMap.end() ) return; + const TSmoothNode & sampleNode = n2sn->second; + const bool refForward = ( sampleNode._triangles[0].IsForward( sampleNode._uv )); - // Smoothing + // Smoothing - for ( int iLoop = 0; iLoop < 5; ++iLoop ) - { - for ( n2sn = smooNoMap.begin(); n2sn != smooNoMap.end(); ++n2sn ) + for ( int iLoop = 0; iLoop < 5; ++iLoop ) { - TSmoothNode& sNode = n2sn->second; - if ( sNode._triangles.empty() ) - continue; // not movable node + for ( n2sn = smooNoMap.begin(); n2sn != smooNoMap.end(); ++n2sn ) + { + TSmoothNode& sNode = n2sn->second; + if ( sNode._triangles.empty() ) + continue; // not movable node - gp_XY newUV; - bool isValid = false; - bool use3D = ( iLoop > 2 ); // 3 loops in 2D and 2, in 3D + gp_XY newUV; + bool isValid = false; + bool use3D = ( iLoop > 2 ); // 3 loops in 2D and 2, in 3D - if ( use3D ) - { - // compute a new XYZ - gp_XYZ newXYZ (0,0,0); - for ( size_t i = 0; i < sNode._triangles.size(); ++i ) - newXYZ += sNode._triangles[i]._n1->_xyz; - newXYZ /= sNode._triangles.size(); - - // compute a new UV by projection - newUV = surface->NextValueOfUV( sNode._uv, newXYZ, 10*tol ).XY(); - - // check validity of the newUV - for ( size_t i = 0; i < sNode._triangles.size() && isValid; ++i ) - isValid = ( sNode._triangles[i].IsForward( newUV ) == refForward ); - } - if ( !isValid ) - { - // compute a new UV by averaging - newUV.SetCoord(0.,0.); - for ( unsigned i = 0; i < sNode._triangles.size(); ++i ) - newUV += sNode._triangles[i]._n1->_uv; - newUV /= sNode._triangles.size(); - - // check validity of the newUV - isValid = true; - for ( unsigned i = 0; i < sNode._triangles.size() && isValid; ++i ) - isValid = ( sNode._triangles[i].IsForward( newUV ) == refForward ); - } - if ( isValid ) - { - sNode._uv = newUV; - sNode._xyz = surface->Value( newUV ).XYZ(); + if ( use3D ) + { + // compute a new XYZ + gp_XYZ newXYZ (0,0,0); + for ( size_t i = 0; i < sNode._triangles.size(); ++i ) + newXYZ += sNode._triangles[i]._n1->_xyz; + newXYZ /= sNode._triangles.size(); + + // compute a new UV by projection + newUV = surface->NextValueOfUV( sNode._uv, newXYZ, 10*tol ).XY(); + + // check validity of the newUV + for ( size_t i = 0; i < sNode._triangles.size() && isValid; ++i ) + isValid = ( sNode._triangles[i].IsForward( newUV ) == refForward ); + } + if ( !isValid ) + { + // compute a new UV by averaging + newUV.SetCoord(0.,0.); + for ( unsigned i = 0; i < sNode._triangles.size(); ++i ) + newUV += sNode._triangles[i]._n1->_uv; + newUV /= sNode._triangles.size(); + + // check validity of the newUV + isValid = true; + for ( unsigned i = 0; i < sNode._triangles.size() && isValid; ++i ) + isValid = ( sNode._triangles[i].IsForward( newUV ) == refForward ); + } + if ( isValid ) + { + sNode._uv = newUV; + sNode._xyz = surface->Value( newUV ).XYZ(); + } } } - } - // Set new XYZ to the smoothed nodes + // Set new XYZ to the smoothed nodes - for ( n2sn = smooNoMap.begin(); n2sn != smooNoMap.end(); ++n2sn ) - { - TSmoothNode& sNode = n2sn->second; - if ( sNode._triangles.empty() ) - continue; // not movable node + for ( n2sn = smooNoMap.begin(); n2sn != smooNoMap.end(); ++n2sn ) + { + TSmoothNode& sNode = n2sn->second; + if ( sNode._triangles.empty() ) + continue; // not movable node - SMDS_MeshNode* node = const_cast< SMDS_MeshNode*>( n2sn->first ); - gp_Pnt xyz = surface->Value( sNode._uv ); - meshDS->MoveNode( node, xyz.X(), xyz.Y(), xyz.Z() ); + SMDS_MeshNode* node = const_cast< SMDS_MeshNode*>( n2sn->first ); + gp_Pnt xyz = surface->Value( sNode._uv ); + meshDS->MoveNode( node, xyz.X(), xyz.Y(), xyz.Z() ); - // store the new UV - node->SetPosition( SMDS_PositionPtr( new SMDS_FacePosition( sNode._uv.X(), sNode._uv.Y() ))); + // store the new UV + node->SetPosition( SMDS_PositionPtr( new SMDS_FacePosition( sNode._uv.X(), sNode._uv.Y() ))); + } } // Move medium nodes in quadratic mesh @@ -4078,6 +4089,7 @@ void StdMeshers_Quadrangle_2D::smooth (FaceQuadStruct::Ptr quad) meshDS->MoveNode( node, xyz.X(), xyz.Y(), xyz.Z() ); } } + return; } //================================================================================ @@ -4104,11 +4116,11 @@ bool StdMeshers_Quadrangle_2D::check() { TError err; TSideVector wireVec = - StdMeshers_FaceSide::GetFaceWires( geomFace, *myHelper->GetMesh(), true, err ); + StdMeshers_FaceSide::GetFaceWires( geomFace, *myHelper->GetMesh(), true, err, myHelper ); StdMeshers_FaceSidePtr wire = wireVec[0]; // find a right angle VERTEX - int iVertex; + int iVertex = 0; double maxAngle = -1e100; for ( int i = 0; i < wire->NbEdges(); ++i ) { @@ -4173,12 +4185,18 @@ bool StdMeshers_Quadrangle_2D::check() if ( myHelper->HasSeam() ) for ( int i = 0; i < nbN && !nInFace; ++i ) if ( !myHelper->IsSeamShape( nn[i]->getshapeId() )) + { nInFace = nn[i]; + gp_XY uv = myHelper->GetNodeUV( geomFace, nInFace ); + if ( myHelper->IsOnSeam( uv )) + nInFace = NULL; + } toCheckUV = true; for ( int i = 0; i < nbN; ++i ) uv[ i ] = myHelper->GetNodeUV( geomFace, nn[i], nInFace, &toCheckUV ); + bool isBad = false; switch ( nbN ) { case 4: { @@ -4191,19 +4209,34 @@ bool StdMeshers_Quadrangle_2D::check() if ( sign1 * sign2 < 0 ) continue; // this should not happen } - if ( sign1 * okSign < 0 ) - badFaces.push_back ( f ); + isBad = ( sign1 * okSign < 0 ); break; } case 3: { double sign = getArea( uv[0], uv[1], uv[2] ); - if ( sign * okSign < 0 ) - badFaces.push_back ( f ); + isBad = ( sign * okSign < 0 ); break; } default:; } + + // if ( isBad && myHelper->HasRealSeam() ) + // { + // // detect a case where a face intersects the seam + // for ( int iPar = 1; iPar < 3; ++iPar ) + // if ( iPar & myHelper->GetPeriodicIndex() ) + // { + // double min = uv[0].Coord( iPar ), max = uv[0].Coord( iPar ); + // for ( int i = 1; i < nbN; ++i ) + // { + // min = Min( min, uv[i].Coord( iPar )); + // max = Max( max, uv[i].Coord( iPar )); + // } + // } + // } + if ( isBad ) + badFaces.push_back ( f ); } if ( !badFaces.empty() ) @@ -4245,7 +4278,10 @@ int StdMeshers_Quadrangle_2D::getCorners(const TopoDS_Face& theFace, theNbDegenEdges = 0; SMESH_MesherHelper helper( theMesh ); - StdMeshers_FaceSide faceSide( theFace, theWire, &theMesh, /*isFwd=*/true, /*skipMedium=*/true); + if ( myHelper ) + helper.CopySubShapeInfo( *myHelper ); + StdMeshers_FaceSide faceSide( theFace, theWire, &theMesh, + /*isFwd=*/true, /*skipMedium=*/true, &helper ); // sort theVertices by angle multimap vertexByAngle; @@ -4254,7 +4290,7 @@ int StdMeshers_Quadrangle_2D::getCorners(const TopoDS_Face& theFace, if ( SMESH_Algo::isDegenerated( prevE )) { list::reverse_iterator edge = ++theWire.rbegin(); - while ( SMESH_Algo::isDegenerated( *edge )) + while ( SMESH_Algo::isDegenerated( *edge ) /*|| helper.IsRealSeam( *edge )*/) ++edge; if ( edge == theWire.rend() ) return false; @@ -4263,7 +4299,7 @@ int StdMeshers_Quadrangle_2D::getCorners(const TopoDS_Face& theFace, list::iterator edge = theWire.begin(); for ( int iE = 0; edge != theWire.end(); ++edge, ++iE ) { - if ( SMESH_Algo::isDegenerated( *edge )) + if ( SMESH_Algo::isDegenerated( *edge ) /*|| helper.IsRealSeam( *edge )*/) { ++theNbDegenEdges; continue; @@ -4517,7 +4553,7 @@ int StdMeshers_Quadrangle_2D::getCorners(const TopoDS_Face& theFace, // move corners to make sides equal by length int nbEqualV = equVerts.size(); int nbExcessV = nbEqualV - ( 1 + nbC[0] + nbC[1] ); - if ( nbExcessV > 0 ) // there is nbExcessV vertices that can become corners + if ( nbExcessV > 0 ) // there are nbExcessV vertices that can become corners { // calculate normalized length of each "side" enclosed between neighbor equVerts vector< double > accuLength; @@ -4557,7 +4593,7 @@ int StdMeshers_Quadrangle_2D::getCorners(const TopoDS_Face& theFace, { d = Abs( idealLen - accuLength[ iEV ]); - // take into account presence of a coresponding halfDivider + // take into account presence of a corresponding halfDivider const double cornerWgt = 0.5 / nbSides; const double vertexWgt = 0.25 / nbSides; TGeoIndex hd = halfDivider[ evVec[ iEV ]]; @@ -4578,6 +4614,7 @@ int StdMeshers_Quadrangle_2D::getCorners(const TopoDS_Face& theFace, if ( iBestEV > iS-1 + nbExcessV ) iBestEV = iS-1 + nbExcessV; theVertices[ iCorner ] = helper.IthVertex( 0, edgeVec[ evVec[ iBestEV ]]); + cornerInd [ iCorner ] = evVec[ iBestEV ]; refinedCorners.insert( evVec[ iBestEV ]); iCorner = helper.WrapIndex( iCorner + 1, cornerInd.size() ); } @@ -5145,6 +5182,8 @@ void StdMeshers_Quadrangle_2D::updateSideUV( FaceQuadStruct::Side& side, for ( iS = 0; iS < q->side.size(); ++iS ) if ( side.grid == q->side[ iS ].grid ) break; + if ( iS == q->side.size() ) + continue; bool isOut; if ( !q->side[ iS ].IsReversed() ) isOut = ( q->side[ iS ].from > iCur || q->side[ iS ].to-1 <= iCur );