X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSMESH%2FSMESH_MeshEditor.cxx;h=4771bf9a02ad536bf87f1b2cd6e90005b4209b2d;hb=95fc74d3fb3e15ea60c2167d20b6d1561d078191;hp=eccd73600dc0c08d225fe911eef8f81f7e14aa26;hpb=fe605cfaac5868bb11b3e9af6df917b0cc2611ec;p=modules%2Fsmesh.git diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx index eccd73600..4771bf9a0 100644 --- a/src/SMESH/SMESH_MeshEditor.cxx +++ b/src/SMESH/SMESH_MeshEditor.cxx @@ -35,6 +35,7 @@ #include "SMDS_FacePosition.hxx" #include "SMDS_SpacePosition.hxx" #include "SMDS_QuadraticFaceOfNodes.hxx" +#include "SMDS_MeshGroup.hxx" #include "SMESHDS_Group.hxx" #include "SMESHDS_Mesh.hxx" @@ -43,31 +44,35 @@ #include "SMESH_ControlsDef.hxx" #include "SMESH_MesherHelper.hxx" #include "SMESH_OctreeNode.hxx" +#include "SMESH_Group.hxx" #include "utilities.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include -#include +#include #include #include +#include #include -#include +#include +#include #include +#include +#include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include @@ -79,26 +84,37 @@ using namespace SMESH::Controls; typedef map > TElemOfNodeListMap; typedef map > TElemOfElemListMap; -typedef map > TNodeOfNodeListMap; -typedef TNodeOfNodeListMap::iterator TNodeOfNodeListMapItr; //typedef map > TNodeOfNodeVecMap; //typedef TNodeOfNodeVecMap::iterator TNodeOfNodeVecMapItr; -typedef map > TElemOfVecOfNnlmiMap; //typedef map > TElemOfVecOfMapNodesMap; -typedef pair< const SMDS_MeshNode*, const SMDS_MeshNode* > NLink; - struct TNodeXYZ : public gp_XYZ { TNodeXYZ( const SMDS_MeshNode* n ):gp_XYZ( n->X(), n->Y(), n->Z() ) {} }; +typedef pair< const SMDS_MeshNode*, const SMDS_MeshNode* > NLink; + +//======================================================================= +/*! + * \brief A sorted pair of nodes + */ +//======================================================================= + +struct TLink: public NLink +{ + TLink(const SMDS_MeshNode* n1, const SMDS_MeshNode* n2 ):NLink( n1, n2 ) + { if ( n1->GetID() < n2->GetID() ) std::swap( first, second ); } + TLink(const NLink& link ):NLink( link ) + { if ( first->GetID() < second->GetID() ) std::swap( first, second ); } +}; + //======================================================================= //function : SMESH_MeshEditor //purpose : //======================================================================= -SMESH_MeshEditor::SMESH_MeshEditor( SMESH_Mesh* theMesh ): -myMesh( theMesh ) +SMESH_MeshEditor::SMESH_MeshEditor( SMESH_Mesh* theMesh ) + :myMesh( theMesh ) // theMesh may be NULL { } @@ -258,18 +274,26 @@ bool SMESH_MeshEditor::Remove (const list< int >& theIDs, if ( !elem ) continue; - // Find sub-meshes to notify about modification - SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator(); - while ( nodeIt->more() ) { - const SMDS_MeshNode* node = static_cast( nodeIt->next() ); - const SMDS_PositionPtr& aPosition = node->GetPosition(); - if ( aPosition.get() ) { - if ( int aShapeID = aPosition->GetShapeId() ) { + // Notify VERTEX sub-meshes about modification + if ( isNodes ) { + const SMDS_MeshNode* node = cast2Node( elem ); + if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX ) + if ( int aShapeID = node->GetPosition()->GetShapeId() ) if ( SMESH_subMesh * sm = GetMesh()->GetSubMeshContaining( aShapeID ) ) smmap.insert( sm ); - } - } } + // Find sub-meshes to notify about modification +// SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator(); +// while ( nodeIt->more() ) { +// const SMDS_MeshNode* node = static_cast( nodeIt->next() ); +// const SMDS_PositionPtr& aPosition = node->GetPosition(); +// if ( aPosition.get() ) { +// if ( int aShapeID = aPosition->GetShapeId() ) { +// if ( SMESH_subMesh * sm = GetMesh()->GetSubMeshContaining( aShapeID ) ) +// smmap.insert( sm ); +// } +// } +// } // Do remove if ( isNodes ) @@ -285,9 +309,9 @@ bool SMESH_MeshEditor::Remove (const list< int >& theIDs, (*smIt)->ComputeStateEngine( SMESH_subMesh::MESH_ENTITY_REMOVED ); } - // Check if the whole mesh becomes empty - if ( SMESH_subMesh * sm = GetMesh()->GetSubMeshContaining( 1 ) ) - sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE ); +// // Check if the whole mesh becomes empty +// if ( SMESH_subMesh * sm = GetMesh()->GetSubMeshContaining( 1 ) ) +// sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE ); return true; } @@ -715,9 +739,8 @@ bool getQuadrangleNodes(const SMDS_MeshNode * theQuadNodes [], const SMDS_MeshNode* n4 = 0; SMDS_ElemIteratorPtr it = tr2->nodesIterator(); int i=0; - //while ( !n4 && it->more() ) { while ( !n4 && i<3 ) { - const SMDS_MeshNode * n = static_cast( it->next() ); + const SMDS_MeshNode * n = cast2Node( it->next() ); i++; bool isDiag = ( n == theNode1 || n == theNode2 ); if ( !isDiag ) @@ -727,9 +750,8 @@ bool getQuadrangleNodes(const SMDS_MeshNode * theQuadNodes [], int iNode = 0, iFirstDiag = -1; it = tr1->nodesIterator(); i=0; - //while ( it->more() ) { while ( i<3 ) { - const SMDS_MeshNode * n = static_cast( it->next() ); + const SMDS_MeshNode * n = cast2Node( it->next() ); i++; bool isDiag = ( n == theNode1 || n == theNode2 ); if ( isDiag ) { @@ -1152,7 +1174,7 @@ void SMESH_MeshEditor::AddToSameGroups (const SMDS_MeshElement* elemToAdd, set::const_iterator grIt = groups.begin(); for ( ; grIt != groups.end(); grIt++ ) { SMESHDS_Group* group = dynamic_cast( *grIt ); - if ( group && group->SMDSGroup().Contains( elemInGroups )) + if ( group && group->Contains( elemInGroups )) group->SMDSGroup().Add( elemToAdd ); } } @@ -1433,27 +1455,19 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems, return false; SMESHDS_Mesh * aMesh = GetMeshDS(); - //LinkID_Gen aLinkID_Gen( aMesh ); // Prepare data for algo: build // 1. map of elements with their linkIDs // 2. map of linkIDs with their elements - //map< long, list< const SMDS_MeshElement* > > mapLi_listEl; - //map< long, list< const SMDS_MeshElement* > >::iterator itLE; - //map< const SMDS_MeshElement*, set< long > > mapEl_setLi; - //map< const SMDS_MeshElement*, set< long > >::iterator itEL; - - map< NLink, list< const SMDS_MeshElement* > > mapLi_listEl; - map< NLink, list< const SMDS_MeshElement* > >::iterator itLE; - map< const SMDS_MeshElement*, set< NLink > > mapEl_setLi; - map< const SMDS_MeshElement*, set< NLink > >::iterator itEL; + map< TLink, list< const SMDS_MeshElement* > > mapLi_listEl; + map< TLink, list< const SMDS_MeshElement* > >::iterator itLE; + map< const SMDS_MeshElement*, set< TLink > > mapEl_setLi; + map< const SMDS_MeshElement*, set< TLink > >::iterator itEL; TIDSortedElemSet::iterator itElem; for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) { const SMDS_MeshElement* elem = *itElem; - //if ( !elem || elem->NbNodes() != 3 ) - // continue; if(!elem || elem->GetType() != SMDSAbs_Face ) continue; bool IsTria = elem->NbNodes()==3 || (elem->NbNodes()==6 && elem->IsQuadratic()); if(!IsTria) continue; @@ -1462,19 +1476,14 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems, const SMDS_MeshNode* aNodes [4]; SMDS_ElemIteratorPtr itN = elem->nodesIterator(); int i = 0; - //while ( itN->more() ) while ( i<3 ) - aNodes[ i++ ] = static_cast( itN->next() ); - ASSERT( i == 3 ); + aNodes[ i++ ] = cast2Node( itN->next() ); aNodes[ 3 ] = aNodes[ 0 ]; // fill maps for ( i = 0; i < 3; i++ ) { - //long linkID = aLinkID_Gen.GetLinkID( aNodes[ i ], aNodes[ i+1 ] ); - NLink link(( aNodes[i] < aNodes[i+1] ? aNodes[i] : aNodes[i+1] ), - ( aNodes[i] < aNodes[i+1] ? aNodes[i+1] : aNodes[i] )); + TLink link( aNodes[i], aNodes[i+1] ); // check if elements sharing a link can be fused - //itLE = mapLi_listEl.find( linkID ); itLE = mapLi_listEl.find( link ); if ( itLE != mapLi_listEl.end() ) { if ((*itLE).second.size() > 1 ) // consider only 2 elems adjacent by a link @@ -1487,10 +1496,8 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems, (*itLE).second.push_back( elem ); } else { - //mapLi_listEl[ linkID ].push_back( elem ); mapLi_listEl[ link ].push_back( elem ); } - //mapEl_setLi [ elem ].insert( linkID ); mapEl_setLi [ elem ].insert( link ); } } @@ -1501,8 +1508,7 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems, int nbElems = (*itLE).second.size(); if ( nbElems < 2 ) { const SMDS_MeshElement* elem = (*itLE).second.front(); - //long link = (*itLE).first; - NLink link = (*itLE).first; + TLink link = (*itLE).first; mapEl_setLi[ elem ].erase( link ); if ( mapEl_setLi[ elem ].empty() ) mapEl_setLi.erase( elem ); @@ -1514,7 +1520,6 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems, while ( ! mapEl_setLi.empty() ) { // Look for the start element: // the element having the least nb of shared links - const SMDS_MeshElement* startElem = 0; int minNbLinks = 4; for ( itEL = mapEl_setLi.begin(); itEL != mapEl_setLi.end(); itEL++ ) { @@ -1529,13 +1534,11 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems, // search elements to fuse starting from startElem or links of elements // fused earlyer - startLinks - //list< long > startLinks; - list< NLink > startLinks; + list< TLink > startLinks; while ( startElem || !startLinks.empty() ) { while ( !startElem && !startLinks.empty() ) { // Get an element to start, by a link - //long linkId = startLinks.front(); - NLink linkId = startLinks.front(); + TLink linkId = startLinks.front(); startLinks.pop_front(); itLE = mapLi_listEl.find( linkId ); if ( itLE != mapLi_listEl.end() ) { @@ -1551,19 +1554,16 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems, if ( startElem ) { // Get candidates to be fused const SMDS_MeshElement *tr1 = startElem, *tr2 = 0, *tr3 = 0; - //long link12, link13; - NLink link12, link13; + const TLink *link12, *link13; startElem = 0; ASSERT( mapEl_setLi.find( tr1 ) != mapEl_setLi.end() ); - //set< long >& setLi = mapEl_setLi[ tr1 ]; - set< NLink >& setLi = mapEl_setLi[ tr1 ]; + set< TLink >& setLi = mapEl_setLi[ tr1 ]; ASSERT( !setLi.empty() ); - //set< long >::iterator itLi; - set< NLink >::iterator itLi; - for ( itLi = setLi.begin(); itLi != setLi.end(); itLi++ ) { - //long linkID = (*itLi); - NLink linkID = (*itLi); - itLE = mapLi_listEl.find( linkID ); + set< TLink >::iterator itLi; + for ( itLi = setLi.begin(); itLi != setLi.end(); itLi++ ) + { + const TLink & link = (*itLi); + itLE = mapLi_listEl.find( link ); if ( itLE == mapLi_listEl.end() ) continue; @@ -1575,50 +1575,36 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems, continue; if ( tr2 ) { tr3 = elem; - link13 = linkID; + link13 = &link; } else { tr2 = elem; - link12 = linkID; + link12 = &link; } // add other links of elem to list of links to re-start from - //set< long >& links = mapEl_setLi[ elem ]; - //set< long >::iterator it; - set< NLink >& links = mapEl_setLi[ elem ]; - set< NLink >::iterator it; + set< TLink >& links = mapEl_setLi[ elem ]; + set< TLink >::iterator it; for ( it = links.begin(); it != links.end(); it++ ) { - //long linkID2 = (*it); - NLink linkID2 = (*it); - if ( linkID2 != linkID ) - startLinks.push_back( linkID2 ); + const TLink& link2 = (*it); + if ( link2 != link ) + startLinks.push_back( link2 ); } } // Get nodes of possible quadrangles const SMDS_MeshNode *n12 [4], *n13 [4]; bool Ok12 = false, Ok13 = false; - //const SMDS_MeshNode *linkNode1, *linkNode2; const SMDS_MeshNode *linkNode1, *linkNode2; if(tr2) { - //const SMDS_MeshNode *linkNode1 = link12.first; - //const SMDS_MeshNode *linkNode2 = link12.second; - linkNode1 = link12.first; - linkNode2 = link12.second; - //if ( tr2 && - // aLinkID_Gen.GetNodes( link12, linkNode1, linkNode2 ) && - // getQuadrangleNodes( n12, linkNode1, linkNode2, tr1, tr2 )) - // Ok12 = true; + linkNode1 = link12->first; + linkNode2 = link12->second; if ( tr2 && getQuadrangleNodes( n12, linkNode1, linkNode2, tr1, tr2 )) Ok12 = true; } if(tr3) { - linkNode1 = link13.first; - linkNode2 = link13.second; - //if ( tr3 && - // aLinkID_Gen.GetNodes( link13, linkNode1, linkNode2 ) && - // getQuadrangleNodes( n13, linkNode1, linkNode2, tr1, tr3 )) - // Ok13 = true; + linkNode1 = link13->first; + linkNode2 = link13->second; if ( tr3 && getQuadrangleNodes( n13, linkNode1, linkNode2, tr1, tr3 )) Ok13 = true; } @@ -1640,7 +1626,7 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems, mapEl_setLi.erase( tr1 ); if ( Ok12 ) { mapEl_setLi.erase( tr2 ); - mapLi_listEl.erase( link12 ); + mapLi_listEl.erase( *link12 ); if(tr1->NbNodes()==3) { if( tr1->GetID() < tr2->GetID() ) { aMesh->ChangeElementNodes( tr1, n12, 4 ); @@ -1685,7 +1671,7 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet & theElems, } else if ( Ok13 ) { mapEl_setLi.erase( tr3 ); - mapLi_listEl.erase( link13 ); + mapLi_listEl.erase( *link13 ); if(tr1->NbNodes()==3) { if( tr1->GetID() < tr2->GetID() ) { aMesh->ChangeElementNodes( tr1, n13, 4 ); @@ -2734,8 +2720,8 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems, // iNotSame is where prevNodes and nextNodes are different //======================================================================= -static bool isReverse(const SMDS_MeshNode* prevNodes[], - const SMDS_MeshNode* nextNodes[], +static bool isReverse(vector prevNodes, + vector nextNodes, const int nbNodes, const int iNotSame) { @@ -2758,26 +2744,37 @@ static bool isReverse(const SMDS_MeshNode* prevNodes[], } //======================================================================= -//function : sweepElement -//purpose : +/*! + * \brief Create elements by sweeping an element + * \param elem - element to sweep + * \param newNodesItVec - nodes generated from each node of the element + * \param newElems - generated elements + * \param nbSteps - number of sweeping steps + * \param srcElements - to append elem for each generated element + */ //======================================================================= -static void sweepElement(SMESHDS_Mesh* aMesh, - const SMDS_MeshElement* elem, - const vector & newNodesItVec, - list& newElems, - const int nbSteps, - SMESH_SequenceOfElemPtr& myLastCreatedElems) +void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement* elem, + const vector & newNodesItVec, + list& newElems, + const int nbSteps, + SMESH_SequenceOfElemPtr& srcElements) { + SMESHDS_Mesh* aMesh = GetMeshDS(); + // Loop on elem nodes: // find new nodes and detect same nodes indices int nbNodes = elem->NbNodes(); - list::const_iterator itNN[ nbNodes ]; - const SMDS_MeshNode* prevNod[ nbNodes ], *nextNod[ nbNodes ], *midlNod[ nbNodes ]; + vector < list< const SMDS_MeshNode* >::const_iterator > itNN( nbNodes ); + vector prevNod( nbNodes ); + vector nextNod( nbNodes ); + vector midlNod( nbNodes ); + int iNode, nbSame = 0, iNotSameNode = 0, iSameNode = 0; vector sames(nbNodes); - bool issimple[nbNodes]; + //bool issimple[nbNodes]; + vector issimple(nbNodes); for ( iNode = 0; iNode < nbNodes; iNode++ ) { TNodeOfNodeListMapItr nnIt = newNodesItVec[ iNode ]; @@ -2844,8 +2841,7 @@ static void sweepElement(SMESHDS_Mesh* aMesh, } // make new elements - int iStep;//, nbSteps = newNodesItVec[ 0 ]->second.size(); - for (iStep = 0; iStep < nbSteps; iStep++ ) { + for (int iStep = 0; iStep < nbSteps; iStep++ ) { // get next nodes for ( iNode = 0; iNode < nbNodes; iNode++ ) { if(issimple[iNode]) { @@ -3061,6 +3057,7 @@ static void sweepElement(SMESHDS_Mesh* aMesh, if ( aNewElem ) { newElems.push_back( aNewElem ); myLastCreatedElems.Append(aNewElem); + srcElements.Append( elem ); } // set new prev nodes @@ -3071,19 +3068,26 @@ static void sweepElement(SMESHDS_Mesh* aMesh, } //======================================================================= -//function : makeWalls -//purpose : create 1D and 2D elements around swept elements +/*! + * \brief Create 1D and 2D elements around swept elements + * \param mapNewNodes - source nodes and ones generated from them + * \param newElemsMap - source elements and ones generated from them + * \param elemNewNodesMap - nodes generated from each node of each element + * \param elemSet - all swept elements + * \param nbSteps - number of sweeping steps + * \param srcElements - to append elem for each generated element + */ //======================================================================= -static void makeWalls (SMESHDS_Mesh* aMesh, - TNodeOfNodeListMap & mapNewNodes, - TElemOfElemListMap & newElemsMap, - TElemOfVecOfNnlmiMap & elemNewNodesMap, - TIDSortedElemSet& elemSet, - const int nbSteps, - SMESH_SequenceOfElemPtr& myLastCreatedElems) +void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap & mapNewNodes, + TElemOfElemListMap & newElemsMap, + TElemOfVecOfNnlmiMap & elemNewNodesMap, + TIDSortedElemSet& elemSet, + const int nbSteps, + SMESH_SequenceOfElemPtr& srcElements) { ASSERT( newElemsMap.size() == elemNewNodesMap.size() ); + SMESHDS_Mesh* aMesh = GetMeshDS(); // Find nodes belonging to only one initial element - sweep them to get edges. @@ -3111,7 +3115,7 @@ static void makeWalls (SMESHDS_Mesh* aMesh, if(!NotCreateEdge) { vector newNodesItVec( 1, nList ); list newEdges; - sweepElement( aMesh, node, newNodesItVec, newEdges, nbSteps, myLastCreatedElems ); + sweepElement( node, newNodesItVec, newEdges, nbSteps, srcElements ); } } } @@ -3129,17 +3133,21 @@ static void makeWalls (SMESHDS_Mesh* aMesh, // create a ceiling edge if (!elem->IsQuadratic()) { if ( !aMesh->FindEdge( vecNewNodes[ 0 ]->second.back(), - vecNewNodes[ 1 ]->second.back())) + vecNewNodes[ 1 ]->second.back())) { myLastCreatedElems.Append(aMesh->AddEdge(vecNewNodes[ 0 ]->second.back(), vecNewNodes[ 1 ]->second.back())); + srcElements.Append( myLastCreatedElems.Last() ); + } } else { if ( !aMesh->FindEdge( vecNewNodes[ 0 ]->second.back(), vecNewNodes[ 1 ]->second.back(), - vecNewNodes[ 2 ]->second.back())) + vecNewNodes[ 2 ]->second.back())) { myLastCreatedElems.Append(aMesh->AddEdge(vecNewNodes[ 0 ]->second.back(), vecNewNodes[ 1 ]->second.back(), vecNewNodes[ 2 ]->second.back())); + srcElements.Append( myLastCreatedElems.Last() ); + } } } if ( elem->GetType() != SMDSAbs_Face ) @@ -3167,12 +3175,14 @@ static void makeWalls (SMESHDS_Mesh* aMesh, hasFreeLinks = true; // make an edge and a ceiling for a new edge if ( !aMesh->FindEdge( n1, n2 )) { - myLastCreatedElems.Append(aMesh->AddEdge( n1, n2 )); + myLastCreatedElems.Append(aMesh->AddEdge( n1, n2 )); // free link edge + srcElements.Append( myLastCreatedElems.Last() ); } n1 = vecNewNodes[ iNode ]->second.back(); n2 = vecNewNodes[ iNext ]->second.back(); if ( !aMesh->FindEdge( n1, n2 )) { - myLastCreatedElems.Append(aMesh->AddEdge( n1, n2 )); + myLastCreatedElems.Append(aMesh->AddEdge( n1, n2 )); // ceiling edge + srcElements.Append( myLastCreatedElems.Last() ); } } } @@ -3191,13 +3201,15 @@ static void makeWalls (SMESHDS_Mesh* aMesh, // find medium node const SMDS_MeshNode* n3 = vecNewNodes[ iNode+nbn ]->first; if ( !aMesh->FindEdge( n1, n2, n3 )) { - myLastCreatedElems.Append(aMesh->AddEdge( n1, n2, n3 )); + myLastCreatedElems.Append(aMesh->AddEdge( n1, n2, n3 )); // free link edge + srcElements.Append( myLastCreatedElems.Last() ); } n1 = vecNewNodes[ iNode ]->second.back(); n2 = vecNewNodes[ iNext ]->second.back(); n3 = vecNewNodes[ iNode+nbn ]->second.back(); if ( !aMesh->FindEdge( n1, n2, n3 )) { - myLastCreatedElems.Append(aMesh->AddEdge( n1, n2, n3 )); + myLastCreatedElems.Append(aMesh->AddEdge( n1, n2, n3 )); // ceiling edge + srcElements.Append( myLastCreatedElems.Last() ); } } } @@ -3210,7 +3222,6 @@ static void makeWalls (SMESHDS_Mesh* aMesh, if ( hasFreeLinks ) { list & newVolumes = itElem->second; - int iStep; //, nbSteps = vecNewNodes[0]->second.size(); int iVol, volNb, nbVolumesByStep = newVolumes.size() / nbSteps; set initNodeSet, faceNodeSet; @@ -3223,24 +3234,51 @@ static void makeWalls (SMESHDS_Mesh* aMesh, while ( iVol++ < volNb ) v++; // find indices of free faces of a volume list< int > fInd; + list< const SMDS_MeshElement* > srcEdges; // source edges of free faces SMDS_VolumeTool vTool( *v ); int iF, nbF = vTool.NbFaces(); for ( iF = 0; iF < nbF; iF ++ ) { if (vTool.IsFreeFace( iF ) && vTool.GetFaceNodes( iF, faceNodeSet ) && initNodeSet != faceNodeSet) // except an initial face + { fInd.push_back( iF ); + // find source edge of a free face iF + vector commonNodes; // shared by the initial and free faces + commonNodes.resize( initNodeSet.size(), NULL ); // avoid spoiling memory + std::set_intersection( faceNodeSet.begin(), faceNodeSet.end(), + initNodeSet.begin(), initNodeSet.end(), + commonNodes.begin()); + if (!commonNodes[ 1 + int((*v)->IsQuadratic()) ]) { +#ifdef _DEBUG_ + throw SALOME_Exception(LOCALIZED("Common nodes not found")); +#else + srcEdges.push_back( NULL ); +#endif + } + if ( (*v)->IsQuadratic() ) + srcEdges.push_back(aMesh-> FindEdge (commonNodes[0],commonNodes[1],commonNodes[2])); + else + srcEdges.push_back(aMesh-> FindEdge (commonNodes[0],commonNodes[1])); +#ifdef _DEBUG_ + if ( !srcEdges.back() ) + throw SALOME_Exception(LOCALIZED("Source edge not found")); +#endif + } } if ( fInd.empty() ) continue; - // create faces for all steps - // if such a face has been already created by sweep of edge, assure that its orientation is OK - for ( iStep = 0; iStep < nbSteps; iStep++ ) { + // create faces for all steps; + // if such a face has been already created by sweep of edge, + // assure that its orientation is OK + for ( int iStep = 0; iStep < nbSteps; iStep++ ) { vTool.Set( *v ); vTool.SetExternalNormal(); list< int >::iterator ind = fInd.begin(); - for ( ; ind != fInd.end(); ind++ ) { + list< const SMDS_MeshElement* >::iterator srcEdge = srcEdges.begin(); + for ( ; ind != fInd.end(); ++ind, ++srcEdge ) // loop on free faces + { const SMDS_MeshNode** nodes = vTool.GetFaceNodes( *ind ); int nbn = vTool.NbFaceNodes( *ind ); switch ( nbn ) { @@ -3290,7 +3328,11 @@ static void makeWalls (SMESHDS_Mesh* aMesh, aMesh->ChangeElementNodes( f, nodes, nbn ); } } - } + while ( srcElements.Length() < myLastCreatedElems.Length() ) + srcElements.Append( *srcEdge ); + + } // loop on free faces + // go to the next volume iVol = 0; while ( iVol++ < nbVolumesByStep ) v++; @@ -3298,7 +3340,7 @@ static void makeWalls (SMESHDS_Mesh* aMesh, } } // sweep free links into faces - // make a ceiling face with a normal external to a volume + // Make a ceiling face with a normal external to a volume SMDS_VolumeTool lastVol( itElem->second.back() ); @@ -3342,6 +3384,9 @@ static void makeWalls (SMESHDS_Mesh* aMesh, myLastCreatedElems.Append(aMesh->AddPolygonalFace(polygon_nodes)); } } // switch + + while ( srcElements.Length() < myLastCreatedElems.Length() ) + srcElements.Append( myLastCreatedElems.Last() ); } } // loop on swept elements } @@ -3351,16 +3396,21 @@ static void makeWalls (SMESHDS_Mesh* aMesh, //purpose : //======================================================================= -void SMESH_MeshEditor::RotationSweep(TIDSortedElemSet & theElems, - const gp_Ax1& theAxis, - const double theAngle, - const int theNbSteps, - const double theTol, - const bool theMakeWalls) +SMESH_MeshEditor::PGroupIDs +SMESH_MeshEditor::RotationSweep(TIDSortedElemSet & theElems, + const gp_Ax1& theAxis, + const double theAngle, + const int theNbSteps, + const double theTol, + const bool theMakeGroups, + const bool theMakeWalls) { myLastCreatedElems.Clear(); myLastCreatedNodes.Clear(); + // source elements for each generated one + SMESH_SequenceOfElemPtr srcElems, srcNodes; + MESSAGE( "RotationSweep()"); gp_Trsf aTrsf; aTrsf.SetRotation( theAxis, theAngle ); @@ -3387,11 +3437,10 @@ void SMESH_MeshEditor::RotationSweep(TIDSortedElemSet & theElems, // loop on elem nodes SMDS_ElemIteratorPtr itN = elem->nodesIterator(); - while ( itN->more() ) { - + while ( itN->more() ) + { // check if a node has been already sweeped - const SMDS_MeshNode* node = - static_cast( itN->next() ); + const SMDS_MeshNode* node = cast2Node( itN->next() ); TNodeOfNodeListMapItr nIt = mapNewNodes.find( node ); if ( nIt == mapNewNodes.end() ) { nIt = mapNewNodes.insert( make_pair( node, list() )).first; @@ -3411,6 +3460,7 @@ void SMESH_MeshEditor::RotationSweep(TIDSortedElemSet & theElems, //aTrsf.Transforms( coord[0], coord[1], coord[2] ); newNode = aMesh->AddNode( coord[0], coord[1], coord[2] ); myLastCreatedNodes.Append(newNode); + srcNodes.Append( node ); listNewNodes.push_back( newNode ); aTrsf2.Transforms( coord[0], coord[1], coord[2] ); //aTrsf.Transforms( coord[0], coord[1], coord[2] ); @@ -3420,6 +3470,7 @@ void SMESH_MeshEditor::RotationSweep(TIDSortedElemSet & theElems, } newNode = aMesh->AddNode( coord[0], coord[1], coord[2] ); myLastCreatedNodes.Append(newNode); + srcNodes.Append( node ); } listNewNodes.push_back( newNode ); } @@ -3441,9 +3492,11 @@ void SMESH_MeshEditor::RotationSweep(TIDSortedElemSet & theElems, newNode = aMesh->AddNode( coord[0], coord[1], coord[2] ); myLastCreatedNodes.Append(newNode); listNewNodes.push_back( newNode ); + srcNodes.Append( node ); aTrsf2.Transforms( coord[0], coord[1], coord[2] ); newNode = aMesh->AddNode( coord[0], coord[1], coord[2] ); myLastCreatedNodes.Append(newNode); + srcNodes.Append( node ); listNewNodes.push_back( newNode ); } } @@ -3452,12 +3505,17 @@ void SMESH_MeshEditor::RotationSweep(TIDSortedElemSet & theElems, newNodesItVec.push_back( nIt ); } // make new elements - sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem], theNbSteps, myLastCreatedElems ); + sweepElement( elem, newNodesItVec, newElemsMap[elem], theNbSteps, srcElems ); } if ( theMakeWalls ) - makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, - theElems, theNbSteps, myLastCreatedElems ); + makeWalls( mapNewNodes, newElemsMap, mapElemNewNodes, theElems, theNbSteps, srcElems ); + + PGroupIDs newGroupIDs; + if ( theMakeGroups ) + newGroupIDs = generateGroups( srcNodes, srcElems, "rotated"); + + return newGroupIDs; } @@ -3510,12 +3568,14 @@ const SMDS_MeshNode* SMESH_MeshEditor::CreateNode(const double x, //purpose : //======================================================================= -void SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet & theElems, - const gp_Vec& theStep, - const int theNbSteps, - TElemOfElemListMap& newElemsMap, - const int theFlags, - const double theTolerance) +SMESH_MeshEditor::PGroupIDs +SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet & theElems, + const gp_Vec& theStep, + const int theNbSteps, + TElemOfElemListMap& newElemsMap, + const bool theMakeGroups, + const int theFlags, + const double theTolerance) { ExtrusParam aParams; aParams.myDir = gp_Dir(theStep); @@ -3525,8 +3585,8 @@ void SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet & theElems, for(i=1; i<=theNbSteps; i++) aParams.mySteps->Append(theStep.Magnitude()); - ExtrusionSweep(theElems,aParams,newElemsMap,theFlags,theTolerance); - + return + ExtrusionSweep(theElems,aParams,newElemsMap,theMakeGroups,theFlags,theTolerance); } @@ -3535,15 +3595,20 @@ void SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet & theElems, //purpose : //======================================================================= -void SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet & theElems, - ExtrusParam& theParams, - TElemOfElemListMap& newElemsMap, - const int theFlags, - const double theTolerance) +SMESH_MeshEditor::PGroupIDs +SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet & theElems, + ExtrusParam& theParams, + TElemOfElemListMap& newElemsMap, + const bool theMakeGroups, + const int theFlags, + const double theTolerance) { myLastCreatedElems.Clear(); myLastCreatedNodes.Clear(); + // source elements for each generated one + SMESH_SequenceOfElemPtr srcElems, srcNodes; + SMESHDS_Mesh* aMesh = GetMeshDS(); int nbsteps = theParams.mySteps->Length(); @@ -3567,11 +3632,10 @@ void SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet & theElems, // loop on elem nodes SMDS_ElemIteratorPtr itN = elem->nodesIterator(); - while ( itN->more() ) { - + while ( itN->more() ) + { // check if a node has been already sweeped - const SMDS_MeshNode* node = - static_cast( itN->next() ); + const SMDS_MeshNode* node = cast2Node( itN->next() ); TNodeOfNodeListMap::iterator nIt = mapNewNodes.find( node ); //TNodeOfNodeVecMap::iterator nIt = mapNewNodes.find( node ); if ( nIt == mapNewNodes.end() ) { @@ -3598,6 +3662,7 @@ void SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet & theElems, else { const SMDS_MeshNode * newNode = aMesh->AddNode(x, y, z); myLastCreatedNodes.Append(newNode); + srcNodes.Append( node ); listNewNodes.push_back( newNode ); } } @@ -3614,6 +3679,7 @@ void SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet & theElems, else { const SMDS_MeshNode * newNode = aMesh->AddNode( coord[0], coord[1], coord[2] ); myLastCreatedNodes.Append(newNode); + srcNodes.Append( node ); listNewNodes.push_back( newNode ); //vecNewNodes[i]=newNode; } @@ -3639,6 +3705,7 @@ void SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet & theElems, else { const SMDS_MeshNode * newNode = aMesh->AddNode(x, y, z); myLastCreatedNodes.Append(newNode); + srcNodes.Append( node ); listNewNodes.push_back( newNode ); } coord[0] = coord[0] + theParams.myDir.X()*theParams.mySteps->Value(i+1); @@ -3652,6 +3719,7 @@ void SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet & theElems, else { const SMDS_MeshNode * newNode = aMesh->AddNode( coord[0], coord[1], coord[2] ); myLastCreatedNodes.Append(newNode); + srcNodes.Append( node ); listNewNodes.push_back( newNode ); } } @@ -3661,12 +3729,17 @@ void SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet & theElems, newNodesItVec.push_back( nIt ); } // make new elements - sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem], nbsteps, myLastCreatedElems ); + sweepElement( elem, newNodesItVec, newElemsMap[elem], nbsteps, srcElems ); } if( theFlags & EXTRUSION_FLAG_BOUNDARY ) { - makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElems, nbsteps, myLastCreatedElems ); + makeWalls( mapNewNodes, newElemsMap, mapElemNewNodes, theElems, nbsteps, srcElems ); } + PGroupIDs newGroupIDs; + if ( theMakeGroups ) + newGroupIDs = generateGroups( srcNodes, srcElems, "extruded"); + + return newGroupIDs; } @@ -3725,12 +3798,15 @@ SMESH_MeshEditor::Extrusion_Error const bool theHasAngles, list& theAngles, const bool theHasRefPoint, - const gp_Pnt& theRefPoint) + const gp_Pnt& theRefPoint, + const bool theMakeGroups) { myLastCreatedElems.Clear(); myLastCreatedNodes.Clear(); - MESSAGE("SMESH_MeshEditor::ExtrusionAlongTrack") + // source elements for each generated one + SMESH_SequenceOfElemPtr srcElems, srcNodes; + int j, aNbTP, aNbE, aNb; double aT1, aT2, aT, aAngle, aX, aY, aZ; std::list aPrms; @@ -3913,9 +3989,11 @@ SMESH_MeshEditor::Extrusion_Error newNodesItVec.reserve( elem->NbNodes() ); // loop on elem nodes + int nodeIndex = -1; SMDS_ElemIteratorPtr itN = elem->nodesIterator(); - while ( itN->more() ) { - + while ( itN->more() ) + { + ++nodeIndex; // check if a node has been already processed const SMDS_MeshNode* node = static_cast( itN->next() ); @@ -3984,6 +4062,7 @@ SMESH_MeshEditor::Extrusion_Error double z = ( aPN1.Z() + aPN0.Z() )/2.; const SMDS_MeshNode* newNode = aMesh->AddNode(x,y,z); myLastCreatedNodes.Append(newNode); + srcNodes.Append( node ); listNewNodes.push_back( newNode ); } aX = aPN1.X(); @@ -3991,6 +4070,7 @@ SMESH_MeshEditor::Extrusion_Error aZ = aPN1.Z(); const SMDS_MeshNode* newNode = aMesh->AddNode( aX, aY, aZ ); myLastCreatedNodes.Append(newNode); + srcNodes.Append( node ); listNewNodes.push_back( newNode ); aPN0 = aPN1; @@ -4016,6 +4096,7 @@ SMESH_MeshEditor::Extrusion_Error double y = ( N->Y() + P.Y() )/2.; double z = ( N->Z() + P.Z() )/2.; const SMDS_MeshNode* newN = aMesh->AddNode(x,y,z); + srcNodes.Append( node ); myLastCreatedNodes.Append(newN); aNodes[2*i] = newN; aNodes[2*i+1] = N; @@ -4034,12 +4115,13 @@ SMESH_MeshEditor::Extrusion_Error // make new elements //sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem], // newNodesItVec[0]->second.size(), myLastCreatedElems ); - sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem], - aNbTP-1, myLastCreatedElems ); + sweepElement( elem, newNodesItVec, newElemsMap[elem], aNbTP-1, srcElems ); } - makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElements, - aNbTP-1, myLastCreatedElems ); + makeWalls( mapNewNodes, newElemsMap, mapElemNewNodes, theElements, aNbTP-1, srcElems ); + + if ( theMakeGroups ) + generateGroups( srcNodes, srcElems, "extruded"); return EXTR_OK; } @@ -4049,24 +4131,43 @@ SMESH_MeshEditor::Extrusion_Error //purpose : //======================================================================= -void SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems, - const gp_Trsf& theTrsf, - const bool theCopy) +SMESH_MeshEditor::PGroupIDs +SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems, + const gp_Trsf& theTrsf, + const bool theCopy, + const bool theMakeGroups, + SMESH_Mesh* theTargetMesh) { myLastCreatedElems.Clear(); myLastCreatedNodes.Clear(); - bool needReverse; + bool needReverse = false; + string groupPostfix; switch ( theTrsf.Form() ) { case gp_PntMirror: + case gp_Ax1Mirror: case gp_Ax2Mirror: needReverse = true; + groupPostfix = "mirrored"; + break; + case gp_Rotation: + groupPostfix = "rotated"; + break; + case gp_Translation: + groupPostfix = "translated"; + break; + case gp_Scale: + groupPostfix = "scaled"; break; default: needReverse = false; + groupPostfix = "transformed"; } - SMESHDS_Mesh* aMesh = GetMeshDS(); + SMESH_MeshEditor targetMeshEditor( theTargetMesh ); + SMESHDS_Mesh* aTgtMesh = theTargetMesh ? theTargetMesh->GetMeshDS() : 0; + SMESHDS_Mesh* aMesh = GetMeshDS(); + // map old node to new one TNodeNodeMap nodeMap; @@ -4075,6 +4176,9 @@ void SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems, // nodes mirrored but are not in theElems are to be reversed TIDSortedElemSet inverseElemSet; + // source elements for each generated one + SMESH_SequenceOfElemPtr srcElems, srcNodes; + // loop on theElems TIDSortedElemSet::iterator itElem; for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) { @@ -4087,9 +4191,10 @@ void SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems, while ( itN->more() ) { // check if a node has been already transformed - const SMDS_MeshNode* node = - static_cast( itN->next() ); - if (nodeMap.find( node ) != nodeMap.end() ) + const SMDS_MeshNode* node = cast2Node( itN->next() ); + pair n2n_isnew = + nodeMap.insert( make_pair ( node, node )); + if ( !n2n_isnew.second ) continue; double coord[3]; @@ -4097,10 +4202,17 @@ void SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems, coord[1] = node->Y(); coord[2] = node->Z(); theTrsf.Transforms( coord[0], coord[1], coord[2] ); - const SMDS_MeshNode * newNode = node; - if ( theCopy ) { - newNode = aMesh->AddNode( coord[0], coord[1], coord[2] ); + if ( theTargetMesh ) { + const SMDS_MeshNode * newNode = aTgtMesh->AddNode( coord[0], coord[1], coord[2] ); + n2n_isnew.first->second = newNode; + myLastCreatedNodes.Append(newNode); + srcNodes.Append( node ); + } + else if ( theCopy ) { + const SMDS_MeshNode * newNode = aMesh->AddNode( coord[0], coord[1], coord[2] ); + n2n_isnew.first->second = newNode; myLastCreatedNodes.Append(newNode); + srcNodes.Append( node ); } else { aMesh->MoveNode( node, coord[0], coord[1], coord[2] ); @@ -4108,10 +4220,9 @@ void SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems, const_cast< SMDS_MeshNode* > ( node )->SetPosition ( SMDS_SpacePosition::originSpacePosition() ); } - nodeMap.insert( TNodeNodeMap::value_type( node, newNode )); // keep inverse elements - if ( !theCopy && needReverse ) { + if ( !theCopy && !theTargetMesh && needReverse ) { SMDS_ElemIteratorPtr invElemIt = node->GetInverseElementIterator(); while ( invElemIt->more() ) { const SMDS_MeshElement* iel = invElemIt->next(); @@ -4121,16 +4232,13 @@ void SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems, } } - // either new elements are to be created - // or a mirrored element are to be reversed - if ( !theCopy && !needReverse) - return; + // either create new elements or reverse mirrored ones + if ( !theCopy && !needReverse && !theTargetMesh ) + return PGroupIDs(); - if ( !inverseElemSet.empty()) { - TIDSortedElemSet::iterator invElemIt = inverseElemSet.begin(); - for ( ; invElemIt != inverseElemSet.end(); invElemIt++ ) - theElems.insert( *invElemIt ); - } + TIDSortedElemSet::iterator invElemIt = inverseElemSet.begin(); + for ( ; invElemIt != inverseElemSet.end(); invElemIt++ ) + theElems.insert( *invElemIt ); // replicate or reverse elements @@ -4151,7 +4259,8 @@ void SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems, { 0, 1, 2, 3, 4, 5, 6, 7 } // FORWARD }; - for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) { + for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) + { const SMDS_MeshElement* elem = *itElem; if ( !elem || elem->GetType() == SMDSAbs_Node ) continue; @@ -4184,8 +4293,13 @@ void SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems, if ( iNode != nbNodes ) continue; // not all nodes transformed - if ( theCopy ) { + if ( theTargetMesh ) { + myLastCreatedElems.Append(aTgtMesh->AddPolygonalFace(poly_nodes)); + srcElems.Append( elem ); + } + else if ( theCopy ) { myLastCreatedElems.Append(aMesh->AddPolygonalFace(poly_nodes)); + srcElems.Append( elem ); } else { aMesh->ChangePolygonNodes(elem, poly_nodes); @@ -4196,7 +4310,7 @@ void SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems, { // ATTENTION: Reversing is not yet done!!! const SMDS_PolyhedralVolumeOfNodes* aPolyedre = - (const SMDS_PolyhedralVolumeOfNodes*) elem; + dynamic_cast( elem ); if (!aPolyedre) { MESSAGE("Warning: bad volumic element"); continue; @@ -4223,26 +4337,31 @@ void SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems, if ( !allTransformed ) continue; // not all nodes transformed - if ( theCopy ) { + if ( theTargetMesh ) { + myLastCreatedElems.Append(aTgtMesh->AddPolyhedralVolume(poly_nodes, quantities)); + srcElems.Append( elem ); + } + else if ( theCopy ) { myLastCreatedElems.Append(aMesh->AddPolyhedralVolume(poly_nodes, quantities)); + srcElems.Append( elem ); } else { aMesh->ChangePolyhedronNodes(elem, poly_nodes, quantities); } } break; - default:; - } - continue; + default:; } + continue; + } - // Regular elements - int* i = index[ FORWARD ]; - if ( needReverse && nbNodes > 2) // reverse mirrored faces and volumes - if ( elemType == SMDSAbs_Face ) - i = index[ REV_FACE ]; - else - i = index[ nbNodes - 4 ]; + // Regular elements + int* i = index[ FORWARD ]; + if ( needReverse && nbNodes > 2) // reverse mirrored faces and volumes + if ( elemType == SMDSAbs_Face ) + i = index[ REV_FACE ]; + else + i = index[ nbNodes - 4 ]; if(elem->IsQuadratic()) { static int anIds[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; @@ -4294,17 +4413,158 @@ void SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems, if ( iNode != nbNodes ) continue; // not all nodes transformed - if ( theCopy ) { - if ( SMDS_MeshElement* elem = AddElement( nodes, elem->GetType(), elem->IsPoly() )) - myLastCreatedElems.Append( elem ); + if ( theTargetMesh ) { + if ( SMDS_MeshElement* copy = + targetMeshEditor.AddElement( nodes, elem->GetType(), elem->IsPoly() )) { + myLastCreatedElems.Append( copy ); + srcElems.Append( elem ); + } } - else - { + else if ( theCopy ) { + if ( SMDS_MeshElement* copy = AddElement( nodes, elem->GetType(), elem->IsPoly() )) { + myLastCreatedElems.Append( copy ); + srcElems.Append( elem ); + } + } + else { // reverse element as it was reversed by transformation if ( nbNodes > 2 ) aMesh->ChangeElementNodes( elem, &nodes[0], nbNodes ); } } + + PGroupIDs newGroupIDs; + + if ( theMakeGroups && theCopy || + theMakeGroups && theTargetMesh ) + newGroupIDs = generateGroups( srcNodes, srcElems, groupPostfix, theTargetMesh ); + + return newGroupIDs; +} + +//======================================================================= +/*! + * \brief Create groups of elements made during transformation + * \param nodeGens - nodes making corresponding myLastCreatedNodes + * \param elemGens - elements making corresponding myLastCreatedElems + * \param postfix - to append to names of new groups + */ +//======================================================================= + +SMESH_MeshEditor::PGroupIDs +SMESH_MeshEditor::generateGroups(const SMESH_SequenceOfElemPtr& nodeGens, + const SMESH_SequenceOfElemPtr& elemGens, + const std::string& postfix, + SMESH_Mesh* targetMesh) +{ + PGroupIDs newGroupIDs( new list ); + SMESH_Mesh* mesh = targetMesh ? targetMesh : GetMesh(); + + // Sort existing groups by types and collect their names + + // to store an old group and a generated new one + typedef pair< SMESHDS_GroupBase*, SMDS_MeshGroup* > TOldNewGroup; + vector< list< TOldNewGroup > > groupsByType( SMDSAbs_NbElementTypes ); + // group names + set< string > groupNames; + // + SMDS_MeshGroup* nullNewGroup = (SMDS_MeshGroup*) 0; + SMESH_Mesh::GroupIteratorPtr groupIt = GetMesh()->GetGroups(); + while ( groupIt->more() ) { + SMESH_Group * group = groupIt->next(); + if ( !group ) continue; + SMESHDS_GroupBase* groupDS = group->GetGroupDS(); + if ( !groupDS || groupDS->IsEmpty() ) continue; + groupNames.insert( group->GetName() ); + groupDS->SetStoreName( group->GetName() ); + groupsByType[ groupDS->GetType() ].push_back( make_pair( groupDS, nullNewGroup )); + } + + // Groups creation + + // loop on nodes and elements + for ( int isNodes = 0; isNodes < 2; ++isNodes ) + { + const SMESH_SequenceOfElemPtr& gens = isNodes ? nodeGens : elemGens; + const SMESH_SequenceOfElemPtr& elems = isNodes ? myLastCreatedNodes : myLastCreatedElems; + if ( gens.Length() != elems.Length() ) + throw SALOME_Exception(LOCALIZED("invalid args")); + + // loop on created elements + for (int iElem = 1; iElem <= elems.Length(); ++iElem ) + { + const SMDS_MeshElement* sourceElem = gens( iElem ); + if ( !sourceElem ) { + MESSAGE("generateGroups(): NULL source element"); + continue; + } + list< TOldNewGroup > & groupsOldNew = groupsByType[ sourceElem->GetType() ]; + if ( groupsOldNew.empty() ) { + while ( iElem < gens.Length() && gens( iElem+1 ) == sourceElem ) + ++iElem; // skip all elements made by sourceElem + continue; + } + // collect all elements made by sourceElem + list< const SMDS_MeshElement* > resultElems; + if ( const SMDS_MeshElement* resElem = elems( iElem )) + if ( resElem != sourceElem ) + resultElems.push_back( resElem ); + while ( iElem < gens.Length() && gens( iElem+1 ) == sourceElem ) + if ( const SMDS_MeshElement* resElem = elems( ++iElem )) + if ( resElem != sourceElem ) + resultElems.push_back( resElem ); + // do not generate element groups from node ones + if ( sourceElem->GetType() == SMDSAbs_Node && + elems( iElem )->GetType() != SMDSAbs_Node ) + continue; + + // add resultElems to groups made by ones the sourceElem belongs to + list< TOldNewGroup >::iterator gOldNew, gLast = groupsOldNew.end(); + for ( gOldNew = groupsOldNew.begin(); gOldNew != gLast; ++gOldNew ) + { + SMESHDS_GroupBase* oldGroup = gOldNew->first; + if ( oldGroup->Contains( sourceElem )) // sourceElem in oldGroup + { + SMDS_MeshGroup* & newGroup = gOldNew->second; + if ( !newGroup )// create a new group + { + // make a name + string name = oldGroup->GetStoreName(); + if ( !targetMesh ) { + name += "_"; + name += postfix; + int nb = 0; + while ( !groupNames.insert( name ).second ) // name exists + { + if ( nb == 0 ) { + name += "_1"; + } + else { + TCollection_AsciiString nbStr(++nb); + name.resize( name.rfind('_') ); + name += nbStr.ToCString(); + } + } + } + // make a group + int id; + SMESH_Group* group = mesh->AddGroup( resultElems.back()->GetType(), + name.c_str(), id ); + SMESHDS_Group* groupDS = static_cast(group->GetGroupDS()); + newGroup = & groupDS->SMDSGroup(); + newGroupIDs->push_back( id ); + } + + // fill in a new group + list< const SMDS_MeshElement* >::iterator resLast = resultElems.end(), resElemIt; + for ( resElemIt = resultElems.begin(); resElemIt != resLast; ++resElemIt ) + newGroup->Add( *resElemIt ); + } + } + } // loop on created elements + }// loop on nodes and elements + + return newGroupIDs; } //======================================================================= @@ -4456,7 +4716,8 @@ int SMESH_MeshEditor::SimplifyFace (const vector faceNode set nodeSet; // get simple seq of nodes - const SMDS_MeshNode* simpleNodes[ nbNodes ]; + //const SMDS_MeshNode* simpleNodes[ nbNodes ]; + vector simpleNodes( nbNodes ); int iSimple = 0, nbUnique = 0; simpleNodes[iSimple++] = faceNodes[0]; @@ -4570,8 +4831,9 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) int aShapeId = FindShape( elem ); set nodeSet; - const SMDS_MeshNode* curNodes[ nbNodes ], *uniqueNodes[ nbNodes ]; - int iUnique = 0, iCur = 0, nbRepl = 0, iRepl [ nbNodes ]; + vector< const SMDS_MeshNode*> curNodes( nbNodes ), uniqueNodes( nbNodes ); + int iUnique = 0, iCur = 0, nbRepl = 0; + vector iRepl( nbNodes ); // get new seq of nodes SMDS_ElemIteratorPtr itN = elem->nodesIterator(); @@ -5047,7 +5309,7 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) } else { // Change regular element or polygon - aMesh->ChangeElementNodes( elem, uniqueNodes, nbUniqueNodes ); + aMesh->ChangeElementNodes( elem, & uniqueNodes[0], nbUniqueNodes ); } } else { @@ -5065,88 +5327,143 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) } -// ================================================= +// ======================================================== // class : SortableElement -// purpose : auxilary -// ================================================= +// purpose : allow sorting elements basing on their nodes +// ======================================================== class SortableElement : public set { public: SortableElement( const SMDS_MeshElement* theElem ) { - myID = theElem->GetID(); + myElem = theElem; SMDS_ElemIteratorPtr nodeIt = theElem->nodesIterator(); while ( nodeIt->more() ) this->insert( nodeIt->next() ); } - const long GetID() const - { return myID; } + const SMDS_MeshElement* Get() const + { return myElem; } - void SetID(const long anID) const - { myID = anID; } + void Set(const SMDS_MeshElement* e) const + { myElem = e; } private: - mutable long myID; + mutable const SMDS_MeshElement* myElem; }; +//======================================================================= +//function : FindEqualElements +//purpose : Return list of group of elements built on the same nodes. +// Search among theElements or in the whole mesh if theElements is empty +//======================================================================= +void SMESH_MeshEditor::FindEqualElements(set & theElements, + TListOfListOfElementsID & theGroupsOfElementsID) +{ + myLastCreatedElems.Clear(); + myLastCreatedNodes.Clear(); + + typedef set TElemsSet; + typedef map< SortableElement, int > TMapOfNodeSet; + typedef list TGroupOfElems; + + TElemsSet elems; + if ( theElements.empty() ) + { // get all elements in the mesh + SMDS_ElemIteratorPtr eIt = GetMeshDS()->elementsIterator(); + while ( eIt->more() ) + elems.insert( elems.end(), eIt->next()); + } + else + elems = theElements; + + vector< TGroupOfElems > arrayOfGroups; + TGroupOfElems groupOfElems; + TMapOfNodeSet mapOfNodeSet; + + TElemsSet::iterator elemIt = elems.begin(); + for ( int i = 0, j=0; elemIt != elems.end(); ++elemIt, ++j ) { + const SMDS_MeshElement* curElem = *elemIt; + SortableElement SE(curElem); + int ind = -1; + // check uniqueness + pair< TMapOfNodeSet::iterator, bool> pp = mapOfNodeSet.insert(make_pair(SE, i)); + if( !(pp.second) ) { + TMapOfNodeSet::iterator& itSE = pp.first; + ind = (*itSE).second; + arrayOfGroups[ind].push_back(curElem->GetID()); + } + else { + groupOfElems.clear(); + groupOfElems.push_back(curElem->GetID()); + arrayOfGroups.push_back(groupOfElems); + i++; + } + } + + vector< TGroupOfElems >::iterator groupIt = arrayOfGroups.begin(); + for ( ; groupIt != arrayOfGroups.end(); ++groupIt ) { + groupOfElems = *groupIt; + if ( groupOfElems.size() > 1 ) { + groupOfElems.sort(); + theGroupsOfElementsID.push_back(groupOfElems); + } + } +} //======================================================================= -//function : MergeEqualElements -//purpose : Remove all but one of elements built on the same nodes. +//function : MergeElements +//purpose : In each given group, substitute all elements by the first one. //======================================================================= -void SMESH_MeshEditor::MergeEqualElements() +void SMESH_MeshEditor::MergeElements(TListOfListOfElementsID & theGroupsOfElementsID) { myLastCreatedElems.Clear(); myLastCreatedNodes.Clear(); + typedef list TListOfIDs; + TListOfIDs rmElemIds; // IDs of elems to remove + SMESHDS_Mesh* aMesh = GetMeshDS(); - SMDS_EdgeIteratorPtr eIt = aMesh->edgesIterator(); - SMDS_FaceIteratorPtr fIt = aMesh->facesIterator(); - SMDS_VolumeIteratorPtr vIt = aMesh->volumesIterator(); - - list< int > rmElemIds; // IDs of elems to remove - - for ( int iDim = 1; iDim <= 3; iDim++ ) { - - set< SortableElement > setOfNodeSet; - while ( 1 ) { - // get next element - const SMDS_MeshElement* elem = 0; - if ( iDim == 1 ) { - if ( eIt->more() ) elem = eIt->next(); - } else if ( iDim == 2 ) { - if ( fIt->more() ) elem = fIt->next(); - } else { - if ( vIt->more() ) elem = vIt->next(); - } - if ( !elem ) break; - - SortableElement SE(elem); - - // check uniqueness - pair< set::iterator, bool> pp = setOfNodeSet.insert(SE); - if( !(pp.second) ) { - set::iterator itSE = pp.first; - SortableElement SEold = *itSE; - if( SEold.GetID() > SE.GetID() ) { - rmElemIds.push_back( SEold.GetID() ); - (*itSE).SetID(SE.GetID()); - } - else { - rmElemIds.push_back( SE.GetID() ); - } - } - } + TListOfListOfElementsID::iterator groupsIt = theGroupsOfElementsID.begin(); + while ( groupsIt != theGroupsOfElementsID.end() ) { + TListOfIDs& aGroupOfElemID = *groupsIt; + aGroupOfElemID.sort(); + int elemIDToKeep = aGroupOfElemID.front(); + const SMDS_MeshElement* elemToKeep = aMesh->FindElement(elemIDToKeep); + aGroupOfElemID.pop_front(); + TListOfIDs::iterator idIt = aGroupOfElemID.begin(); + while ( idIt != aGroupOfElemID.end() ) { + int elemIDToRemove = *idIt; + const SMDS_MeshElement* elemToRemove = aMesh->FindElement(elemIDToRemove); + // add the kept element in groups of removed one (PAL15188) + AddToSameGroups( elemToKeep, elemToRemove, aMesh ); + rmElemIds.push_back( elemIDToRemove ); + ++idIt; + } + ++groupsIt; } Remove( rmElemIds, false ); } +//======================================================================= +//function : MergeEqualElements +//purpose : Remove all but one of elements built on the same nodes. +//======================================================================= + +void SMESH_MeshEditor::MergeEqualElements() +{ + set aMeshElements; /* empty input - + to merge equal elements in the whole mesh */ + TListOfListOfElementsID aGroupsOfElementsID; + FindEqualElements(aMeshElements, aGroupsOfElementsID); + MergeElements(aGroupsOfElementsID); +} + //======================================================================= //function : FindFaceInSet //purpose : Return a face having linked nodes n1 and n2 and which is @@ -5170,7 +5487,9 @@ const SMDS_MeshElement* continue; // get face nodes and find index of n1 int i1, nbN = elem->NbNodes(), iNode = 0; - const SMDS_MeshNode* faceNodes[ nbN ], *n; + //const SMDS_MeshNode* faceNodes[ nbN ], *n; + vector faceNodes( nbN ); + const SMDS_MeshNode* n; SMDS_ElemIteratorPtr nIt = elem->nodesIterator(); while ( nIt->more() ) { faceNodes[ iNode ] = static_cast( nIt->next() ); @@ -5287,7 +5606,9 @@ bool SMESH_MeshEditor::FindFreeBorder (const SMDS_MeshNode* theFirst if ( e == curElem || foundElems.insert( e ).second ) { // get nodes int iNode = 0, nbNodes = e->NbNodes(); - const SMDS_MeshNode* nodes[nbNodes+1]; + //const SMDS_MeshNode* nodes[nbNodes+1]; + vector nodes(nbNodes+1); + if(e->IsQuadratic()) { const SMDS_QuadraticFaceOfNodes* F = static_cast(e); @@ -5554,12 +5875,11 @@ SMESH_MeshEditor::Sew_Error const SMDS_MeshElement* elem = invElemIt->next(); // prepare data for a loop on links coming to prevSideNode, of a face or a volume int iPrevNode, iNode = 0, nbNodes = elem->NbNodes(); - const SMDS_MeshNode* faceNodes[ nbNodes ]; + vector< const SMDS_MeshNode* > faceNodes( nbNodes, (const SMDS_MeshNode*)0 ); bool isVolume = volume.Set( elem ); - const SMDS_MeshNode** nodes = isVolume ? volume.GetNodes() : faceNodes; + const SMDS_MeshNode** nodes = isVolume ? volume.GetNodes() : & faceNodes[0]; if ( isVolume ) // --volume hasVolumes = true; - //else if ( nbNodes > 2 ) { // --face else if ( elem->GetType()==SMDSAbs_Face ) { // --face // retrieve all face nodes and find iPrevNode - an index of the prevSideNode if(elem->IsQuadratic()) { @@ -5576,7 +5896,7 @@ SMESH_MeshEditor::Sew_Error else { SMDS_ElemIteratorPtr nIt = elem->nodesIterator(); while ( nIt->more() ) { - nodes[ iNode ] = static_cast( nIt->next() ); + nodes[ iNode ] = cast2Node( nIt->next() ); if ( nodes[ iNode++ ] == prevSideNode ) iPrevNode = iNode - 1; } @@ -5608,7 +5928,7 @@ SMESH_MeshEditor::Sew_Error // test a link geometrically gp_XYZ nextXYZ ( n->X(), n->Y(), n->Z() ); bool linkIsBetter = false; - double dot, dist; + double dot = 0.0, dist = 0.0; if ( searchByDir ) { // choose most co-directed link dot = bordDir * ( nextXYZ - prevXYZ ).Normalized(); linkIsBetter = ( dot > maxDot ); @@ -5680,7 +6000,7 @@ SMESH_MeshEditor::Sew_Error { nodeGroupsToMerge.push_back( list() ); nodeGroupsToMerge.back().push_back( *nIt[1] ); // to keep - nodeGroupsToMerge.back().push_back( *nIt[0] ); // tp remove + nodeGroupsToMerge.back().push_back( *nIt[0] ); // to remove } } else { @@ -5688,7 +6008,10 @@ SMESH_MeshEditor::Sew_Error // insert new nodes into the border and the side to get equal nb of segments // get normalized parameters of nodes on the borders - double param[ 2 ][ maxNbNodes ]; + //double param[ 2 ][ maxNbNodes ]; + double* param[ 2 ]; + param[0] = new double [ maxNbNodes ]; + param[1] = new double [ maxNbNodes ]; int iNode, iBord; for ( iBord = 0; iBord < 2; iBord++ ) { // loop on 2 borders list< const SMDS_MeshNode* >& nodes = nSide[ iBord ]; @@ -5849,6 +6172,8 @@ SMESH_MeshEditor::Sew_Error } } + delete param[0]; + delete param[1]; } // end: insert new nodes MergeNodes ( nodeGroupsToMerge ); @@ -5873,7 +6198,8 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement* theFace, // find indices of 2 link nodes and of the rest nodes int iNode = 0, il1, il2, i3, i4; il1 = il2 = i3 = i4 = -1; - const SMDS_MeshNode* nodes[ theFace->NbNodes() ]; + //const SMDS_MeshNode* nodes[ theFace->NbNodes() ]; + vector nodes( theFace->NbNodes() ); if(theFace->IsQuadratic()) { const SMDS_QuadraticFaceOfNodes* F = @@ -6002,7 +6328,8 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement* theFace, // put aNodesToInsert between theBetweenNode1 and theBetweenNode2 int nbLinkNodes = 2 + aNodesToInsert.size(); - const SMDS_MeshNode* linkNodes[ nbLinkNodes ]; + //const SMDS_MeshNode* linkNodes[ nbLinkNodes ]; + vector linkNodes( nbLinkNodes ); linkNodes[ 0 ] = nodes[ il1 ]; linkNodes[ nbLinkNodes - 1 ] = nodes[ il2 ]; list::iterator nIt = aNodesToInsert.begin(); @@ -6169,7 +6496,8 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement* theFace, } // create needed triangles using n1,n2,n3 and inserted nodes int nbn = 2 + aNodesToInsert.size(); - const SMDS_MeshNode* aNodes[nbn]; + //const SMDS_MeshNode* aNodes[nbn]; + vector aNodes(nbn); aNodes[0] = nodes[n1]; aNodes[nbn-1] = nodes[n2]; list::iterator nIt = aNodesToInsert.begin(); @@ -6275,18 +6603,22 @@ void SMESH_MeshEditor::UpdateVolumes (const SMDS_MeshNode* theBetweenNode } //======================================================================= -//function : ConvertElemToQuadratic -//purpose : +/*! + * \brief Convert elements contained in a submesh to quadratic + * \retval int - nb of checked elements + */ //======================================================================= -void SMESH_MeshEditor::ConvertElemToQuadratic(SMESHDS_SubMesh * theSm, + +int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh * theSm, SMESH_MesherHelper& theHelper, const bool theForce3d) { - if( !theSm ) return; - SMESHDS_Mesh* meshDS = GetMeshDS(); + int nbElem = 0; + if( !theSm ) return nbElem; SMDS_ElemIteratorPtr ElemItr = theSm->GetElements(); while(ElemItr->more()) { + nbElem++; const SMDS_MeshElement* elem = ElemItr->next(); if( !elem || elem->IsQuadratic() ) continue; @@ -6301,7 +6633,7 @@ void SMESH_MeshEditor::ConvertElemToQuadratic(SMESHDS_SubMesh * theSm, SMDSAbs_ElementType aType = elem->GetType(); theSm->RemoveElement(elem); - meshDS->SMDS_Mesh::RemoveFreeElement(elem); + GetMeshDS()->SMDS_Mesh::RemoveFreeElement(elem); const SMDS_MeshElement* NewElem = 0; @@ -6351,12 +6683,13 @@ void SMESH_MeshEditor::ConvertElemToQuadratic(SMESHDS_SubMesh * theSm, } if( NewElem ) { - AddToSameGroups( NewElem, elem, meshDS); + AddToSameGroups( NewElem, elem, GetMeshDS()); theSm->AddElement( NewElem ); } if ( NewElem != elem ) - RemoveElemFromGroups (elem, meshDS); + RemoveElemFromGroups (elem, GetMeshDS()); } + return nbElem; } //======================================================================= @@ -6369,24 +6702,24 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d) SMESH_MesherHelper aHelper(*myMesh); aHelper.SetIsQuadratic( true ); - const TopoDS_Shape& aShape = meshDS->ShapeToMesh(); - if ( !aShape.IsNull() && GetMesh()->GetSubMeshContaining(aShape) ) + int nbCheckedElems = 0; + if ( myMesh->HasShapeToMesh() ) { - SMESH_subMesh *aSubMesh = GetMesh()->GetSubMeshContaining(aShape); - - const map < int, SMESH_subMesh * >& aMapSM = aSubMesh->DependsOn(); - map < int, SMESH_subMesh * >::const_iterator itsub; - for (itsub = aMapSM.begin(); itsub != aMapSM.end(); itsub++) + if ( SMESH_subMesh *aSubMesh = myMesh->GetSubMeshContaining(myMesh->GetShapeToMesh())) { - SMESHDS_SubMesh *sm = ((*itsub).second)->GetSubMeshDS(); - aHelper.SetSubShape( (*itsub).second->GetSubShape() ); - ConvertElemToQuadratic(sm, aHelper, theForce3d); + SMESH_subMeshIteratorPtr smIt = aSubMesh->getDependsOnIterator(true,false); + while ( smIt->more() ) { + SMESH_subMesh* sm = smIt->next(); + if ( SMESHDS_SubMesh *smDS = sm->GetSubMeshDS() ) { + aHelper.SetSubShape( sm->GetSubShape() ); + nbCheckedElems += convertElemToQuadratic(smDS, aHelper, theForce3d); + } + } } - aHelper.SetSubShape( aSubMesh->GetSubShape() ); - ConvertElemToQuadratic(aSubMesh->GetSubMeshDS(), aHelper, theForce3d); } - else + int totalNbElems = meshDS->NbEdges() + meshDS->NbFaces() + meshDS->NbVolumes(); + if ( nbCheckedElems < totalNbElems ) // not all elements in submeshes { SMDS_EdgeIteratorPtr aEdgeItr = meshDS->edgesIterator(); while(aEdgeItr->more()) @@ -6485,17 +6818,22 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d) } //======================================================================= -//function : RemoveQuadElem -//purpose : +/*! + * \brief Convert quadratic elements to linear ones and remove quadratic nodes + * \retval int - nb of checked elements + */ //======================================================================= -void SMESH_MeshEditor::RemoveQuadElem(SMESHDS_SubMesh * theSm, - SMDS_ElemIteratorPtr theItr, - const int theShapeID) + +int SMESH_MeshEditor::removeQuadElem(SMESHDS_SubMesh * theSm, + SMDS_ElemIteratorPtr theItr, + const int theShapeID) { + int nbElem = 0; SMESHDS_Mesh* meshDS = GetMeshDS(); while( theItr->more() ) { const SMDS_MeshElement* elem = theItr->next(); + nbElem++; if( elem && elem->IsQuadratic()) { int id = elem->GetID(); @@ -6516,7 +6854,7 @@ void SMESH_MeshEditor::RemoveQuadElem(SMESHDS_SubMesh * theSm, if( aNds.empty() ) continue; SMDSAbs_ElementType aType = elem->GetType(); - //remove old quadratic elements + //remove old quadratic element meshDS->SMDS_Mesh::RemoveFreeElement( elem ); if ( theSm ) theSm->RemoveElement( elem ); @@ -6543,6 +6881,7 @@ void SMESH_MeshEditor::RemoveQuadElem(SMESHDS_SubMesh * theSm, } } } + return nbElem; } //======================================================================= @@ -6551,29 +6890,26 @@ void SMESH_MeshEditor::RemoveQuadElem(SMESHDS_SubMesh * theSm, //======================================================================= bool SMESH_MeshEditor::ConvertFromQuadratic() { - SMESHDS_Mesh* meshDS = GetMeshDS(); - const TopoDS_Shape& aShape = meshDS->ShapeToMesh(); - - if ( !aShape.IsNull() && GetMesh()->GetSubMeshContaining(aShape) ) + int nbCheckedElems = 0; + if ( myMesh->HasShapeToMesh() ) { - SMESH_subMesh *aSubMesh = GetMesh()->GetSubMeshContaining(aShape); - - const map < int, SMESH_subMesh * >& aMapSM = aSubMesh->DependsOn(); - map < int, SMESH_subMesh * >::const_iterator itsub; - for (itsub = aMapSM.begin(); itsub != aMapSM.end(); itsub++) + if ( SMESH_subMesh *aSubMesh = myMesh->GetSubMeshContaining(myMesh->GetShapeToMesh())) { - SMESHDS_SubMesh *sm = ((*itsub).second)->GetSubMeshDS(); - if( sm ) - RemoveQuadElem( sm, sm->GetElements(), itsub->second->GetId() ); + SMESH_subMeshIteratorPtr smIt = aSubMesh->getDependsOnIterator(true,false); + while ( smIt->more() ) { + SMESH_subMesh* sm = smIt->next(); + if ( SMESHDS_SubMesh *smDS = sm->GetSubMeshDS() ) + nbCheckedElems += removeQuadElem( smDS, smDS->GetElements(), sm->GetId() ); + } } - SMESHDS_SubMesh *Sm = aSubMesh->GetSubMeshDS(); - if( Sm ) - RemoveQuadElem( Sm, Sm->GetElements(), aSubMesh->GetId() ); } - else + + int totalNbElems = + GetMeshDS()->NbEdges() + GetMeshDS()->NbFaces() + GetMeshDS()->NbVolumes(); + if ( nbCheckedElems < totalNbElems ) // not all elements in submeshes { SMESHDS_SubMesh *aSM = 0; - RemoveQuadElem( aSM, meshDS->elementsIterator(), 0 ); + removeQuadElem( aSM, GetMeshDS()->elementsIterator(), 0 ); } return true; @@ -7170,17 +7506,6 @@ SMESH_MeshEditor::Sew_Error return aResult; } -/*! - * \brief A sorted pair of nodes - */ -struct TLink: public NLink -{ - TLink(const SMDS_MeshNode* n1, const SMDS_MeshNode* n2 ):NLink( n1, n2 ) - { if ( n1 < n2 ) std::swap( first, second ); } - TLink(const NLink& link ):NLink( link ) - { if ( first < second ) std::swap( first, second ); } -}; - //================================================================================ /*! * \brief Find corresponding nodes in two sets of faces @@ -7195,7 +7520,9 @@ struct TLink: public NLink */ //================================================================================ +#ifdef _DEBUG_ //#define DEBUG_MATCHING_NODES +#endif SMESH_MeshEditor::Sew_Error SMESH_MeshEditor::FindMatchingNodes(set& theSide1,