X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMESH_I%2FSMESH_Mesh_i.cxx;h=164b27407e5de45f978b8c9f6374c491841cf9ae;hp=8371ccf2f28b34df70397330b2d982b4343012b9;hb=a4e0e20f3c55871a70a54e708ed1c42f3d208375;hpb=0635c9fc80f67d1e5dc0e94ec85f487286a92070 diff --git a/src/SMESH_I/SMESH_Mesh_i.cxx b/src/SMESH_I/SMESH_Mesh_i.cxx index 8371ccf2f..164b27407 100644 --- a/src/SMESH_I/SMESH_Mesh_i.cxx +++ b/src/SMESH_I/SMESH_Mesh_i.cxx @@ -37,6 +37,7 @@ #include "DriverMED_R_SMESHDS_Mesh.h" #include "DriverMED_W_SMESHDS_Mesh.h" #include "SMDS_VolumeTool.hxx" +#include "SMDS_ElemIterator.hxx" #include "SMESHDS_Command.hxx" #include "SMESHDS_CommandType.hxx" #include "SMESHDS_GroupOnGeom.hxx" @@ -52,6 +53,7 @@ #include "Utils_ExceptHandlers.hxx" #include "Utils_SINGLETON.hxx" #include "utilities.h" +#include "GEOMImpl_Types.hxx" // OCCT Includes #include @@ -63,6 +65,7 @@ #include #include #include +#include #include #include @@ -92,8 +95,8 @@ int SMESH_Mesh_i::myIdGenerator = 0; //============================================================================= SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA, - SMESH_Gen_i* gen_i, - CORBA::Long studyId ) + SMESH_Gen_i* gen_i, + CORBA::Long studyId ) : SALOME::GenericObj_i( thePOA ) { MESSAGE("SMESH_Mesh_i"); @@ -146,6 +149,8 @@ void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject ) catch(SALOME_Exception & S_ex) { THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); } + // to track changes of GEOM groups + addGeomGroupData( theShapeObject, _this() ); } //================================================================================ @@ -200,6 +205,7 @@ void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception) Unexpect aCatch(SALOME_SalomeException); try { _impl->Clear(); + CheckGeomGroupModif(); // issue 20145 } catch(SALOME_Exception & S_ex) { THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); @@ -519,21 +525,21 @@ SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aS SMESH_Hypothesis::Hypothesis_Status SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject, SMESH::SMESH_Hypothesis_ptr anHyp) { - if(MYDEBUG) MESSAGE("removeHypothesis()"); - // **** proposer liste de subShape (selection multiple) + if(MYDEBUG) MESSAGE("removeHypothesis()"); + // **** proposer liste de subShape (selection multiple) - if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh()) - THROW_SALOME_CORBA_EXCEPTION("bad subShape reference", - SALOME::BAD_PARAM); + if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh()) + THROW_SALOME_CORBA_EXCEPTION("bad subShape reference", + SALOME::BAD_PARAM); - SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp); - if (CORBA::is_nil(myHyp)) - THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", - SALOME::BAD_PARAM); + SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp); + if (CORBA::is_nil(myHyp)) + THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", + SALOME::BAD_PARAM); - SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK; - try - { + SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK; + try + { TopoDS_Shape myLocSubShape; //use PseudoShape in case if mesh has no shape if(HasShapeToMesh()) @@ -542,15 +548,15 @@ SMESH_Hypothesis::Hypothesis_Status SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Ob myLocSubShape = _impl->GetShapeToMesh(); int hypId = myHyp->GetId(); - status = _impl->RemoveHypothesis(myLocSubShape, hypId); + status = _impl->RemoveHypothesis(myLocSubShape, hypId); if ( !SMESH_Hypothesis::IsStatusFatal(status) ) _mapHypo.erase( hypId ); - } - catch(SALOME_Exception & S_ex) - { - THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); - } - return status; + } + catch(SALOME_Exception & S_ex) + { + THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); + } + return status; } //============================================================================= @@ -560,19 +566,21 @@ SMESH_Hypothesis::Hypothesis_Status SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Ob //============================================================================= SMESH::ListOfHypothesis * - SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject) + SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject) throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); if (MYDEBUG) MESSAGE("GetHypothesisList"); - if (CORBA::is_nil(aSubShapeObject)) + if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShapeObject)) THROW_SALOME_CORBA_EXCEPTION("bad subShape reference", - SALOME::BAD_PARAM); + SALOME::BAD_PARAM); SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis(); try { TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject); + if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() ) + myLocSubShape = _impl->GetShapeToMesh(); const list& aLocalList = _impl->GetHypothesisList( myLocSubShape ); int i = 0, n = aLocalList.size(); aList->length( n ); @@ -580,7 +588,7 @@ throw(SALOME::SALOME_Exception) for ( list::const_iterator anIt = aLocalList.begin(); i < n && anIt != aLocalList.end(); anIt++ ) { SMESHDS_Hypothesis* aHyp = (SMESHDS_Hypothesis*)(*anIt); if ( _mapHypo.find( aHyp->GetID() ) != _mapHypo.end() ) - aList[i++] = SMESH::SMESH_Hypothesis::_narrow( _mapHypo[aHyp->GetID()] ); + aList[i++] = SMESH::SMESH_Hypothesis::_narrow( _mapHypo[aHyp->GetID()] ); } aList->length( i ); @@ -598,14 +606,14 @@ throw(SALOME::SALOME_Exception) */ //============================================================================= SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject, - const char* theName ) + const char* theName ) throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); MESSAGE("SMESH_Mesh_i::GetSubMesh"); if (CORBA::is_nil(aSubShapeObject)) THROW_SALOME_CORBA_EXCEPTION("bad subShape reference", - SALOME::BAD_PARAM); + SALOME::BAD_PARAM); SMESH::SMESH_subMesh_var subMesh; SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(_this()); @@ -620,7 +628,6 @@ SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShap // create a new subMesh object servant if there is none for the shape if ( subMesh->_is_nil() ) subMesh = createSubMesh( aSubShapeObject ); - if ( _gen_i->CanPublishInStudy( subMesh )) { SALOMEDS::SObject_var aSO = _gen_i->PublishSubMesh(_gen_i->GetCurrentStudy(), aMesh, @@ -660,7 +667,7 @@ void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh ) long aTag = SMESH_Gen_i::GetRefOnShapeTag(); SALOMEDS::SObject_var anObj, aRef; if ( anSO->FindSubObject( aTag, anObj ) && anObj->ReferencedObject( aRef ) ) - aSubShapeObject = GEOM::GEOM_Object::_narrow( aRef->GetObject() ); + aSubShapeObject = GEOM::GEOM_Object::_narrow( aRef->GetObject() ); aStudy->NewBuilder()->RemoveObjectWithChildren( anSO ); @@ -733,9 +740,11 @@ SMESH::SMESH_GroupOnGeom_ptr SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementTy SMESH::SMESH_GroupOnGeom_var aNewGroup; TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj ); - if ( !aShape.IsNull() ) { + if ( !aShape.IsNull() ) + { aNewGroup = SMESH::SMESH_GroupOnGeom::_narrow ( createGroup( theElemType, theName, aShape )); + if ( _gen_i->CanPublishInStudy( aNewGroup ) ) { SALOMEDS::SObject_var aSO = _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(), @@ -1496,61 +1505,126 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup( //================================================================================ /*! - * \brief Return group items of a group present in a study + * \brief Remember GEOM group data */ //================================================================================ -static GEOM::GEOM_Object_ptr getGroupItemsFromStudy(CORBA::Object_ptr theMesh, - SMESH_Gen_i* theGen, - list & theItems) +void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj, + CORBA::Object_ptr theSmeshObj) { - GEOM::GEOM_Object_var groupObj; - SALOMEDS::Study_var study = theGen->GetCurrentStudy(); - GEOM::GEOM_Gen_var geomGen = theGen->GetGeomEngine(); - if ( study->_is_nil() || geomGen->_is_nil() ) - return groupObj._retn(); - + if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP ) + return; + // group SO + SALOMEDS::Study_var study = _gen_i->GetCurrentStudy(); + SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study, theGeomObj ); + if ( groupSO->_is_nil() ) + return; + // group indices + GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine(); GEOM::GEOM_IGroupOperations_var groupOp = - geomGen->GetIGroupOperations( theGen->GetCurrentStudyID() ); - GEOM::GEOM_IShapesOperations_var shapeOp = - geomGen->GetIShapesOperations( theGen->GetCurrentStudyID() ); - - SALOMEDS::SObject_var meshOS = theGen->ObjectToSObject(study, theMesh); - if ( meshOS->_is_nil() || groupOp->_is_nil() || shapeOp->_is_nil() ) - return groupObj._retn(); - SALOMEDS::SObject_var fatherSO = meshOS->GetFather(); - if ( fatherSO->_is_nil() || fatherSO->Tag() != theGen->GetSubMeshOnCompoundTag() ) - return groupObj._retn(); // keep only submeshes on groups - - SALOMEDS::ChildIterator_var anIter = study->NewChildIterator(meshOS); - if ( anIter->_is_nil() ) return groupObj._retn(); - for ( ; anIter->More(); anIter->Next()) - { - SALOMEDS::SObject_var aSObject = anIter->Value(); - SALOMEDS::SObject_var aRefSO; - if ( !aSObject->_is_nil() && aSObject->ReferencedObject(aRefSO) ) - { - groupObj = GEOM::GEOM_Object::_narrow(aRefSO->GetObject()); - if ( groupObj->_is_nil() ) break; - GEOM::ListOfLong_var ids = groupOp->GetObjects( groupObj ); - GEOM::GEOM_Object_var mainShape = groupObj->GetMainShape(); - for ( int i = 0; i < ids->length(); ++i ) { - GEOM::GEOM_Object_var subShape = shapeOp->GetSubShape( mainShape, ids[i] ); - TopoDS_Shape S = theGen->GeomObjectToShape( subShape ); - if ( !S.IsNull() ) - theItems.push_back( S ); - } - break; + geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() ); + GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj ); + + // store data + _geomGroupData.push_back( TGeomGroupData() ); + TGeomGroupData & groupData = _geomGroupData.back(); + // entry + CORBA::String_var entry = groupSO->GetID(); + groupData._groupEntry = entry.in(); + // indices + for ( int i = 0; i < ids->length(); ++i ) + groupData._indices.insert( ids[i] ); + // SMESH object + groupData._smeshObject = theSmeshObj; +} + +//================================================================================ +/*! + * Remove GEOM group data relating to removed smesh object + */ +//================================================================================ + +void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj) +{ + list::iterator + data = _geomGroupData.begin(), dataEnd = _geomGroupData.end(); + for ( ; data != dataEnd; ++data ) { + if ( theSmeshObj->_is_equivalent( data->_smeshObject )) { + _geomGroupData.erase( data ); + return; } } - return groupObj._retn(); } -//============================================================================= +//================================================================================ /*! - * \brief Update hypotheses assigned to geom groups if the latter change + * \brief Return new group contents if it has been changed and update group data + */ +//================================================================================ + +TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData) +{ + TopoDS_Shape newShape; + + // get geom group + SALOMEDS::Study_var study = _gen_i->GetCurrentStudy(); + if ( study->_is_nil() ) return newShape; // means "not changed" + SALOMEDS::SObject_var groupSO = study->FindObjectID( groupData._groupEntry.c_str() ); + if ( !groupSO->_is_nil() ) + { + CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO ); + if ( CORBA::is_nil( groupObj )) return newShape; + GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj ); + + // get indices of group items + set curIndices; + GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine(); + GEOM::GEOM_IGroupOperations_var groupOp = + geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() ); + GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup ); + for ( int i = 0; i < ids->length(); ++i ) + curIndices.insert( ids[i] ); + + if ( groupData._indices == curIndices ) + return newShape; // group not changed + + // update data + groupData._indices = curIndices; + + GEOM_Client* geomClient = _gen_i->GetShapeReader(); + if ( !geomClient ) return newShape; + TCollection_AsciiString groupIOR = geomGen->GetStringFromIOR( geomGroup ); + geomClient->RemoveShapeFromBuffer( groupIOR ); + newShape = _gen_i->GeomObjectToShape( geomGroup ); + } + + if ( newShape.IsNull() ) { + // geom group becomes empty - return empty compound + TopoDS_Compound compound; + BRep_Builder().MakeCompound(compound); + newShape = compound; + } + return newShape; +} + +namespace { + //============================================================================= + /*! + * \brief Storage of shape and index used in CheckGeomGroupModif() + */ + //============================================================================= + struct TIndexedShape { + int _index; + TopoDS_Shape _shape; + TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {} + }; +} +//============================================================================= +/*! + * \brief Update objects depending on changed geom groups * - * NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation" + * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation + * issue 0020210: Update of a smesh group after modification of the associated geom group */ //============================================================================= @@ -1561,70 +1635,222 @@ void SMESH_Mesh_i::CheckGeomGroupModif() SALOMEDS::Study_var study = _gen_i->GetCurrentStudy(); if ( study->_is_nil() ) return; - // check if items of groups changed - map::iterator i_sm = _mapSubMesh.begin(); - for ( ; i_sm != _mapSubMesh.end(); ++i_sm ) - { - const TopoDS_Shape & oldGroupShape = i_sm->second->GetSubShape(); - SMESHDS_SubMesh * oldDS = i_sm->second->GetSubMeshDS(); - if ( !oldDS /*|| !oldDS->IsComplexSubmesh()*/ ) - continue; - int oldID = i_sm->first; - map::iterator i_smIor = _mapSubMeshIor.find( oldID ); - if ( i_smIor == _mapSubMeshIor.end() ) - continue; - list< TopoDS_Shape> newItems; - GEOM::GEOM_Object_var groupObj = getGroupItemsFromStudy ( i_smIor->second, _gen_i, newItems ); - if ( groupObj->_is_nil() ) - continue; + CORBA::Long nbEntities = NbNodes() + NbElements(); - int nbOldItems = oldDS->IsComplexSubmesh() ? oldDS->NbSubMeshes() : 1; - int nbNewItems = newItems.size(); - bool groupChanged = ( nbOldItems != nbNewItems); - if ( !groupChanged ) { - if ( !oldDS->IsComplexSubmesh() ) { // old group has one item - groupChanged = ( oldGroupShape != newItems.front() ); - } - else { - list::iterator item = newItems.begin(); - for ( ; item != newItems.end() && !groupChanged; ++item ) - { - SMESHDS_SubMesh * itemDS = _impl->GetMeshDS()->MeshElements( *item ); - groupChanged = ( !itemDS || !oldDS->ContainsSubMesh( itemDS )); - } - } + // Check if group contents changed + + typedef map< string, TopoDS_Shape > TEntry2Geom; + TEntry2Geom newGroupContents; + + list::iterator + data = _geomGroupData.begin(), dataEnd = _geomGroupData.end(); + for ( ; data != dataEnd; ++data ) + { + pair< TEntry2Geom::iterator, bool > it_new = + newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() )); + bool processedGroup = !it_new.second; + TopoDS_Shape& newShape = it_new.first->second; + if ( !processedGroup ) + newShape = newGroupShape( *data ); + if ( newShape.IsNull() ) + continue; // no changes + + if ( processedGroup ) { // update group indices + list::iterator data2 = data; + for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {} + data->_indices = data2->_indices; } - // update hypotheses and submeshes if necessary - if ( groupChanged ) + + // Update SMESH objects according to new GEOM group contents + + SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject ); + if ( !submesh->_is_nil() ) // -------------- Sub mesh --------------------- { - // get a new group shape - GEOM_Client* geomClient = _gen_i->GetShapeReader(); - if ( !geomClient ) continue; - TCollection_AsciiString groupIOR = _gen_i->GetGeomEngine()->GetStringFromIOR( groupObj ); - geomClient->RemoveShapeFromBuffer( groupIOR ); - TopoDS_Shape newGroupShape = _gen_i->GeomObjectToShape( groupObj ); + int oldID = submesh->GetId(); + if ( _mapSubMeshIor.find( oldID ) == _mapSubMeshIor.end() ) + continue; + TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape(); + // update hypotheses - list hyps = _impl->GetHypothesisList(oldGroupShape); + list hyps = _impl->GetHypothesisList(oldShape); list ::iterator hypIt; for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt ) { - _impl->RemoveHypothesis( oldGroupShape, (*hypIt)->GetID()); - _impl->AddHypothesis ( newGroupShape, (*hypIt)->GetID()); + _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID()); + _impl->AddHypothesis ( newShape, (*hypIt)->GetID()); } // care of submeshes - SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newGroupShape ); + SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape ); int newID = newSubmesh->GetId(); if ( newID != oldID ) { _mapSubMesh [ newID ] = newSubmesh; _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ]; _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ]; - _mapSubMesh.erase (oldID); - _mapSubMesh_i.erase (oldID); + _mapSubMesh. erase(oldID); + _mapSubMesh_i. erase(oldID); _mapSubMeshIor.erase(oldID); _mapSubMesh_i [ newID ]->changeLocalId( newID ); } + continue; } + + SMESH::SMESH_GroupOnGeom_var smeshGroup = + SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject ); + if ( !smeshGroup->_is_nil() ) // ------------ GROUP ----------------------- + { + SMESH_GroupOnGeom_i* group_i = SMESH::DownCast( smeshGroup ); + if ( group_i ) { + ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() ); + SMESHDS_GroupOnGeom* ds = static_cast( group->GetGroupDS() ); + ds->SetShape( newShape ); + } + continue; + } + + SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject ); + if ( !mesh->_is_nil() ) // -------------- MESH ---------------------------- + { + // Remove groups and submeshes basing on removed sub-shapes + + TopTools_MapOfShape newShapeMap; + TopoDS_Iterator shapeIt( newShape ); + for ( ; shapeIt.More(); shapeIt.Next() ) + newShapeMap.Add( shapeIt.Value() ); + + SMESHDS_Mesh* meshDS = _impl->GetMeshDS(); + for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() ) + { + if ( newShapeMap.Contains( shapeIt.Value() )) + continue; + TopTools_IndexedMapOfShape oldShapeMap; + TopExp::MapShapes( shapeIt.Value(), oldShapeMap ); + for ( int i = 1; i <= oldShapeMap.Extent(); ++i ) + { + const TopoDS_Shape& oldShape = oldShapeMap(i); + int oldInd = meshDS->ShapeToIndex( oldShape ); + // -- submeshes -- + map::iterator i_smIor = _mapSubMeshIor.find( oldInd ); + if ( i_smIor != _mapSubMeshIor.end() ) { + RemoveSubMesh( i_smIor->second ); // one submesh per shape index + } + // --- groups --- + map::iterator i_grp = _mapGroups.begin(); + for ( ; i_grp != _mapGroups.end(); ++i_grp ) + { + // check if a group bases on oldInd shape + SMESHDS_GroupOnGeom* grpOnGeom = 0; + if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first )) + grpOnGeom = dynamic_cast( g->GetGroupDS() ); + if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() )) + { // remove + RemoveGroup( i_grp->second ); // several groups can base on same shape + i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration + } + } + } + } + // Reassign hypotheses and update groups after setting the new shape to mesh + + // collect anassigned hypotheses + typedef list< pair< TIndexedShape, list > > TShapeHypList; + list ::const_iterator hypIt; + TShapeHypList assignedHyps; + for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i ) + { + const TopoDS_Shape& oldShape = meshDS->IndexToShape(i); + list hyps = meshDS->GetHypothesis( oldShape );// copy + if ( !hyps.empty() ) { + assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps )); + for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt ) + _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID()); + } + } + // collect shapes supporting groups + typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList; + TShapeTypeList groupData; + const set& groups = meshDS->GetGroups(); + set::const_iterator grIt = groups.begin(); + for ( ; grIt != groups.end(); ++grIt ) + { + if ( SMESHDS_GroupOnGeom* gog = dynamic_cast( *grIt )) + groupData.push_back + ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType())); + } + // set new shape to mesh -> DS of submeshes and geom groups is deleted + _impl->ShapeToMesh( newShape ); + + // reassign hypotheses + TShapeHypList::iterator indS_hyps = assignedHyps.begin(); + for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps ) + { + TIndexedShape& geom = indS_hyps->first; + list& hyps = indS_hyps->second; + int oldID = geom._index; + int newID = meshDS->ShapeToIndex( geom._shape ); + if ( !newID ) + continue; + if ( oldID == 1 ) { // main shape + newID = 1; + geom._shape = newShape; + } + for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt ) + _impl->AddHypothesis( geom._shape, (*hypIt)->GetID()); + // care of submeshes + SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape ); + if ( newID != oldID ) { + _mapSubMesh [ newID ] = newSubmesh; + _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ]; + _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ]; + _mapSubMesh. erase(oldID); + _mapSubMesh_i. erase(oldID); + _mapSubMeshIor.erase(oldID); + _mapSubMesh_i [ newID ]->changeLocalId( newID ); + } + } + // recreate groups + TShapeTypeList::iterator geomType = groupData.begin(); + for ( ; geomType != groupData.end(); ++geomType ) + { + const TIndexedShape& geom = geomType->first; + int oldID = geom._index; + if ( _mapGroups.find( oldID ) == _mapGroups.end() ) + continue; + // get group name + SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] ); + CORBA::String_var name = groupSO->GetName(); + // update + SMESH_GroupBase_i* group_i = SMESH::DownCast(_mapGroups[oldID] ); + int newID; + if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape )) + group_i->changeLocalId( newID ); + } + + break; // everything has been updated + + } // update mesh + } // loop on group data + + // Update icons + + CORBA::Long newNbEntities = NbNodes() + NbElements(); + list< SALOMEDS::SObject_var > soToUpdateIcons; + if ( newNbEntities != nbEntities ) + { + // Add all SObjects with icons + soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh + + for (map::iterator i_sm = _mapSubMeshIor.begin(); + i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes + soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second )); + + for ( map::iterator i_gr = _mapGroups.begin(); + i_gr != _mapGroups.end(); ++i_gr ) // groups + soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second )); } + + list< SALOMEDS::SObject_var >::iterator so = soToUpdateIcons.begin(); + for ( ; so != soToUpdateIcons.end(); ++so ) + _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" ); } //============================================================================= @@ -1650,10 +1876,9 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupOnGe int anId = aGroupToRem->GetLocalID(); if ( !_impl->ConvertToStandalone( anId ) ) return aGroup._retn(); + removeGeomGroupData( theGroup ); - SMESH_GroupBase_i* aGroupImpl; - aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId ); - + SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId ); // remove old instance of group from own map _mapGroups.erase( anId ); @@ -1720,6 +1945,9 @@ SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theS int nextId = _gen_i->RegisterObject( subMesh ); if(MYDEBUG) MESSAGE( "Add submesh to map with id = "<< nextId); + // to track changes of GEOM groups + addGeomGroupData( theSubShapeObject, subMesh ); + return subMesh._retn(); } @@ -1760,6 +1988,7 @@ void SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh, catch( const SALOME::SALOME_Exception& ) { INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!"); } + removeGeomGroupData( theSubShapeObject ); int subMeshId = theSubMesh->GetId(); @@ -1799,6 +2028,12 @@ SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElem // register CORBA object for persistence int nextId = _gen_i->RegisterObject( aGroup ); if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId); + + // to track changes of GEOM groups + if ( !theShape.IsNull() ) { + GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape ); + addGeomGroupData( geom, aGroup ); + } } return aGroup._retn(); } @@ -1815,6 +2050,7 @@ void SMESH_Mesh_i::removeGroup( const int theId ) { if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" ); if ( _mapGroups.find( theId ) != _mapGroups.end() ) { + removeGeomGroupData( _mapGroups[theId] ); _mapGroups.erase( theId ); _impl->RemoveGroup( theId ); } @@ -1860,14 +2096,14 @@ throw(SALOME::SALOME_Exception) aLog[indexLog].coords.length(rnum); aLog[indexLog].indexes.length(inum); for(int i = 0; i < rnum; i++){ - aLog[indexLog].coords[i] = *ir; - //MESSAGE(" "<GetName(); // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes if ( !aStudy->GetProperties()->IsLocked() ) - { - SALOMEDS::GenericAttribute_var anAttr; - SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder(); - SALOMEDS::AttributeExternalFileDef_var aFileName; - anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef"); - aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr); - ASSERT(!aFileName->_is_nil()); + { + SALOMEDS::GenericAttribute_var anAttr; + SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder(); + SALOMEDS::AttributeExternalFileDef_var aFileName; + anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef"); + aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr); + ASSERT(!aFileName->_is_nil()); aFileName->SetValue(file); SALOMEDS::AttributeFileType_var aFileType; anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType"); aFileType = SALOMEDS::AttributeFileType::_narrow(anAttr); ASSERT(!aFileType->_is_nil()); aFileType->SetValue("FICHIERMED"); - } + } } } // Update Python script @@ -2094,7 +2330,7 @@ void SMESH_Mesh_i::ExportToMED (const char* file, } void SMESH_Mesh_i::ExportMED (const char* file, - CORBA::Boolean auto_groups) + CORBA::Boolean auto_groups) throw(SALOME::SALOME_Exception) { ExportToMED(file,auto_groups,SMESH::MED_V2_1); @@ -2178,7 +2414,18 @@ CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception) CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); - return NbEdges() + NbFaces() + NbVolumes(); + return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes(); +} + +//============================================================================= +/*! + * + */ +//============================================================================= +CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + return _impl->Nb0DElements(); } //============================================================================= @@ -3159,3 +3406,36 @@ SMESH::string_array* SMESH_Mesh_i::GetLastParameters() } return aResult._retn(); } + +//============================================================================= +/*! + * \brief Returns statistic of mesh elements + */ +//============================================================================= +SMESH::long_array* SMESH_Mesh_i::GetMeshInfo() +{ + SMESH::long_array_var aRes = new SMESH::long_array(); + aRes->length(SMESH::Entity_Last); + for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++) + aRes[i] = 0; + SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS(); + if (!aMeshDS) + return aRes._retn(); + const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo(); + for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++) + aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i); + return aRes._retn(); +} + +//============================================================================= +/*! + * \brief Collect statistic of mesh elements given by iterator + */ +//============================================================================= +void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr, + SMESH::long_array& theInfo) +{ + if (!theItr) return; + while (theItr->more()) + theInfo[ theItr->next()->GetEntityType() ]++; +}