X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMESH%2FSMESH_Pattern.cxx;h=926f78cf73a2e3292b085ed190f767199eb4b8b5;hp=1ab83c71e927aa94cf2a3864683deeacdaeffa2d;hb=bd8f1aee7c78f7d2eb82bd4fec5e08c9e3d280ce;hpb=79b1ac2b6df9117f16f11d444b1f165d477a1813 diff --git a/src/SMESH/SMESH_Pattern.cxx b/src/SMESH/SMESH_Pattern.cxx index 1ab83c71e..926f78cf7 100644 --- a/src/SMESH/SMESH_Pattern.cxx +++ b/src/SMESH/SMESH_Pattern.cxx @@ -1,28 +1,29 @@ -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// +// Copyright (C) 2007-2013 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 +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// // File : SMESH_Pattern.hxx // Created : Mon Aug 2 10:30:00 2004 // Author : Edward AGAPOV (eap) -using namespace std; - #include "SMESH_Pattern.hxx" #include @@ -32,13 +33,14 @@ using namespace std; #include #include #include +#include #include #include #include #include #include #include -//#include +#include #include #include #include @@ -69,9 +71,12 @@ using namespace std; #include "SMESHDS_SubMesh.hxx" #include "SMESH_Block.hxx" #include "SMESH_Mesh.hxx" -#include "SMESH_MeshEditor.hxx" +#include "SMESH_MesherHelper.hxx" #include "SMESH_subMesh.hxx" +#include + +#include #include "utilities.h" using namespace std; @@ -209,6 +214,8 @@ bool SMESH_Pattern::Load (const char* theFileContents) { MESSAGE("Load( file ) "); + Kernel_Utils::Localizer loc; + // file structure: // ! This is a comment @@ -251,7 +258,7 @@ bool SMESH_Pattern::Load (const char* theFileContents) MESSAGE(" Too few points "); return setErrorCode( ERR_READ_TOO_FEW_POINTS ); } - + // read the rest points int iPoint; for ( iPoint = 1; iPoint < nbPoints; iPoint++ ) @@ -352,6 +359,9 @@ bool SMESH_Pattern::Load (const char* theFileContents) bool SMESH_Pattern::Save (ostream& theFile) { MESSAGE(" ::Save(file) " ); + + Kernel_Utils::Localizer loc; + if ( !IsLoaded() ) { MESSAGE(" Pattern not loaded "); return setErrorCode( ERR_SAVE_NOT_LOADED ); @@ -398,7 +408,7 @@ bool SMESH_Pattern::Save (ostream& theFile) } theFile << endl; - + return setErrorCode( ERR_OK ); } @@ -436,8 +446,13 @@ static gp_XY project (const SMDS_MeshNode* theNode, } double u, v, minVal = DBL_MAX; for ( int i = theProjectorPS.NbExt(); i > 0; i-- ) +#if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1 + if ( theProjectorPS.SquareDistance( i ) < minVal ) { + minVal = theProjectorPS.SquareDistance( i ); +#else if ( theProjectorPS.Value( i ) < minVal ) { minVal = theProjectorPS.Value( i ); +#endif theProjectorPS.Point( i ).Parameter( u, v ); } return gp_XY( u, v ); @@ -456,8 +471,7 @@ template bool areNodesBound( TFaceIterator & faceItr ) while ( nIt->more() ) { const SMDS_MeshNode* node = smdsNode( nIt->next() ); - SMDS_PositionPtr pos = node->GetPosition(); - if ( !pos || !pos->GetShapeId() ) { + if (node->getshapeId() <1) { return false; } } @@ -500,7 +514,8 @@ static bool isMeshBoundToShape(SMESHDS_Mesh * aMeshDS, bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, const TopoDS_Face& theFace, - bool theProject) + bool theProject, + TopoDS_Vertex the1stVertex) { MESSAGE(" ::Load(face) " ); Clear(); @@ -508,6 +523,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, SMESHDS_Mesh * aMeshDS = theMesh->GetMeshDS(); SMESHDS_SubMesh * fSubMesh = aMeshDS->MeshElements( theFace ); + const bool isQuadMesh = aMeshDS->GetMeshInfo().NbFaces( ORDER_QUADRATIC ); SMESH_MesherHelper helper( *theMesh ); helper.SetSubShape( theFace ); @@ -521,12 +537,11 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, TopoDS_Face face = TopoDS::Face( theFace.Oriented( TopAbs_FORWARD )); - // check that face is not closed + // check if face is closed bool isClosed = helper.HasSeam(); - TopoDS_Vertex bidon; list eList; list::iterator elIt; - SMESH_Block::GetOrderedEdges( face, bidon, eList, myNbKeyPntInBoundary ); + SMESH_Block::GetOrderedEdges( face, eList, myNbKeyPntInBoundary, the1stVertex ); // check that requested or needed projection is possible bool isMainShape = theMesh->IsMainShape( face ); @@ -576,15 +591,15 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, { myElemPointIDs.push_back( TElemDef() ); TElemDef& elemPoints = myElemPointIDs.back(); - SMDS_ElemIteratorPtr nIt = (*fIt)->nodesIterator(); - while ( nIt->more() ) + int nbNodes = (*fIt)->NbCornerNodes(); + for ( int i = 0;i < nbNodes; ++i ) { - const SMDS_MeshElement* node = nIt->next(); - TNodePointIDMap::iterator nIdIt = nodePointIDMap.find( node ); - if ( nIdIt == nodePointIDMap.end() ) + const SMDS_MeshElement* node = (*fIt)->GetNode( i ); + TNodePointIDMap::iterator nIdIt = nodePointIDMap.insert( make_pair( node, -1 )).first; + if ( nIdIt->second == -1 ) { elemPoints.push_back( iPoint ); - nodePointIDMap.insert( make_pair( node, iPoint++ )); + nIdIt->second = iPoint++; } else elemPoints.push_back( (*nIdIt).second ); @@ -633,11 +648,15 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, // vertices for ( elIt = eList.begin(); elIt != eList.end(); elIt++ ) { + int nbV = myShapeIDMap.Extent(); myShapeIDMap.Add( TopExp::FirstVertex( *elIt, true )); - if ( BRep_Tool::IsClosed( *elIt, theFace ) ) - myShapeIDMap.Add( TopExp::LastVertex( *elIt, true )); - SMESHDS_SubMesh * eSubMesh = aMeshDS->MeshElements( *elIt ); - if ( eSubMesh ) + bool added = ( nbV < myShapeIDMap.Extent() ); + if ( !added ) { // vertex encountered twice + // a seam vertex have two corresponding key points + myShapeIDMap.Add( TopExp::FirstVertex( *elIt, true ).Reversed()); + ++nbNodes; + } + if ( SMESHDS_SubMesh * eSubMesh = aMeshDS->MeshElements( *elIt )) nbNodes += eSubMesh->NbNodes() + 1; } // edges @@ -655,9 +674,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, TopoDS_Edge & edge = *elIt; list< TPoint* > & ePoints = getShapePoints( edge ); double f, l; - Handle(Geom2d_Curve) C2d; - if ( !theProject ) - C2d = BRep_Tool::CurveOnSurface( edge, face, f, l ); + Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface( edge, face, f, l ); bool isForward = ( edge.Orientation() == TopAbs_FORWARD ); TopoDS_Shape v1 = TopExp::FirstVertex( edge, true ); // always FORWARD @@ -667,18 +684,18 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, v2.Reverse(); // on closed face we must have REVERSED some of seam vertices - bool isSeam = helper.IsSeamShape( edge ); if ( isClosed ) { - if ( isSeam ) { // reverse on reversed SEAM edge - if ( !isForward ) { + if ( helper.IsSeamShape( edge ) ) { + if ( helper.IsRealSeam( edge ) && !isForward ) { + // reverse on reversed SEAM edge v1.Reverse(); v2.Reverse(); } } - else { // on CLOSED edge + else { // on CLOSED edge (i.e. having one vertex with different orienations) for ( int is2 = 0; is2 < 2; ++is2 ) { TopoDS_Shape & v = is2 ? v2 : v1; - if ( helper.IsSeamShape( v ) ) { + if ( helper.IsRealSeam( v ) ) { // reverse or not depending on orientation of adjacent seam TopoDS_Edge seam; list::iterator eIt2 = elIt; @@ -726,16 +743,52 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, // loop on nodes of an edge: sort them by param on edge typedef map < double, const SMDS_MeshNode* > TParamNodeMap; TParamNodeMap paramNodeMap; + int nbMeduimNodes = 0; SMDS_NodeIteratorPtr nIt = eSubMesh->GetNodes(); while ( nIt->more() ) { - const SMDS_MeshNode* node = smdsNode( nIt->next() ); + const SMDS_MeshNode* node = nIt->next(); + if ( isQuadMesh && helper.IsMedium( node, SMDSAbs_Face )) { + ++nbMeduimNodes; + continue; + } const SMDS_EdgePosition* epos = - static_cast(node->GetPosition().get()); + static_cast(node->GetPosition()); double u = epos->GetUParameter(); - paramNodeMap.insert( TParamNodeMap::value_type( u, node )); + paramNodeMap.insert( make_pair( u, node )); + } + if ( paramNodeMap.size() != eSubMesh->NbNodes() ) { + // wrong U on edge, project + Extrema_ExtPC proj; + BRepAdaptor_Curve aCurve( edge ); + proj.Initialize( aCurve, f, l ); + paramNodeMap.clear(); + nIt = eSubMesh->GetNodes(); + for ( int iNode = 0; nIt->more(); ++iNode ) { + const SMDS_MeshNode* node = nIt->next(); + if ( isQuadMesh && helper.IsMedium( node, SMDSAbs_Face )) + continue; + proj.Perform( gp_Pnt( node->X(), node->Y(), node->Z())); + double u = 0; + if ( proj.IsDone() ) { + for ( int i = 1, nb = proj.NbExt(); i <= nb; ++i ) + if ( proj.IsMin( i )) { + u = proj.Point( i ).Parameter(); + break; + } + } else { + u = isForward ? iNode : eSubMesh->NbNodes() - iNode; + } + paramNodeMap.insert( make_pair( u, node )); + } + + //rnv : To fix the bug IPAL21999 Pattern Mapping - New - collapse of pattern mesh + if ( paramNodeMap.size() != eSubMesh->NbNodes() - nbMeduimNodes ) + return setErrorCode(ERR_UNEXPECTED); } + // put U in [0,1] so that the first key-point has U==0 + bool isSeam = helper.IsRealSeam( edge ); double du = l - f; TParamNodeMap::iterator unIt = paramNodeMap.begin(); TParamNodeMap::reverse_iterator unRIt = paramNodeMap.rbegin(); @@ -816,7 +869,9 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, SMDS_NodeIteratorPtr nIt = fSubMesh->GetNodes(); while ( nIt->more() ) { - const SMDS_MeshNode* node = smdsNode( nIt->next() ); + const SMDS_MeshNode* node = nIt->next(); + if ( isQuadMesh && helper.IsMedium( node, SMDSAbs_Face )) + continue; nodePointIDMap.insert( make_pair( node, iPoint )); TPoint* p = &myPoints[ iPoint++ ]; fPoints.push_back( p ); @@ -824,12 +879,13 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, p->myInitUV = project( node, projector ); else { const SMDS_FacePosition* pos = - static_cast(node->GetPosition().get()); + static_cast(node->GetPosition()); p->myInitUV.SetCoord( pos->GetUParameter(), pos->GetVParameter() ); } p->myInitXYZ.SetCoord( p->myInitUV.X(), p->myInitUV.Y(), 0 ); } // load elements + TNodePointIDMap::iterator n_id, not_found = closeNodePointIDMap.end(); SMDS_ElemIteratorPtr elemIt = fSubMesh->GetElements(); while ( elemIt->more() ) { @@ -841,12 +897,13 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, while ( nIt->more() ) { const SMDS_MeshNode* node = smdsNode( nIt->next() ); - iPoint = nodePointIDMap[ node ]; // point index of interest + n_id = nodePointIDMap.find( node ); + if ( n_id == nodePointIDMap.end() ) + continue; // medium node + iPoint = n_id->second; // point index of interest // for a node on a seam edge there are two points - TNodePointIDMap::iterator n_id = closeNodePointIDMap.end(); - if ( helper.IsSeamShape( node->GetPosition()->GetShapeId() )) - n_id = closeNodePointIDMap.find( node ); - if ( n_id != closeNodePointIDMap.end() ) + if ( helper.IsRealSeam( node->getshapeId() ) && + ( n_id = closeNodePointIDMap.find( node )) != not_found ) { TPoint & p1 = myPoints[ iPoint ]; TPoint & p2 = myPoints[ n_id->second ]; @@ -856,7 +913,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, // find node not on a seam edge while ( nIt2->more() && !notSeamNode ) { const SMDS_MeshNode* n = smdsNode( nIt2->next() ); - if ( !helper.IsSeamShape( n->GetPosition()->GetShapeId() )) + if ( !helper.IsSeamShape( n->getshapeId() )) notSeamNode = n; } gp_Pnt2d uv = helper.GetNodeUV( theFace, node, notSeamNode ); @@ -869,6 +926,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, } } } + myPoints.resize( nodePointIDMap.size() + closeNodePointIDMap.size() ); myIsBoundaryPointsFound = true; } @@ -978,7 +1036,7 @@ static bool intersectIsolines(const gp_XY& uv11, const gp_XY& uv12, const double // resUV = loc1 * len2 / ( len1 + len2 ) + loc2 * len1 / ( len1 + len2 ); // return true; - + // gp_Lin2d line1( uv11, uv12 - uv11 ); // gp_Lin2d line2( uv21, uv22 - uv21 ); // double angle = Abs( line1.Angle( line2 ) ); @@ -992,7 +1050,7 @@ static bool intersectIsolines(const gp_XY& uv11, const gp_XY& uv12, const double // inter.Perform( line1, line2 ); // interUV = inter.Point(1).Value(); // resUV += interUV.XY(); - + // resUV /= 2.; // } if ( isDeformed ) { @@ -1032,7 +1090,7 @@ bool SMESH_Pattern::compUVByIsoIntersection (const list< list< TPoint* > >& theB const list< TPoint* > & bndPoints = * bndIt; TPoint* prevP = bndPoints.back(); // this is the first point list< TPoint* >::const_iterator pIt = bndPoints.begin(); - bool coincPrev = false; + bool coincPrev = false; // loop on the edge-points for ( ; pIt != bndPoints.end(); pIt++ ) { @@ -1203,7 +1261,7 @@ static bool checkQuads (const TIsoNode* node, maxLen2 = Max( maxLen2, ( n[1]->myUV - n[2]->myUV ).SquareModulus() ); } maxLen2 = Max( maxLen2, ( n[2]->myUV - node->myUV ).SquareModulus() ); - minDiag = sqrt( maxLen2 ) * PI / 60.; // ~ maxLen * Sin( 3 deg ) + minDiag = sqrt( maxLen2 ) * M_PI / 60.; // ~ maxLen * Sin( 3 deg ) } // check if newUV is behind 3 dirs: n[0]-n[1], n[1]-n[2] and n[0]-n[2] @@ -1297,7 +1355,7 @@ static bool checkQuads (const TIsoNode* node, gp_XY uv1, uv2 = node->myUV; for ( i = isTriangle ? 2 : 0; i < 3; i++ ) // mark not computed vectors if ( wasOk[i] ) - moveVec[ i ].SetCoord( 1, 2e100); // not use this vector + moveVec[ i ].SetCoord( 1, 2e100); // not use this vector while ( !isOldOk ) { // find the least moveVec int i, iMin = 4; @@ -1728,7 +1786,7 @@ bool SMESH_Pattern:: aNorm[1-iDir].Normalize(); double r = Abs ( ratio[iDir] - 0.5 ) * 2.0; // [0,1] - distance from the middle r *= r; - + node->myDir[iDir] = //aTgt[iDir]; aNorm[1-iDir] * r + aTgt[iDir] * ( 1. - r ); } @@ -1754,7 +1812,7 @@ bool SMESH_Pattern:: double initAngle = initTgt1.Angle( initTgt2 ); double angle = node->myDir[0].Angle( node->myDir[1] ); if ( reversed ) angle = -angle; - if ( initAngle > angle && initAngle - angle > PI / 2.1 ) { + if ( initAngle > angle && initAngle - angle > M_PI / 2.1 ) { // find a close internal node TIsoNode* nClose = 0; list< TIsoNode* > testNodes; @@ -1848,7 +1906,7 @@ bool SMESH_Pattern:: for ( nIt = startNodes.begin(); nIt != startNodes.end(); nIt++ ) { - TIsoNode* prevN[2], *node = *nIt; + TIsoNode *node = *nIt; if ( node->IsUVComputed() || !node->IsMovable() ) continue; gp_XY newUV( 0, 0 ), sumDir( 0, 0 ); @@ -1909,7 +1967,6 @@ bool SMESH_Pattern:: newUV += prevNode1->myUV + dir * step[ iDir ]; } sumDir += dir; - prevN[ iDir ] = prevNode1; nbComp++; } } @@ -1929,7 +1986,7 @@ bool SMESH_Pattern:: } internNodes.push_back( node ); } - + // Move nodes static int maxNbIter = 100; @@ -1941,7 +1998,7 @@ bool SMESH_Pattern:: int nbNodeMove = 0; if ( !useNbMoveNode ) maxNbIter = ( maxNbIter < 0 ) ? 100 : -1; -#endif +#endif double maxMove; int nbIter = 0; do { @@ -1971,7 +2028,7 @@ bool SMESH_Pattern:: } // define ratio bool ok = true; // <- stupid fix TO AVOID PB OF NODES WITH NULL BND NODES - double locR[2] = { 0, 0 }; +// double locR[2] = { 0, 0 }; for ( iDir = 0; iDir < 2; iDir++ ) { const int iCoord = 2 - iDir; // coord changing along an isoline @@ -1985,7 +2042,7 @@ bool SMESH_Pattern:: double par3 = bndNode2->myInitUV.Coord( iCoord ); double r = ( par2 - par1 ) / ( par3 - par1 ); r = Abs ( r - 0.5 ) * 2.0; // [0,1] - distance from the middle - locR[ iDir ] = ( 1 - r * r ) * 0.25; +// locR[ iDir ] = ( 1 - r * r ) * 0.25; } //locR[0] = locR[1] = 0.25; // intersect the 2 lines and move a node @@ -2038,8 +2095,7 @@ bool SMESH_Pattern:: } } } - - + return true; } @@ -2065,7 +2121,7 @@ double SMESH_Pattern::setFirstEdge (list< TopoDS_Edge > & theWire, int theFirstE int eID = theFirstEdgeID; for ( iE = 0; iE < nbEdges; iE++ ) maxNbPnt = Max ( maxNbPnt, getShapePoints( eID++ ).size() ); - + // compute bnd boxes TopoDS_Face face = TopoDS::Face( myShape ); Bnd_Box2d bndBox, eBndBox; @@ -2093,8 +2149,8 @@ double SMESH_Pattern::setFirstEdge (list< TopoDS_Edge > & theWire, int theFirstE bndBox.Get( minPar[0], minPar[1], maxPar[0], maxPar[1] ); eBndBox.Get( eMinPar[0], eMinPar[1], eMaxPar[0], eMaxPar[1] ); #ifdef DBG_SETFIRSTEDGE - cout << "EDGES: X: " << eMinPar[0] << " - " << eMaxPar[0] << " Y: " - << eMinPar[1] << " - " << eMaxPar[1] << endl; + MESSAGE ( "EDGES: X: " << eMinPar[0] << " - " << eMaxPar[0] << " Y: " + << eMinPar[1] << " - " << eMaxPar[1] ); #endif for ( int iC = 1, i = 0; i < 2; iC++, i++ ) // loop on 2 coordinates { @@ -2120,7 +2176,7 @@ double SMESH_Pattern::setFirstEdge (list< TopoDS_Edge > & theWire, int theFirstE for ( iE = 0 ; iE < nbEdges; iE++ ) { #ifdef DBG_SETFIRSTEDGE - cout << " VARIANT " << iE << endl; + MESSAGE ( " VARIANT " << iE ); #endif // evaluate the distance between UV computed by the 2 methods: // by isos intersection ( myXYZ ) and by edge p-curves ( myUV ) @@ -2134,13 +2190,13 @@ double SMESH_Pattern::setFirstEdge (list< TopoDS_Edge > & theWire, int theFirstE TPoint* p = (*pIt); dist += ( p->myUV - gp_XY( p->myXYZ.X(), p->myXYZ.Y() )).SquareModulus(); #ifdef DBG_SETFIRSTEDGE - cout << " ISO : ( " << p->myXYZ.X() << ", "<< p->myXYZ.Y() << " ) PCURVE : ( " << - p->myUV.X() << ", " << p->myUV.Y() << ") " << endl; + MESSAGE ( " ISO : ( " << p->myXYZ.X() << ", "<< p->myXYZ.Y() << " ) PCURVE : ( " << + p->myUV.X() << ", " << p->myUV.Y() << ") " ); #endif } } #ifdef DBG_SETFIRSTEDGE - cout << "dist -- " << dist << endl; + MESSAGE ( "dist -- " << dist ); #endif if ( dist < minDist ) { minDist = dist; @@ -2260,7 +2316,7 @@ bool SMESH_Pattern::sortSameSizeWires (TListOfEdgesList & theWire bndIndWirePosMap.insert( TIntWirePosMap::value_type( bIndex, wlIt )); } - // Treat each wire + // Treat each wire TIntWirePosMap::iterator bIndWPosIt = bndIndWirePosMap.begin(); eID = theFirstEdgeID; @@ -2271,7 +2327,7 @@ bool SMESH_Pattern::sortSameSizeWires (TListOfEdgesList & theWire // choose the best first edge of a wire setFirstEdge( wire, eID ); - + // compute eventual UV and fill theEdgesPointsList theEdgesPointsList.push_back( list< TPoint* >() ); list< TPoint* > & edgesPoints = theEdgesPointsList.back(); @@ -2314,7 +2370,7 @@ bool SMESH_Pattern::Apply (const TopoDS_Face& theFace, list< TopoDS_Edge > eList; list< int > nbVertexInWires; - int nbWires = SMESH_Block::GetOrderedEdges( face, theVertexOnKeyPoint1, eList, nbVertexInWires); + int nbWires = SMESH_Block::GetOrderedEdges( face, eList, nbVertexInWires, theVertexOnKeyPoint1); if ( !theVertexOnKeyPoint1.IsSame( TopExp::FirstVertex( eList.front(), true ))) { MESSAGE( " theVertexOnKeyPoint1 not found in the outer wire "); @@ -2333,8 +2389,24 @@ bool SMESH_Pattern::Apply (const TopoDS_Face& theFace, list::iterator elIt = eList.begin(); for ( ; elIt != eList.end(); elIt++ ) { myShapeIDMap.Add( TopExp::FirstVertex( *elIt, true )); - if ( BRep_Tool::IsClosed( *elIt, theFace ) ) - myShapeIDMap.Add( TopExp::LastVertex( *elIt, true )); + bool isClosed1 = BRep_Tool::IsClosed( *elIt, theFace ); + // BEGIN: jfa for bug 0019943 + if (isClosed1) { + isClosed1 = false; + for (TopExp_Explorer expw (theFace, TopAbs_WIRE); expw.More() && !isClosed1; expw.Next()) { + const TopoDS_Wire& wire = TopoDS::Wire(expw.Current()); + int nbe = 0; + for (BRepTools_WireExplorer we (wire, theFace); we.More() && !isClosed1; we.Next()) { + if (we.Current().IsSame(*elIt)) { + nbe++; + if (nbe == 2) isClosed1 = true; + } + } + } + } + // END: jfa for bug 0019943 + if (isClosed1) + myShapeIDMap.Add( TopExp::LastVertex( *elIt, true ));// vertex orienation is REVERSED } int nbVertices = myShapeIDMap.Extent(); @@ -2343,7 +2415,7 @@ bool SMESH_Pattern::Apply (const TopoDS_Face& theFace, myShapeIDMap.Add( face ); - if ( myShapeIDToPointsMap.size() != myShapeIDMap.Extent()/* + nbSeamShapes*/ ) { + if ( myShapeIDToPointsMap.size() != myShapeIDMap.Extent() ) { MESSAGE( myShapeIDToPointsMap.size() <<" != " << myShapeIDMap.Extent()); return setErrorCode( ERR_APPLF_INTERNAL_EEROR ); } @@ -2440,7 +2512,7 @@ bool SMESH_Pattern::Apply (const TopoDS_Face& theFace, } // find boundary - wire correspondence for several wires of same size - + id1 = nbVertices + nbEdgesInOuterWire + 1; wlIt = wireList.begin(); while ( wlIt != wireList.end() ) @@ -2460,7 +2532,7 @@ bool SMESH_Pattern::Apply (const TopoDS_Face& theFace, } // add well-ordered edges to eList - + for ( wlIt = wireList.begin(); wlIt != wireList.end(); wlIt++ ) { list< TopoDS_Edge >& wire = (*wlIt); @@ -2475,7 +2547,7 @@ bool SMESH_Pattern::Apply (const TopoDS_Face& theFace, for ( elIt = eList.begin(); elIt != eList.end(); elIt++ ) myShapeIDMap.Add( *elIt ); myShapeIDMap.Add( face ); - + } // there are inner wires // Compute XYZ of on-edge points @@ -2549,8 +2621,9 @@ bool SMESH_Pattern::Apply (const SMDS_MeshFace* theFace, } // check nb of nodes - if (theFace->NbNodes() != myNbKeyPntInBoundary.front() ) { - MESSAGE( myKeyPointIDs.size() << " != " << theFace->NbNodes() ); + const int nbFaceNodes = theFace->NbCornerNodes(); + if ( nbFaceNodes != myNbKeyPntInBoundary.front() ) { + MESSAGE( myKeyPointIDs.size() << " != " << nbFaceNodes ); return setErrorCode( ERR_APPL_BAD_NB_VERTICES ); } @@ -2569,7 +2642,7 @@ bool SMESH_Pattern::Apply (const SMDS_MeshFace* theFace, list< const SMDS_MeshNode* >::iterator n = nodes.end(); SMDS_ElemIteratorPtr noIt = theFace->nodesIterator(); int iSub = 0; - while ( noIt->more() ) { + while ( noIt->more() && iSub < nbFaceNodes ) { const SMDS_MeshNode* node = smdsNode( noIt->next() ); nodes.push_back( node ); if ( iSub++ == theNodeIndexOnKeyPoint1 ) @@ -2585,7 +2658,7 @@ bool SMESH_Pattern::Apply (const SMDS_MeshFace* theFace, nodes.splice( nodes.end(), nodes, nodes.begin(), n ); } list< gp_XYZ > xyzList; - myOrderedNodes.resize( theFace->NbNodes() ); + myOrderedNodes.resize( nbFaceNodes ); for ( iSub = 0, n = nodes.begin(); n != nodes.end(); ++n ) { xyzList.push_back( gp_XYZ( (*n)->X(), (*n)->Y(), (*n)->Z() )); myOrderedNodes[ iSub++] = *n; @@ -2625,7 +2698,7 @@ bool SMESH_Pattern::Apply (const SMDS_MeshFace* theFace, { gp_XYZ& xyz1 = *xyzIt++; gp_XYZ& xyz2 = ( xyzIt != xyzList.end() ) ? *xyzIt : xyzList.front(); - + list< TPoint* > & ePoints = getShapePoints( iSub ); ePoints.back()->myInitU = 1.0; list< TPoint* >::const_iterator pIt = ++ePoints.begin(); @@ -2899,7 +2972,7 @@ bool SMESH_Pattern::Apply (SMESH_Mesh* theMesh, // meshed geometry TopoDS_Shape shape; // int shapeID = 0; -// SMESH_MeshEditor editor( theMesh ); +// SMESH_MeshEditor editor( theMesh ); // apply to each face in theFaces set set::iterator face = theFaces.begin(); @@ -2940,7 +3013,7 @@ bool SMESH_Pattern::Apply (SMESH_Mesh* theMesh, } // put points on links to myIdsOnBoundary, // they will be used to sew new elements on adjacent refined elements - int nbNodes = (*face)->NbNodes(), eID = nbNodes + 1; + int nbNodes = (*face)->NbCornerNodes(), eID = nbNodes + 1; for ( int i = 0; i < nbNodes; i++ ) { list< TPoint* > & linkPoints = getShapePoints( eID++ ); @@ -3100,6 +3173,8 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, myIs2D = false; SMESHDS_SubMesh * aSubMesh; + const bool isQuadMesh = theMesh->NbVolumes( ORDER_QUADRATIC ); + // load shapes in myShapeIDMap SMESH_Block block; TopoDS_Vertex v1, v2; @@ -3132,6 +3207,8 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, // store a node and a point while ( nIt->more() ) { const SMDS_MeshNode* node = smdsNode( nIt->next() ); + if ( isQuadMesh && SMESH_MeshEditor::IsMedium( node, SMDSAbs_Volume )) + continue; nodePointIDMap.insert( make_pair( node, iPoint )); if ( block.IsVertexID( shapeID )) myKeyPointIDs.push_back( iPoint ); @@ -3166,9 +3243,11 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, nIt = aSubMesh->GetNodes(); for ( ; nIt->more(); pIt++ ) { - const SMDS_MeshNode* node = smdsNode( nIt->next() ); + const SMDS_MeshNode* node = nIt->next(); + if ( isQuadMesh && SMESH_MeshEditor::IsMedium( node, SMDSAbs_Edge )) + continue; const SMDS_EdgePosition* epos = - static_cast(node->GetPosition().get()); + static_cast(node->GetPosition()); double u = ( epos->GetUParameter() - f ) / ( l - f ); (*pIt)->myInitXYZ.SetCoord( iCoord, isForward ? u : 1 - u ); } @@ -3192,11 +3271,12 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, { SMDS_ElemIteratorPtr elemIt = aSubMesh->GetElements(); while ( elemIt->more() ) { - SMDS_ElemIteratorPtr nIt = elemIt->next()->nodesIterator(); + const SMDS_MeshElement* elem = elemIt->next(); myElemPointIDs.push_back( TElemDef() ); TElemDef& elemPoints = myElemPointIDs.back(); - while ( nIt->more() ) - elemPoints.push_back( nodePointIDMap[ nIt->next() ]); + int nbNodes = elem->NbCornerNodes(); + for ( int i = 0;i < nbNodes; ++i ) + elemPoints.push_back( nodePointIDMap[ elem->GetNode( i )]); } } @@ -3644,13 +3724,8 @@ bool SMESH_Pattern:: vector& theQuantity) { bool makePoly = false; -// cout << "FROM FACE NODES: " < bndNodeSet; - for ( int i = 0; i < theNbBndNodes; ++i ) - bndNodeSet.insert( theBndNodes[ i ]); + set< const SMDS_MeshNode* > bndNodeSet( theBndNodes, theBndNodes + theNbBndNodes); map< TNodeSet, list< list< int > > >::iterator nn_IdList; @@ -3659,12 +3734,13 @@ bool SMESH_Pattern:: if ( !myIs2D ) { // for 2D, merge only edges nn_IdList = myIdsOnBoundary.find( bndNodeSet ); if ( nn_IdList != myIdsOnBoundary.end() ) { - makePoly = true; list< int > & faceIds = nn_IdList->second.front(); - ids.insert( faceIds.begin(), faceIds.end() ); + if ( !faceIds.empty() ) { + makePoly = true; + ids.insert( faceIds.begin(), faceIds.end() ); + } } } - //bool hasIdsInFace = !ids.empty(); // add ids on links and bnd nodes int lastFreeId = Max( myXYZIdToNodeMap.rbegin()->first, theNodes.size() ); @@ -3680,22 +3756,26 @@ bool SMESH_Pattern:: bndId = nn_IdList->second.front().front(); ids.insert( bndId ); } - else + else { myXYZIdToNodeMap.insert( make_pair( bndId, theBndNodes[ iN ] )); + } faceDef.push_back( bndId ); // add ids on a link TNodeSet linkNodes; linkNodes.insert( theBndNodes[ iN ]); - linkNodes.insert( theBndNodes[ iN + 1 == theNbBndNodes ? 0 : iN + 1 ]); + linkNodes.insert( theBndNodes[ (iN + 1) % theNbBndNodes] ); nn_IdList = myIdsOnBoundary.find( linkNodes ); if ( nn_IdList != myIdsOnBoundary.end() ) { - makePoly = true; list< int > & linkIds = nn_IdList->second.front(); - ids.insert( linkIds.begin(), linkIds.end() ); - if ( isReversed( theBndNodes[ iN ], linkIds )) - faceDef.insert( faceDef.end(), linkIds.begin(), linkIds.end() ); - else - faceDef.insert( faceDef.end(), linkIds.rbegin(), linkIds.rend() ); + if ( !linkIds.empty() ) + { + makePoly = true; + ids.insert( linkIds.begin(), linkIds.end() ); + if ( isReversed( theBndNodes[ iN ], linkIds )) + faceDef.insert( faceDef.end(), linkIds.begin(), linkIds.end() ); + else + faceDef.insert( faceDef.end(), linkIds.rbegin(), linkIds.rend() ); + } } } @@ -3717,9 +3797,7 @@ bool SMESH_Pattern:: { if ( !checkedVolDefs.insert( *pIdList ).second ) continue; // skip already checked volume definition - vector< int > idVec; - idVec.reserve( (*pIdList)->size() ); - idVec.insert( idVec.begin(), (*pIdList)->begin(), (*pIdList)->end() ); + vector< int > idVec( (*pIdList)->begin(), (*pIdList)->end() ); // loop on face defs of a volume SMDS_VolumeTool::VolumeType volType = vol.GetType( idVec.size() ); if ( volType == SMDS_VolumeTool::UNKNOWN ) @@ -3749,7 +3827,7 @@ bool SMESH_Pattern:: } if ( !defsAdded ) { theQuantity.push_back( faceDef.size() ); - theFaceDefs.splice( theFaceDefs.end(), faceDef, faceDef.begin(), faceDef.end() ); + theFaceDefs.splice( theFaceDefs.end(), faceDef ); } return makePoly; @@ -3766,11 +3844,9 @@ static bool clearSubMesh( SMESH_Mesh* theMesh, bool removed = false; if ( SMESH_subMesh * aSubMesh = theMesh->GetSubMeshContaining( theShape )) { - if ( aSubMesh->GetSubMeshDS() ) { - removed = - aSubMesh->GetSubMeshDS()->NbElements() || aSubMesh->GetSubMeshDS()->NbNodes(); + removed = !aSubMesh->IsEmpty(); + if ( removed ) aSubMesh->ComputeStateEngine( SMESH_subMesh::CLEAN ); - } } else { SMESHDS_Mesh* aMeshDS = theMesh->GetMeshDS(); @@ -3815,7 +3891,7 @@ void SMESH_Pattern::clearMesh(SMESH_Mesh* theMesh) const // coordinates computed by either of Apply...() methods // WARNING : StdMeshers_Projection_... relies on MakeMesh() behavior: that // it does not care of nodes and elements already existing on -// subshapes. DO NOT MERGE them or modify also StdMeshers_Projection_.. +// sub-shapes. DO NOT MERGE them or modify also StdMeshers_Projection_.. //======================================================================= bool SMESH_Pattern::MakeMesh(SMESH_Mesh* theMesh, @@ -3884,7 +3960,7 @@ bool SMESH_Pattern::MakeMesh(SMESH_Mesh* theMesh, point->myXYZ.Z()); nodesVector [ pIndex ] = node; - if ( true /*subMeshDS*/ ) { + if ( !S.IsNull() /*subMeshDS*/ ) { // !!!!! do not merge new nodes with ones existing on submeshes (see method comment) switch ( S.ShapeType() ) { case TopAbs_VERTEX: { @@ -3922,6 +3998,8 @@ bool SMESH_Pattern::MakeMesh(SMESH_Mesh* theMesh, createElements( theMesh, nodesVector, myElemPointIDs, myElements ); } + aMeshDS->compactMesh(); + // const map& sm = aMeshDS->SubMeshes(); // map::const_iterator i_sm = sm.begin(); // for ( ; i_sm != sm.end(); i_sm++ ) @@ -3948,7 +4026,7 @@ void SMESH_Pattern::createElements(SMESH_Mesh* theMes const vector& theElements) { SMESHDS_Mesh* aMeshDS = theMesh->GetMeshDS(); - SMESH_MeshEditor editor( theMesh ); + SMESH_MeshEditor editor( theMesh ); bool onMeshElements = !theElements.empty(); @@ -4069,10 +4147,12 @@ void SMESH_Pattern::createElements(SMESH_Mesh* theMes SMDS_ElemIteratorPtr noIt = elem->nodesIterator(); while ( noIt->more() ) { SMDS_MeshNode* node = const_cast(smdsNode( noIt->next() )); - if (!node->GetPosition()->GetShapeId() && + if (!node->getshapeId() && shellNodes.find( node ) == shellNodes.end() ) { if ( S.ShapeType() == TopAbs_FACE ) - aMeshDS->SetNodeOnFace( node, shapeID ); + aMeshDS->SetNodeOnFace( node, shapeID, + Precision::Infinite(),// <- it's a sign that UV is not set + Precision::Infinite()); else { aMeshDS->SetNodeInVolume( node, shapeID ); shellNodes.insert( node ); @@ -4164,7 +4244,7 @@ void SMESH_Pattern::arrangeBoundaries (list< list< TPoint* > >& boundaryList) if ( nbBoundaries > 2 ) { // move boundaries in tmp list - list< list< TPoint* > > tmpList; + list< list< TPoint* > > tmpList; tmpList.splice( tmpList.begin(), boundaryList, boundaryList.begin(), boundaryList.end()); // make a map nb-key-points to boundary-position-in-tmpList, // boundary-positions get ordered in it @@ -4207,7 +4287,7 @@ void SMESH_Pattern::arrangeBoundaries (list< list< TPoint* > >& boundaryList) boundaryList.splice( boundaryList.begin(), boundaryList, outerBndPos, ++outerBndPos ); } // if nbBoundaries > 1 - + // Check boundaries orientation and re-fill myKeyPointIDs set< TPoint* > keyPointSet; @@ -4478,7 +4558,7 @@ bool SMESH_Pattern::findBoundaryPoints() getShapePoints( shapeID ).push_back( point ); // detect key-points if ( SMESH_Block::IsVertexID( shapeID )) - myKeyPointIDs.push_back( i ); + myKeyPointIDs.push_back( i ); } } @@ -4502,6 +4582,29 @@ void SMESH_Pattern::Clear() myShapeIDMap.Clear(); myShape.Nullify(); myNbKeyPntInBoundary.clear(); + + myXYZ.clear(); + myElemXYZIDs.clear(); + myXYZIdToNodeMap.clear(); + myElements.clear(); + myOrderedNodes.clear(); + myPolyElems.clear(); + myPolyElemXYZIDs.clear(); + myPolyhedronQuantities.clear(); + myIdsOnBoundary.clear(); + myReverseConnectivity.clear(); +} + +//================================================================================ +/*! + * \brief set ErrorCode and return true if it is Ok + */ +//================================================================================ + +bool SMESH_Pattern::setErrorCode( const ErrorCode theErrorCode ) +{ + myErrorCode = theErrorCode; + return myErrorCode == ERR_OK; } //======================================================================= @@ -4526,13 +4629,19 @@ bool SMESH_Pattern::setShapeToMesh(const TopoDS_Shape& theShape) // check if a face is closed int nbNodeOnSeamEdge = 0; if ( myIs2D ) { + TopTools_MapOfShape seamVertices; TopoDS_Face face = TopoDS::Face( theShape ); TopExp_Explorer eExp( theShape, TopAbs_EDGE ); - for ( ; eExp.More() && nbNodeOnSeamEdge == 0; eExp.Next() ) - if ( BRep_Tool::IsClosed( TopoDS::Edge( eExp.Current() ), face )) - nbNodeOnSeamEdge = 2; + for ( ; eExp.More() && nbNodeOnSeamEdge == 0; eExp.Next() ) { + const TopoDS_Edge& ee = TopoDS::Edge(eExp.Current()); + if ( BRep_Tool::IsClosed(ee, face) ) { + // seam edge and vertices encounter twice in theFace + if ( !seamVertices.Add( TopExp::FirstVertex( ee ))) nbNodeOnSeamEdge++; + if ( !seamVertices.Add( TopExp::LastVertex( ee ))) nbNodeOnSeamEdge++; + } + } } - + // check nb of vertices TopTools_IndexedMapOfShape vMap; TopExp::MapShapes( theShape, TopAbs_VERTEX, vMap ); @@ -4634,7 +4743,7 @@ void SMESH_Pattern::DumpPoints() const #ifdef _DEBUG_ vector< TPoint >::const_iterator pVecIt = myPoints.begin(); for ( int i = 0; pVecIt != myPoints.end(); pVecIt++, i++ ) - cout << i << ": " << *pVecIt; + MESSAGE_ADD ( std::endl << i << ": " << *pVecIt ); #endif } @@ -4674,6 +4783,6 @@ ostream & operator <<(ostream & OS, const SMESH_Pattern::TPoint& p) OS << " uv( " << xy.X() << " " << xy.Y() << " )"; u = p.myU; OS << " u( " << u << " ))" << endl; - + return OS; }