+ //-----------------------------------------------------------------------------
+ /*!
+ * \brief Data to re-create a group on geometry
+ */
+ struct TGroupOnGeomData
+ {
+ int _oldID;
+ int _shapeID;
+ SMDSAbs_ElementType _type;
+ std::string _name;
+ Quantity_Color _color;
+ };
+}
+
+//=============================================================================
+/*!
+ * \brief Update data if geometry changes
+ *
+ * Issue 0022501
+ */
+//=============================================================================
+
+void SMESH_Mesh_i::CheckGeomModif()
+{
+ if ( !_impl->HasShapeToMesh() ) return;
+
+ SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
+ if ( study->_is_nil() ) return;
+
+ GEOM::GEOM_Object_var mainGO = _gen_i->ShapeToGeomObject( _impl->GetShapeToMesh() );
+ if ( mainGO->_is_nil() ) return;
+
+ if ( mainGO->GetType() == GEOM_GROUP ||
+ mainGO->GetTick() == _mainShapeTick )
+ {
+ CheckGeomGroupModif();
+ return;
+ }
+
+ GEOM_Client* geomClient = _gen_i->GetShapeReader();
+ if ( !geomClient ) return;
+ GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
+ if ( geomGen->_is_nil() ) return;
+
+ CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
+ geomClient->RemoveShapeFromBuffer( ior.in() );
+
+ // Update data taking into account that
+ // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
+
+ _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
+ vector< TGroupOnGeomData > groupsData;
+ const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
+ groupsData.reserve( groups.size() );
+ set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
+ for ( ; g != groups.end(); ++g )
+ if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
+ {
+ TGroupOnGeomData data;
+ data._oldID = group->GetID();
+ data._shapeID = meshDS->ShapeToIndex( group->GetShape() );
+ data._type = group->GetType();
+ data._name = group->GetStoreName();
+ data._color = group->GetColor();
+ groupsData.push_back( data );
+ }
+ // store assigned hypotheses
+ vector< pair< int, THypList > > ids2Hyps;
+ const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
+ for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
+ {
+ const TopoDS_Shape& s = s2hyps.Key();
+ const THypList& hyps = s2hyps.ChangeValue();
+ ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
+ }
+
+ // change shape to mesh
+ int oldNbSubShapes = meshDS->MaxShapeIndex();
+ _impl->ShapeToMesh( TopoDS_Shape() );
+ _impl->ShapeToMesh( newShape );
+
+ // re-add shapes of geom groups
+ list<TGeomGroupData>::iterator data = _geomGroupData.begin();
+ for ( ; data != _geomGroupData.end(); ++data )
+ {
+ TopoDS_Shape newShape = newGroupShape( *data );
+ if ( !newShape.IsNull() )
+ {
+ if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
+ {
+ TopoDS_Compound compound;
+ BRep_Builder().MakeCompound( compound );
+ BRep_Builder().Add( compound, newShape );
+ newShape = compound;
+ }
+ _impl->GetSubMesh( newShape );
+ }
+ }
+ if ( oldNbSubShapes != meshDS->MaxShapeIndex() )
+ THROW_SALOME_CORBA_EXCEPTION( "SMESH_Mesh_i::CheckGeomModif() bug",
+ SALOME::INTERNAL_ERROR );
+
+ // re-assign hypotheses
+ for ( size_t i = 0; i < ids2Hyps.size(); ++i )
+ {
+ const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
+ const THypList& hyps = ids2Hyps[i].second;
+ THypList::const_iterator h = hyps.begin();
+ for ( ; h != hyps.end(); ++h )
+ _impl->AddHypothesis( s, (*h)->GetID() );
+ }
+
+ // restore groups
+ for ( size_t i = 0; i < groupsData.size(); ++i )
+ {
+ const TGroupOnGeomData& data = groupsData[i];
+
+ map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
+ if ( i2g == _mapGroups.end() ) continue;
+
+ SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
+ if ( !gr_i ) continue;
+
+ int id;
+ SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), id,
+ meshDS->IndexToShape( data._shapeID ));
+ if ( !g )
+ {
+ _mapGroups.erase( i2g );
+ }
+ else
+ {
+ g->GetGroupDS()->SetColor( data._color );
+ gr_i->changeLocalId( id );
+ _mapGroups[ id ] = i2g->second;
+ if ( data._oldID != id )
+ _mapGroups.erase( i2g );
+ }
+ }
+
+ // update _mapSubMesh
+ map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
+ for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
+ i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
+