X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSMESH_I%2FSMESH_Mesh_i.cxx;h=cb57e77f450d2134c9fc84c852dfbbf1639194d3;hb=2b3c553f4facafcea7cb1b2f23ab4b91b64771df;hp=016bf658bf9db8be14c9d603d3e8b0a512df6a20;hpb=09bc0414c91ebabb67c7fe200549044a1854e199;p=modules%2Fsmesh.git diff --git a/src/SMESH_I/SMESH_Mesh_i.cxx b/src/SMESH_I/SMESH_Mesh_i.cxx index 016bf658b..cb57e77f4 100644 --- a/src/SMESH_I/SMESH_Mesh_i.cxx +++ b/src/SMESH_I/SMESH_Mesh_i.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2019 CEA/DEN, EDF R&D, OPEN CASCADE // // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS @@ -240,7 +240,7 @@ GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh() for ( ; data != _geomGroupData.end(); ++data ) if ( data->_smeshObject->_is_equivalent( _this() )) { - SALOMEDS::SObject_wrap so = SMESH_Gen_i::getStudyServant()->FindObjectID( data->_groupEntry.c_str() ); + SALOMEDS::SObject_wrap so = _gen_i->getStudyServant()->FindObjectID( data->_groupEntry.c_str() ); CORBA::Object_var obj = _gen_i->SObjectToObject( so ); aShapeObj = GEOM::GEOM_Object::_narrow( obj ); break; @@ -254,6 +254,24 @@ GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh() return aShapeObj._retn(); } +//================================================================================ +/*! +* \brief Replaces a shape in the mesh +*/ +//================================================================================ +void SMESH_Mesh_i::ReplaceShape(GEOM::GEOM_Object_ptr theNewGeom) + throw (SALOME::SALOME_Exception) +{ + TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh(); + GEOM_Client* geomClient = _gen_i->GetShapeReader(); + TCollection_AsciiString aIOR; + if (geomClient->Find(S, aIOR)) { + geomClient->RemoveShapeFromBuffer(aIOR); + } + _impl->UndefShapeToMesh(); + SetShape(theNewGeom); +} + //================================================================================ /*! * \brief Return false if the mesh is not yet fully loaded from the study file @@ -772,6 +790,9 @@ SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape, if (CORBA::is_nil( anHyp )) THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM); + if ( _preMeshInfo ) + _preMeshInfo->ForgetOrLoad(); + SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK; try { @@ -955,7 +976,7 @@ void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh ) // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617) // aSubShape = theSubMesh->GetSubShape(); - SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder(); + SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder(); builder->RemoveObjectWithChildren( anSO ); // Update Python script @@ -1101,6 +1122,10 @@ void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup ) if ( !aGroup ) return; + if ( aGroup->GetMeshServant() != this ) + THROW_SALOME_CORBA_EXCEPTION( "RemoveGroup(): group does not belong to this mesh", + SALOME::BAD_PARAM ); + SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( theGroup ); if ( !aGroupSO->_is_nil() ) { @@ -1135,6 +1160,11 @@ void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup if ( theGroup->_is_nil() ) return; + SMESH_GroupBase_i* groupImpl = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup ); + if ( !groupImpl || groupImpl->GetMeshServant() != this ) + THROW_SALOME_CORBA_EXCEPTION( "RemoveGroupWithContents(): group does not belong to this mesh", + SALOME::BAD_PARAM); + vector nodeIds; // to remove nodes becoming free bool isNodal = ( theGroup->GetType() == SMESH::NODE ); if ( !isNodal && !theGroup->IsEmpty() ) @@ -1968,8 +1998,8 @@ 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(); - GEOM::GEOM_IGroupOperations_wrap groupOp = + GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( theGeomObj ); + GEOM::GEOM_IGroupOperations_ptr groupOp = geomGen->GetIGroupOperations(); GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj ); @@ -2027,8 +2057,8 @@ TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData) // get indices of group items set curIndices; - GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine(); - GEOM::GEOM_IGroupOperations_wrap groupOp = + 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 ) @@ -2075,11 +2105,66 @@ namespace struct TGroupOnGeomData { int _oldID; - int _shapeID; + TopoDS_Shape _shape; SMDSAbs_ElementType _type; std::string _name; Quantity_Color _color; + + TGroupOnGeomData( const SMESHDS_GroupOnGeom* group ) + { + _oldID = group->GetID(); + _type = group->GetType(); + _name = group->GetStoreName(); + _color = group->GetColor(); + } }; + + //----------------------------------------------------------------------------- + /*! + * \brief Check if a filter is still valid after geometry removal + */ + bool isValidGeomFilter( SMESH::Filter_var theFilter ) + { + if ( theFilter->_is_nil() ) + return false; + SMESH::Filter::Criteria_var criteria; + theFilter->GetCriteria( criteria.out() ); + + for ( CORBA::ULong iCr = 0; iCr < criteria->length(); ++iCr ) + { + const char* thresholdID = criteria[ iCr ].ThresholdID.in(); + std::string entry; + switch ( criteria[ iCr ].Type ) + { + case SMESH::FT_BelongToGeom: + case SMESH::FT_BelongToPlane: + case SMESH::FT_BelongToCylinder: + case SMESH::FT_BelongToGenSurface: + case SMESH::FT_LyingOnGeom: + entry = thresholdID; + break; + case SMESH::FT_ConnectedElements: + if ( thresholdID ) + { + entry = thresholdID; + break; + } + default: + continue; + } + SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen(); + SALOMEDS::SObject_wrap so = gen->getStudyServant()->FindObjectID( entry.c_str() ); + if ( so->_is_nil() ) + return false; + CORBA::Object_var obj = so->GetObject(); + GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( obj ); + if ( gen->GeomObjectToShape( geom ).IsNull() ) + return false; + + } // loop on criteria + + return true; + } } //============================================================================= @@ -2092,19 +2177,67 @@ namespace void SMESH_Mesh_i::CheckGeomModif() { + SMESH::SMESH_Mesh_var me = _this(); + GEOM::GEOM_Object_var mainGO = GetShapeToMesh(); + + //bool removedFromClient = false; + + if ( mainGO->_is_nil() ) // GEOM_Client cleared or geometry removed? (IPAL52735, PAL23636) + { + //removedFromClient = _impl->HasShapeToMesh(); + + // try to find geometry by study reference + SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me ); + SALOMEDS::SObject_wrap geomRefSO, geomSO; + if ( !meshSO->_is_nil() && + meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) && + geomRefSO->ReferencedObject( geomSO.inout() )) + { + CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO ); + mainGO = GEOM::GEOM_Object::_narrow( geomObj ); + } + + if ( mainGO->_is_nil() && // geometry removed ==> + !geomRefSO->_is_nil() ) // remove geom dependent data: sub-meshes etc. + { + // convert geom dependent groups into standalone ones + CheckGeomGroupModif(); + + _impl->ShapeToMesh( TopoDS_Shape() ); + + // remove sub-meshes + std::map::iterator i_sm = _mapSubMeshIor.begin(); + while ( i_sm != _mapSubMeshIor.end() ) + { + SMESH::SMESH_subMesh_ptr sm = i_sm->second; + ++i_sm; + RemoveSubMesh( sm ); + } + // remove all children except groups in the study + SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder(); + SALOMEDS::SObject_wrap so; + for ( CORBA::Long tag = SMESH::Tag_RefOnShape; tag <= SMESH::Tag_LastSubMesh; ++tag ) + if ( meshSO->FindSubObject( tag, so.inout() )) + builder->RemoveObjectWithChildren( so ); + + _gen_i->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED" ); + + return; + } + } + if ( !_impl->HasShapeToMesh() ) return; - GEOM::GEOM_Object_var mainGO = _gen_i->ShapeToGeomObject( _impl->GetShapeToMesh() ); - //if ( mainGO->_is_nil() ) return; // Update after group modification - if ( mainGO->_is_nil() || /* shape was removed from GEOM_Client by newGroupShape() - called by other mesh (IPAL52735) */ - mainGO->GetType() == GEOM_GROUP || + if ( mainGO->GetType() == GEOM_GROUP || // is group or not modified mainGO->GetTick() == _mainShapeTick ) { + int nb = NbNodes() + NbElements(); CheckGeomGroupModif(); + if ( nb != NbNodes() + NbElements() ) // something removed due to hypotheses change + _gen_i->UpdateIcons( me ); return; } @@ -2112,7 +2245,7 @@ void SMESH_Mesh_i::CheckGeomModif() GEOM_Client* geomClient = _gen_i->GetShapeReader(); if ( !geomClient ) return; - GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine(); + GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( mainGO ); if ( geomGen->_is_nil() ) return; CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO ); @@ -2126,28 +2259,47 @@ void SMESH_Mesh_i::CheckGeomModif() if ( newShape.IsNull() ) return; + // for the SHAPER-STUDY: the geometry may be updated, so, add a warning icon + if (_mainShapeTick != mainGO->GetTick()) { + SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me ); + if ( !meshSO->_is_nil()) + _gen_i->SetPixMap(meshSO, "ICON_SMESH_TREE_MESH_WARN"); + } + _mainShapeTick = mainGO->GetTick(); SMESHDS_Mesh * meshDS = _impl->GetMeshDS(); // store data of groups on geometry - vector< TGroupOnGeomData > groupsData; - const set& groups = meshDS->GetGroups(); + std::vector< TGroupOnGeomData > groupsData; + const std::set& groups = meshDS->GetGroups(); groupsData.reserve( groups.size() ); - set::const_iterator g = groups.begin(); + std::set::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 ); + groupsData.push_back( TGroupOnGeomData( group )); + + // get a new shape + SMESH::SMESH_GroupOnGeom_var gog; + std::map::iterator i_grp = _mapGroups.find( group->GetID() ); + if ( i_grp != _mapGroups.end() ) + gog = SMESH::SMESH_GroupOnGeom::_narrow( i_grp->second ); + + GEOM::GEOM_Object_var geom; + if ( !gog->_is_nil() ) + geom = gog->GetShape(); + if ( !geom->_is_nil() ) + { + CORBA::String_var ior = geomGen->GetStringFromIOR( geom ); + geomClient->RemoveShapeFromBuffer( ior.in() ); + groupsData.back()._shape = _gen_i->GeomObjectToShape( geom ); + } } + } // store assigned hypotheses - vector< pair< int, THypList > > ids2Hyps; + std::vector< pair< int, THypList > > ids2Hyps; const ShapeToHypothesis & hyps = meshDS->GetHypotheses(); for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() ) { @@ -2162,7 +2314,7 @@ void SMESH_Mesh_i::CheckGeomModif() _impl->ShapeToMesh( newShape ); // re-add shapes of geom groups - list::iterator data = _geomGroupData.begin(); + std::list::iterator data = _geomGroupData.begin(); for ( ; data != _geomGroupData.end(); ++data ) { TopoDS_Shape newShape = newGroupShape( *data ); @@ -2192,36 +2344,28 @@ void SMESH_Mesh_i::CheckGeomModif() _impl->AddHypothesis( s, (*h)->GetID() ); } - // restore groups + // restore groups on geometry for ( size_t i = 0; i < groupsData.size(); ++i ) { const TGroupOnGeomData& data = groupsData[i]; + if ( data._shape.IsNull() ) + continue; - map::iterator i2g = _mapGroups.find( data._oldID ); + std::map::iterator i2g = _mapGroups.find( data._oldID ); if ( i2g == _mapGroups.end() ) continue; SMESH_GroupBase_i* gr_i = SMESH::DownCast( i2g->second ); if ( !gr_i ) continue; - int id; - SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), id, - meshDS->IndexToShape( data._shapeID )); + SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), data._oldID, data._shape ); 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::iterator i_sm = _mapSubMesh.begin(); + std::map::iterator i_sm = _mapSubMesh.begin(); for ( ; i_sm != _mapSubMesh.end(); ++i_sm ) i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first )); @@ -2238,6 +2382,98 @@ void SMESH_Mesh_i::CheckGeomModif() void SMESH_Mesh_i::CheckGeomGroupModif() { + // remove sub-meshes referring a removed sub-shapes (if main shape still exists) + SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder(); + GEOM::GEOM_Object_var mainGO = GetShapeToMesh(); + SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( SMESH::SMESH_Mesh_var( _this() )); + if ( !mainGO->_is_nil() && !meshSO->_is_nil() ) + { + SALOMEDS::SObject_wrap rootSO, geomRefSO, geomSO; + for ( CORBA::Long tag = SMESH::Tag_FirstSubMesh; tag <= SMESH::Tag_LastSubMesh; ++tag ) + if ( meshSO->FindSubObject( tag, rootSO.inout() )) + { + int nbValid = 0, nbRemoved = 0; + SALOMEDS::ChildIterator_wrap chItr = _gen_i->getStudyServant()->NewChildIterator( rootSO ); + for ( ; chItr->More(); chItr->Next() ) + { + SALOMEDS::SObject_wrap smSO = chItr->Value(); // sub-mesh SO + if ( !smSO->_is_nil() && + smSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) && + geomRefSO->ReferencedObject( geomSO.inout() )) // find geometry by reference + { + CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO ); + GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( geomObj ); + if ( !geom->_non_existent() ) + { + ++nbValid; + continue; // keep the sub-mesh + } + } + CORBA::Object_var smObj = _gen_i->SObjectToObject( smSO ); + SMESH::SMESH_subMesh_var sm = SMESH::SMESH_subMesh::_narrow( smObj ); + if ( !sm->_is_nil() && !sm->_non_existent() ) + { + GEOM::GEOM_Object_var smGeom = sm->GetSubShape(); + if ( smGeom->_is_nil() ) + { + RemoveSubMesh( sm ); + ++nbRemoved; + } + } + else + { + if ( _preMeshInfo ) + _preMeshInfo->ForgetAllData(); // unknown hypothesis modified + builder->RemoveObjectWithChildren( smSO ); // sub-shape removed before loading SMESH + ++nbRemoved; + } + } + if ( /*nbRemoved > 0 &&*/ nbValid == 0 ) + builder->RemoveObjectWithChildren( rootSO ); + } + } + + // check for removed sub-shapes and convert geom dependent groups into standalone ones + std::map::iterator i_gr = _mapGroups.begin(); + while ( i_gr != _mapGroups.end()) + { + SMESH::SMESH_GroupBase_ptr group = i_gr->second; + ++i_gr; + SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( group ), refSO; + 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() ); + } + else if ( !onFilt->_is_nil() ) + { + isValidGeom = isValidGeomFilter( onFilt->GetFilter() ); + } + else // standalone + { + isValidGeom = ( !groupSO->_is_nil() && + !groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() )); + } + if ( !isValidGeom ) + { + if ( !IsLoaded() || group->IsEmpty() ) + { + RemoveGroup( group ); + } + else if ( !onGeom->_is_nil() || !onFilt->_is_nil() ) + { + SMESH::SMESH_Group_var ( ConvertToStandalone( group )); + } + else // is it possible? + { + builder->RemoveObjectWithChildren( refSO ); + } + } + } + + if ( !_impl->HasShapeToMesh() ) return; CORBA::Long nbEntities = NbNodes() + NbElements(); @@ -2384,7 +2620,7 @@ void SMESH_Mesh_i::CheckGeomGroupModif() groupData.push_back ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType())); } - // set new shape to mesh -> DS of sub-meshes and geom groups are deleted + // set new shape to mesh -> DS of sub-meshes and geom groups is deleted _impl->Clear(); _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730 _impl->ShapeToMesh( newShape ); @@ -2510,9 +2746,11 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase // remove reference to geometry SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO); for ( ; chItr->More(); chItr->Next() ) + { // Remove group's child SObject - builder->RemoveObject( chItr->Value() ); - + SALOMEDS::SObject_wrap so = chItr->Value(); + builder->RemoveObject( so ); + } // Update Python script TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this()) << ".ConvertToStandalone( " << aGroupSO << " )"; @@ -2520,9 +2758,9 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase // change icon of Group on Filter if ( isOnFilter ) { - SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes(); - const int isEmpty = ( elemTypes->length() == 0 ); - if ( !isEmpty ) + // SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes(); + // const int isEmpty = ( elemTypes->length() == 0 ); + // if ( !isEmpty ) { SALOMEDS::GenericAttribute_wrap anAttr = builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" ); @@ -2631,14 +2869,17 @@ bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh, if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617) { - if ( _mapSubMesh.find( subMeshId ) != _mapSubMesh.end() && - _mapSubMesh[ subMeshId ]) + SMESH_subMesh* sm; + if (( _mapSubMesh.count( subMeshId )) && + ( sm = _impl->GetSubMeshContaining( subMeshId ))) { - TopoDS_Shape S = _mapSubMesh[ subMeshId ]->GetSubShape(); + TopoDS_Shape S = sm->GetSubShape(); if ( !S.IsNull() ) { list hyps = _impl->GetHypothesisList( S ); isHypChanged = !hyps.empty(); + if ( isHypChanged && _preMeshInfo ) + _preMeshInfo->ForgetOrLoad(); list::const_iterator hyp = hyps.begin(); for ( ; hyp != hyps.end(); ++hyp ) _impl->RemoveHypothesis(S, (*hyp)->GetID()); @@ -3076,9 +3317,9 @@ CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED() void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite) { - SMESH_File aFile( file ); + SMESH_File aFile( file, false ); SMESH_Comment msg; - if (aFile.exists()) { + if ( aFile.exists() ) { // existing filesystem node if ( !aFile.isDirectory() ) { if ( aFile.openForWriting() ) { @@ -4720,8 +4961,9 @@ SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id) if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) ) { aResult->length( elem->NbNodes() ); - for ( int i = 0; i < elem->NbNodes(); ++i ) - aResult[ i ] = elem->GetNode( i )->GetID(); + for ( CORBA::ULong i = 0; i < aResult->length(); ++i ) + if ( const SMDS_MeshNode* n = elem->GetNode( i )) + aResult[ i ] = n->GetID(); } } return aResult._retn(); @@ -4837,7 +5079,7 @@ SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId, { if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) ) { - SMDS_VolumeTool vtool( elem ); + SMDS_VolumeTool vtool( elem, /*skipCentralNodes = */false ); if ( faceIndex < vtool.NbFaces() ) { aResult->length( vtool.NbFaceNodes( faceIndex )); @@ -4851,7 +5093,7 @@ SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId, } //======================================================================= -//function : GetElemFaceNodes +//function : GetFaceNormal //purpose : Returns three components of normal of given mesh face. //======================================================================= @@ -5148,7 +5390,7 @@ void SMESH_Mesh_i::CreateGroupServants() while ( groupIt->more() ) { ::SMESH_Group* group = groupIt->next(); - int anId = group->GetGroupDS()->GetID(); + int anId = group->GetID(); map::iterator it = _mapGroups.find(anId); if ( it != _mapGroups.end() && !CORBA::is_nil( it->second )) @@ -5866,19 +6108,23 @@ class SMESH_DimHyp if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound)) return false; -// bool checkSubShape = ( _dim >= theOther->_dim ) -// ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) ) -// : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ; bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim)); if ( !checkSubShape ) - return false; + return false; // check algorithms to be same - if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() )) - return true; // different algorithms -> concurrency ! + const SMESH_Algo* a1 = this->GetAlgo(); + const SMESH_Algo* a2 = theOther->GetAlgo(); + bool isSame = checkAlgo( a1, a2 ); + if ( !isSame ) + { + if ( !a1 || !a2 ) + return false; // pb? + return a1->GetDim() == a2->GetDim(); // different algorithms of same dim -> concurrency ! + } // check hypothesises for concurrence (skip first as algorithm) - int nbSame = 0; + size_t nbSame = 0; // pointers should be same, because it is referened from mesh hypothesis partition list ::const_iterator hypIt = _hypotheses.begin(); list ::const_iterator otheEndIt = theOther->_hypotheses.end(); @@ -5886,7 +6132,7 @@ class SMESH_DimHyp if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt ) nbSame++; // the submeshes are concurrent if their algorithms has different parameters - return nbSame != (int)theOther->_hypotheses.size() - 1; + return nbSame != theOther->_hypotheses.size() - 1; } // Return true if algorithm of this SMESH_DimHyp is used if no @@ -6219,11 +6465,15 @@ TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes() aPythonDump << " ]"; subMeshOrder.push_back( subMeshIds ); - // clear collected submeshes + // clear collected sub-meshes set::iterator clrIt = subMeshToClear.begin(); for ( ; clrIt != subMeshToClear.end(); clrIt++ ) if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt ) + { sm->ComputeStateEngine( SMESH_subMesh::CLEAN ); + if ( SMESH_Algo* algo = sm->GetAlgo() ) // #16748 + sm->AlgoStateEngine( SMESH_subMesh::MODIF_HYP, algo ); // to clear a cached algo + } } aPythonDump << " ])"; @@ -6406,6 +6656,48 @@ const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const return 0; } // ------------------------------------------------------------------------------------- +bool SMESH_MeshPartDS::HasNumerationHoles() +{ + if ( _meshDS ) return _meshDS->HasNumerationHoles(); + + return ( MinNodeID() != 1 || + MaxNodeID() != NbNodes() || + MinElementID() != 1 || + MaxElementID() != NbElements() ); +} +// ------------------------------------------------------------------------------------- +int SMESH_MeshPartDS::MaxNodeID() const +{ + if ( _meshDS ) return _meshDS->MaxNodeID(); + return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].rbegin())->GetID(); +} +// ------------------------------------------------------------------------------------- +int SMESH_MeshPartDS::MinNodeID() const +{ + if ( _meshDS ) return _meshDS->MinNodeID(); + return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].begin())->GetID(); +} +// ------------------------------------------------------------------------------------- +int SMESH_MeshPartDS::MaxElementID() const +{ + if ( _meshDS ) return _meshDS->MaxElementID(); + int maxID = 0; + for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType ) + if ( !_elements[ iType ].empty() ) + maxID = Max( maxID, (*_elements[ iType ].rbegin())->GetID() ); + return maxID; +} +// ------------------------------------------------------------------------------------- +int SMESH_MeshPartDS::MinElementID() const +{ + if ( _meshDS ) return _meshDS->MinElementID(); + int minID = 0; + for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType ) + if ( !_elements[ iType ].empty() ) + minID = Min( minID, (*_elements[ iType ].begin())->GetID() ); + return minID; +} +// ------------------------------------------------------------------------------------- SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const { if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );