X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSMESH_I%2FSMESH_Mesh_i.cxx;h=9988bf4cbf0a137ed9cb962eb72be50801f285ec;hb=52a5308f7c377c0a514b911f9741260da202026c;hp=d4e396cbdfacd0556715d974ba7d7b1d655a9077;hpb=6472eab132825fec572beda8276947593f85ffa1;p=modules%2Fsmesh.git diff --git a/src/SMESH_I/SMESH_Mesh_i.cxx b/src/SMESH_I/SMESH_Mesh_i.cxx index d4e396cbd..9988bf4cb 100644 --- a/src/SMESH_I/SMESH_Mesh_i.cxx +++ b/src/SMESH_I/SMESH_Mesh_i.cxx @@ -270,6 +270,16 @@ void SMESH_Mesh_i::ReplaceShape(GEOM::GEOM_Object_ptr theNewGeom) if (geomClient->Find(S, aIOR)) { geomClient->RemoveShapeFromBuffer(aIOR); } + // clear buffer also for sub-groups + const std::set& groups = _impl->GetMeshDS()->GetGroups(); + std::set::const_iterator g = groups.begin(); + for (; g != groups.end(); ++g) + if (const SMESHDS_GroupOnGeom* group = dynamic_cast(*g)) + { + const TopoDS_Shape& s = group->GetShape(); + if (geomClient->Find(s, aIOR)) + geomClient->RemoveShapeFromBuffer(aIOR); + } // update the reference to theNewGeom (needed for correct execution of a dumped python script) SMESH::SMESH_Mesh_var me = _this(); @@ -2028,9 +2038,9 @@ void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj, if ( groupSO->_is_nil() ) return; // group indices - GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( theGeomObj ); - GEOM::GEOM_IGroupOperations_ptr groupOp = geomGen->GetIGroupOperations(); - GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj ); + GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( theGeomObj ); + GEOM::GEOM_IGroupOperations_wrap groupOp = geomGen->GetIGroupOperations(); + GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj ); // store data _geomGroupData.push_back( TGeomGroupData() ); @@ -2076,59 +2086,82 @@ enum { ONLY_IF_CHANGED, IS_BREAK_LINK, MAIN_TRANSFORMED }; TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData, int how ) { TopoDS_Shape newShape; + SALOMEDS::SObject_wrap groupSO; if ( how == IS_BREAK_LINK ) { SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( groupData._smeshObject ); - SALOMEDS::SObject_wrap geomRefSO, geomSO; + SALOMEDS::SObject_wrap geomRefSO; if ( !meshSO->_is_nil() && - meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) && - geomRefSO->ReferencedObject( geomSO.inout() )) + meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() )) { - CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO ); - GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( geomObj ); - newShape = _gen_i->GeomObjectToShape( geom ); - CORBA::String_var entry = geom->GetStudyEntry(); - groupData._groupEntry = entry.in(); + geomRefSO->ReferencedObject( groupSO.inout() ); } } else { // get geom group - SALOMEDS::SObject_wrap groupSO = SMESH_Gen_i::getStudyServant()->FindObjectID( groupData._groupEntry.c_str() ); - if ( !groupSO->_is_nil() ) + groupSO = _gen_i->getStudyServant()->FindObjectID( groupData._groupEntry.c_str() ); + } + + if ( groupSO->_is_nil() ) + return newShape; + + CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO ); + GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj ); + if ( geomGroup->_is_nil() ) + return newShape; + + // get indices of group items + set curIndices; + GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( geomGroup ); + GEOM::GEOM_IGroupOperations_wrap groupOp = geomGen->GetIGroupOperations(); + GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup ); + for ( CORBA::ULong i = 0; i < ids->length(); ++i ) + curIndices.insert( ids[i] ); + + bool sameIndices = ( groupData._indices == curIndices ); + if ( how == ONLY_IF_CHANGED && sameIndices ) + return newShape; // group not changed + + // update data + CORBA::String_var entry = geomGroup->GetStudyEntry(); + groupData._groupEntry = entry.in(); + groupData._indices = curIndices; + + newShape = _gen_i->GeomObjectToShape( geomGroup ); + + // check if newShape is up-to-date + if ( !newShape.IsNull() && ids->length() > 0 ) + { + bool toUpdate = ! _impl->GetMeshDS()->IsGroupOfSubShapes( newShape ); + if ( !toUpdate ) { - 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( geomGroup ); - GEOM::GEOM_IGroupOperations_ptr groupOp = geomGen->GetIGroupOperations(); - GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup ); - for ( CORBA::ULong i = 0; i < ids->length(); ++i ) - curIndices.insert( ids[i] ); - - if ( how == ONLY_IF_CHANGED && groupData._indices == curIndices ) - return newShape; // group not changed - - // update data - groupData._indices = curIndices; - - GEOM_Client* geomClient = _gen_i->GetShapeReader(); - if ( !geomClient ) return newShape; + TopExp_Explorer exp( newShape, (TopAbs_ShapeEnum)( groupOp->GetType( geomGroup ))); + for ( ; exp.More() && !toUpdate; exp.Next() ) + { + int ind = _impl->GetMeshDS()->ShapeToIndex( exp.Current() ); + toUpdate = ( curIndices.erase( ind ) == 0 ); + } + if ( !curIndices.empty() ) + toUpdate = true; + } + if ( toUpdate ) + { + GEOM_Client* geomClient = _gen_i->GetShapeReader(); CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup ); geomClient->RemoveShapeFromBuffer( groupIOR.in() ); newShape = _gen_i->GeomObjectToShape( geomGroup ); } } - if ( newShape.IsNull() ) { + else + { // geom group becomes empty - return empty compound TopoDS_Compound compound; BRep_Builder().MakeCompound(compound); newShape = compound; } + return newShape; } @@ -2295,9 +2328,18 @@ void SMESH_Mesh_i::CheckGeomModif( bool isBreakLink ) if ( !geomClient ) return; GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( mainGO ); if ( geomGen->_is_nil() ) return; + CORBA::String_var geomComponentType = geomGen->ComponentDataType(); + bool isShaper = ( strcmp( geomComponentType.in(), "SHAPERSTUDY" ) == 0 ); - CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO ); - geomClient->RemoveShapeFromBuffer( ior.in() ); + SMESHDS_Mesh * meshDS = _impl->GetMeshDS(); + + TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO ); + if ( meshDS->ShapeToIndex( newShape ) == 1 ) // not yet updated + { + CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO ); + geomClient->RemoveShapeFromBuffer( ior.in() ); + newShape = _gen_i->GeomObjectToShape( mainGO ); + } // Update data taking into account that if topology doesn't change // all sub-shapes change but IDs of sub-shapes remain (except for geom groups) @@ -2305,18 +2347,14 @@ void SMESH_Mesh_i::CheckGeomModif( bool isBreakLink ) if ( _preMeshInfo ) _preMeshInfo->ForgetAllData(); - - if (isBreakLink) + if ( isBreakLink || !isShaper ) _impl->Clear(); - TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO ); if ( newShape.IsNull() ) return; _mainShapeTick = mainGO->GetTick(); - SMESHDS_Mesh * meshDS = _impl->GetMeshDS(); - - // store data of groups on geometry + // store data of groups on geometry including new TopoDS_Shape's std::vector< TGroupOnGeomData > groupsData; const std::set& groups = meshDS->GetGroups(); groupsData.reserve( groups.size() ); @@ -2337,7 +2375,10 @@ void SMESH_Mesh_i::CheckGeomModif( bool isBreakLink ) GEOM::GEOM_Object_var geom; if ( !gog->_is_nil() ) { - if ( isBreakLink ) + if ( !isBreakLink ) + geom = gog->GetShape(); + + if ( isBreakLink || geom->_is_nil() ) { SALOMEDS::SObject_wrap grpSO = _gen_i->ObjectToSObject( gog ); SALOMEDS::SObject_wrap geomRefSO, geomSO; @@ -2349,22 +2390,23 @@ void SMESH_Mesh_i::CheckGeomModif( bool isBreakLink ) geom = GEOM::GEOM_Object::_narrow( geomObj ); } } - else - { - geom = gog->GetShape(); - } } - if ( !geom->_is_nil() ) + if ( old2newShapeMap.IsBound( group->GetShape() )) { - CORBA::String_var ior = geomGen->GetStringFromIOR( geom ); - geomClient->RemoveShapeFromBuffer( ior.in() ); - groupsData.back()._shape = _gen_i->GeomObjectToShape( geom ); - old2newShapeMap.Bind( group->GetShape(), groupsData.back()._shape ); + groupsData.back()._shape = old2newShapeMap( group->GetShape() ); } - else if ( old2newShapeMap.IsBound( group->GetShape() )) + else if ( !geom->_is_nil() ) { - groupsData.back()._shape = old2newShapeMap( group->GetShape() ); + groupsData.back()._shape = _gen_i->GeomObjectToShape( geom ); + if ( meshDS->IsGroupOfSubShapes( groupsData.back()._shape )) + { + CORBA::String_var ior = geomGen->GetStringFromIOR( geom ); + geomClient->RemoveShapeFromBuffer( ior.in() ); + groupsData.back()._shape = _gen_i->GeomObjectToShape( geom ); + } + old2newShapeMap.Bind( group->GetShape(), groupsData.back()._shape ); } + } } // store assigned hypotheses @@ -2377,7 +2419,7 @@ void SMESH_Mesh_i::CheckGeomModif( bool isBreakLink ) ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps )); } - std::map< std::set, int > ii2iMap; // group sub-ids to group id in SMESHDS + std::multimap< std::set, int > ii2iMap; // group sub-ids to group id in SMESHDS // count shapes excluding compounds corresponding to geom groups int oldNbSubShapes = meshDS->MaxShapeIndex(); @@ -2411,19 +2453,43 @@ void SMESH_Mesh_i::CheckGeomModif( bool isBreakLink ) } // re-add shapes (compounds) of geom groups + typedef std::map< std::vector< int >, TGeomGroupData* > TIndices2GroupData; + TIndices2GroupData ii2grData; + std::vector< int > ii; std::map< int, int > old2newIDs; // group IDs - std::list::iterator data = _geomGroupData.begin(); - for ( ; data != _geomGroupData.end(); ++data ) + std::list::iterator dataIt = _geomGroupData.begin(); + for ( ; dataIt != _geomGroupData.end(); ++dataIt ) { + TGeomGroupData* data = &(*dataIt); + ii.reserve( data->_indices.size() ); + ii.assign( data->_indices.begin(), data->_indices.end() ); + TIndices2GroupData::iterator ii2gd = ii2grData.insert( std::make_pair( ii, data )).first; + if ( ii2gd->second != data ) + { + data->_groupEntry = ii2gd->second->_groupEntry; + data->_indices = ii2gd->second->_indices; + continue; + } + const int oldNbSub = data->_indices.size(); + const int soleOldID = oldNbSub == 1 ? *data->_indices.begin() : 0; int oldID = 0; - std::map< std::set, int >::iterator ii2i = ii2iMap.find( data->_indices ); + std::multimap< std::set, int >::iterator ii2i = ii2iMap.find( data->_indices ); if ( ii2i != ii2iMap.end() ) + { oldID = ii2i->second; + ii2iMap.erase( ii2i ); + } + if ( !oldID && oldNbSub == 1 ) + oldID = soleOldID; + if ( old2newIDs.count( oldID )) + continue; + + int how = ( isBreakLink || !sameTopology ) ? IS_BREAK_LINK : MAIN_TRANSFORMED; + newShape = newGroupShape( *data, how ); - TopoDS_Shape newShape = newGroupShape( *data, isBreakLink ? IS_BREAK_LINK : MAIN_TRANSFORMED ); if ( !newShape.IsNull() ) { - if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape + if ( oldNbSub > 1 && meshDS->ShapeToIndex( newShape ) > 0 ) // group reduced to one sub-shape { TopoDS_Compound compound; BRep_Builder().MakeCompound( compound ); @@ -2431,33 +2497,31 @@ void SMESH_Mesh_i::CheckGeomModif( bool isBreakLink ) newShape = compound; } int newID = _impl->GetSubMesh( newShape )->GetId(); - if ( oldID && oldID != newID ) + if ( oldID /*&& oldID != newID*/ ) old2newIDs.insert( std::make_pair( oldID, newID )); + if ( oldNbSub == 1 ) + old2newIDs.insert( std::make_pair( soleOldID, newID )); } } // re-assign hypotheses for ( size_t i = 0; i < ids2Hyps.size(); ++i ) { - if ( !sameTopology && ids2Hyps[i].first != 1 ) - continue; // assign only global hypos int sID = ids2Hyps[i].first; std::map< int, int >::iterator o2n = old2newIDs.find( sID ); if ( o2n != old2newIDs.end() ) sID = o2n->second; + else if ( !sameTopology && sID != 1 ) + continue; const TopoDS_Shape& s = meshDS->IndexToShape( sID ); - const THypList& hyps = ids2Hyps[i].second; + if ( s.IsNull() ) + continue; + const THypList& hyps = ids2Hyps[i].second; THypList::const_iterator h = hyps.begin(); for ( ; h != hyps.end(); ++h ) _impl->AddHypothesis( s, (*h)->GetID() ); } - if ( !sameTopology ) - { - // remove invalid study sub-objects - CheckGeomGroupModif(); - } - else { // restore groups on geometry for ( size_t i = 0; i < groupsData.size(); ++i ) @@ -2479,23 +2543,26 @@ void SMESH_Mesh_i::CheckGeomModif( bool isBreakLink ) g->GetGroupDS()->SetColor( data._color ); } - std::map< int, int >::iterator o2n = old2newIDs.begin(); - for ( ; o2n != old2newIDs.end(); ++o2n ) + if ( !sameTopology ) { - int newID = o2n->second, oldID = o2n->first; - if ( !_mapSubMesh.count( oldID )) - continue; - if ( newID > 0 ) + std::map< int, int >::iterator o2n = old2newIDs.begin(); + for ( ; o2n != old2newIDs.end(); ++o2n ) { - _mapSubMesh [ newID ] = _impl->GetSubMeshContaining( newID ); - _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ]; - _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ]; + int newID = o2n->second, oldID = o2n->first; + if ( newID == oldID || !_mapSubMesh.count( oldID )) + continue; + if ( newID > 0 ) + { + _mapSubMesh [ newID ] = _impl->GetSubMeshContaining( newID ); + _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ]; + _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ]; + } + _mapSubMesh. erase(oldID); + _mapSubMesh_i. erase(oldID); + _mapSubMeshIor.erase(oldID); + if ( newID > 0 ) + _mapSubMesh_i [ newID ]->changeLocalId( newID ); } - _mapSubMesh. erase(oldID); - _mapSubMesh_i. erase(oldID); - _mapSubMeshIor.erase(oldID); - if ( newID > 0 ) - _mapSubMesh_i [ newID ]->changeLocalId( newID ); } // update _mapSubMesh @@ -2504,9 +2571,15 @@ void SMESH_Mesh_i::CheckGeomModif( bool isBreakLink ) i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first )); } + if ( !sameTopology ) + { + // remove invalid study sub-objects + CheckGeomGroupModif(); + } + _gen_i->UpdateIcons( me ); - if ( !isBreakLink ) + if ( !isBreakLink && isShaper ) { SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me ); if ( !meshSO->_is_nil() ) @@ -2582,13 +2655,21 @@ void SMESH_Mesh_i::CheckGeomGroupModif() { SMESH::SMESH_GroupBase_ptr group = i_gr->second; ++i_gr; - SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( group ), refSO; + SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( group ), refSO, geomSO; SMESH::SMESH_GroupOnGeom_var onGeom = SMESH::SMESH_GroupOnGeom::_narrow ( group ); SMESH::SMESH_GroupOnFilter_var onFilt = SMESH::SMESH_GroupOnFilter::_narrow( group ); bool isValidGeom = false; if ( !onGeom->_is_nil() ) { - isValidGeom = ( ! GEOM::GEOM_Object_var( onGeom->GetShape() )->_is_nil() ); + isValidGeom = ( ! GEOM::GEOM_Object_var( onGeom->GetShape() )->_is_nil() ); // check TopoDS + if ( !isValidGeom ) // check reference + { + isValidGeom = ( ! groupSO->_is_nil() && + groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() ) && + refSO->ReferencedObject( geomSO.inout() ) && + ! geomSO->_is_nil() && + !CORBA::is_nil( CORBA::Object_var( geomSO->GetObject() ))); + } } else if ( !onFilt->_is_nil() ) {