From c5c2208a8cbf09d24d4dfa4f2b615f630d631ca7 Mon Sep 17 00:00:00 2001 From: eap Date: Thu, 4 May 2006 13:37:38 +0000 Subject: [PATCH] Take care of having predictable results. Keep results of the last operation. --- src/SMESH/SMESH_MeshEditor.cxx | 476 +++++++++++++++++++++++---------- src/SMESH/SMESH_MeshEditor.hxx | 41 ++- 2 files changed, 364 insertions(+), 153 deletions(-) diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx index 731cbfdf5..1650e1bd7 100644 --- a/src/SMESH/SMESH_MeshEditor.cxx +++ b/src/SMESH/SMESH_MeshEditor.cxx @@ -102,6 +102,8 @@ myMesh( theMesh ) bool SMESH_MeshEditor::Remove (const list< int >& theIDs, const bool isNodes ) { + myLastCreatedElems.Clear(); + myLastCreatedNodes.Clear(); SMESHDS_Mesh* aMesh = GetMeshDS(); set< SMESH_subMesh *> smmap; @@ -158,6 +160,9 @@ bool SMESH_MeshEditor::Remove (const list< int >& theIDs, int SMESH_MeshEditor::FindShape (const SMDS_MeshElement * theElem) { + myLastCreatedElems.Clear(); + myLastCreatedNodes.Clear(); + SMESHDS_Mesh * aMesh = GetMeshDS(); if ( aMesh->ShapeToMesh().IsNull() ) return 0; @@ -310,6 +315,9 @@ static bool GetNodesFromTwoTria(const SMDS_MeshElement * theTria1, bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshElement * theTria1, const SMDS_MeshElement * theTria2 ) { + myLastCreatedElems.Clear(); + myLastCreatedNodes.Clear(); + if (!theTria1 || !theTria2) return false; @@ -453,7 +461,14 @@ static bool findTriangles(const SMDS_MeshNode * theNode1, if ( elem->GetType() == SMDSAbs_Face && emap.find( elem ) != emap.end() ) if ( theTria1 ) { - theTria2 = elem; + // theTria1 must be element with minimum ID + if( theTria1->GetID() < elem->GetID() ) { + theTria2 = elem; + } + else { + theTria2 = theTria1; + theTria1 = elem; + } break; } else { @@ -473,6 +488,9 @@ static bool findTriangles(const SMDS_MeshNode * theNode1, bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshNode * theNode1, const SMDS_MeshNode * theNode2) { + myLastCreatedElems.Clear(); + myLastCreatedNodes.Clear(); + MESSAGE( "::InverseDiag()" ); const SMDS_MeshElement *tr1, *tr2; @@ -604,6 +622,9 @@ bool getQuadrangleNodes(const SMDS_MeshNode * theQuadNodes [], bool SMESH_MeshEditor::DeleteDiag (const SMDS_MeshNode * theNode1, const SMDS_MeshNode * theNode2) { + myLastCreatedElems.Clear(); + myLastCreatedNodes.Clear(); + MESSAGE( "::DeleteDiag()" ); const SMDS_MeshElement *tr1, *tr2; @@ -623,6 +644,7 @@ bool SMESH_MeshEditor::DeleteDiag (const SMDS_MeshNode * theNode1, //MESSAGE( endl << tr1 << tr2 ); GetMeshDS()->ChangeElementNodes( tr1, aNodes, 4 ); + myLastCreatedElems.Append(tr1); GetMeshDS()->RemoveElement( tr2 ); //MESSAGE( endl << tr1 ); @@ -667,6 +689,7 @@ bool SMESH_MeshEditor::DeleteDiag (const SMDS_MeshNode * theNode1, aNodes[7] = N1[5]; GetMeshDS()->ChangeElementNodes( tr1, aNodes, 8 ); + myLastCreatedElems.Append(tr1); GetMeshDS()->RemoveElement( tr2 ); // remove middle node (9) @@ -682,6 +705,9 @@ bool SMESH_MeshEditor::DeleteDiag (const SMDS_MeshNode * theNode1, bool SMESH_MeshEditor::Reorient (const SMDS_MeshElement * theElem) { + myLastCreatedElems.Clear(); + myLastCreatedNodes.Clear(); + if (!theElem) return false; SMDS_ElemIteratorPtr it = theElem->nodesIterator(); @@ -785,9 +811,12 @@ static double getBadRate (const SMDS_MeshElement* theElem, // theCrit is used to select a diagonal to cut //======================================================================= -bool SMESH_MeshEditor::QuadToTri (set & theElems, +bool SMESH_MeshEditor::QuadToTri (map & theElems, SMESH::Controls::NumericalFunctorPtr theCrit) { + myLastCreatedElems.Clear(); + myLastCreatedNodes.Clear(); + MESSAGE( "::QuadToTri()" ); if ( !theCrit.get() ) @@ -795,9 +824,9 @@ bool SMESH_MeshEditor::QuadToTri (set & theElems, SMESHDS_Mesh * aMesh = GetMeshDS(); - set< const SMDS_MeshElement * >::iterator itElem; + map::iterator itElem; for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) { - const SMDS_MeshElement* elem = (*itElem); + const SMDS_MeshElement* elem = (*itElem).second; if ( !elem || elem->GetType() != SMDSAbs_Face ) continue; @@ -839,6 +868,7 @@ bool SMESH_MeshEditor::QuadToTri (set & theElems, elem = aMesh->AddFace( aNodes[3], aNodes[0], aNodes[1] ); } //MESSAGE( endl << elem ); + myLastCreatedElems.Append(elem); // put a new triangle on the same shape if ( aShapeId ) @@ -875,6 +905,7 @@ bool SMESH_MeshEditor::QuadToTri (set & theElems, z += aNodes[i]->Z(); } const SMDS_MeshNode* newN = aMesh->AddNode(x/4, y/4, z/4); + myLastCreatedNodes.Append(newN); if ( aBadRate1 <= aBadRate2 ) { // tr1 + tr2 is better @@ -902,6 +933,7 @@ bool SMESH_MeshEditor::QuadToTri (set & theElems, elem = aMesh->AddFace(aNodes[3], aNodes[0], aNodes[1], aNodes[7], aNodes[4], newN ); } + myLastCreatedElems.Append(elem); // put a new triangle on the same shape if ( aShapeId ) { aMesh->SetMeshElementOnShape( elem, aShapeId ); @@ -919,6 +951,9 @@ bool SMESH_MeshEditor::QuadToTri (set & theElems, int SMESH_MeshEditor::BestSplit (const SMDS_MeshElement* theQuad, SMESH::Controls::NumericalFunctorPtr theCrit) { + myLastCreatedElems.Clear(); + myLastCreatedNodes.Clear(); + if (!theCrit.get()) return -1; @@ -954,7 +989,6 @@ int SMESH_MeshEditor::BestSplit (const SMDS_MeshElement* theQuad, return -1; } - //======================================================================= //function : AddToSameGroups //purpose : add elemToAdd to the groups the elemInGroups belongs to @@ -973,6 +1007,7 @@ void SMESH_MeshEditor::AddToSameGroups (const SMDS_MeshElement* elemToAdd, } } + //======================================================================= //function : RemoveElemFromGroups //purpose : Remove removeelem to the groups the elemInGroups belongs to @@ -992,22 +1027,27 @@ void SMESH_MeshEditor::RemoveElemFromGroups (const SMDS_MeshElement* removeelem, } } } + + //======================================================================= //function : QuadToTri //purpose : Cut quadrangles into triangles. // theCrit is used to select a diagonal to cut //======================================================================= -bool SMESH_MeshEditor::QuadToTri (std::set & theElems, +bool SMESH_MeshEditor::QuadToTri (std::map & theElems, const bool the13Diag) { + myLastCreatedElems.Clear(); + myLastCreatedNodes.Clear(); + MESSAGE( "::QuadToTri()" ); SMESHDS_Mesh * aMesh = GetMeshDS(); - set< const SMDS_MeshElement * >::iterator itElem; + map::iterator itElem; for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) { - const SMDS_MeshElement* elem = (*itElem); + const SMDS_MeshElement* elem = (*itElem).second; if ( !elem || elem->GetType() != SMDSAbs_Face ) continue; bool isquad = elem->NbNodes()==4 || elem->NbNodes()==8; @@ -1031,6 +1071,7 @@ bool SMESH_MeshEditor::QuadToTri (std::set & theElems, aMesh->ChangeElementNodes( elem, &aNodes[1], 3 ); newElem = aMesh->AddFace( aNodes[3], aNodes[0], aNodes[1] ); } + myLastCreatedElems.Append(newElem); // put a new triangle on the same shape and add to the same groups if ( aShapeId ) aMesh->SetMeshElementOnShape( newElem, aShapeId ); @@ -1054,6 +1095,7 @@ bool SMESH_MeshEditor::QuadToTri (std::set & theElems, z += aNodes[i]->Z(); } const SMDS_MeshNode* newN = aMesh->AddNode(x/4, y/4, z/4); + myLastCreatedNodes.Append(newN); int aShapeId = FindShape( elem ); const SMDS_MeshElement* newElem = 0; @@ -1081,6 +1123,7 @@ bool SMESH_MeshEditor::QuadToTri (std::set & theElems, elem = aMesh->AddFace(aNodes[3], aNodes[0], aNodes[1], aNodes[7], aNodes[4], newN ); } + myLastCreatedElems.Append(elem); // put a new triangle on the same shape and add to the same groups if ( aShapeId ) aMesh->SetMeshElementOnShape( newElem, aShapeId ); @@ -1194,10 +1237,13 @@ class LinkID_Gen { // fusion is still performed. //======================================================================= -bool SMESH_MeshEditor::TriToQuad (set & theElems, +bool SMESH_MeshEditor::TriToQuad (map & theElems, SMESH::Controls::NumericalFunctorPtr theCrit, const double theMaxAngle) { + myLastCreatedElems.Clear(); + myLastCreatedNodes.Clear(); + MESSAGE( "::TriToQuad()" ); if ( !theCrit.get() ) @@ -1220,9 +1266,9 @@ bool SMESH_MeshEditor::TriToQuad (set & theElems, map< const SMDS_MeshElement*, set< NLink > > mapEl_setLi; map< const SMDS_MeshElement*, set< NLink > >::iterator itEL; - set::iterator itElem; + map::iterator itElem; for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) { - const SMDS_MeshElement* elem = (*itElem); + const SMDS_MeshElement* elem = (*itElem).second; //if ( !elem || elem->NbNodes() != 3 ) // continue; if(!elem || elem->GetType() != SMDSAbs_Face ) continue; @@ -1413,8 +1459,16 @@ bool SMESH_MeshEditor::TriToQuad (set & theElems, mapEl_setLi.erase( tr2 ); mapLi_listEl.erase( link12 ); if(tr1->NbNodes()==3) { - aMesh->ChangeElementNodes( tr1, n12, 4 ); - aMesh->RemoveElement( tr2 ); + if( tr1->GetID() < tr2->GetID() ) { + aMesh->ChangeElementNodes( tr1, n12, 4 ); + myLastCreatedElems.Append(tr1); + aMesh->RemoveElement( tr2 ); + } + else { + aMesh->ChangeElementNodes( tr2, n12, 4 ); + myLastCreatedElems.Append(tr2); + aMesh->RemoveElement( tr1); + } } else { const SMDS_MeshNode* N1 [6]; @@ -1432,8 +1486,16 @@ bool SMESH_MeshEditor::TriToQuad (set & theElems, aNodes[5] = N2[5]; aNodes[6] = N2[3]; aNodes[7] = N1[5]; - GetMeshDS()->ChangeElementNodes( tr1, aNodes, 8 ); - GetMeshDS()->RemoveElement( tr2 ); + if( tr1->GetID() < tr2->GetID() ) { + GetMeshDS()->ChangeElementNodes( tr1, aNodes, 8 ); + myLastCreatedElems.Append(tr1); + GetMeshDS()->RemoveElement( tr2 ); + } + else { + GetMeshDS()->ChangeElementNodes( tr2, aNodes, 8 ); + myLastCreatedElems.Append(tr2); + GetMeshDS()->RemoveElement( tr1 ); + } // remove middle node (9) GetMeshDS()->RemoveNode( N1[4] ); } @@ -1442,8 +1504,16 @@ bool SMESH_MeshEditor::TriToQuad (set & theElems, mapEl_setLi.erase( tr3 ); mapLi_listEl.erase( link13 ); if(tr1->NbNodes()==3) { - aMesh->ChangeElementNodes( tr1, n13, 4 ); - aMesh->RemoveElement( tr3 ); + if( tr1->GetID() < tr2->GetID() ) { + aMesh->ChangeElementNodes( tr1, n13, 4 ); + myLastCreatedElems.Append(tr1); + aMesh->RemoveElement( tr3 ); + } + else { + aMesh->ChangeElementNodes( tr3, n13, 4 ); + myLastCreatedElems.Append(tr3); + aMesh->RemoveElement( tr1 ); + } } else { const SMDS_MeshNode* N1 [6]; @@ -1461,8 +1531,16 @@ bool SMESH_MeshEditor::TriToQuad (set & theElems, aNodes[5] = N2[5]; aNodes[6] = N2[3]; aNodes[7] = N1[5]; - GetMeshDS()->ChangeElementNodes( tr1, aNodes, 8 ); - GetMeshDS()->RemoveElement( tr3 ); + if( tr1->GetID() < tr2->GetID() ) { + GetMeshDS()->ChangeElementNodes( tr1, aNodes, 8 ); + myLastCreatedElems.Append(tr1); + GetMeshDS()->RemoveElement( tr3 ); + } + else { + GetMeshDS()->ChangeElementNodes( tr3, aNodes, 8 ); + myLastCreatedElems.Append(tr3); + GetMeshDS()->RemoveElement( tr1 ); + } // remove middle node (9) GetMeshDS()->RemoveNode( N1[4] ); } @@ -1931,13 +2009,16 @@ static bool getClosestUV (Extrema_GenExtPS& projector, // on edges and boundary nodes are always fixed. //======================================================================= -void SMESH_MeshEditor::Smooth (set & theElems, +void SMESH_MeshEditor::Smooth (map & theElems, set & theFixedNodes, const SmoothMethod theSmoothMethod, const int theNbIterations, double theTgtAspectRatio, const bool the2D) { + myLastCreatedElems.Clear(); + myLastCreatedNodes.Clear(); + MESSAGE((theSmoothMethod==LAPLACIAN ? "LAPLACIAN" : "CENTROIDAL") << "--::Smooth()"); if ( theTgtAspectRatio < 1.0 ) @@ -1952,15 +2033,17 @@ void SMESH_MeshEditor::Smooth (set & theElems, if ( theElems.empty() ) { // add all faces to theElems SMDS_FaceIteratorPtr fIt = aMesh->facesIterator(); - while ( fIt->more() ) - theElems.insert( fIt->next() ); + while ( fIt->more() ) { + const SMDS_MeshElement* face = fIt->next(); + theElems.insert( make_pair(face->GetID(),face) ); + } } // get all face ids theElems are on set< int > faceIdSet; - set< const SMDS_MeshElement* >::iterator itElem; + map::iterator itElem; if ( the2D ) for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) { - int fId = FindShape( *itElem ); + int fId = FindShape( (*itElem).second ); // check that corresponding submesh exists and a shape is face if (fId && faceIdSet.find( fId ) == faceIdSet.end() && @@ -2023,7 +2106,7 @@ void SMESH_MeshEditor::Smooth (set & theElems, if ( faceSubMesh && nbElemOnFace == faceSubMesh->NbElements() ) break; // all elements found - const SMDS_MeshElement* elem = (*itElem); + const SMDS_MeshElement* elem = (*itElem).second; if ( !elem || elem->GetType() != SMDSAbs_Face || elem->NbNodes() < 3 || ( faceSubMesh && !faceSubMesh->Contains( elem ))) { ++itElem; @@ -2413,7 +2496,7 @@ void SMESH_MeshEditor::Smooth (set & theElems, Ns.push_back( anIter->next() ); Ns.push_back( Ns[0] ); double x, y, z; - for ( int i=0; iNbNodes(); i=i+2 ) { + for(int i=0; iNbNodes(); i=i+2) { if ( !surface.IsNull() ) { gp_XY uv1 = helper.GetNodeUV( face, Ns[i], Ns[i+2] ); gp_XY uv2 = helper.GetNodeUV( face, Ns[i+2], Ns[i] ); @@ -2480,7 +2563,8 @@ static void sweepElement(SMESHDS_Mesh* aMesh, const SMDS_MeshElement* elem, const vector & newNodesItVec, list& newElems, - const int nbSteps) + const int nbSteps, + SMESH_SequenceOfElemPtr& myLastCreatedElems) { // Loop on elem nodes: // find new nodes and detect same nodes indices @@ -2773,6 +2857,7 @@ static void sweepElement(SMESHDS_Mesh* aMesh, if ( aNewElem ) { newElems.push_back( aNewElem ); + myLastCreatedElems.Append(aNewElem); } // set new prev nodes @@ -2791,8 +2876,9 @@ static void makeWalls (SMESHDS_Mesh* aMesh, TNodeOfNodeListMap & mapNewNodes, TElemOfElemListMap & newElemsMap, TElemOfVecOfNnlmiMap & elemNewNodesMap, - set& elemSet, - const int nbSteps) + map& elemSet, + const int nbSteps, + SMESH_SequenceOfElemPtr& myLastCreatedElems) { ASSERT( newElemsMap.size() == elemNewNodesMap.size() ); @@ -2808,7 +2894,7 @@ static void makeWalls (SMESHDS_Mesh* aMesh, while ( eIt->more() && nbInitElems < 2 ) { el = eIt->next(); //if ( elemSet.find( eIt->next() ) != elemSet.end() ) - if ( elemSet.find(el) != elemSet.end() ) + if ( elemSet.find(el->GetID()) != elemSet.end() ) nbInitElems++; } if ( nbInitElems < 2 ) { @@ -2816,7 +2902,7 @@ static void makeWalls (SMESHDS_Mesh* aMesh, if(!NotCreateEdge) { vector newNodesItVec( 1, nList ); list newEdges; - sweepElement( aMesh, node, newNodesItVec, newEdges, nbSteps ); + sweepElement( aMesh, node, newNodesItVec, newEdges, nbSteps, myLastCreatedElems ); } } } @@ -2833,23 +2919,25 @@ static void makeWalls (SMESHDS_Mesh* aMesh, if ( elem->GetType() == SMDSAbs_Edge ) { if(!elem->IsQuadratic()) { // create a ceiling edge - aMesh->AddEdge(vecNewNodes[ 0 ]->second.back(), - vecNewNodes[ 1 ]->second.back() ); + myLastCreatedElems.Append(aMesh->AddEdge(vecNewNodes[ 0 ]->second.back(), + vecNewNodes[ 1 ]->second.back())); } else { // create a ceiling edge - aMesh->AddEdge(vecNewNodes[ 0 ]->second.back(), - vecNewNodes[ 1 ]->second.back(), - vecNewNodes[ 2 ]->second.back()); + myLastCreatedElems.Append(aMesh->AddEdge(vecNewNodes[ 0 ]->second.back(), + vecNewNodes[ 1 ]->second.back(), + vecNewNodes[ 2 ]->second.back())); } } if ( elem->GetType() != SMDSAbs_Face ) continue; + if(itElem->second.size()==0) continue; + bool hasFreeLinks = false; - set avoidSet; - avoidSet.insert( elem ); + map avoidSet; + avoidSet.insert( make_pair(elem->GetID(),elem) ); set aFaceLastNodes; int iNode, nbNodes = vecNewNodes.size(); @@ -2866,12 +2954,12 @@ static void makeWalls (SMESHDS_Mesh* aMesh, hasFreeLinks = true; // make an edge and a ceiling for a new edge if ( !aMesh->FindEdge( n1, n2 )) { - aMesh->AddEdge( n1, n2 ); + myLastCreatedElems.Append(aMesh->AddEdge( n1, n2 )); } n1 = vecNewNodes[ iNode ]->second.back(); n2 = vecNewNodes[ iNext ]->second.back(); if ( !aMesh->FindEdge( n1, n2 )) { - aMesh->AddEdge( n1, n2 ); + myLastCreatedElems.Append(aMesh->AddEdge( n1, n2 )); } } } @@ -2890,13 +2978,13 @@ static void makeWalls (SMESHDS_Mesh* aMesh, // find medium node const SMDS_MeshNode* n3 = vecNewNodes[ iNode+nbn ]->first; if ( !aMesh->FindEdge( n1, n2, n3 )) { - aMesh->AddEdge( n1, n2, n3 ); + myLastCreatedElems.Append(aMesh->AddEdge( n1, n2, n3 )); } n1 = vecNewNodes[ iNode ]->second.back(); n2 = vecNewNodes[ iNext ]->second.back(); n3 = vecNewNodes[ iNode+nbn ]->second.back(); if ( !aMesh->FindEdge( n1, n2, n3 )) { - aMesh->AddEdge( n1, n2, n3 ); + myLastCreatedElems.Append(aMesh->AddEdge( n1, n2, n3 )); } } } @@ -2944,19 +3032,19 @@ static void makeWalls (SMESHDS_Mesh* aMesh, //switch ( vTool.NbFaceNodes( *ind ) ) { switch ( nbn ) { case 3: - aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] ); break; + myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] )); break; case 4: - aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ] ); break; + myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ] )); break; default: { if( (*v)->IsQuadratic() ) { if(nbn==6) { - aMesh->AddFace(nodes[0], nodes[2], nodes[4], - nodes[1], nodes[3], nodes[5]); break; + myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[2], nodes[4], + nodes[1], nodes[3], nodes[5])); break; } else { - aMesh->AddFace(nodes[0], nodes[2], nodes[4], nodes[6], - nodes[1], nodes[3], nodes[5], nodes[7]); + myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[2], nodes[4], nodes[6], + nodes[1], nodes[3], nodes[5], nodes[7])); break; } } @@ -2966,7 +3054,7 @@ static void makeWalls (SMESHDS_Mesh* aMesh, for (int inode = 0; inode < nbPolygonNodes; inode++) { polygon_nodes[inode] = nodes[inode]; } - aMesh->AddPolygonalFace(polygon_nodes); + myLastCreatedElems.Append(aMesh->AddPolygonalFace(polygon_nodes)); } break; } @@ -2992,12 +3080,12 @@ static void makeWalls (SMESHDS_Mesh* aMesh, case 3: if (!hasFreeLinks || !aMesh->FindFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ])) - aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] ); + myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] )); break; case 4: if (!hasFreeLinks || !aMesh->FindFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ])) - aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ] ); + myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ] )); break; default: { @@ -3006,16 +3094,16 @@ static void makeWalls (SMESHDS_Mesh* aMesh, if (!hasFreeLinks || !aMesh->FindFace(nodes[0], nodes[2], nodes[4], nodes[1], nodes[3], nodes[5]) ) { - aMesh->AddFace(nodes[0], nodes[2], nodes[4], - nodes[1], nodes[3], nodes[5]); break; + myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[2], nodes[4], + nodes[1], nodes[3], nodes[5])); break; } } else { // nbn==8 if (!hasFreeLinks || !aMesh->FindFace(nodes[0], nodes[2], nodes[4], nodes[6], nodes[1], nodes[3], nodes[5], nodes[7]) ) - aMesh->AddFace(nodes[0], nodes[2], nodes[4], nodes[6], - nodes[1], nodes[3], nodes[5], nodes[7]); + myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[2], nodes[4], nodes[6], + nodes[1], nodes[3], nodes[5], nodes[7])); } } else { @@ -3025,7 +3113,7 @@ static void makeWalls (SMESHDS_Mesh* aMesh, polygon_nodes[inode] = nodes[inode]; } if (!hasFreeLinks || !aMesh->FindFace(polygon_nodes)) - aMesh->AddPolygonalFace(polygon_nodes); + myLastCreatedElems.Append(aMesh->AddPolygonalFace(polygon_nodes)); } } break; @@ -3039,12 +3127,15 @@ static void makeWalls (SMESHDS_Mesh* aMesh, //purpose : //======================================================================= -void SMESH_MeshEditor::RotationSweep(set & theElems, +void SMESH_MeshEditor::RotationSweep(map & theElems, const gp_Ax1& theAxis, const double theAngle, const int theNbSteps, const double theTol) { + myLastCreatedElems.Clear(); + myLastCreatedNodes.Clear(); + MESSAGE( "RotationSweep()"); gp_Trsf aTrsf; aTrsf.SetRotation( theAxis, theAngle ); @@ -3061,9 +3152,9 @@ void SMESH_MeshEditor::RotationSweep(set & theElems, TElemOfElemListMap newElemsMap; // loop on theElems - set< const SMDS_MeshElement* >::iterator itElem; + map::iterator itElem; for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) { - const SMDS_MeshElement* elem = (*itElem); + const SMDS_MeshElement* elem = (*itElem).second; if ( !elem ) continue; vector & newNodesItVec = mapElemNewNodes[ elem ]; @@ -3094,6 +3185,7 @@ void SMESH_MeshEditor::RotationSweep(set & theElems, aTrsf2.Transforms( coord[0], coord[1], coord[2] ); //aTrsf.Transforms( coord[0], coord[1], coord[2] ); newNode = aMesh->AddNode( coord[0], coord[1], coord[2] ); + myLastCreatedNodes.Append(newNode); listNewNodes.push_back( newNode ); aTrsf2.Transforms( coord[0], coord[1], coord[2] ); //aTrsf.Transforms( coord[0], coord[1], coord[2] ); @@ -3102,6 +3194,7 @@ void SMESH_MeshEditor::RotationSweep(set & theElems, aTrsf.Transforms( coord[0], coord[1], coord[2] ); } newNode = aMesh->AddNode( coord[0], coord[1], coord[2] ); + myLastCreatedNodes.Append(newNode); } listNewNodes.push_back( newNode ); } @@ -3121,9 +3214,11 @@ void SMESH_MeshEditor::RotationSweep(set & theElems, for(int i = 0; iAddNode( coord[0], coord[1], coord[2] ); + myLastCreatedNodes.Append(newNode); listNewNodes.push_back( newNode ); aTrsf2.Transforms( coord[0], coord[1], coord[2] ); newNode = aMesh->AddNode( coord[0], coord[1], coord[2] ); + myLastCreatedNodes.Append(newNode); listNewNodes.push_back( newNode ); } } @@ -3132,10 +3227,10 @@ void SMESH_MeshEditor::RotationSweep(set & theElems, newNodesItVec.push_back( nIt ); } // make new elements - sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem], theNbSteps ); + sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem], theNbSteps, myLastCreatedElems ); } - makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElems, theNbSteps ); + makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElems, theNbSteps, myLastCreatedElems ); } @@ -3150,6 +3245,9 @@ const SMDS_MeshNode* SMESH_MeshEditor::CreateNode(const double x, const double tolnode, SMESH_SequenceOfNode& aNodes) { + myLastCreatedElems.Clear(); + myLastCreatedNodes.Clear(); + gp_Pnt P1(x,y,z); SMESHDS_Mesh * aMesh = myMesh->GetMeshDS(); @@ -3176,6 +3274,7 @@ const SMDS_MeshNode* SMESH_MeshEditor::CreateNode(const double x, // create new node and return it const SMDS_MeshNode* NewNode = aMesh->AddNode(x,y,z); + myLastCreatedNodes.Append(NewNode); return NewNode; } @@ -3186,7 +3285,7 @@ const SMDS_MeshNode* SMESH_MeshEditor::CreateNode(const double x, //======================================================================= void SMESH_MeshEditor::ExtrusionSweep - (set & theElems, + (map & theElems, const gp_Vec& theStep, const int theNbSteps, TElemOfElemListMap& newElemsMap, @@ -3212,12 +3311,15 @@ void SMESH_MeshEditor::ExtrusionSweep //======================================================================= void SMESH_MeshEditor::ExtrusionSweep - (set & theElems, + (map & theElems, ExtrusParam& theParams, TElemOfElemListMap& newElemsMap, const int theFlags, const double theTolerance) { + myLastCreatedElems.Clear(); + myLastCreatedNodes.Clear(); + SMESHDS_Mesh* aMesh = GetMeshDS(); int nbsteps = theParams.mySteps->Length(); @@ -3228,10 +3330,10 @@ void SMESH_MeshEditor::ExtrusionSweep //TElemOfVecOfMapNodesMap mapElemNewNodes; // loop on theElems - set< const SMDS_MeshElement* >::iterator itElem; + map::iterator itElem; for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) { // check element type - const SMDS_MeshElement* elem = (*itElem); + const SMDS_MeshElement* elem = (*itElem).second; if ( !elem ) continue; @@ -3271,6 +3373,7 @@ void SMESH_MeshEditor::ExtrusionSweep } else { const SMDS_MeshNode * newNode = aMesh->AddNode(x, y, z); + myLastCreatedNodes.Append(newNode); listNewNodes.push_back( newNode ); } } @@ -3286,6 +3389,7 @@ void SMESH_MeshEditor::ExtrusionSweep } else { const SMDS_MeshNode * newNode = aMesh->AddNode( coord[0], coord[1], coord[2] ); + myLastCreatedNodes.Append(newNode); listNewNodes.push_back( newNode ); //vecNewNodes[i]=newNode; } @@ -3310,6 +3414,7 @@ void SMESH_MeshEditor::ExtrusionSweep } else { const SMDS_MeshNode * newNode = aMesh->AddNode(x, y, z); + myLastCreatedNodes.Append(newNode); listNewNodes.push_back( newNode ); } coord[0] = coord[0] + theParams.myDir.X()*theParams.mySteps->Value(i+1); @@ -3322,6 +3427,7 @@ void SMESH_MeshEditor::ExtrusionSweep } else { const SMDS_MeshNode * newNode = aMesh->AddNode( coord[0], coord[1], coord[2] ); + myLastCreatedNodes.Append(newNode); listNewNodes.push_back( newNode ); } } @@ -3331,10 +3437,11 @@ void SMESH_MeshEditor::ExtrusionSweep newNodesItVec.push_back( nIt ); } // make new elements - sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem], nbsteps ); + sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem], nbsteps, myLastCreatedElems ); } + if( theFlags & EXTRUSION_FLAG_BOUNDARY ) { - makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElems, nbsteps ); + makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElems, nbsteps, myLastCreatedElems ); } } @@ -3388,7 +3495,7 @@ protected: //purpose : //======================================================================= SMESH_MeshEditor::Extrusion_Error - SMESH_MeshEditor::ExtrusionAlongTrack (std::set & theElements, + SMESH_MeshEditor::ExtrusionAlongTrack (std::map & theElements, SMESH_subMesh* theTrack, const SMDS_MeshNode* theN1, const bool theHasAngles, @@ -3396,12 +3503,15 @@ SMESH_MeshEditor::Extrusion_Error const bool theHasRefPoint, const gp_Pnt& theRefPoint) { + myLastCreatedElems.Clear(); + myLastCreatedNodes.Clear(); + MESSAGE("SMESH_MeshEditor::ExtrusionAlongTrack") int j, aNbTP, aNbE, aNb; double aT1, aT2, aT, aAngle, aX, aY, aZ; std::list aPrms; std::list::iterator aItD; - std::set< const SMDS_MeshElement* >::iterator itElem; + std::map::iterator itElem; Standard_Real aTx1, aTx2, aL2, aTolVec, aTolVec2; gp_Pnt aP3D, aV0; @@ -3541,7 +3651,7 @@ SMESH_MeshEditor::Extrusion_Error itElem = theElements.begin(); for ( ; itElem != theElements.end(); itElem++ ) { - const SMDS_MeshElement* elem = (*itElem); + const SMDS_MeshElement* elem = (*itElem).second; SMDS_ElemIteratorPtr itN = elem->nodesIterator(); while ( itN->more() ) { @@ -3570,7 +3680,7 @@ SMESH_MeshEditor::Extrusion_Error for ( itElem = theElements.begin(); itElem != theElements.end(); itElem++ ) { // check element type - const SMDS_MeshElement* elem = (*itElem); + const SMDS_MeshElement* elem = (*itElem).second; aTypeE = elem->GetType(); if ( !elem || ( aTypeE != SMDSAbs_Face && aTypeE != SMDSAbs_Edge ) ) continue; @@ -3649,12 +3759,14 @@ SMESH_MeshEditor::Extrusion_Error double y = ( aPN1.Y() + aPN0.Y() )/2.; double z = ( aPN1.Z() + aPN0.Z() )/2.; const SMDS_MeshNode* newNode = aMesh->AddNode(x,y,z); + myLastCreatedNodes.Append(newNode); listNewNodes.push_back( newNode ); } aX = aPN1.X(); aY = aPN1.Y(); aZ = aPN1.Z(); const SMDS_MeshNode* newNode = aMesh->AddNode( aX, aY, aZ ); + myLastCreatedNodes.Append(newNode); listNewNodes.push_back( newNode ); aPN0 = aPN1; @@ -3680,6 +3792,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); + myLastCreatedNodes.Append(newN); aNodes[2*i] = newN; aNodes[2*i+1] = N; P = gp_XYZ(N->X(),N->Y(),N->Z()); @@ -3695,12 +3808,14 @@ SMESH_MeshEditor::Extrusion_Error newNodesItVec.push_back( nIt ); } // make new elements + //sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem], + // newNodesItVec[0]->second.size(), myLastCreatedElems ); sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem], - newNodesItVec[0]->second.size() ); + aNbTP-1, myLastCreatedElems ); } makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElements, - aNbTP-1 ); + aNbTP-1, myLastCreatedElems ); return EXTR_OK; } @@ -3710,10 +3825,13 @@ SMESH_MeshEditor::Extrusion_Error //purpose : //======================================================================= -void SMESH_MeshEditor::Transform (set & theElems, +void SMESH_MeshEditor::Transform (map & theElems, const gp_Trsf& theTrsf, const bool theCopy) { + myLastCreatedElems.Clear(); + myLastCreatedNodes.Clear(); + bool needReverse; switch ( theTrsf.Form() ) { case gp_PntMirror: @@ -3731,12 +3849,12 @@ void SMESH_MeshEditor::Transform (set & theElems, // elements sharing moved nodes; those of them which have all // nodes mirrored but are not in theElems are to be reversed - set inverseElemSet; + map inverseElemSet; // loop on theElems - set< const SMDS_MeshElement* >::iterator itElem; + map::iterator itElem; for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) { - const SMDS_MeshElement* elem = (*itElem); + const SMDS_MeshElement* elem = (*itElem).second; if ( !elem ) continue; @@ -3756,8 +3874,10 @@ void SMESH_MeshEditor::Transform (set & theElems, coord[2] = node->Z(); theTrsf.Transforms( coord[0], coord[1], coord[2] ); const SMDS_MeshNode * newNode = node; - if ( theCopy ) + if ( theCopy ) { newNode = aMesh->AddNode( coord[0], coord[1], coord[2] ); + myLastCreatedNodes.Append(newNode); + } else { aMesh->MoveNode( node, coord[0], coord[1], coord[2] ); // node position on shape becomes invalid @@ -3769,8 +3889,10 @@ void SMESH_MeshEditor::Transform (set & theElems, // keep inverse elements if ( !theCopy && needReverse ) { SMDS_ElemIteratorPtr invElemIt = node->GetInverseElementIterator(); - while ( invElemIt->more() ) - inverseElemSet.insert( invElemIt->next() ); + while ( invElemIt->more() ) { + const SMDS_MeshElement* iel = invElemIt->next(); + inverseElemSet.insert( make_pair(iel->GetID(),iel) ); + } } } } @@ -3781,7 +3903,7 @@ void SMESH_MeshEditor::Transform (set & theElems, return; if ( !inverseElemSet.empty()) { - set::iterator invElemIt = inverseElemSet.begin(); + map::iterator invElemIt = inverseElemSet.begin(); for ( ; invElemIt != inverseElemSet.end(); invElemIt++ ) theElems.insert( *invElemIt ); } @@ -3806,7 +3928,7 @@ void SMESH_MeshEditor::Transform (set & theElems, }; for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) { - const SMDS_MeshElement* elem = (*itElem); + const SMDS_MeshElement* elem = (*itElem).second; if ( !elem || elem->GetType() == SMDSAbs_Node ) continue; @@ -3839,8 +3961,9 @@ void SMESH_MeshEditor::Transform (set & theElems, continue; // not all nodes transformed if ( theCopy ) { - aMesh->AddPolygonalFace(poly_nodes); - } else { + myLastCreatedElems.Append(aMesh->AddPolygonalFace(poly_nodes)); + } + else { aMesh->ChangePolygonNodes(elem, poly_nodes); } } @@ -3877,8 +4000,9 @@ void SMESH_MeshEditor::Transform (set & theElems, continue; // not all nodes transformed if ( theCopy ) { - aMesh->AddPolyhedralVolume(poly_nodes, quantities); - } else { + myLastCreatedElems.Append(aMesh->AddPolyhedralVolume(poly_nodes, quantities)); + } + else { aMesh->ChangePolyhedronNodes(elem, poly_nodes, quantities); } } @@ -3951,50 +4075,50 @@ void SMESH_MeshEditor::Transform (set & theElems, switch ( elemType ) { case SMDSAbs_Edge: if ( nbNodes == 2 ) - aMesh->AddEdge( nodes[ 0 ], nodes[ 1 ] ); + myLastCreatedElems.Append(aMesh->AddEdge( nodes[ 0 ], nodes[ 1 ] )); else - aMesh->AddEdge( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] ); + myLastCreatedElems.Append(aMesh->AddEdge( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] )); break; case SMDSAbs_Face: if ( nbNodes == 3 ) - aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] ); + myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] )); else if(nbNodes==4) - aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ]); + myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ])); else if(nbNodes==6) - aMesh->AddFace(nodes[0], nodes[1], nodes[2], nodes[3], - nodes[4], nodes[5]); + myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[1], nodes[2], nodes[3], + nodes[4], nodes[5])); else // nbNodes==8 - aMesh->AddFace(nodes[0], nodes[1], nodes[2], nodes[3], - nodes[4], nodes[5], nodes[6], nodes[7]); + myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[1], nodes[2], nodes[3], + nodes[4], nodes[5], nodes[6], nodes[7])); break; case SMDSAbs_Volume: if ( nbNodes == 4 ) - aMesh->AddVolume( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ] ); + myLastCreatedElems.Append(aMesh->AddVolume( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ] )); else if ( nbNodes == 8 ) - aMesh->AddVolume( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ], - nodes[ 4 ], nodes[ 5 ], nodes[ 6 ] , nodes[ 7 ]); + myLastCreatedElems.Append(aMesh->AddVolume( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ], + nodes[ 4 ], nodes[ 5 ], nodes[ 6 ] , nodes[ 7 ])); else if ( nbNodes == 6 ) - aMesh->AddVolume( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ], - nodes[ 4 ], nodes[ 5 ]); + myLastCreatedElems.Append(aMesh->AddVolume( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ], + nodes[ 4 ], nodes[ 5 ])); else if ( nbNodes == 5 ) - aMesh->AddVolume( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ], - nodes[ 4 ]); + myLastCreatedElems.Append(aMesh->AddVolume( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ], + nodes[ 4 ])); else if(nbNodes==10) - aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], - nodes[5], nodes[6], nodes[7], nodes[8], nodes[9]); + myLastCreatedElems.Append(aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], + nodes[5], nodes[6], nodes[7], nodes[8], nodes[9])); else if(nbNodes==13) - aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], - nodes[5], nodes[6], nodes[7], nodes[8], nodes[9], - nodes[10], nodes[11], nodes[12]); + myLastCreatedElems.Append(aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], + nodes[5], nodes[6], nodes[7], nodes[8], nodes[9], + nodes[10], nodes[11], nodes[12])); else if(nbNodes==15) - aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], - nodes[5], nodes[6], nodes[7], nodes[8], nodes[9], - nodes[10], nodes[11], nodes[12], nodes[13], nodes[14]); + myLastCreatedElems.Append(aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], + nodes[5], nodes[6], nodes[7], nodes[8], nodes[9], + nodes[10], nodes[11], nodes[12], nodes[13], nodes[14])); else // nbNodes==20 - aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], - nodes[5], nodes[6], nodes[7], nodes[8], nodes[9], - nodes[10], nodes[11], nodes[12], nodes[13], nodes[14], - nodes[15], nodes[16], nodes[17], nodes[18], nodes[19]); + myLastCreatedElems.Append(aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], + nodes[5], nodes[6], nodes[7], nodes[8], nodes[9], + nodes[10], nodes[11], nodes[12], nodes[13], nodes[14], + nodes[15], nodes[16], nodes[17], nodes[18], nodes[19])); break; default:; } @@ -4018,6 +4142,9 @@ void SMESH_MeshEditor::FindCoincidentNodes (set & theNodes const double theTolerance, TListOfListOfNodes & theGroupsOfNodes) { + myLastCreatedElems.Clear(); + myLastCreatedNodes.Clear(); + double tol2 = theTolerance * theTolerance; list nodes; @@ -4051,7 +4178,10 @@ void SMESH_MeshEditor::FindCoincidentNodes (set & theNodes groupPtr = & theGroupsOfNodes.back(); groupPtr->push_back( n1 ); } - groupPtr->push_back( n2 ); + if(groupPtr->front()>n2) + groupPtr->push_front( n2 ); + else + groupPtr->push_back( n2 ); it2 = nodes.erase( it2 ); it2--; } @@ -4149,6 +4279,9 @@ int SMESH_MeshEditor::SimplifyFace (const vector faceNode void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) { + myLastCreatedElems.Clear(); + myLastCreatedNodes.Clear(); + SMESHDS_Mesh* aMesh = GetMeshDS(); TNodeNodeMap nodeNodeMap; // node to replace - new node @@ -4236,6 +4369,7 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) poly_nodes[ii] = polygons_nodes[inode]; } SMDS_MeshElement* newElem = aMesh->AddPolygonalFace(poly_nodes); + myLastCreatedElems.Append(newElem); if (aShapeId) aMesh->SetMeshElementOnShape(newElem, aShapeId); } @@ -4350,6 +4484,7 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) curNodes[ 4 ], curNodes[ 5 ], curNodes[ iRepl[ 0 ] == 2 ? 1 : 2 ]); + myLastCreatedElems.Append(newElem); if ( aShapeId ) aMesh->SetMeshElementOnShape( newElem, aShapeId ); // 2. : reverse a bottom @@ -4515,6 +4650,7 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) curNodes[ind[ 3 ]], curNodes[ind[ 2 ]], curNodes[indTop[ 0 ]]); + myLastCreatedElems.Append(newElem); if ( aShapeId ) aMesh->SetMeshElementOnShape( newElem, aShapeId ); isOk = true; @@ -4580,6 +4716,7 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) curNodes[ i2 ], curNodes[ i3d ], curNodes[ i2t ]); + myLastCreatedElems.Append(newElem); if ( aShapeId ) aMesh->SetMeshElementOnShape( newElem, aShapeId ); isOk = true; @@ -4676,6 +4813,35 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) } + +// ================================================= +// class : SortableElement +// purpose : auxilary +// ================================================= +class SortableElement : public set +{ + public: + + SortableElement( const SMDS_MeshElement* theElem ) + { + myID = theElem->GetID(); + SMDS_ElemIteratorPtr nodeIt = theElem->nodesIterator(); + while ( nodeIt->more() ) + this->insert( nodeIt->next() ); + } + + const long GetID() const + { return myID; } + + void SetID(const long anID) const + { myID = anID; } + + + private: + mutable long myID; +}; + + //======================================================================= //function : MergeEqualElements //purpose : Remove all but one of elements built on the same nodes. @@ -4683,6 +4849,9 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) void SMESH_MeshEditor::MergeEqualElements() { + myLastCreatedElems.Clear(); + myLastCreatedNodes.Clear(); + SMESHDS_Mesh* aMesh = GetMeshDS(); SMDS_EdgeIteratorPtr eIt = aMesh->edgesIterator(); @@ -4693,8 +4862,7 @@ void SMESH_MeshEditor::MergeEqualElements() for ( int iDim = 1; iDim <= 3; iDim++ ) { - set< set > setOfNodeSet; - + set< SortableElement > setOfNodeSet; while ( 1 ) { // get next element const SMDS_MeshElement* elem = 0; @@ -4707,16 +4875,21 @@ void SMESH_MeshEditor::MergeEqualElements() } if ( !elem ) break; - // get elem nodes - set nodeSet; - SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator(); - while ( nodeIt->more() ) - nodeSet.insert( nodeIt->next() ); + SortableElement SE(elem); // check uniqueness - bool isUnique = setOfNodeSet.insert( nodeSet ).second; - if ( !isUnique ) - rmElemIds.push_back( elem->GetID() ); + 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() ); + } + } } } @@ -4733,17 +4906,17 @@ void SMESH_MeshEditor::MergeEqualElements() const SMDS_MeshElement* SMESH_MeshEditor::FindFaceInSet(const SMDS_MeshNode* n1, const SMDS_MeshNode* n2, - const set& elemSet, - const set& avoidSet) + const map& elemSet, + const map& avoidSet) { SMDS_ElemIteratorPtr invElemIt = n1->GetInverseElementIterator(); while ( invElemIt->more() ) { // loop on inverse elements of n1 const SMDS_MeshElement* elem = invElemIt->next(); if (elem->GetType() != SMDSAbs_Face || - avoidSet.find( elem ) != avoidSet.end() ) + avoidSet.find( elem->GetID() ) != avoidSet.end() ) continue; - if ( !elemSet.empty() && elemSet.find( elem ) == elemSet.end()) + if ( !elemSet.empty() && elemSet.find( elem->GetID() ) == elemSet.end()) continue; // get face nodes and find index of n1 int i1, nbN = elem->NbNodes(), iNode = 0; @@ -4815,9 +4988,9 @@ static const SMDS_MeshElement* findAdjacentFace(const SMDS_MeshNode* n1, const SMDS_MeshNode* n2, const SMDS_MeshElement* elem) { - set elemSet, avoidSet; + map elemSet, avoidSet; if ( elem ) - avoidSet.insert ( elem ); + avoidSet.insert ( make_pair(elem->GetID(),elem) ); return SMESH_MeshEditor::FindFaceInSet( n1, n2, elemSet, avoidSet ); } @@ -4994,6 +5167,9 @@ SMESH_MeshEditor::Sew_Error const bool toCreatePolygons, const bool toCreatePolyedrs) { + myLastCreatedElems.Clear(); + myLastCreatedNodes.Clear(); + MESSAGE("::SewFreeBorder()"); Sew_Error aResult = SEW_OK; @@ -5560,6 +5736,7 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement* theFace, int aShapeId = FindShape( theFace ); SMDS_MeshElement* newElem = aMesh->AddPolygonalFace(poly_nodes); + myLastCreatedElems.Append(newElem); if ( aShapeId && newElem ) aMesh->SetMeshElementOnShape( newElem, aShapeId ); @@ -5632,6 +5809,7 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement* theFace, newElem = aMesh->AddFace (linkNodes[ i1++ ], linkNodes[ i2++ ], nodes[ iSplit < iBestQuad ? i4 : i3 ]); + myLastCreatedElems.Append(newElem); if ( aShapeId && newElem ) aMesh->SetMeshElementOnShape( newElem, aShapeId ); } @@ -5677,11 +5855,13 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement* theFace, if(nbFaceNodes==6) { // quadratic triangle SMDS_MeshElement* newElem = aMesh->AddFace(nodes[3],nodes[4],nodes[5]); + myLastCreatedElems.Append(newElem); if ( aShapeId && newElem ) aMesh->SetMeshElementOnShape( newElem, aShapeId ); if(theFace->IsMediumNode(nodes[il1])) { // create quadrangle newElem = aMesh->AddFace(nodes[0],nodes[1],nodes[3],nodes[5]); + myLastCreatedElems.Append(newElem); if ( aShapeId && newElem ) aMesh->SetMeshElementOnShape( newElem, aShapeId ); n1 = 1; @@ -5691,6 +5871,7 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement* theFace, else { // create quadrangle newElem = aMesh->AddFace(nodes[1],nodes[2],nodes[3],nodes[5]); + myLastCreatedElems.Append(newElem); if ( aShapeId && newElem ) aMesh->SetMeshElementOnShape( newElem, aShapeId ); n1 = 0; @@ -5701,17 +5882,21 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement* theFace, else { // nbFaceNodes==8 - quadratic quadrangle SMDS_MeshElement* newElem = aMesh->AddFace(nodes[3],nodes[4],nodes[5]); + myLastCreatedElems.Append(newElem); if ( aShapeId && newElem ) aMesh->SetMeshElementOnShape( newElem, aShapeId ); newElem = aMesh->AddFace(nodes[5],nodes[6],nodes[7]); + myLastCreatedElems.Append(newElem); if ( aShapeId && newElem ) aMesh->SetMeshElementOnShape( newElem, aShapeId ); newElem = aMesh->AddFace(nodes[5],nodes[7],nodes[3]); + myLastCreatedElems.Append(newElem); if ( aShapeId && newElem ) aMesh->SetMeshElementOnShape( newElem, aShapeId ); if(theFace->IsMediumNode(nodes[il1])) { // create quadrangle newElem = aMesh->AddFace(nodes[0],nodes[1],nodes[3],nodes[7]); + myLastCreatedElems.Append(newElem); if ( aShapeId && newElem ) aMesh->SetMeshElementOnShape( newElem, aShapeId ); n1 = 1; @@ -5721,6 +5906,7 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement* theFace, else { // create quadrangle newElem = aMesh->AddFace(nodes[1],nodes[2],nodes[3],nodes[7]); + myLastCreatedElems.Append(newElem); if ( aShapeId && newElem ) aMesh->SetMeshElementOnShape( newElem, aShapeId ); n1 = 0; @@ -5740,6 +5926,7 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement* theFace, for(i=1; iAddFace(aNodes[i-1],aNodes[i],nodes[n3]); + myLastCreatedElems.Append(newElem); if ( aShapeId && newElem ) aMesh->SetMeshElementOnShape( newElem, aShapeId ); } @@ -5756,6 +5943,9 @@ void SMESH_MeshEditor::UpdateVolumes (const SMDS_MeshNode* theBetweenNode const SMDS_MeshNode* theBetweenNode2, list& theNodesToInsert) { + myLastCreatedElems.Clear(); + myLastCreatedNodes.Clear(); + SMDS_ElemIteratorPtr invElemIt = theBetweenNode1->GetInverseElementIterator(); while (invElemIt->more()) { // loop on inverse elements of theBetweenNode1 const SMDS_MeshElement* elem = invElemIt->next(); @@ -5824,6 +6014,7 @@ void SMESH_MeshEditor::UpdateVolumes (const SMDS_MeshNode* theBetweenNode SMDS_MeshElement* newElem = aMesh->AddPolyhedralVolume(poly_nodes, quantities); + myLastCreatedElems.Append(newElem); if (aShapeId && newElem) aMesh->SetMeshElementOnShape(newElem, aShapeId); @@ -6171,13 +6362,16 @@ bool SMESH_MeshEditor::ConvertFromQuadratic() //======================================================================= SMESH_MeshEditor::Sew_Error - SMESH_MeshEditor::SewSideElements (set& theSide1, - set& theSide2, + SMESH_MeshEditor::SewSideElements (map& theSide1, + map& theSide2, const SMDS_MeshNode* theFirstNode1, const SMDS_MeshNode* theFirstNode2, const SMDS_MeshNode* theSecondNode1, const SMDS_MeshNode* theSecondNode2) { + myLastCreatedElems.Clear(); + myLastCreatedNodes.Clear(); + MESSAGE ("::::SewSideElements()"); if ( theSide1.size() != theSide2.size() ) return SEW_DIFF_NB_OF_ELEMENTS; @@ -6204,15 +6398,16 @@ SMESH_MeshEditor::Sew_Error set * faceSetPtr[] = { &faceSet1, &faceSet2 }; set * volSetPtr[] = { &volSet1, &volSet2 }; set * nodeSetPtr[] = { &nodeSet1, &nodeSet2 }; - set * elemSetPtr[] = { &theSide1, &theSide2 }; + map * elemSetPtr[] = { &theSide1, &theSide2 }; int iSide, iFace, iNode; for ( iSide = 0; iSide < 2; iSide++ ) { set * nodeSet = nodeSetPtr[ iSide ]; - set * elemSet = elemSetPtr[ iSide ]; + map * elemSet = elemSetPtr[ iSide ]; set * faceSet = faceSetPtr[ iSide ]; set * volSet = volSetPtr [ iSide ]; - set::iterator vIt, eIt; + set::iterator vIt; + map::iterator eIt; set::iterator nIt; // check that given nodes belong to given elements @@ -6220,7 +6415,7 @@ SMESH_MeshEditor::Sew_Error const SMDS_MeshNode* n2 = ( iSide == 0 ) ? theSecondNode1 : theSecondNode2; int firstIndex = -1, secondIndex = -1; for (eIt = elemSet->begin(); eIt != elemSet->end(); eIt++ ) { - const SMDS_MeshElement* elem = *eIt; + const SMDS_MeshElement* elem = (*eIt).second; if ( firstIndex < 0 ) firstIndex = elem->GetNodeIndex( n1 ); if ( secondIndex < 0 ) secondIndex = elem->GetNodeIndex( n2 ); if ( firstIndex > -1 && secondIndex > -1 ) break; @@ -6240,7 +6435,8 @@ SMESH_MeshEditor::Sew_Error // loop on the given element of a side for (eIt = elemSet->begin(); eIt != elemSet->end(); eIt++ ) { - const SMDS_MeshElement* elem = *eIt; + //const SMDS_MeshElement* elem = *eIt; + const SMDS_MeshElement* elem = (*eIt).second; if ( elem->GetType() == SMDSAbs_Face ) { faceSet->insert( elem ); set faceNodeSet; @@ -6356,7 +6552,7 @@ SMESH_MeshEditor::Sew_Error const SMDS_MeshElement* e = invElemIt->next(); if ( faceSet->find( e ) != faceSet->end() ) nbSharedNodes++; - if ( elemSet->find( e ) != elemSet->end() ) + if ( elemSet->find( e->GetID() ) != elemSet->end() ) nbSharedNodes++; } } @@ -6373,10 +6569,10 @@ SMESH_MeshEditor::Sew_Error // choose a face most close to the bary center of the opposite side gp_XYZ aBC( 0., 0., 0. ); set addedNodes; - set * elemSet2 = elemSetPtr[ 1 - iSide ]; + map * elemSet2 = elemSetPtr[ 1 - iSide ]; eIt = elemSet2->begin(); for ( eIt = elemSet2->begin(); eIt != elemSet2->end(); eIt++ ) { - SMDS_ElemIteratorPtr nodeIt = (*eIt)->nodesIterator(); + SMDS_ElemIteratorPtr nodeIt = (*eIt).second->nodesIterator(); while ( nodeIt->more() ) { // loop on free face nodes const SMDS_MeshNode* n = static_cast( nodeIt->next() ); diff --git a/src/SMESH/SMESH_MeshEditor.hxx b/src/SMESH/SMESH_MeshEditor.hxx index c95ded87b..68a15d1b3 100644 --- a/src/SMESH/SMESH_MeshEditor.hxx +++ b/src/SMESH/SMESH_MeshEditor.hxx @@ -33,6 +33,7 @@ #include "SMESH_Mesh.hxx" #include "SMESH_Controls.hxx" #include "SMESH_SequenceOfNode.hxx" +#include "SMESH_SequenceOfElemPtr.hxx" #include "gp_Dir.hxx" #include "TColStd_HSequenceOfReal.hxx" #include "SMESH_MesherHelper.hxx" @@ -89,7 +90,7 @@ class SMESH_MeshEditor { * is still performed; theMaxAngle is mesured in radians. * \retval bool - Success or not. */ - bool TriToQuad (std::set & theElems, + bool TriToQuad (std::map & theElems, SMESH::Controls::NumericalFunctorPtr theCriterion, const double theMaxAngle); @@ -99,7 +100,7 @@ class SMESH_MeshEditor { * \param theCriterion - Is used to choose a diagonal for splitting. * \retval bool - Success or not. */ - bool QuadToTri (std::set & theElems, + bool QuadToTri (std::map & theElems, SMESH::Controls::NumericalFunctorPtr theCriterion); /*! @@ -108,7 +109,7 @@ class SMESH_MeshEditor { * \param the13Diag - Is used to choose a diagonal for splitting. * \retval bool - Success or not. */ - bool QuadToTri (std::set & theElems, + bool QuadToTri (std::map & theElems, const bool the13Diag); /*! @@ -123,7 +124,7 @@ class SMESH_MeshEditor { enum SmoothMethod { LAPLACIAN = 0, CENTROIDAL }; - void Smooth (std::set & theElements, + void Smooth (std::map & theElements, std::set & theFixedNodes, const SmoothMethod theSmoothMethod, const int theNbIterations, @@ -139,7 +140,7 @@ class SMESH_MeshEditor { // on geometrical faces - void RotationSweep (std::set & theElements, + void RotationSweep (std::map & theElements, const gp_Ax1& theAxis, const double theAngle, const int theNbSteps, @@ -189,7 +190,7 @@ class SMESH_MeshEditor { * EXTRUSION_FLAG_SEW is set */ void ExtrusionSweep - (set & theElems, + (map & theElems, const gp_Vec& theStep, const int theNbSteps, TElemOfElemListMap& newElemsMap, @@ -206,7 +207,7 @@ class SMESH_MeshEditor { * EXTRUSION_FLAG_SEW is set * param theParams - special structure for manage of extrusion */ - void ExtrusionSweep (set & theElems, + void ExtrusionSweep (map & theElems, ExtrusParam& theParams, TElemOfElemListMap& newElemsMap, const int theFlags, @@ -226,7 +227,7 @@ class SMESH_MeshEditor { EXTR_CANT_GET_TANGENT }; - Extrusion_Error ExtrusionAlongTrack (std::set & theElements, + Extrusion_Error ExtrusionAlongTrack (std::map & theElements, SMESH_subMesh* theTrackPattern, const SMDS_MeshNode* theNodeStart, const bool theHasAngles, @@ -236,7 +237,7 @@ class SMESH_MeshEditor { // Generate new elements by extrusion of theElements along path given by theTrackPattern, // theHasAngles are the rotation angles, base point can be given by theRefPoint - void Transform (std::set & theElements, + void Transform (std::map & theElements, const gp_Trsf& theTrsf, const bool theCopy); // Move or copy theElements applying theTrsf to their nodes @@ -313,8 +314,8 @@ class SMESH_MeshEditor { // nodes are inserted. // Return false, if sewing failed. - Sew_Error SewSideElements (std::set& theSide1, - std::set& theSide2, + Sew_Error SewSideElements (std::map& theSide1, + std::map& theSide2, const SMDS_MeshNode* theFirstNode1ToMerge, const SMDS_MeshNode* theFirstNode2ToMerge, const SMDS_MeshNode* theSecondNode1ToMerge, @@ -372,8 +373,8 @@ class SMESH_MeshEditor { static const SMDS_MeshElement* FindFaceInSet(const SMDS_MeshNode* n1, const SMDS_MeshNode* n2, - const std::set& elemSet, - const std::set& avoidSet); + const std::map& elemSet, + const std::map& avoidSet); // Return a face having linked nodes n1 and n2 and which is // - not in avoidSet, // - in elemSet provided that !elemSet.empty() @@ -395,6 +396,10 @@ class SMESH_MeshEditor { SMESHDS_Mesh * GetMeshDS() { return myMesh->GetMeshDS(); } + SMESH_SequenceOfElemPtr GetLastCreatedNodes() { return myLastCreatedNodes; } + + SMESH_SequenceOfElemPtr GetLastCreatedElems() { return myLastCreatedElems; } + private: void ConvertElemToQuadratic(SMESHDS_SubMesh *theSm, @@ -412,6 +417,16 @@ private: SMESH_Mesh * myMesh; + /*! + * Sequence for keeping nodes created during last operation + */ + SMESH_SequenceOfElemPtr myLastCreatedNodes; + + /*! + * Sequence for keeping elements created during last operation + */ + SMESH_SequenceOfElemPtr myLastCreatedElems; + }; #endif -- 2.39.2