From efa9d475b83e4613c8536fa705c3c233d1ae025c Mon Sep 17 00:00:00 2001 From: ptv Date: Thu, 1 Oct 2009 06:47:15 +0000 Subject: [PATCH] 0020427: EDF 868 SMESH : Be able to define the submeshing order 1. Add Store/Retrieve into/from HDF study 2. Clear submesh affected in submesh order modification 3. Set Modified flag in GUI object browser --- src/SMESH/SMESH_subMesh.cxx | 26 +++++++++++++ src/SMESH/SMESH_subMesh.hxx | 9 +++++ src/SMESHGUI/SMESHGUI_MeshOrderOp.cxx | 7 ++++ src/SMESH_I/SMESH_Gen_i.cxx | 55 ++++++++++++++++++++++++++- src/SMESH_I/SMESH_Mesh_i.cxx | 42 ++++++++++++++++++++ 5 files changed, 137 insertions(+), 2 deletions(-) diff --git a/src/SMESH/SMESH_subMesh.cxx b/src/SMESH/SMESH_subMesh.cxx index 21d167518..b8615dcc2 100644 --- a/src/SMESH/SMESH_subMesh.cxx +++ b/src/SMESH/SMESH_subMesh.cxx @@ -2191,3 +2191,29 @@ SMESH_subMeshIteratorPtr SMESH_subMesh::getDependsOnIterator(const bool includeS ( new _Iterator( new SMDS_mapIterator( DependsOn() ), prepend, append )); } } + +//================================================================================ +/*! + * \brief Find common submeshes (based on shared subshapes with other + * \param theOther submesh to check + * \param theSetOfCommon set of common submesh + */ +//================================================================================ + +bool SMESH_subMesh::FindIntersection(const SMESH_subMesh* theOther, + std::set& theSetOfCommon ) const +{ + int oldNb = theSetOfCommon.size(); + // check main submeshes + const map ::const_iterator otherEnd = theOther->_mapDepend.end(); + if ( theOther->_mapDepend.find(this->GetId()) != otherEnd ) + theSetOfCommon.insert( this ); + if ( _mapDepend.find(theOther->GetId()) != _mapDepend.end() ) + theSetOfCommon.insert( theOther ); + // check common submeshes + map ::const_iterator mapIt = _mapDepend.begin(); + for( ; mapIt != _mapDepend.end(); mapIt++ ) + if ( theOther->_mapDepend.find((*mapIt).first) != otherEnd ) + theSetOfCommon.insert( (*mapIt).second ); + return oldNb < theSetOfCommon.size(); +} diff --git a/src/SMESH/SMESH_subMesh.hxx b/src/SMESH/SMESH_subMesh.hxx index d4c0468f9..bba5665fc 100644 --- a/src/SMESH/SMESH_subMesh.hxx +++ b/src/SMESH/SMESH_subMesh.hxx @@ -228,6 +228,15 @@ public: void SetIsAlwaysComputed(bool isAlCo); bool IsAlwaysComputed() { return _alwaysComputed; } + + /*! + * \brief Find common submeshes (based on shared subshapes with other + * \param theOther submesh to check + * \param theCommonIds set of common submesh IDs + * NOTE: this method does not cleat set before collect common IDs + */ + bool FindIntersection( const SMESH_subMesh * theOther, + std::set& theSetOfCommon ) const; protected: // ================================================================== diff --git a/src/SMESHGUI/SMESHGUI_MeshOrderOp.cxx b/src/SMESHGUI/SMESHGUI_MeshOrderOp.cxx index 5c26efc2c..00b63da3a 100644 --- a/src/SMESHGUI/SMESHGUI_MeshOrderOp.cxx +++ b/src/SMESHGUI/SMESHGUI_MeshOrderOp.cxx @@ -299,6 +299,11 @@ bool SMESHGUI_MeshOrderMgr::SetMeshOrder( const ListListId& theListListIds ) } } + // is it enought to set modifid attribute on root mesh objects only? + // it is seems that modifaction flag will be set on child submeshes + // automatically (see SMESH::ModifiedMesh for details) + SMESH::ModifiedMesh( aMeshSObj, false, false ); + SMESH::submesh_array_array_var meshOrder = new SMESH::submesh_array_array(); meshOrder->length(theListListIds.count() ); ListListId::const_iterator it = theListListIds.constBegin(); @@ -313,6 +318,8 @@ bool SMESHGUI_MeshOrderMgr::SetMeshOrder( const ListListId& theListListIds ) meshOrder[ i++ ] = subMeshList; } + // update object browser + SMESHGUI::GetSMESHGUI()->updateObjBrowser( true, 0 ); return myMesh->SetMeshOrder(meshOrder); } diff --git a/src/SMESH_I/SMESH_Gen_i.cxx b/src/SMESH_I/SMESH_Gen_i.cxx index 514eb9380..f0faba9fd 100644 --- a/src/SMESH_I/SMESH_Gen_i.cxx +++ b/src/SMESH_I/SMESH_Gen_i.cxx @@ -2703,6 +2703,40 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, //if ( shapeRefFound ) //myWriter.AddAllSubMeshes(); + // store submesh order if any + const TListOfListOfInt& theOrderIds = myLocMesh.GetMeshOrder(); + if ( theOrderIds.size() ) { + char order_list[ 30 ]; + strcpy( order_list, "Mesh Order" ); + // count number of submesh ids + int nbIDs = 0; + TListOfListOfInt::const_iterator idIt = theOrderIds.begin(); + for ( ; idIt != theOrderIds.end(); idIt++ ) + nbIDs += (*idIt).size(); + // number of values = number of IDs + + // number of lists (for separators) - 1 + int* smIDs = new int [ nbIDs + theOrderIds.size() - 1 ]; + idIt = theOrderIds.begin(); + for ( int i = 0; idIt != theOrderIds.end(); idIt++ ) { + const TListOfInt& idList = *idIt; + if (idIt != theOrderIds.begin()) // not first list + smIDs[ i++ ] = -1/* *idList.size()*/; // separator between lists + // dump submesh ids from current list + TListOfInt::const_iterator id_smId = idList.begin(); + for( ; id_smId != idList.end(); id_smId++ ) + smIDs[ i++ ] = *id_smId; + } + // write HDF group + aSize[ 0 ] = nbIDs + theOrderIds.size() - 1; + + aDataset = new HDFdataset( order_list, aTopGroup, HDF_INT32, aSize, 1 ); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk( smIDs ); + aDataset->CloseOnDisk(); + // + delete[] smIDs; + } + // groups root sub-branch SALOMEDS::SObject_var myGroupsBranch; for ( int i = GetNodeGroupsTag(); i <= GetVolumeGroupsTag(); i++ ) { @@ -2887,7 +2921,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, aDataset->WriteOnDisk( smIDs ); aDataset->CloseOnDisk(); // - delete smIDs; + delete[] smIDs; } // Store node positions on sub-shapes (SMDS_Position): @@ -3475,7 +3509,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, } } } - } } } @@ -4098,6 +4131,24 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, aGroup->CloseOnDisk(); } } + // read submeh order if any + if( aTopGroup->ExistInternalObject( "Mesh Order" ) ) { + aDataset = new HDFdataset( "Mesh Order", aTopGroup ); + aDataset->OpenOnDisk(); + size = aDataset->GetSize(); + int* smIDs = new int[ size ]; + aDataset->ReadFromDisk( smIDs ); + aDataset->CloseOnDisk(); + TListOfListOfInt anOrderIds; + anOrderIds.push_back( TListOfInt() ); + for ( int i = 0; i < size; i++ ) + if ( smIDs[ i ] < 0 ) // is separator + anOrderIds.push_back( TListOfInt() ); + else + anOrderIds.back().push_back(smIDs[ i ]); + + myNewMeshImpl->GetImpl().SetMeshOrder( anOrderIds ); + } } // close mesh group if(aTopGroup) diff --git a/src/SMESH_I/SMESH_Mesh_i.cxx b/src/SMESH_I/SMESH_Mesh_i.cxx index 63a39472c..cb38dc547 100644 --- a/src/SMESH_I/SMESH_Mesh_i.cxx +++ b/src/SMESH_I/SMESH_Mesh_i.cxx @@ -3728,6 +3728,29 @@ SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder() return aResult._retn(); } +//============================================================================= +/*! + * \brief find common submeshes with given submesh + * \param theSubMeshList list of already collected submesh to check + * \param theSubMesh given submesh to intersect with other + * \param theCommonSubMeshes collected common submeshes + */ +//============================================================================= + +static void findCommonSubMesh + (std::list& theSubMeshList, + const SMESH_subMesh* theSubMesh, + std::set& theCommon ) +{ + if ( !theSubMesh ) + return; + std::list::const_iterator it = theSubMeshList.begin(); + for ( ; it != theSubMeshList.end(); it++ ) + theSubMesh->FindIntersection( *it, theCommon ); + theSubMeshList.push_back( theSubMesh ); + //theCommon.insert( theSubMesh ); +} + //============================================================================= /*! * \brief Set submesh object order @@ -3749,6 +3772,11 @@ SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder() const SMESH::submesh_array& aSMArray = theSubMeshArray[i]; TListOfInt subMeshIds; aPythonDump << "[ "; + // Collect subMeshes which should be clear + // do it list-by-list, because modification of submesh order + // take effect between concurrent submeshes only + std::set subMeshToClear; + std::list subMeshList; for ( int j = 0, jn = aSMArray.length(); j < jn; j++ ) { const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]); @@ -3756,9 +3784,21 @@ SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder() aPythonDump << ", "; aPythonDump << subMesh; subMeshIds.push_back( subMesh->GetId() ); + // detech common parts of submeshes + if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() ) + findCommonSubMesh( subMeshList, (*_mapSubMesh.find(subMesh->GetId())).second, subMeshToClear ); } aPythonDump << " ]"; subMeshOrder.push_back( subMeshIds ); + + // clear collected submeshes + std::set::iterator clrIt = subMeshToClear.begin(); + for ( ; clrIt != subMeshToClear.end(); clrIt++ ) { + SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt; + if ( sm ) + sm->ComputeStateEngine( SMESH_subMesh::CLEAN ); + // ClearSubMesh( *clrIt ); + } } aPythonDump << " ])"; @@ -3799,6 +3839,8 @@ void SMESH_Mesh_i::convertMeshOrder aResSubSet->length(aSubOrder.size()); TListOfInt::const_iterator subIt = aSubOrder.begin(); for( int j = 0; subIt != aSubOrder.end(); subIt++ ) { + if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() ) + continue; SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate( (*_mapSubMeshIor.find(*subIt)).second ); if ( theIsDump ) { -- 2.39.2