From f899a9e718eecb1dfdd4474a08a277e333a55857 Mon Sep 17 00:00:00 2001 From: akl Date: Fri, 23 Mar 2007 13:58:53 +0000 Subject: [PATCH] PAL13190 (EDF159 SMESH: in Merge Nodes and Merge Elements, visualisze nodes or meshes twice): add FindEqualElements(); modify MergeEqualElements(). --- idl/SMESH_MeshEditor.idl | 5 +- src/SMESH/SMESH_MeshEditor.cxx | 120 +++++++++++++++++++---------- src/SMESH/SMESH_MeshEditor.hxx | 9 ++- src/SMESH_I/SMESH_MeshEditor_i.cxx | 72 ++++++++++++++++- src/SMESH_I/SMESH_MeshEditor_i.hxx | 4 +- 5 files changed, 162 insertions(+), 48 deletions(-) diff --git a/idl/SMESH_MeshEditor.idl b/idl/SMESH_MeshEditor.idl index 492e95440..8638407cb 100644 --- a/idl/SMESH_MeshEditor.idl +++ b/idl/SMESH_MeshEditor.idl @@ -335,7 +335,10 @@ module SMESH void MergeNodes (in array_of_long_array GroupsOfNodes); - void MergeEqualElements(); + void FindEqualElements (in SMESH_IDSource MeshOrSubMeshOrGroup, + out array_of_long_array GroupsOfElementsID); + + void MergeEqualElements(in array_of_long_array GroupsOfElementsID); /*! * If the given ID is a valid node ID (nodeID > 0), just move this node, else * move the node closest to the point to point's location and return ID of the node diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx index 6c9417453..1838b6da4 100644 --- a/src/SMESH/SMESH_MeshEditor.cxx +++ b/src/SMESH/SMESH_MeshEditor.cxx @@ -5069,60 +5069,96 @@ class SortableElement : public set mutable const SMDS_MeshElement* myElem; }; +//======================================================================= +//function : FindEqualElements +//purpose : +//======================================================================= +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. //======================================================================= -void SMESH_MeshEditor::MergeEqualElements() +void SMESH_MeshEditor::MergeEqualElements(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; - const SortableElement & SEold = *itSE; - if( SEold.Get()->GetID() > elem->GetID() ) { - // keep elem, remove old - rmElemIds.push_back( SEold.Get()->GetID() ); - // add kept elem in groups of removed one (PAL15188) - AddToSameGroups( elem, SEold.Get(), GetMeshDS() ); - SEold.Set( elem ); - } - else { // remove elem - rmElemIds.push_back( elem->GetID() ); - AddToSameGroups( SEold.Get(), elem, GetMeshDS() ); - } - } - } + 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 ); diff --git a/src/SMESH/SMESH_MeshEditor.hxx b/src/SMESH/SMESH_MeshEditor.hxx index 81b085096..d68fca860 100644 --- a/src/SMESH/SMESH_MeshEditor.hxx +++ b/src/SMESH/SMESH_MeshEditor.hxx @@ -315,7 +315,14 @@ public: // In each group, the cdr of nodes are substituted by the first one // in all elements. - void MergeEqualElements(); + typedef std::list< std::list< int > > TListOfListOfElementsID; + + void FindEqualElements(std::set & theElements, + TListOfListOfElementsID & theGroupsOfElementsID); + // Return list of group of elements build on the same nodes. + // Search among theElements or in the whole mesh if theElements is empty. + + void MergeEqualElements(TListOfListOfElementsID & theGroupsOfElementsID); // Remove all but one of elements built on the same nodes. // Return nb of successfully merged groups. diff --git a/src/SMESH_I/SMESH_MeshEditor_i.cxx b/src/SMESH_I/SMESH_MeshEditor_i.cxx index afb4896da..a545dbd20 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.cxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.cxx @@ -1884,20 +1884,86 @@ void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfN aTPythonDump << "])"; } +//======================================================================= +//function : FindEqualElements +//purpose : +//======================================================================= +void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObject, + SMESH::array_of_long_array_out GroupsOfElementsID) +{ + initData(); + if ( !(!CORBA::is_nil(SMESH::SMESH_GroupBase::_narrow(theObject)) && + SMESH::SMESH_GroupBase::_narrow(theObject)->GetType() == SMESH::NODE) ) { + typedef list TListOfIDs; + set elems; + SMESH::long_array_var aElementsId = theObject->GetIDs(); + SMESHDS_Mesh* aMesh = GetMeshDS(); + + for(int i = 0; i < aElementsId->length(); i++) { + CORBA::Long anID = aElementsId[i]; + const SMDS_MeshElement * elem = aMesh->FindElement(anID); + if (elem) { + elems.insert(elem); + } + } + + ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID; + ::SMESH_MeshEditor anEditor( myMesh ); + anEditor.FindEqualElements( elems, aListOfListOfElementsID ); + + GroupsOfElementsID = new SMESH::array_of_long_array; + GroupsOfElementsID->length( aListOfListOfElementsID.size() ); + + ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt = aListOfListOfElementsID.begin(); + for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j) { + SMESH::long_array& aGroup = GroupsOfElementsID[ j ]; + TListOfIDs& listOfIDs = *arraysIt; + aGroup.length( listOfIDs.size() ); + TListOfIDs::iterator idIt = listOfIDs.begin(); + for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k ) { + aGroup[ k ] = *idIt; + } + } + + // Update Python script + TPythonDump() << "equal_elements = " << this << ".FindEqualElements( " + <() ); + list< int >& aListOfElemsID = aListOfListOfElementsID.back(); + for ( int j = 0; j < anElemsIDGroup.length(); j++ ) { + CORBA::Long id = anElemsIDGroup[ j ]; + aListOfElemsID.push_back( id ); + } + if ( aListOfElemsID.size() < 2 ) + aListOfListOfElementsID.pop_back(); + if ( i > 0 ) aTPythonDump << ", "; + aTPythonDump << anElemsIDGroup; + } + ::SMESH_MeshEditor anEditor( myMesh ); - anEditor.MergeEqualElements(); + anEditor.MergeEqualElements(aListOfListOfElementsID); // Update Python script - TPythonDump() << this << ".MergeEqualElements()"; + aTPythonDump << "] )"; } //================================================================================ diff --git a/src/SMESH_I/SMESH_MeshEditor_i.hxx b/src/SMESH_I/SMESH_MeshEditor_i.hxx index 331177bbd..005395781 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.hxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.hxx @@ -208,7 +208,9 @@ class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor CORBA::Double Tolerance, SMESH::array_of_long_array_out GroupsOfNodes); void MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes); - void MergeEqualElements(); + void FindEqualElements(SMESH::SMESH_IDSource_ptr theObject, + SMESH::array_of_long_array_out GroupsOfElementsID); + void MergeEqualElements(const SMESH::array_of_long_array& GroupsOfElementsID); CORBA::Long MoveClosestNodeToPoint(CORBA::Double x, CORBA::Double y, CORBA::Double z, -- 2.39.2