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=728a75ddb8ee179295e70d97e17a5fff2a4e54ff;hp=c5aaf0d5bf7e03c6275836d1307a828e87ca0c7b;hb=6472eab132825fec572beda8276947593f85ffa1;hpb=d0aa6dbc4a660cc8a2ba2caf3cd99b07c3829657 diff --git a/src/SMESH_I/SMESH_Mesh_i.cxx b/src/SMESH_I/SMESH_Mesh_i.cxx index c5aaf0d5b..d4e396cbd 100644 --- a/src/SMESH_I/SMESH_Mesh_i.cxx +++ b/src/SMESH_I/SMESH_Mesh_i.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2013 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 @@ -6,7 +6,7 @@ // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either -// version 2.1 of the License. +// version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -26,24 +26,30 @@ #include "SMESH_Mesh_i.hxx" #include "DriverMED_R_SMESHDS_Mesh.h" +#include "DriverMED_W_Field.h" #include "DriverMED_W_SMESHDS_Mesh.h" #include "MED_Factory.hxx" +#include "SMDS_LinearEdge.hxx" #include "SMDS_EdgePosition.hxx" #include "SMDS_ElemIterator.hxx" #include "SMDS_FacePosition.hxx" #include "SMDS_IteratorOnIterators.hxx" #include "SMDS_MeshGroup.hxx" #include "SMDS_SetIterator.hxx" +#include "SMDS_StdIterator.hxx" #include "SMDS_VolumeTool.hxx" #include "SMESHDS_Command.hxx" #include "SMESHDS_CommandType.hxx" #include "SMESHDS_Group.hxx" #include "SMESHDS_GroupOnGeom.hxx" +#include "SMESH_Controls.hxx" +#include "SMESH_File.hxx" #include "SMESH_Filter_i.hxx" #include "SMESH_Gen_i.hxx" #include "SMESH_Group.hxx" #include "SMESH_Group_i.hxx" -#include "SMESH_MEDMesh_i.hxx" +#include "SMESH_Mesh.hxx" +#include "SMESH_MeshAlgos.hxx" #include "SMESH_MeshEditor.hxx" #include "SMESH_MeshEditor_i.hxx" #include "SMESH_MeshPartDS.hxx" @@ -52,12 +58,9 @@ #include "SMESH_PythonDump.hxx" #include "SMESH_subMesh_i.hxx" -#include #include #include -#include #include -#include #include #include @@ -65,30 +68,26 @@ // OCCT Includes #include -#include -#include -#include -#include -#include -#include +#include #include -#include -#include #include #include +#include #include #include #include -#include "SMESH_TryCatch.hxx" // include after OCCT headers! - // STL Includes #include -#include #include #include -#include +#include + +// to pass CORBA exception through SMESH_TRY +#define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; } + +#include "SMESH_TryCatch.hxx" // include after OCCT headers! #ifdef _DEBUG_ static int MYDEBUG = 0; @@ -98,6 +97,7 @@ static int MYDEBUG = 0; using namespace std; using SMESH::TPythonDump; +using SMESH::TVar; int SMESH_Mesh_i::_idGenerator = 0; @@ -108,16 +108,17 @@ int SMESH_Mesh_i::_idGenerator = 0; //============================================================================= SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA, - SMESH_Gen_i* gen_i, - CORBA::Long studyId ) + SMESH_Gen_i* gen_i ) : SALOME::GenericObj_i( thePOA ) { - MESSAGE("SMESH_Mesh_i"); - _impl = NULL; - _gen_i = gen_i; - _id = _idGenerator++; - _studyId = studyId; - _preMeshInfo = NULL; + _impl = NULL; + _gen_i = gen_i; + _id = _idGenerator++; + _nbInvalidHypos= -1; + _editor = NULL; + _previewEditor = NULL; + _preMeshInfo = NULL; + _mainShapeTick = 0; } //============================================================================= @@ -128,17 +129,13 @@ SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA, SMESH_Mesh_i::~SMESH_Mesh_i() { - MESSAGE("~SMESH_Mesh_i"); - // destroy groups map::iterator itGr; for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++) if (SMESH_GroupBase_i* aGroup = SMESH::DownCast(itGr->second)) { - // _impl->RemoveGroup() is called by ~SMESH_GroupBase_i() (PAL6331) - //_impl->RemoveGroup( aGroup->GetLocalID() ); - aGroup->myMeshServant = 0; aGroup->UnRegister(); + SMESH::SMESH_GroupBase_var( itGr->second ); } _mapGroups.clear(); @@ -148,18 +145,29 @@ SMESH_Mesh_i::~SMESH_Mesh_i() if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast( itSM->second )) { aSubMesh->UnRegister(); + SMESH::SMESH_subMesh_var( itSM->second ); } _mapSubMeshIor.clear(); - // destroy hypotheses + // destroy hypotheses. _mapHypo contains all hyps ever been assigned map::iterator itH; - for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) - if ( SMESH_Hypothesis_i* aHypo = SMESH::DownCast( itH->second )) - { - aHypo->UnRegister(); - } + for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) { + if ( SMESH_Hypothesis_i* hyp_i = SMESH::DownCast( itH->second )) + if ( SMESH_Hypothesis * smHyp = _impl->GetHypothesis( itH->first )) + if ( _impl->GetMeshDS()->IsUsedHypothesis( smHyp )) + hyp_i->UnRegister(); + + SMESH::SMESH_Hypothesis_var( itH->second ); // decref CORBA object + } _mapHypo.clear(); + // clear cached shapes if no more meshes remain; (the cache is blame, + // together with publishing, of spent time increasing in issue 22874) + if ( _impl->NbMeshes() == 1 ) + _gen_i->GetShapeReader()->ClearClientBuffer(); + + delete _editor; _editor = NULL; + delete _previewEditor; _previewEditor = NULL; delete _impl; _impl = NULL; delete _preMeshInfo; _preMeshInfo = NULL; } @@ -185,7 +193,10 @@ void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject ) THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); } // to track changes of GEOM groups - addGeomGroupData( theShapeObject, _this() ); + SMESH::SMESH_Mesh_var mesh = _this(); + addGeomGroupData( theShapeObject, mesh ); + if ( !CORBA::is_nil( theShapeObject )) + _mainShapeTick = theShapeObject->GetTick(); } //================================================================================ @@ -221,7 +232,23 @@ GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh() try { TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh(); if ( !S.IsNull() ) + { aShapeObj = _gen_i->ShapeToGeomObject( S ); + if ( aShapeObj->_is_nil() ) + { + // S was removed from GEOM_Client by newGroupShape() called by other mesh; + // find GEOM_Object by entry (IPAL52735) + list::iterator data = _geomGroupData.begin(); + for ( ; data != _geomGroupData.end(); ++data ) + if ( data->_smeshObject->_is_equivalent( _this() )) + { + 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; + } + } + } } catch(SALOME_Exception & S_ex) { THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); @@ -229,6 +256,47 @@ 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->GetShapeToMesh(); + GEOM_Client* geomClient = _gen_i->GetShapeReader(); + TCollection_AsciiString aIOR; + 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(); + SALOMEDS::SObject_wrap aSO = _gen_i->ObjectToSObject( me ); + CORBA::String_var entry = theNewGeom->GetStudyEntry(); + if ( !aSO->_is_nil() ) + { + SALOMEDS::SObject_wrap aShapeRefSO; + if ( aSO->FindSubObject( _gen_i->GetRefOnShapeTag(), aShapeRefSO.inout() )) + { + SALOMEDS::SObject_wrap aShapeSO = _gen_i->getStudyServant()->FindObjectID( entry ); + SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder(); + builder->Addreference( aShapeRefSO, aShapeSO ); + } + } + + // re-assign global hypotheses to the new shape + _mainShapeTick = -1; + CheckGeomModif( true ); + + TPythonDump() << "SHAPERSTUDY.breakLinkForSubElements(salome.ObjectToSObject(" + << me <<".GetMesh()), " << entry.in() << ")"; + + TPythonDump() << me << ".ReplaceShape( " << entry.in() << " )"; + +} + //================================================================================ /*! * \brief Return false if the mesh is not yet fully loaded from the study file @@ -264,18 +332,20 @@ void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); if ( _preMeshInfo ) - _preMeshInfo->ForgetAllData(); + _preMeshInfo->ForgetOrLoad(); // load in case if !HasShapeToMesh() try { _impl->Clear(); - CheckGeomGroupModif(); // issue 20145 + //CheckGeomGroupModif(); // issue 20145 } catch(SALOME_Exception & S_ex) { THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); } - _impl->GetMeshDS()->Modified(); - TPythonDump() << _this() << ".Clear()"; + TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()"; + + SMESH::SMESH_Mesh_var mesh = _this(); + _gen_i->UpdateIcons( mesh ); } //================================================================================ @@ -299,7 +369,7 @@ void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID) } _impl->GetMeshDS()->Modified(); - TPythonDump() << _this() << ".ClearSubMesh( " << ShapeID << " )"; + TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )"; } //============================================================================= @@ -348,7 +418,7 @@ static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr } else { - errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName ); + errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName ); errVar->comment = errorPtr->myComment.c_str(); } return errVar._retn(); @@ -381,22 +451,15 @@ SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName ) CreateGroupServants(); int major, minor, release; - if( !MED::getMEDVersion( theFileName, major, minor, release ) ) - major = minor = release = -1; - _medFileInfo = new SALOME_MED::MedFileInfo(); + major = minor = release = 0; + MED::GetMEDVersion(theFileName, major, minor, release); + _medFileInfo = new SMESH::MedFileInfo(); _medFileInfo->fileName = theFileName; _medFileInfo->fileSize = 0; -#ifdef WIN32 - struct _stati64 d; - if ( ::_stati64( theFileName, &d ) != -1 ) -#else - struct stat64 d; - if ( ::stat64( theFileName, &d ) != -1 ) -#endif - _medFileInfo->fileSize = d.st_size; _medFileInfo->major = major; _medFileInfo->minor = minor; _medFileInfo->release = release; + _medFileInfo->fileSize = SMESH_File( theFileName ).size(); return ConvertDriverMEDReadStatus(status); } @@ -426,6 +489,13 @@ SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileNa CreateGroupServants(); + _medFileInfo = new SMESH::MedFileInfo(); + _medFileInfo->fileName = theFileName; + _medFileInfo->major = 0; + _medFileInfo->minor = 0; + _medFileInfo->release = 0; + _medFileInfo->fileSize = SMESH_File( theFileName ).size(); + return ConvertDriverMEDReadStatus(status); } @@ -435,13 +505,30 @@ SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileNa */ //================================================================================ -char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits) +char* SMESH_Mesh_i::GetVersionString(CORBA::Long minor, CORBA::Short nbDigits) { - string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version), - nbDigits); + string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(minor, + nbDigits); return CORBA::string_dup( ver.c_str() ); } +//================================================================================ +/*! + * Return the list of med versions compatibles for write/append, + * encoded in 10*major+minor (for instance, code for med 3.2.1 is 32) + */ +//================================================================================ +SMESH::long_array* SMESH_Mesh_i::GetMEDVersionsCompatibleForAppend() +{ + SMESH::long_array_var aResult = new SMESH::long_array(); + std::vector mvok = MED::GetMEDVersionsAppendCompatible(); + long nbver = mvok.size(); + aResult->length( nbver ); + for ( int i = 0; i < nbver; i++ ) + aResult[i] = mvok[i]; + return aResult._retn(); +} + //============================================================================= /*! * ImportUNVFile @@ -460,6 +547,13 @@ int SMESH_Mesh_i::ImportUNVFile( const char* theFileName ) CreateGroupServants(); + _medFileInfo = new SMESH::MedFileInfo(); + _medFileInfo->fileName = theFileName; + _medFileInfo->major = 0; + _medFileInfo->minor = 0; + _medFileInfo->release = 0; + _medFileInfo->fileSize = SMESH_File( theFileName ).size(); + SMESH_CATCH( SMESH::throwCorbaException ); return 1; @@ -478,7 +572,18 @@ int SMESH_Mesh_i::ImportSTLFile( const char* theFileName ) SMESH_TRY; // Read mesh with name = into SMESH_Mesh - _impl->STLToMesh( theFileName ); + std::string name = _impl->STLToMesh( theFileName ); + if ( !name.empty() ) + { + SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( _this() ); + _gen_i->SetName( meshSO, name.c_str() ); + } + _medFileInfo = new SMESH::MedFileInfo(); + _medFileInfo->fileName = theFileName; + _medFileInfo->major = 0; + _medFileInfo->minor = 0; + _medFileInfo->release = 0; + _medFileInfo->fileSize = SMESH_File( theFileName ).size(); SMESH_CATCH( SMESH::throwCorbaException ); @@ -517,6 +622,13 @@ SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName, error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups ); + _medFileInfo = new SMESH::MedFileInfo(); + _medFileInfo->fileName = theFileName; + _medFileInfo->major = 0; + _medFileInfo->minor = 0; + _medFileInfo->release = 0; + _medFileInfo->fileSize = SMESH_File( theFileName ).size(); + SMESH_CATCH( exceptionToComputeError ); #undef SMESH_CAUGHT #define SMESH_CAUGHT @@ -540,7 +652,7 @@ SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus switch (theStatus) { RETURNCASE( HYP_OK ); RETURNCASE( HYP_MISSING ); - RETURNCASE( HYP_CONCURENT ); + RETURNCASE( HYP_CONCURRENT ); RETURNCASE( HYP_BAD_PARAMETER ); RETURNCASE( HYP_HIDDEN_ALGO ); RETURNCASE( HYP_HIDING_ALGO ); @@ -552,6 +664,7 @@ SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus RETURNCASE( HYP_BAD_SUBSHAPE ); RETURNCASE( HYP_BAD_GEOMETRY ); RETURNCASE( HYP_NEED_SHAPE ); + RETURNCASE( HYP_INCOMPAT_HYPS ); default:; } return SMESH::HYP_UNKNOWN_FATAL; @@ -567,31 +680,37 @@ SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus */ //============================================================================= -SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject, - SMESH::SMESH_Hypothesis_ptr anHyp) +SMESH::Hypothesis_Status +SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape, + SMESH::SMESH_Hypothesis_ptr anHyp, + CORBA::String_out anErrorText) throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); if ( _preMeshInfo ) _preMeshInfo->ForgetOrLoad(); - SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp ); + const int prevNbMeshEnt = _impl->NbNodes() + _impl->GetMeshDS()->NbElements(); + std::string error; + SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error ); + anErrorText = error.c_str(); + + SMESH::SMESH_Mesh_var mesh( _this() ); if ( !SMESH_Hypothesis::IsStatusFatal(status) ) - _gen_i->AddHypothesisToShape(_gen_i->GetCurrentStudy(), _this(), - aSubShapeObject, anHyp ); + { + _gen_i->AddHypothesisToShape( mesh, aSubShape, anHyp ); + int newNbMeshEnt = _impl->NbNodes() + _impl->GetMeshDS()->NbElements(); + if ( newNbMeshEnt != prevNbMeshEnt ) + _gen_i->UpdateIcons( mesh ); + } if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status ); // Update Python script - //if(_impl->HasShapeToMesh()) { - TPythonDump() << "status = " << _this() << ".AddHypothesis( " - << aSubShapeObject << ", " << anHyp << " )"; - // } - // else { - // TPythonDump() << "status = " << _this() << ".AddHypothesis( "<< anHyp << " )"; - // } - + TPythonDump() << "status = " << mesh << ".AddHypothesis( " + << aSubShape << ", " << anHyp << " )"; + return ConvertHypothesisStatus(status); } @@ -602,19 +721,17 @@ SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr //============================================================================= SMESH_Hypothesis::Hypothesis_Status - SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject, - SMESH::SMESH_Hypothesis_ptr anHyp) +SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape, + SMESH::SMESH_Hypothesis_ptr anHyp, + std::string* anErrorText) { if(MYDEBUG) MESSAGE("addHypothesis"); - if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh()) - THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", - SALOME::BAD_PARAM); + if (CORBA::is_nil( aSubShape ) && HasShapeToMesh()) + THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape 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); + if (CORBA::is_nil( anHyp )) + THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM); SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK; try @@ -622,22 +739,28 @@ SMESH_Hypothesis::Hypothesis_Status TopoDS_Shape myLocSubShape; //use PseudoShape in case if mesh has no shape if(HasShapeToMesh()) - myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject); - else + myLocSubShape = _gen_i->GeomObjectToShape( aSubShape); + else myLocSubShape = _impl->GetShapeToMesh(); - - int hypId = myHyp->GetId(); - status = _impl->AddHypothesis(myLocSubShape, hypId); - if ( !SMESH_Hypothesis::IsStatusFatal(status) ) { - _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( myHyp ); - _mapHypo[hypId]->Register(); + + const int hypId = anHyp->GetId(); + std::string error; + status = _impl->AddHypothesis( myLocSubShape, hypId, &error ); + if ( !SMESH_Hypothesis::IsStatusFatal(status) ) + { + _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp ); + anHyp->Register(); // assure there is a corresponding submesh if ( !_impl->IsMainShape( myLocSubShape )) { int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape ); if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() ) - createSubMesh( aSubShapeObject ); + SMESH::SMESH_subMesh_var( createSubMesh( aSubShape )); } } + else if ( anErrorText ) + { + *anErrorText = error; + } } catch(SALOME_Exception & S_ex) { @@ -652,30 +775,29 @@ SMESH_Hypothesis::Hypothesis_Status */ //============================================================================= -SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject, +SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape, SMESH::SMESH_Hypothesis_ptr anHyp) - throw(SALOME::SALOME_Exception) + throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); if ( _preMeshInfo ) _preMeshInfo->ForgetOrLoad(); - SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShapeObject, anHyp ); + SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp ); + SMESH::SMESH_Mesh_var mesh = _this(); if ( !SMESH_Hypothesis::IsStatusFatal(status) ) - _gen_i->RemoveHypothesisFromShape(_gen_i->GetCurrentStudy(), _this(), - aSubShapeObject, anHyp ); - - // Update Python script - // Update Python script - if(_impl->HasShapeToMesh()) { - TPythonDump() << "status = " << _this() << ".RemoveHypothesis( " - << aSubShapeObject << ", " << anHyp << " )"; + { + _gen_i->RemoveHypothesisFromShape( mesh, aSubShape, anHyp ); + _gen_i->UpdateIcons( mesh ); } - else { - TPythonDump() << "status = " << _this() << ".RemoveHypothesis( " + // Update Python script + if(_impl->HasShapeToMesh()) + TPythonDump() << "status = " << mesh << ".RemoveHypothesis( " + << aSubShape << ", " << anHyp << " )"; + else + TPythonDump() << "status = " << mesh << ".RemoveHypothesis( " << anHyp << " )"; - } return ConvertHypothesisStatus(status); } @@ -687,33 +809,37 @@ 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_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape, SMESH::SMESH_Hypothesis_ptr anHyp) { if(MYDEBUG) MESSAGE("removeHypothesis()"); - // **** proposer liste de sub-shape (selection multiple) - if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh()) + if (CORBA::is_nil( aSubShape ) && HasShapeToMesh()) THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM); - SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp); - if (CORBA::is_nil(myHyp)) + 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 { TopoDS_Shape myLocSubShape; //use PseudoShape in case if mesh has no shape - if(HasShapeToMesh()) - myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject); + if( _impl->HasShapeToMesh() ) + myLocSubShape = _gen_i->GeomObjectToShape( aSubShape ); else myLocSubShape = _impl->GetShapeToMesh(); - int hypId = myHyp->GetId(); + const int hypId = anHyp->GetId(); status = _impl->RemoveHypothesis(myLocSubShape, hypId); -// if ( !SMESH_Hypothesis::IsStatusFatal(status) ) EAP: hyp can be used on many sub-shapes -// _mapHypo.erase( hypId ); + if ( !SMESH_Hypothesis::IsStatusFatal(status) ) + { + // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes + anHyp->UnRegister(); + } } catch(SALOME_Exception & S_ex) { @@ -729,30 +855,32 @@ SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject, //============================================================================= SMESH::ListOfHypothesis * - SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject) +SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape) throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); if (MYDEBUG) MESSAGE("GetHypothesisList"); - if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShapeObject)) + if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape)) THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM); SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis(); try { - TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject); + TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape); if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() ) myLocSubShape = _impl->GetShapeToMesh(); const list& aLocalList = _impl->GetHypothesisList( myLocSubShape ); int i = 0, n = aLocalList.size(); aList->length( n ); - 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()] ); + list::const_iterator aHyp = aLocalList.begin(); + std::map::iterator id_hypptr; + for ( ; i < n && aHyp != aLocalList.end(); aHyp++ ) + { + id_hypptr = _mapHypo.find( (*aHyp)->GetID() ); + if ( id_hypptr != _mapHypo.end() ) + aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second ); } - aList->length( i ); } catch(SALOME_Exception & S_ex) { @@ -793,7 +921,7 @@ SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Excepti // Update Python script if ( !_mapSubMeshIor.empty() ) - aPythonDump << " ] = " << _this() << ".GetSubMeshes()"; + aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()"; return aList._retn(); } @@ -803,20 +931,19 @@ SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Excepti * */ //============================================================================= -SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject, + +SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape, 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 Sub-shape reference", - SALOME::BAD_PARAM); + if (CORBA::is_nil(aSubShape)) + THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM); SMESH::SMESH_subMesh_var subMesh; - SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(_this()); + SMESH::SMESH_Mesh_var aMesh = _this(); try { - TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject); + TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape); //Get or Create the SMESH_subMesh object implementation @@ -832,15 +959,15 @@ 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 )) { + subMesh = createSubMesh( aSubShape ); + if ( _gen_i->CanPublishInStudy( subMesh )) + { SALOMEDS::SObject_wrap aSO = - _gen_i->PublishSubMesh(_gen_i->GetCurrentStudy(), aMesh, - subMesh, aSubShapeObject, theName ); + _gen_i->PublishSubMesh( aMesh, subMesh, aSubShape, theName ); if ( !aSO->_is_nil()) { // Update Python script - TPythonDump() << aSO << " = " << _this() << ".GetSubMesh( " - << aSubShapeObject << ", '" << theName << "' )"; + TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( " + << aSubShape << ", '" << theName << "' )"; } } } @@ -860,36 +987,33 @@ void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh ) throw (SALOME::SALOME_Exception) { SMESH_TRY; - + if ( theSubMesh->_is_nil() ) return; - GEOM::GEOM_Object_var aSubShapeObject; - SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy(); - if ( !aStudy->_is_nil() ) { - // Remove submesh's SObject - SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh ); - if ( !anSO->_is_nil() ) { - long aTag = SMESH_Gen_i::GetRefOnShapeTag(); - SALOMEDS::SObject_wrap anObj, aRef; - if ( anSO->FindSubObject( aTag, anObj.inout() ) && - anObj->ReferencedObject( aRef.inout() )) - { - CORBA::Object_var obj = aRef->GetObject(); - aSubShapeObject = GEOM::GEOM_Object::_narrow( obj ); - } - // if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617) - // aSubShapeObject = theSubMesh->GetSubShape(); + GEOM::GEOM_Object_var aSubShape; + // Remove submesh's SObject + SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( theSubMesh ); + if ( !anSO->_is_nil() ) { + long aTag = SMESH_Gen_i::GetRefOnShapeTag(); + SALOMEDS::SObject_wrap anObj, aRef; + if ( anSO->FindSubObject( aTag, anObj.inout() ) && + anObj->ReferencedObject( aRef.inout() )) + { + CORBA::Object_var obj = aRef->GetObject(); + aSubShape = GEOM::GEOM_Object::_narrow( obj ); + } + // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617) + // aSubShape = theSubMesh->GetSubShape(); - SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder(); - builder->RemoveObjectWithChildren( anSO ); + SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder(); + builder->RemoveObjectWithChildren( anSO ); - // Update Python script - TPythonDump() << _this() << ".RemoveSubMesh( " << anSO << " )"; - } + // Update Python script + TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )"; } - if ( removeSubMesh( theSubMesh, aSubShapeObject.in() )) + if ( removeSubMesh( theSubMesh, aSubShape.in() )) if ( _preMeshInfo ) _preMeshInfo->ForgetOrLoad(); @@ -904,7 +1028,7 @@ void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh ) SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType, const char* theName ) - throw(SALOME::SALOME_Exception) + throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); if ( _preMeshInfo ) @@ -913,20 +1037,19 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType SMESH::SMESH_Group_var aNewGroup = SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName )); - if ( _gen_i->CanPublishInStudy( aNewGroup ) ) { + if ( _gen_i->CanPublishInStudy( aNewGroup ) ) + { + SMESH::SMESH_Mesh_var mesh = _this(); SALOMEDS::SObject_wrap aSO = - _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(), - aNewGroup, GEOM::GEOM_Object::_nil(), theName); - if ( !aSO->_is_nil()) { + _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName); + if ( !aSO->_is_nil()) // Update Python script - TPythonDump() << aSO << " = " << _this() << ".CreateGroup( " + TPythonDump() << aSO << " = " << mesh << ".CreateGroup( " << theElemType << ", '" << theName << "' )"; - } } return aNewGroup._retn(); } - //============================================================================= /*! * @@ -936,7 +1059,7 @@ SMESH::SMESH_GroupOnGeom_ptr SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType, const char* theName, GEOM::GEOM_Object_ptr theGeomObj) - throw(SALOME::SALOME_Exception) + throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); if ( _preMeshInfo ) @@ -947,18 +1070,17 @@ SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType, TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj ); if ( !aShape.IsNull() ) { - aNewGroup = SMESH::SMESH_GroupOnGeom::_narrow - ( createGroup( theElemType, theName, aShape )); + aNewGroup = + SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, /*id=*/-1, aShape )); - if ( _gen_i->CanPublishInStudy( aNewGroup ) ) { + if ( _gen_i->CanPublishInStudy( aNewGroup ) ) + { + SMESH::SMESH_Mesh_var mesh = _this(); SALOMEDS::SObject_wrap aSO = - _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(), - aNewGroup, theGeomObj, theName); - if ( !aSO->_is_nil()) { - // Update Python script - TPythonDump() << aSO << " = " << _this() << ".CreateGroupFromGEOM(" + _gen_i->PublishGroup( mesh, aNewGroup, theGeomObj, theName ); + if ( !aSO->_is_nil()) + TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( " << theElemType << ", '" << theName << "', " << theGeomObj << " )"; - } } } @@ -979,7 +1101,7 @@ SMESH::SMESH_GroupOnFilter_ptr SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType, const char* theName, SMESH::Filter_ptr theFilter ) - throw (SALOME::SALOME_Exception) + throw (SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); if ( _preMeshInfo ) @@ -993,7 +1115,7 @@ SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType, THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM); SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow - ( createGroup( theElemType, theName, TopoDS_Shape(), predicate )); + ( createGroup( theElemType, theName, /*id=*/-1, TopoDS_Shape(), predicate )); TPythonDump pd; if ( !aNewGroup->_is_nil() ) @@ -1001,16 +1123,14 @@ SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType, if ( _gen_i->CanPublishInStudy( aNewGroup ) ) { + SMESH::SMESH_Mesh_var mesh = _this(); SALOMEDS::SObject_wrap aSO = - _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(), aNewGroup, - GEOM::GEOM_Object::_nil(), theName); - if ( !aSO->_is_nil()) { - // Update Python script - pd << aSO << " = " << _this() << ".CreateGroupFromFilter(" + _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName ); + + if ( !aSO->_is_nil()) + pd << aSO << " = " << mesh << ".CreateGroupFromFilter( " << theElemType << ", '" << theName << "', " << theFilter << " )"; - } } - return aNewGroup._retn(); } @@ -1021,31 +1141,32 @@ SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType, //============================================================================= void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup ) - throw (SALOME::SALOME_Exception) + throw (SALOME::SALOME_Exception) { if ( theGroup->_is_nil() ) return; SMESH_TRY; - SMESH_GroupBase_i* aGroup = - dynamic_cast( SMESH_Gen_i::GetServant( theGroup ).in() ); + SMESH_GroupBase_i* aGroup = SMESH::DownCast( theGroup ); if ( !aGroup ) return; - SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy(); - if ( !aStudy->_is_nil() ) { - SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup ); + if ( aGroup->GetMeshServant() != this ) + THROW_SALOME_CORBA_EXCEPTION( "RemoveGroup(): group does not belong to this mesh", + SALOME::BAD_PARAM ); - if ( !aGroupSO->_is_nil() ) { - // Update Python script - TPythonDump() << _this() << ".RemoveGroup( " << aGroupSO << " )"; + SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( theGroup ); + if ( !aGroupSO->_is_nil() ) + { + // Update Python script + TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )"; - // Remove group's SObject - SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder(); - builder->RemoveObjectWithChildren( aGroupSO ); - } + // Remove group's SObject + SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder(); + builder->RemoveObjectWithChildren( aGroupSO ); } + aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion // Remove the group from SMESH data structures removeGroup( aGroup->GetLocalID() ); @@ -1069,35 +1190,68 @@ void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup if ( theGroup->_is_nil() ) return; - SMESH_GroupBase_i* aGroup = - dynamic_cast( SMESH_Gen_i::GetServant( theGroup ).in() ); - if ( !aGroup ) - return; - - SMESH::long_array_var anIds = aGroup->GetListOfID(); - SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor(); + 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); - TPythonDump pyDump; // Supress dump from RemoveNodes/Elements() and RemoveGroup() + vector nodeIds; // to remove nodes becoming free + bool isNodal = ( theGroup->GetType() == SMESH::NODE ); + if ( !isNodal && !theGroup->IsEmpty() ) + { + CORBA::Long elemID = theGroup->GetID( 1 ); + int nbElemNodes = GetElemNbNodes( elemID ); + if ( nbElemNodes > 0 ) + nodeIds.reserve( theGroup->Size() * nbElemNodes ); + } - // Remove contents - if ( aGroup->GetType() == SMESH::NODE ) - aMeshEditor->RemoveNodes( anIds ); - else - aMeshEditor->RemoveElements( anIds ); + // Retrieve contents + SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup ); + SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() ); + SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > elemBeg( elemIt ), elemEnd; + std::vector< const SMDS_MeshElement* > elems( theGroup->Size() ); + elems.assign( elemBeg, elemEnd ); - // Update Python script (theGroup must be alive for this) - pyDump << _this() << ".RemoveGroupWithContents( " << theGroup << " )"; + TPythonDump pyDump; // Suppress dump from RemoveGroup() // Remove group RemoveGroup( theGroup ); + // Remove contents + for ( size_t i = 0; i < elems.size(); ++i ) + { + // if ( !_impl->GetMeshDS()->Contains( elems[i] )) + // continue; + if ( !isNodal ) + { + for ( SMDS_ElemIteratorPtr nIt = elems[i]->nodesIterator(); nIt->more(); ) + nodeIds.push_back( nIt->next()->GetID() ); + + _impl->GetMeshDS()->RemoveFreeElement( elems[i], /*sm=*/0 ); + } + else + { + _impl->GetMeshDS()->RemoveElement( elems[i] ); + } + } + + // Remove free nodes + for ( size_t i = 0 ; i < nodeIds.size(); ++i ) + if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] )) + if ( n->NbInverseElements() == 0 ) + _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 ); + + // Update Python script (theGroup must be alive for this) + pyDump << SMESH::SMESH_Mesh_var(_this()) + << ".RemoveGroupWithContents( " << theGroup << " )"; + SMESH_CATCH( SMESH::throwCorbaException ); } //================================================================================ /*! * \brief Get the list of groups existing in the mesh - * \retval SMESH::ListOfGroups * - list of groups + * \retval SMESH::ListOfGroups * - list of groups */ //================================================================================ @@ -1129,7 +1283,7 @@ SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception) catch(SALOME_Exception & S_ex) { THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); } - aPythonDump << " ] = " << _this() << ".GetGroups()"; + aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()"; } return aList._retn(); } @@ -1147,14 +1301,14 @@ CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception) } //============================================================================= -/*! UnionGroups - * New group is created. All mesh elements that are - * present in initial groups are added to the new one +/*! + * New group including all mesh elements present in initial groups is created. */ //============================================================================= + SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1, SMESH::SMESH_GroupBase_ptr theGroup2, - const char* theName ) + const char* theName ) throw (SALOME::SALOME_Exception) { SMESH::SMESH_Group_var aResGrp; @@ -1163,10 +1317,12 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr the if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - if ( theGroup1->_is_nil() || theGroup2->_is_nil() || - theGroup1->GetType() != theGroup2->GetType() ) - return SMESH::SMESH_Group::_nil(); - + if ( theGroup1->_is_nil() || theGroup2->_is_nil() ) + THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group", + SALOME::BAD_PARAM); + if ( theGroup1->GetType() != theGroup2->GetType() ) + THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types", + SALOME::BAD_PARAM); TPythonDump pyDump; // Create Union @@ -1174,31 +1330,12 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr the if ( aResGrp->_is_nil() ) return SMESH::SMESH_Group::_nil(); - SMESH::long_array_var anIds1 = theGroup1->GetListOfID(); - SMESH::long_array_var anIds2 = theGroup2->GetListOfID(); - - TColStd_MapOfInteger aResMap; - - for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ ) - aResMap.Add( anIds1[ i1 ] ); - - for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ ) - aResMap.Add( anIds2[ i2 ] ); - - SMESH::long_array_var aResIds = new SMESH::long_array; - aResIds->length( aResMap.Extent() ); - - int resI = 0; - TColStd_MapIteratorOfMapOfInteger anIter( aResMap ); - for( ; anIter.More(); anIter.Next() ) - aResIds[ resI++ ] = anIter.Key(); - - aResGrp->Add( aResIds ); + aResGrp->AddFrom( theGroup1 ); + aResGrp->AddFrom( theGroup2 ); // Update Python script - pyDump << aResGrp << " = " << _this() << ".UnionGroups( " - << theGroup1 << ", " << theGroup2 << ", '" - << theName << "' )"; + pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) + << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )"; SMESH_CATCH( SMESH::throwCorbaException ); @@ -1207,72 +1344,62 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr the //============================================================================= /*! - \brief Union list of groups. New group is created. All mesh elements that are - present in initial groups are added to the new one. - \param theGroups list of groups - \param theName name of group to be created - \return pointer on the group -*/ + * \brief New group including all mesh elements present in initial groups is created. + * \param theGroups list of groups + * \param theName name of group to be created + * \return pointer to the new group + */ //============================================================================= + SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups, const char* theName ) throw (SALOME::SALOME_Exception) { + SMESH::SMESH_Group_var aResGrp; + if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); if ( !theName ) return SMESH::SMESH_Group::_nil(); - SMESH::SMESH_Group_var aResGrp; - SMESH_TRY; - vector< int > anIds; + // check types SMESH::ElementType aType = SMESH::ALL; for ( int g = 0, n = theGroups.length(); g < n; g++ ) { SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ]; if ( CORBA::is_nil( aGrp ) ) continue; - - // check type - SMESH::ElementType aCurrType = aGrp->GetType(); if ( aType == SMESH::ALL ) - aType = aCurrType; - else - { - if ( aType != aCurrType ) - return SMESH::SMESH_Group::_nil(); - } - - // unite ids - SMESH::long_array_var aCurrIds = aGrp->GetListOfID(); - for ( int i = 0, n = aCurrIds->length(); i < n; i++ ) - { - int aCurrId = aCurrIds[ i ]; - anIds.push_back( aCurrId ); - } + aType = aGrp->GetType(); + else if ( aType != aGrp->GetType() ) + THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types", + SALOME::BAD_PARAM); } + if ( aType == SMESH::ALL ) + return SMESH::SMESH_Group::_nil(); TPythonDump pyDump; - // Create group + // Create Union aResGrp = CreateGroup( aType, theName ); if ( aResGrp->_is_nil() ) return SMESH::SMESH_Group::_nil(); - // Create array of identifiers - SMESH::long_array_var aResIds = new SMESH::long_array; - aResIds->length( anIds.size() ); - - for ( size_t i = 0; iAdd( aResIds ); - - // Update Python script - pyDump << aResGrp << " = " << _this() << ".UnionListOfGroups( " - << &theGroups << ", '" << theName << "' )"; + pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ "; + for ( int g = 0, n = theGroups.length(); g < n; g++ ) + { + SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ]; + if ( !CORBA::is_nil( aGrp ) ) + { + aResGrp->AddFrom( aGrp ); + if ( g > 0 ) pyDump << ", "; + pyDump << aGrp; + } + } + pyDump << " ], '" << theName << "' )"; SMESH_CATCH( SMESH::throwCorbaException ); @@ -1280,11 +1407,12 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups } //============================================================================= -/*! IntersectGroups +/*! * New group is created. All mesh elements that are * present in both initial groups are added to the new one. */ //============================================================================= + SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1, SMESH::SMESH_GroupBase_ptr theGroup2, const char* theName ) @@ -1293,41 +1421,47 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr SMESH::SMESH_Group_var aResGrp; SMESH_TRY; + if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - if ( theGroup1->_is_nil() || theGroup2->_is_nil() || - theGroup1->GetType() != theGroup2->GetType() ) - return SMESH::SMESH_Group::_nil(); - + if ( theGroup1->_is_nil() || theGroup2->_is_nil() ) + THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group", + SALOME::BAD_PARAM); + if ( theGroup1->GetType() != theGroup2->GetType() ) + THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types", + SALOME::BAD_PARAM); TPythonDump pyDump; // Create Intersection aResGrp = CreateGroup( theGroup1->GetType(), theName ); if ( aResGrp->_is_nil() ) - return aResGrp; - - SMESH::long_array_var anIds1 = theGroup1->GetListOfID(); - SMESH::long_array_var anIds2 = theGroup2->GetListOfID(); - - TColStd_MapOfInteger aMap1; + return aResGrp._retn(); - for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ ) - aMap1.Add( anIds1[ i1 ] ); + SMESHDS_GroupBase* groupDS1 = 0; + if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 )) + groupDS1 = grp_i->GetGroupDS(); - TColStd_SequenceOfInteger aSeq; - for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ ) - if ( aMap1.Contains( anIds2[ i2 ] ) ) - aSeq.Append( anIds2[ i2 ] ); + SMESHDS_GroupBase* groupDS2 = 0; + if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 )) + groupDS2 = grp_i->GetGroupDS(); - SMESH::long_array_var aResIds = new SMESH::long_array; - aResIds->length( aSeq.Length() ); - for ( size_t resI = 0, resN = aSeq.Length(); resI < resN; resI++ ) - aResIds[ resI ] = aSeq( resI + 1 ); - aResGrp->Add( aResIds ); + SMESHDS_Group* resGroupDS = 0; + if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp )) + resGroupDS = dynamic_cast( grp_i->GetGroupDS() ); + if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() ) + { + SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements(); + while ( elemIt1->more() ) + { + const SMDS_MeshElement* e = elemIt1->next(); + if ( groupDS2->Contains( e )) + resGroupDS->SMDSGroup().Add( e ); + } + } // Update Python script - pyDump << aResGrp << " = " << _this() << ".IntersectGroups( " + pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "')"; SMESH_CATCH( SMESH::throwCorbaException ); @@ -1337,7 +1471,7 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr //============================================================================= /*! - \brief Intersect list of groups. New group is created. All mesh elements that + \brief Intersect list of groups. New group is created. All mesh elements that are present in all initial groups simultaneously are added to the new one. \param theGroups list of groups \param theName name of group to be created @@ -1352,72 +1486,69 @@ SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups, SMESH::SMESH_Group_var aResGrp; SMESH_TRY; + if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); if ( !theName ) return SMESH::SMESH_Group::_nil(); - NCollection_DataMap< int, int > anIdToCount; + // check types and get SMESHDS_GroupBase's SMESH::ElementType aType = SMESH::ALL; + vector< SMESHDS_GroupBase* > groupVec; for ( int g = 0, n = theGroups.length(); g < n; g++ ) { SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ]; if ( CORBA::is_nil( aGrp ) ) continue; - - // check type - SMESH::ElementType aCurrType = aGrp->GetType(); if ( aType == SMESH::ALL ) - aType = aCurrType; - else - { - if ( aType != aCurrType ) - return SMESH::SMESH_Group::_nil(); - } - - // calculates number of occurance ids in groups - SMESH::long_array_var aCurrIds = aGrp->GetListOfID(); - for ( int i = 0, n = aCurrIds->length(); i < n; i++ ) - { - int aCurrId = aCurrIds[ i ]; - if ( !anIdToCount.IsBound( aCurrId ) ) - anIdToCount.Bind( aCurrId, 1 ); - else - anIdToCount( aCurrId ) = anIdToCount( aCurrId ) + 1; - } - } + aType = aGrp->GetType(); + else if ( aType != aGrp->GetType() ) + THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types", + SALOME::BAD_PARAM); - // create map of ids - int nbGrp = theGroups.length(); - vector< int > anIds; - NCollection_DataMap< int, int >::Iterator anIter( anIdToCount ); - for ( ; anIter.More(); anIter.Next() ) - { - int aCurrId = anIter.Key(); - int aCurrNb = anIter.Value(); - if ( aCurrNb == nbGrp ) - anIds.push_back( aCurrId ); + if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp )) + if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() ) + { + if ( grpDS->IsEmpty() ) + { + groupVec.clear(); + break; + } + groupVec.push_back( grpDS ); + } } + if ( aType == SMESH::ALL ) // all groups are nil + return SMESH::SMESH_Group::_nil(); TPythonDump pyDump; - // Create group + // Create a group aResGrp = CreateGroup( aType, theName ); - if ( aResGrp->_is_nil() ) - return SMESH::SMESH_Group::_nil(); - // Create array of identifiers - SMESH::long_array_var aResIds = new SMESH::long_array; - aResIds->length( anIds.size() ); + SMESHDS_Group* resGroupDS = 0; + if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp )) + resGroupDS = dynamic_cast( grp_i->GetGroupDS() ); + if ( !resGroupDS || groupVec.empty() ) + return aResGrp._retn(); + + // Fill the group + size_t i, nb = groupVec.size(); + SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements(); + while ( elemIt1->more() ) + { + const SMDS_MeshElement* e = elemIt1->next(); + bool inAll = true; + for ( i = 1; ( i < nb && inAll ); ++i ) + inAll = groupVec[i]->Contains( e ); - for ( size_t i = 0; iAdd( aResIds ); + if ( inAll ) + resGroupDS->SMDSGroup().Add( e ); + } // Update Python script - pyDump << aResGrp << " = " << _this() << ".IntersectListOfGroups( " - << &theGroups << ", '" << theName << "' )"; + pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() ) + << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )"; SMESH_CATCH( SMESH::throwCorbaException ); @@ -1425,11 +1556,12 @@ SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups, } //============================================================================= -/*! CutGroups +/*! * New group is created. All mesh elements that are present in - * main group but do not present in tool group are added to the new one + * a main group but is not present in a tool group are added to the new one */ //============================================================================= + SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1, SMESH::SMESH_GroupBase_ptr theGroup2, const char* theName ) @@ -1438,44 +1570,47 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGr SMESH::SMESH_Group_var aResGrp; SMESH_TRY; + if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - if ( theGroup1->_is_nil() || theGroup2->_is_nil() || - theGroup1->GetType() != theGroup2->GetType() ) - return SMESH::SMESH_Group::_nil(); - + if ( theGroup1->_is_nil() || theGroup2->_is_nil() ) + THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group", + SALOME::BAD_PARAM); + if ( theGroup1->GetType() != theGroup2->GetType() ) + THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types", + SALOME::BAD_PARAM); TPythonDump pyDump; - // Perform Cutting aResGrp = CreateGroup( theGroup1->GetType(), theName ); if ( aResGrp->_is_nil() ) - return aResGrp; - - SMESH::long_array_var anIds1 = theGroup1->GetListOfID(); - SMESH::long_array_var anIds2 = theGroup2->GetListOfID(); - - TColStd_MapOfInteger aMap2; - - for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ ) - aMap2.Add( anIds2[ i2 ] ); + return aResGrp._retn(); - TColStd_SequenceOfInteger aSeq; - for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ ) - if ( !aMap2.Contains( anIds1[ i1 ] ) ) - aSeq.Append( anIds1[ i1 ] ); + SMESHDS_GroupBase* groupDS1 = 0; + if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 )) + groupDS1 = grp_i->GetGroupDS(); - SMESH::long_array_var aResIds = new SMESH::long_array; - aResIds->length( aSeq.Length() ); + SMESHDS_GroupBase* groupDS2 = 0; + if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 )) + groupDS2 = grp_i->GetGroupDS(); - for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ ) - aResIds[ resI ] = aSeq( resI + 1 ); - aResGrp->Add( aResIds ); + SMESHDS_Group* resGroupDS = 0; + if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp )) + resGroupDS = dynamic_cast( grp_i->GetGroupDS() ); + if ( groupDS1 && groupDS2 && resGroupDS ) + { + SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements(); + while ( elemIt1->more() ) + { + const SMDS_MeshElement* e = elemIt1->next(); + if ( !groupDS2->Contains( e )) + resGroupDS->SMDSGroup().Add( e ); + } + } // Update Python script - pyDump << aResGrp << " = " << _this() << ".CutGroups( " - << theGroup1 << ", " << theGroup2 << ", '" - << theName << "' )"; + pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( " + << theGroup1 << ", " << theGroup2 << ", '" << theName << "')"; SMESH_CATCH( SMESH::throwCorbaException ); @@ -1484,7 +1619,7 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGr //============================================================================= /*! - \brief Cut lists of groups. New group is created. All mesh elements that are + \brief Cut lists of groups. New group is created. All mesh elements that are present in main groups but do not present in tool groups are added to the new one \param theMainGroups list of main groups \param theToolGroups list of tool groups @@ -1493,122 +1628,142 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGr */ //============================================================================= SMESH::SMESH_Group_ptr -SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups, - const SMESH::ListOfGroups& theToolGroups, +SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups, + const SMESH::ListOfGroups& theToolGroups, const char* theName ) throw (SALOME::SALOME_Exception) { SMESH::SMESH_Group_var aResGrp; SMESH_TRY; + if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); if ( !theName ) return SMESH::SMESH_Group::_nil(); - set< int > aToolIds; + // check types and get SMESHDS_GroupBase's SMESH::ElementType aType = SMESH::ALL; - int g, n; - // iterate through tool groups - for ( g = 0, n = theToolGroups.length(); g < n; g++ ) + vector< SMESHDS_GroupBase* > toolGroupVec; + vector< SMDS_ElemIteratorPtr > mainIterVec; + + for ( int g = 0, n = theMainGroups.length(); g < n; g++ ) { - SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ]; + SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ]; if ( CORBA::is_nil( aGrp ) ) continue; - - // check type - SMESH::ElementType aCurrType = aGrp->GetType(); if ( aType == SMESH::ALL ) - aType = aCurrType; - else - { - if ( aType != aCurrType ) - return SMESH::SMESH_Group::_nil(); - } - - // unite tool ids - SMESH::long_array_var aCurrIds = aGrp->GetListOfID(); - for ( int i = 0, n = aCurrIds->length(); i < n; i++ ) - { - int aCurrId = aCurrIds[ i ]; - aToolIds.insert( aCurrId ); - } + aType = aGrp->GetType(); + else if ( aType != aGrp->GetType() ) + THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types", + SALOME::BAD_PARAM); + if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp )) + if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() ) + if ( !grpDS->IsEmpty() ) + mainIterVec.push_back( grpDS->GetElements() ); } + if ( aType == SMESH::ALL ) // all main groups are nil + return SMESH::SMESH_Group::_nil(); + if ( mainIterVec.empty() ) // all main groups are empty + return aResGrp._retn(); - vector< int > anIds; // result - - // Iterate through main group - for ( g = 0, n = theMainGroups.length(); g < n; g++ ) + for ( int g = 0, n = theToolGroups.length(); g < n; g++ ) { - SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ]; + SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ]; if ( CORBA::is_nil( aGrp ) ) continue; - - // check type - SMESH::ElementType aCurrType = aGrp->GetType(); - if ( aType == SMESH::ALL ) - aType = aCurrType; - else - { - if ( aType != aCurrType ) - return SMESH::SMESH_Group::_nil(); - } - - // unite tool ids - SMESH::long_array_var aCurrIds = aGrp->GetListOfID(); - for ( int i = 0, n = aCurrIds->length(); i < n; i++ ) - { - int aCurrId = aCurrIds[ i ]; - if ( !aToolIds.count( aCurrId ) ) - anIds.push_back( aCurrId ); - } - } + if ( aType != aGrp->GetType() ) + THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types", + SALOME::BAD_PARAM); + if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp )) + if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() ) + toolGroupVec.push_back( grpDS ); + } TPythonDump pyDump; - // Create group + // Create a group aResGrp = CreateGroup( aType, theName ); - if ( aResGrp->_is_nil() ) - return SMESH::SMESH_Group::_nil(); - // Create array of identifiers - SMESH::long_array_var aResIds = new SMESH::long_array; - aResIds->length( anIds.size() ); + SMESHDS_Group* resGroupDS = 0; + if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp )) + resGroupDS = dynamic_cast( grp_i->GetGroupDS() ); + if ( !resGroupDS ) + return aResGrp._retn(); + + // Fill the group + size_t i, nb = toolGroupVec.size(); + SMDS_ElemIteratorPtr mainElemIt + ( new SMDS_IteratorOnIterators + < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec )); + while ( mainElemIt->more() ) + { + const SMDS_MeshElement* e = mainElemIt->next(); + bool isIn = false; + for ( i = 0; ( i < nb && !isIn ); ++i ) + isIn = toolGroupVec[i]->Contains( e ); - for (int i=0; iAdd( aResIds ); + if ( !isIn ) + resGroupDS->SMDSGroup().Add( e ); + } // Update Python script - pyDump << aResGrp << " = " << _this() << ".CutListOfGroups( " - << &theMainGroups << ", " << &theToolGroups << ", '" - << theName << "' )"; + pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() ) + << ".CutListOfGroups( " << theMainGroups << ", " + << theToolGroups << ", '" << theName << "' )"; SMESH_CATCH( SMESH::throwCorbaException ); return aResGrp._retn(); } +namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM +{ + bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners, + bool & toStopChecking ) + { + toStopChecking = ( nbCommon < nbChecked ); + return nbCommon == nbNodes; + } + bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners, + bool & toStopChecking ) + { + toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners ); + return nbCommon == nbCorners; + } + bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners, + bool & toStopChecking ) + { + return nbCommon > 0; + } + bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners, + bool & toStopChecking ) + { + return nbCommon >= (nbNodes+1) / 2; + } +} + //============================================================================= /*! - \brief Create groups of entities from existing groups of superior dimensions - System - 1) extract all nodes from each group, - 2) combine all elements of specified dimension laying on these nodes. - \param theGroups list of source groups - \param theElemType dimension of elements - \param theName name of new group - \return pointer on new group - * - IMP 19939 + * Create a group of entities basing on nodes of other groups. + * \param [in] theGroups - list of either groups, sub-meshes or filters. + * \param [in] anElemType - a type of elements to include to the new group. + * \param [in] theName - a name of the new group. + * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group. + * \param [in] theUnderlyingOnly - if \c True, an element is included to the + * new group provided that it is based on nodes of an element of \a aListOfGroups + * \return SMESH_Group - the created group */ +// IMP 19939, bug 22010, IMP 22635 //============================================================================= SMESH::SMESH_Group_ptr -SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups, - SMESH::ElementType theElemType, - const char* theName ) +SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups, + SMESH::ElementType theElemType, + const char* theName, + SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes, + CORBA::Boolean theUnderlyingOnly) throw (SALOME::SALOME_Exception) { SMESH::SMESH_Group_var aResGrp; @@ -1624,6 +1779,17 @@ SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups, SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType; + bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop); + SMESH_Comment nbCoNoStr( "SMESH."); + switch ( theNbCommonNodes ) { + case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break; + case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break; + case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break; + case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break; + default: return aResGrp._retn(); + } + int nbChecked, nbCommon, nbNodes, nbCorners; + // Create a group TPythonDump pyDump; @@ -1636,14 +1802,19 @@ SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups, SMESH::DownCast( aResGrp )->GetGroupDS(); SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup(); + vector isNodeInGroups; + for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups { - SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ]; + SMESH::SMESH_IDSource_var aGrp = theGroups[ g ]; if ( CORBA::is_nil( aGrp ) ) continue; + SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh(); + if ( mesh->_is_nil() || mesh->GetId() != this->GetId() ) + continue; - groupBaseDS = SMESH::DownCast( aGrp )->GetGroupDS(); - SMDS_ElemIteratorPtr elIt = groupBaseDS->GetElements(); + SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL ); + if ( !elIt ) continue; if ( theElemType == SMESH::NODE ) // get all nodes of elements { @@ -1654,30 +1825,93 @@ SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups, resGroupCore.Add( nIt->next() ); } } - else // get elements of theElemType based on nodes of every element of group + // get elements of theElemType based on nodes of every element of group + else if ( theUnderlyingOnly ) { while ( elIt->more() ) { - const SMDS_MeshElement* el = elIt->next(); // an element of group + const SMDS_MeshElement* el = elIt->next(); // an element of ref group TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() ); TIDSortedElemSet checkedElems; - SMDS_ElemIteratorPtr nIt = el->nodesIterator(); + SMDS_NodeIteratorPtr nIt = el->nodeIterator(); while ( nIt->more() ) { - const SMDS_MeshNode* n = static_cast( nIt->next() ); + const SMDS_MeshNode* n = nIt->next(); SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType ); // check nodes of elements of theElemType around el while ( elOfTypeIt->more() ) { const SMDS_MeshElement* elOfType = elOfTypeIt->next(); if ( !checkedElems.insert( elOfType ).second ) continue; - + nbNodes = elOfType->NbNodes(); + nbCorners = elOfType->NbCornerNodes(); + nbCommon = 0; + bool toStopChecking = false; SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator(); - bool allNodesOK = true; - while ( nIt2->more() && allNodesOK ) - allNodesOK = elNodes.count( nIt2->next() ); - if ( allNodesOK ) - resGroupCore.Add( elOfType ); + for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked ) + if ( elNodes.count( nIt2->next() ) && + isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking )) + { + resGroupCore.Add( elOfType ); + break; + } + } + } + } + } + // get all nodes of elements of groups + else + { + while ( elIt->more() ) + { + const SMDS_MeshElement* el = elIt->next(); // an element of group + SMDS_NodeIteratorPtr nIt = el->nodeIterator(); + while ( nIt->more() ) + { + const SMDS_MeshNode* n = nIt->next(); + if ( n->GetID() >= (int) isNodeInGroups.size() ) + isNodeInGroups.resize( n->GetID() + 1, false ); + isNodeInGroups[ n->GetID() ] = true; + } + } + } + } + + // Get elements of theElemType based on a certain number of nodes of elements of groups + if ( !theUnderlyingOnly && !isNodeInGroups.empty() ) + { + const SMDS_MeshNode* n; + vector isElemChecked( aMeshDS->MaxElementID() + 1 ); + const int isNodeInGroupsSize = isNodeInGroups.size(); + for ( int iN = 0; iN < isNodeInGroupsSize; ++iN ) + { + if ( !isNodeInGroups[ iN ] || + !( n = aMeshDS->FindNode( iN ))) + continue; + + // check nodes of elements of theElemType around n + SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType ); + while ( elOfTypeIt->more() ) + { + const SMDS_MeshElement* elOfType = elOfTypeIt->next(); + vector::reference isChecked = isElemChecked[ elOfType->GetID() ]; + if ( isChecked ) + continue; + isChecked = true; + + nbNodes = elOfType->NbNodes(); + nbCorners = elOfType->NbCornerNodes(); + nbCommon = 0; + bool toStopChecking = false; + SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator(); + for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked ) + { + const int nID = nIt->next()->GetID(); + if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] && + isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking )) + { + resGroupCore.Add( elOfType ); + break; } } } @@ -1685,14 +1919,99 @@ SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups, } // Update Python script - pyDump << aResGrp << " = " << _this() << ".CreateDimGroup( " - << &theGroups << ", " << theElemType << ", '" << theName << "' )"; + pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this()) + << ".CreateDimGroup( " + << theGroups << ", " << theElemType << ", '" << theName << "', " + << nbCoNoStr << ", " << theUnderlyingOnly << ")"; SMESH_CATCH( SMESH::throwCorbaException ); return aResGrp._retn(); } +//================================================================================ +/*! + * \brief Distribute all faces of the mesh between groups using sharp edges and optionally + * existing 1D elements as group boundaries. + * \param [in] theSharpAngle - edge is considered sharp if an angle between normals of + * adjacent faces is more than \a sharpAngle in degrees. + * \param [in] theCreateEdges - to create 1D elements for detected sharp edges. + * \param [in] theUseExistingEdges - to use existing edges as group boundaries + * \return ListOfGroups - the created groups + */ +//================================================================================ + +SMESH::ListOfGroups* +SMESH_Mesh_i::FaceGroupsSeparatedByEdges( CORBA::Double theSharpAngle, + CORBA::Boolean theCreateEdges, + CORBA::Boolean theUseExistingEdges ) + throw (SALOME::SALOME_Exception) +{ + if ( theSharpAngle < 0 || theSharpAngle > 180 ) + THROW_SALOME_CORBA_EXCEPTION("Invalid sharp angle, it must be between 0 and 180 degrees", + SALOME::BAD_PARAM); + + SMESH::ListOfGroups_var resultGroups = new SMESH::ListOfGroups; + + TPythonDump pyDump; + + SMESH_TRY; + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + + SMESHDS_Mesh* meshDS = _impl->GetMeshDS(); + + std::vector< SMESH_MeshAlgos::Edge > edges = + SMESH_MeshAlgos::FindSharpEdges( meshDS, theSharpAngle, theUseExistingEdges ); + + if ( theCreateEdges ) + { + std::vector nodes(2); + for ( size_t i = 0; i < edges.size(); ++i ) + { + nodes[0] = edges[i]._node1; + nodes[1] = edges[i]._node2; + if ( meshDS->FindElement( nodes, SMDSAbs_Edge )) + continue; + if ( edges[i]._medium ) + meshDS->AddEdge( edges[i]._node1, edges[i]._node2, edges[i]._medium ); + else + meshDS->AddEdge( edges[i]._node1, edges[i]._node2 ); + } + } + + std::vector< std::vector< const SMDS_MeshElement* > > faceGroups = + SMESH_MeshAlgos::SeparateFacesByEdges( meshDS, edges ); + + SMESH::SMESH_MeshEditor_var editor = GetMeshEditor(); // create _editor + + resultGroups->length( faceGroups.size() ); + for ( size_t iG = 0; iG < faceGroups.size(); ++iG ) + { + SMESH::SMESH_Group_var group = CreateGroup( SMESH::FACE, + _editor->GenerateGroupName("Group").c_str()); + resultGroups[iG] = SMESH::SMESH_Group::_duplicate( group ); + + SMESHDS_GroupBase* groupBaseDS = + SMESH::DownCast( group )->GetGroupDS(); + SMDS_MeshGroup& groupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup(); + + std::vector< const SMDS_MeshElement* >& faces = faceGroups[ iG ]; + for ( size_t i = 0; i < faces.size(); ++i ) + groupCore.Add( faces[i] ); + } + + pyDump << resultGroups << " = " << SMESH::SMESH_Mesh_var(_this()) + << ".FaceGroupsSeparatedByEdges( " + << TVar( theSharpAngle ) << ", " + << theCreateEdges << ", " + << theUseExistingEdges << " )"; + + SMESH_CATCH( SMESH::throwCorbaException ); + return resultGroups._retn(); + +} + //================================================================================ /*! * \brief Remember GEOM group data @@ -1705,14 +2024,12 @@ void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj, if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP ) return; // group SO - SALOMEDS::Study_var study = _gen_i->GetCurrentStudy(); - SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study, theGeomObj ); + SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( theGeomObj ); if ( groupSO->_is_nil() ) return; // group indices - GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine(); - GEOM::GEOM_IGroupOperations_wrap groupOp = - geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() ); + GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( theGeomObj ); + GEOM::GEOM_IGroupOperations_ptr groupOp = geomGen->GetIGroupOperations(); GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj ); // store data @@ -1722,10 +2039,13 @@ void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj, CORBA::String_var entry = groupSO->GetID(); groupData._groupEntry = entry.in(); // indices - for ( int i = 0; i < ids->length(); ++i ) + for ( CORBA::ULong i = 0; i < ids->length(); ++i ) groupData._indices.insert( ids[i] ); // SMESH object - groupData._smeshObject = theSmeshObj; + groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj ); + // shape index in SMESHDS + // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj ); + // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId(); } //================================================================================ @@ -1751,43 +2071,58 @@ void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj) * \brief Return new group contents if it has been changed and update group data */ //================================================================================ +enum { ONLY_IF_CHANGED, IS_BREAK_LINK, MAIN_TRANSFORMED }; -TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData) +TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData, int how ) { TopoDS_Shape newShape; - // get geom group - SALOMEDS::Study_var study = _gen_i->GetCurrentStudy(); - if ( study->_is_nil() ) return newShape; // means "not changed" - SALOMEDS::SObject_wrap groupSO = study->FindObjectID( groupData._groupEntry.c_str() ); - if ( !groupSO->_is_nil() ) + if ( how == IS_BREAK_LINK ) { - 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_wrap 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 ); + SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( groupData._smeshObject ); + 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 ); + 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(); + } + } + else + { + // get geom group + SALOMEDS::SObject_wrap groupSO = SMESH_Gen_i::getStudyServant()->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( 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; + CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup ); + geomClient->RemoveShapeFromBuffer( groupIOR.in() ); + newShape = _gen_i->GeomObjectToShape( geomGroup ); + } } - if ( newShape.IsNull() ) { // geom group becomes empty - return empty compound TopoDS_Compound compound; @@ -1799,33 +2134,490 @@ TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData) 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 Data to re-create a group on geometry + */ + struct TGroupOnGeomData + { + int _oldID; + 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; + } +} + +//============================================================================= +/*! + * \brief Update data if geometry changes + * + * Issue 0022501 + */ +//============================================================================= + +void SMESH_Mesh_i::CheckGeomModif( bool isBreakLink ) +{ + SMESH::SMESH_Mesh_var me = _this(); + GEOM::GEOM_Object_var mainGO = GetShapeToMesh(); + + TPythonDump dumpNothing; // prevent any dump + + //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; + + + // Update after group modification + + 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; + } + + // Update after shape modification + + GEOM_Client* geomClient = _gen_i->GetShapeReader(); + if ( !geomClient ) return; + GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( mainGO ); + if ( geomGen->_is_nil() ) return; + + CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO ); + geomClient->RemoveShapeFromBuffer( ior.in() ); + + // 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) + + if ( _preMeshInfo ) + _preMeshInfo->ForgetAllData(); + + + if (isBreakLink) + _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 + std::vector< TGroupOnGeomData > groupsData; + const std::set& groups = meshDS->GetGroups(); + groupsData.reserve( groups.size() ); + TopTools_DataMapOfShapeShape old2newShapeMap; + std::set::const_iterator g = groups.begin(); + for ( ; g != groups.end(); ++g ) + { + if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g )) + { + 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() ) + { + if ( isBreakLink ) + { + SALOMEDS::SObject_wrap grpSO = _gen_i->ObjectToSObject( gog ); + SALOMEDS::SObject_wrap geomRefSO, geomSO; + if ( !grpSO->_is_nil() && + grpSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) && + geomRefSO->ReferencedObject( geomSO.inout() )) + { + CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO ); + geom = GEOM::GEOM_Object::_narrow( geomObj ); + } + } + else + { + 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 ); + old2newShapeMap.Bind( group->GetShape(), groupsData.back()._shape ); + } + else if ( old2newShapeMap.IsBound( group->GetShape() )) + { + groupsData.back()._shape = old2newShapeMap( group->GetShape() ); + } + } + } + // store assigned hypotheses + std::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 )); + } + + std::map< std::set, int > ii2iMap; // group sub-ids to group id in SMESHDS + + // count shapes excluding compounds corresponding to geom groups + int oldNbSubShapes = meshDS->MaxShapeIndex(); + for ( ; oldNbSubShapes > 0; --oldNbSubShapes ) + { + const TopoDS_Shape& s = meshDS->IndexToShape( oldNbSubShapes ); + if ( s.IsNull() || s.ShapeType() != TopAbs_COMPOUND ) + break; + // fill ii2iMap + std::set subIds; + for ( TopoDS_Iterator it( s ); it.More(); it.Next() ) + subIds.insert( meshDS->ShapeToIndex( it.Value() )); + ii2iMap.insert( std::make_pair( subIds, oldNbSubShapes )); + } + + // check if shape topology changes - save shape type per shape ID + std::vector< TopAbs_ShapeEnum > shapeTypes( Max( oldNbSubShapes + 1, 1 )); + for ( int shapeID = oldNbSubShapes; shapeID > 0; --shapeID ) + shapeTypes[ shapeID ] = meshDS->IndexToShape( shapeID ).ShapeType(); + + // change shape to mesh + _impl->ShapeToMesh( TopoDS_Shape() ); + _impl->ShapeToMesh( newShape ); + + // check if shape topology changes - check new shape types + bool sameTopology = ( oldNbSubShapes == meshDS->MaxShapeIndex() ); + for ( int shapeID = oldNbSubShapes; shapeID > 0 && sameTopology; --shapeID ) + { + const TopoDS_Shape& s = meshDS->IndexToShape( shapeID ); + sameTopology = ( !s.IsNull() && s.ShapeType() == shapeTypes[ shapeID ]); + } + + // re-add shapes (compounds) of geom groups + std::map< int, int > old2newIDs; // group IDs + std::list::iterator data = _geomGroupData.begin(); + for ( ; data != _geomGroupData.end(); ++data ) + { + int oldID = 0; + std::map< std::set, int >::iterator ii2i = ii2iMap.find( data->_indices ); + if ( ii2i != ii2iMap.end() ) + oldID = ii2i->second; + + 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 + { + TopoDS_Compound compound; + BRep_Builder().MakeCompound( compound ); + BRep_Builder().Add( compound, newShape ); + newShape = compound; + } + int newID = _impl->GetSubMesh( newShape )->GetId(); + if ( oldID && oldID != newID ) + old2newIDs.insert( std::make_pair( oldID, 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; + const TopoDS_Shape& s = meshDS->IndexToShape( sID ); + 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 ) + { + const TGroupOnGeomData& data = groupsData[i]; + if ( data._shape.IsNull() ) + continue; + + 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; + + 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 ); + } + + std::map< int, int >::iterator o2n = old2newIDs.begin(); + for ( ; o2n != old2newIDs.end(); ++o2n ) + { + int newID = o2n->second, oldID = o2n->first; + if ( !_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 ); + } + + // update _mapSubMesh + std::map::iterator i_sm = _mapSubMesh.begin(); + for ( ; i_sm != _mapSubMesh.end(); ++i_sm ) + i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first )); + } + + _gen_i->UpdateIcons( me ); + + if ( !isBreakLink ) + { + SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me ); + if ( !meshSO->_is_nil() ) + _gen_i->SetPixMap(meshSO, "ICON_SMESH_TREE_GEOM_MODIF"); + } } + //============================================================================= /*! * \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 modify mesh computation * issue 0020210: Update of a smesh group after modification of the associated geom group */ //============================================================================= void SMESH_Mesh_i::CheckGeomGroupModif() { - if ( !_impl->HasShapeToMesh() ) return; + // 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 ); + } + } + } - SALOMEDS::Study_var study = _gen_i->GetCurrentStudy(); - if ( study->_is_nil() ) return; + + if ( !_impl->HasShapeToMesh() ) return; CORBA::Long nbEntities = NbNodes() + NbElements(); @@ -1843,7 +2635,7 @@ void SMESH_Mesh_i::CheckGeomGroupModif() bool processedGroup = !it_new.second; TopoDS_Shape& newShape = it_new.first->second; if ( !processedGroup ) - newShape = newGroupShape( *data ); + newShape = newGroupShape( *data, ONLY_IF_CHANGED ); if ( newShape.IsNull() ) continue; // no changes @@ -1862,7 +2654,7 @@ void SMESH_Mesh_i::CheckGeomGroupModif() if ( !submesh->_is_nil() ) // -------------- Sub mesh --------------------- { int oldID = submesh->GetId(); - if ( _mapSubMeshIor.find( oldID ) == _mapSubMeshIor.end() ) + if ( !_mapSubMeshIor.count( oldID )) continue; TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape(); @@ -1971,9 +2763,11 @@ void SMESH_Mesh_i::CheckGeomGroupModif() 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 + // set new shape to mesh -> DS of sub-meshes and geom groups is deleted + _impl->Clear(); + _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730 _impl->ShapeToMesh( newShape ); - + // reassign hypotheses TShapeHypList::iterator indS_hyps = assignedHyps.begin(); for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps ) @@ -1990,7 +2784,7 @@ void SMESH_Mesh_i::CheckGeomGroupModif() continue; for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt ) _impl->AddHypothesis( geom._shape, (*hypIt)->GetID()); - // care of submeshes + // care of sub-meshes SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape ); if ( newID != oldID ) { _mapSubMesh [ newID ] = newSubmesh; @@ -2011,13 +2805,13 @@ void SMESH_Mesh_i::CheckGeomGroupModif() if ( _mapGroups.find( oldID ) == _mapGroups.end() ) continue; // get group name - SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] ); + SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( _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 ); + if ( SMESH_GroupBase_i* group_i = SMESH::DownCast(_mapGroups[oldID])) + if ( SMESH_Group* group = _impl->AddGroup( geomType->second, name.in(), + /*id=*/-1, geom._shape )) + group_i->changeLocalId( group->GetID() ); } break; // everything has been updated @@ -2032,15 +2826,15 @@ void SMESH_Mesh_i::CheckGeomGroupModif() if ( newNbEntities != nbEntities ) { // Add all SObjects with icons to soToUpdateIcons - soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh + soToUpdateIcons.push_back( _gen_i->ObjectToSObject( _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 )); + soToUpdateIcons.push_back( _gen_i->ObjectToSObject( 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 )); + soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_gr->second )); } list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin(); @@ -2067,14 +2861,13 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase if ( theGroup->_is_nil() ) return aGroup._retn(); - SMESH_GroupBase_i* aGroupToRem = - dynamic_cast( SMESH_Gen_i::GetServant( theGroup ).in() ); + SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast( theGroup ); if ( !aGroupToRem ) return aGroup._retn(); const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup )); - int anId = aGroupToRem->GetLocalID(); + const int anId = aGroupToRem->GetLocalID(); if ( !_impl->ConvertToStandalone( anId ) ) return aGroup._retn(); removeGeomGroupData( theGroup ); @@ -2082,32 +2875,35 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId ); // remove old instance of group from own map + { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object _mapGroups.erase( anId ); SALOMEDS::StudyBuilder_var builder; - SALOMEDS::SObject_wrap aGroupSO; - SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy(); + SALOMEDS::SObject_wrap aGroupSO; + SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant(); if ( !aStudy->_is_nil() ) { builder = aStudy->NewBuilder(); - aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup ); + aGroupSO = _gen_i->ObjectToSObject( theGroup ); if ( !aGroupSO->_is_nil() ) { // 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 << " = " << _this() << ".ConvertToStandalone( " - << aGroupSO << " )"; + TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this()) + << ".ConvertToStandalone( " << aGroupSO << " )"; // 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" ); @@ -2126,7 +2922,9 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase _gen_i->RegisterObject( aGroup ); CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup ); - builder->SetIOR( aGroupSO, ior.in() ); + builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register(); + //aGroup->Register(); + aGroupToRem->UnRegister(); SMESH_CATCH( SMESH::throwCorbaException ); @@ -2142,25 +2940,43 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject ) { if(MYDEBUG) MESSAGE( "createSubMesh" ); - TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject); - + TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject); ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape); - int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape ); - SMESH_subMesh_i *subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId); - SMESH::SMESH_subMesh_var subMesh - = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this()); + int subMeshId = 0; - _mapSubMesh[subMeshId] = mySubMesh; - _mapSubMesh_i[subMeshId] = subMeshServant; - _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate(subMesh); + SMESH_subMesh_i * subMeshServant; + if ( mySubMesh ) + { + subMeshId = mySubMesh->GetId(); + subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId); + } + else // "invalid sub-mesh" + { + // The invalid sub-mesh is created for the case where a valid sub-shape not found + // by SMESH_Gen_i::CopyMeshWithGeom(). The invalid sub-mesh has GetId() < 0. + if ( _mapSubMesh.empty() ) + subMeshId = -1; + else + subMeshId = _mapSubMesh.begin()->first - 1; + subMeshServant = new SMESH_Invalid_subMesh_i(myPOA, _gen_i, this, subMeshId, theSubShapeObject); + } + + SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this(); + + _mapSubMesh [subMeshId] = mySubMesh; + _mapSubMesh_i [subMeshId] = subMeshServant; + _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh ); + + subMeshServant->Register(); // register CORBA object for persistence int nextId = _gen_i->RegisterObject( subMesh ); if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); } - else { nextId = 0; } // avoid "unused variable" warning in release mode + else { nextId = 0; } // avoid "unused variable" warning // to track changes of GEOM groups - addGeomGroupData( theSubShapeObject, subMesh ); + if ( subMeshId > 0 ) + addGeomGroupData( theSubShapeObject, subMesh ); return subMesh._retn(); } @@ -2179,7 +2995,6 @@ SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID) return SMESH::SMESH_subMesh::_duplicate( (*it).second ); } - //============================================================================= /*! * @@ -2193,16 +3008,21 @@ bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh, if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ ) return isHypChanged; + const int subMeshId = theSubMesh->GetId(); + if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617) { - CORBA::Long shapeId = theSubMesh->GetId(); - if ( _mapSubMesh.find( shapeId ) != _mapSubMesh.end()) + SMESH_subMesh* sm; + if (( _mapSubMesh.count( subMeshId )) && + ( sm = _impl->GetSubMeshContaining( subMeshId ))) { - TopoDS_Shape S = _mapSubMesh[ shapeId ]->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()); @@ -2223,7 +3043,16 @@ bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh, } removeGeomGroupData( theSubShapeObject ); } - int subMeshId = theSubMesh->GetId(); + + // remove a servant + std::map::iterator id_smi = _mapSubMesh_i.find( subMeshId ); + if ( id_smi != _mapSubMesh_i.end() ) + id_smi->second->UnRegister(); + + // remove a CORBA object + std::map::iterator id_smptr = _mapSubMeshIor.find( subMeshId ); + if ( id_smptr != _mapSubMeshIor.end() ) + SMESH::SMESH_subMesh_var( id_smptr->second ); _mapSubMesh.erase(subMeshId); _mapSubMesh_i.erase(subMeshId); @@ -2240,25 +3069,30 @@ bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh, SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType, const char* theName, + const int theID, const TopoDS_Shape& theShape, const SMESH_PredicatePtr& thePredicate ) { std::string newName; - if ( !theName || strlen( theName ) == 0 ) + if ( !theName || !theName[0] ) { std::set< std::string > presentNames; std::map::const_iterator i_gr = _mapGroups.begin(); for ( ; i_gr != _mapGroups.end(); ++i_gr ) - presentNames.insert( i_gr->second->GetName() ); + { + CORBA::String_var name = i_gr->second->GetName(); + presentNames.insert( name.in() ); + } do { newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 ); } while ( !presentNames.insert( newName ).second ); theName = newName.c_str(); } - int anId; SMESH::SMESH_GroupBase_var aGroup; - if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate )) + if ( SMESH_Group* g = _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, + theID, theShape, thePredicate )) { + int anId = g->GetID(); SMESH_GroupBase_i* aGroupImpl; if ( !theShape.IsNull() ) aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId ); @@ -2267,13 +3101,14 @@ SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType else aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId ); - aGroup = SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() ); + aGroup = aGroupImpl->_this(); _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup ); + aGroupImpl->Register(); // register CORBA object for persistence int nextId = _gen_i->RegisterObject( aGroup ); if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); } - else { nextId = 0; } // avoid "unused variable" warning in release mode + else { nextId = ( nextId > 0 ); } // avoid "unused variable" warning in release mode // to track changes of GEOM groups if ( !theShape.IsNull() ) { @@ -2296,14 +3131,15 @@ void SMESH_Mesh_i::removeGroup( const int theId ) { if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" ); if ( _mapGroups.find( theId ) != _mapGroups.end() ) { - SMESH::SMESH_GroupBase_ptr group = _mapGroups[theId]; + SMESH::SMESH_GroupBase_var group = _mapGroups[theId]; _mapGroups.erase( theId ); removeGeomGroupData( group ); - if (! _impl->RemoveGroup( theId )) + if ( !_impl->RemoveGroup( theId )) { // it seems to be a call up from _impl caused by hyp modification (issue 0020918) RemoveGroup( group ); } + group->UnRegister(); } } @@ -2393,17 +3229,6 @@ CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception) return _id; } -//============================================================================= -/*! - * - */ -//============================================================================= - -CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception) -{ - return _studyId; -} - //============================================================================= namespace { @@ -2415,21 +3240,56 @@ namespace SMESH_Mesh_i* _mesh; TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {} virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); } - virtual void HypothesisModified () { _mesh->onHypothesisModified(); } + virtual void HypothesisModified( int hypID, + bool updIcons) { _mesh->onHypothesisModified( hypID, + updIcons ); } virtual void Load () { _mesh->Load(); } + virtual bool IsLoaded() { return _mesh->IsLoaded(); } }; } //================================================================================ /*! - * \brief callback from _impl to forget not loaded mesh data (issue 0021208) + * \brief callback from _impl to + * 1) forget not loaded mesh data (issue 0021208) + * 2) mark hypothesis as valid */ //================================================================================ -void SMESH_Mesh_i::onHypothesisModified() +void SMESH_Mesh_i::onHypothesisModified(int theHypID, bool theUpdateIcons) { if ( _preMeshInfo ) _preMeshInfo->ForgetOrLoad(); + + if ( theUpdateIcons ) + { + SMESH::SMESH_Mesh_var mesh = _this(); + _gen_i->UpdateIcons( mesh ); + } + + if ( _nbInvalidHypos != 0 ) + { + // mark a hypothesis as valid after edition + int nbInvalid = 0; + SALOMEDS::SComponent_wrap smeshComp = _gen_i->PublishComponent(); + SALOMEDS::SObject_wrap hypRoot; + if ( !smeshComp->_is_nil() && + smeshComp->FindSubObject( _gen_i->GetHypothesisRootTag(), hypRoot.inout() )) + { + SALOMEDS::ChildIterator_wrap anIter = _gen_i->getStudyServant()->NewChildIterator( hypRoot ); + for ( ; anIter->More(); anIter->Next() ) + { + SALOMEDS::SObject_wrap hypSO = anIter->Value(); + CORBA::Object_var obj = _gen_i->SObjectToObject( hypSO ); + SMESH::SMESH_Hypothesis_var hyp = SMESH::SMESH_Hypothesis::_narrow( obj ); + if ( !hyp->_is_nil() && hyp->GetId() == theHypID ) + _gen_i->HighLightInvalid( hyp, false ); + else + nbInvalid += _gen_i->IsInvalid( hypSO ); + } + } + _nbInvalidHypos = nbInvalid; + } } //============================================================================= @@ -2474,11 +3334,13 @@ SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor() _preMeshInfo->FullLoadFromFile(); // Create MeshEditor - SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, false ); - aMeshEdVar = aMeshEditor->_this(); + if ( !_editor ) + _editor = new SMESH_MeshEditor_i( this, false ); + aMeshEdVar = _editor->_this(); // Update Python script - TPythonDump() << aMeshEditor << " = " << _this() << ".GetMeshEditor()"; + TPythonDump() << _editor << " = " + << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()"; SMESH_CATCH( SMESH::throwCorbaException ); @@ -2500,8 +3362,9 @@ SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer() if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, true ); - aMeshEdVar = aMeshEditor->_this(); + if ( !_previewEditor ) + _previewEditor = new SMESH_MeshEditor_i( this, true ); + aMeshEdVar = _previewEditor->_this(); SMESH_CATCH( SMESH::throwCorbaException ); @@ -2569,7 +3432,7 @@ void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOM _impl->SetAutoColor(theAutoColor); TPythonDump pyDump; // not to dump group->SetColor() from below code - pyDump<<_this()<<".SetAutoColor( "< aReservedColors; map::iterator it = _mapGroups.begin(); @@ -2612,44 +3475,36 @@ CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED() void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite) { - TCollection_AsciiString aFullName ((char*)file); - OSD_Path aPath (aFullName); - OSD_File aFile (aPath); - if (aFile.Exists()) { + SMESH_File aFile( file, false ); + SMESH_Comment msg; + if ( aFile.exists() ) { // existing filesystem node - if (aFile.KindOfFile() == OSD_FILE) { - if (aFile.IsWriteable()) { - if (overwrite) { - aFile.Reset(); - aFile.Remove(); - } - if (aFile.Failed()) { - TCollection_AsciiString msg ("File "); - msg += aFullName + " cannot be replaced."; - THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM); + if ( !aFile.isDirectory() ) { + if ( aFile.openForWriting() ) { + if ( overwrite && ! aFile.remove()) { + msg << "Can't replace " << aFile.getName(); } } else { - TCollection_AsciiString msg ("File "); - msg += aFullName + " cannot be overwritten."; - THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM); + msg << "Can't write into " << aFile.getName(); } } else { - TCollection_AsciiString msg ("Location "); - msg += aFullName + " is not a file."; - THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM); + msg << "Location " << aFile.getName() << " is not a file"; } - } else { + } + else { // nonexisting file; check if it can be created - aFile.Reset(); - aFile.Build(OSD_WriteOnly, OSD_Protection()); - if (aFile.Failed()) { - TCollection_AsciiString msg ("You cannot create the file "); - msg += aFullName + ". Check the directory existance and access rights."; - THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM); - } else { - aFile.Close(); - aFile.Remove(); + if ( !aFile.openForWriting() ) { + msg << "You cannot create the file " + << aFile.getName() + << ". Check the directory existence and access rights"; } + aFile.remove(); + } + + if ( !msg.empty() ) + { + msg << "."; + THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM); } } @@ -2668,9 +3523,9 @@ string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file, // Perform Export PrepareForWriting(file, overwrite); string aMeshName = "Mesh"; - SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy(); + SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant(); if ( !aStudy->_is_nil() ) { - SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() ); + SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() ); if ( !aMeshSO->_is_nil() ) { CORBA::String_var name = aMeshSO->GetName(); aMeshName = name; @@ -2692,7 +3547,8 @@ string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file, } // Update Python script // set name of mesh before export - TPythonDump() << _gen_i << ".SetName(" << _this() << ", '" << aMeshName.c_str() << "')"; + TPythonDump() << _gen_i << ".SetName(" + << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')"; // check names of groups checkGroupNames(); @@ -2702,55 +3558,34 @@ string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file, //================================================================================ /*! - * \brief Export to med file + * \brief Export to MED file */ //================================================================================ -void SMESH_Mesh_i::ExportToMEDX (const char* file, - CORBA::Boolean auto_groups, - SMESH::MED_VERSION theVersion, - CORBA::Boolean overwrite, - CORBA::Boolean autoDimension) +void SMESH_Mesh_i::ExportMED(const char* file, + CORBA::Boolean auto_groups, + CORBA::Long version, + CORBA::Boolean overwrite, + CORBA::Boolean autoDimension) throw(SALOME::SALOME_Exception) { - Unexpect aCatch(SALOME_SalomeException); + //MESSAGE("MED minor version: "<< minor); + SMESH_TRY; if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); string aMeshName = prepareMeshNameAndGroups(file, overwrite); - TPythonDump() << _this() << ".ExportToMEDX( r'" - << file << "', " << auto_groups << ", " - << theVersion << ", " << overwrite << ", " - << autoDimension << " )"; - - _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion, 0, autoDimension ); -} - -//================================================================================ -/*! - * \brief Export a mesh to a med file - */ -//================================================================================ - -void SMESH_Mesh_i::ExportToMED (const char* file, - CORBA::Boolean auto_groups, - SMESH::MED_VERSION theVersion) - throw(SALOME::SALOME_Exception) -{ - ExportToMEDX(file,auto_groups,theVersion,true); -} + _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, 0, autoDimension ); -//================================================================================ -/*! - * \brief Export a mesh to a med file - */ -//================================================================================ + TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'" + << file << "', " + << "auto_groups=" <FullLoadFromFile(); string aMeshName = prepareMeshNameAndGroups(file, true); - TPythonDump() << _this() << ".ExportSAUV( r'" << file << "', " << auto_groups << " )"; + TPythonDump() << SMESH::SMESH_Mesh_var( _this()) + << ".ExportSAUV( r'" << file << "', " << auto_groups << " )"; _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups); } @@ -2789,7 +3625,7 @@ void SMESH_Mesh_i::ExportDAT (const char *file) // Update Python script // check names of groups checkGroupNames(); - TPythonDump() << _this() << ".ExportDAT( r'" << file << "' )"; + TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )"; // Perform Export PrepareForWriting(file); @@ -2812,7 +3648,7 @@ void SMESH_Mesh_i::ExportUNV (const char *file) // Update Python script // check names of groups checkGroupNames(); - TPythonDump() << _this() << ".ExportUNV( r'" << file << "' )"; + TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )"; // Perform Export PrepareForWriting(file); @@ -2835,11 +3671,17 @@ void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii) // Update Python script // check names of groups checkGroupNames(); - TPythonDump() << _this() << ".ExportSTL( r'" << file << "', " << isascii << " )"; + TPythonDump() << SMESH::SMESH_Mesh_var(_this()) + << ".ExportSTL( r'" << file << "', " << isascii << " )"; + + CORBA::String_var name; + SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() ); + if ( !so->_is_nil() ) + name = so->GetName(); // Perform Export - PrepareForWriting(file); - _impl->ExportSTL(file, isascii); + PrepareForWriting( file ); + _impl->ExportSTL( file, isascii, name.in() ); } //================================================================================ @@ -2848,20 +3690,68 @@ void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii) */ //================================================================================ -void SMESH_Mesh_i::ExportPartToMED(::SMESH::SMESH_IDSource_ptr meshPart, - const char* file, - CORBA::Boolean auto_groups, - ::SMESH::MED_VERSION version, - ::CORBA::Boolean overwrite, - ::CORBA::Boolean autoDimension) +void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart, + const char* file, + CORBA::Boolean auto_groups, + CORBA::Long version, + CORBA::Boolean overwrite, + CORBA::Boolean autoDimension, + const GEOM::ListOfFields& fields, + const char* geomAssocFields, + CORBA::Double ZTolerance) throw (SALOME::SALOME_Exception) { - Unexpect aCatch(SALOME_SalomeException); - TPythonDump pyDump; + MESSAGE("MED version: "<< version); + SMESH_TRY; + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + + // check fields + bool have0dField = false; + if ( fields.length() > 0 ) + { + GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh(); + if ( shapeToMesh->_is_nil() ) + THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR ); + + for ( size_t i = 0; i < fields.length(); ++i ) + { + if ( fields[i]->GetDataType() == GEOM::FDT_String ) + THROW_SALOME_CORBA_EXCEPTION + ( "Export of string fields is not supported", SALOME::BAD_PARAM); + GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape(); + if ( fieldShape->_is_nil() ) + THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR ); + if ( !fieldShape->IsSame( shapeToMesh ) ) + THROW_SALOME_CORBA_EXCEPTION + ( "Field defined not on shape", SALOME::BAD_PARAM); + if ( fields[i]->GetDimension() == 0 ) + have0dField = true; + } + if ( geomAssocFields ) + for ( int i = 0; geomAssocFields[i]; ++i ) + switch ( geomAssocFields[i] ) { + case 'v':case 'e':case 'f':case 's': break; + case 'V':case 'E':case 'F':case 'S': break; + default: THROW_SALOME_CORBA_EXCEPTION + ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM); + } + } + + SMESHDS_Mesh* meshDS = _impl->GetMeshDS(); - if ( SMESH_Mesh_i * mesh = SMESH::DownCast< SMESH_Mesh_i* >( meshPart )) + // write mesh + + string aMeshName = "Mesh"; + SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0); + if ( CORBA::is_nil( meshPart ) || + SMESH::DownCast< SMESH_Mesh_i* >( meshPart )) { - mesh->ExportToMEDX( file, auto_groups, version, autoDimension ); + aMeshName = prepareMeshNameAndGroups(file, overwrite); + _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, + 0, autoDimension, /*addODOnVertices=*/have0dField, + ZTolerance); + meshDS = _impl->GetMeshDS(); } else { @@ -2870,21 +3760,320 @@ void SMESH_Mesh_i::ExportPartToMED(::SMESH::SMESH_IDSource_ptr meshPart, PrepareForWriting(file, overwrite); - string aMeshName = "Mesh"; - SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy(); - if ( !aStudy->_is_nil() ) { - SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( aStudy, meshPart ); - if ( !SO->_is_nil() ) { - CORBA::String_var name = SO->GetName(); - aMeshName = name; - } + SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart ); + if ( !SO->_is_nil() ) { + CORBA::String_var name = SO->GetName(); + aMeshName = name; } - SMESH_MeshPartDS partDS( meshPart ); - _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, &partDS, autoDimension ); + + SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart ); + _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, + partDS, autoDimension, /*addODOnVertices=*/have0dField, ZTolerance); + meshDS = tmpDSDeleter._obj = partDS; + } + + // write fields + + if ( _impl->HasShapeToMesh() ) + { + DriverMED_W_Field fieldWriter; + fieldWriter.SetFile( file ); + fieldWriter.SetMeshName( aMeshName ); + fieldWriter.AddODOnVertices( have0dField ); + + exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields ); + } + + // dump + GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO; + goList->length( fields.length() ); + for ( size_t i = 0; i < fields.length(); ++i ) + { + GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] ); + goList[i] = gbo; } - pyDump << _this() << ".ExportPartToMED( " << meshPart << ", r'" << file << "', " - << auto_groups << ", " << version << ", " << overwrite << ", " - << autoDimension << " )"; + TPythonDump() << _this() << ".ExportPartToMED( " + << meshPart << ", r'" + << file << "', " + << auto_groups << ", " + << version << ", " + << overwrite << ", " + << autoDimension << ", " + << goList << ", '" + << ( geomAssocFields ? geomAssocFields : "" ) << "'," + << TVar( ZTolerance ) + << " )"; + + SMESH_CATCH( SMESH::throwCorbaException ); +} + +//================================================================================ +/*! + * Write GEOM fields to MED file + */ +//================================================================================ + +void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter, + SMESHDS_Mesh* meshDS, + const GEOM::ListOfFields& fields, + const char* geomAssocFields) +{ +#define METH "SMESH_Mesh_i::exportMEDFields() " + + if (( fields.length() < 1 ) && + ( !geomAssocFields || !geomAssocFields[0] )) + return; + + std::vector< std::vector< double > > dblVals; + std::vector< std::vector< int > > intVals; + std::vector< int > subIdsByDim[ 4 ]; + const double noneDblValue = 0.; + const double noneIntValue = 0; + + for ( size_t iF = 0; iF < fields.length(); ++iF ) + { + // set field data + + int dim = fields[ iF ]->GetDimension(); + SMDSAbs_ElementType elemType; + TopAbs_ShapeEnum shapeType; + switch ( dim ) { + case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break; + case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break; + case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break; + case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break; + default: + continue; // skip fields on whole shape + } + GEOM::field_data_type dataType = fields[ iF ]->GetDataType(); + if ( dataType == GEOM::FDT_String ) + continue; + GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps(); + if ( stepIDs->length() < 1 ) + continue; + GEOM::string_array_var comps = fields[ iF ]->GetComponents(); + if ( comps->length() < 1 ) + continue; + CORBA::String_var name = fields[ iF ]->GetName(); + + if ( !fieldWriter.Set( meshDS, + name.in(), + elemType, + comps->length(), + /*isIntData=*/false ))//( dataType == GEOM::FDT_Int ))) + continue; + + for ( size_t iC = 0; iC < comps->length(); ++iC ) + fieldWriter.SetCompName( iC, comps[ iC ].in() ); + + dblVals.resize( comps->length() ); + intVals.resize( comps->length() ); + + // find sub-shape IDs + + std::vector< int >& subIds = subIdsByDim[ dim ]; + if ( subIds.empty() ) + for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id ) + if ( meshDS->IndexToShape( id ).ShapeType() == shapeType ) + subIds.push_back( id ); + + // write steps + + SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems(); + if ( !elemIt ) + continue; + + for ( size_t iS = 0; iS < stepIDs->length(); ++iS ) + { + GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]); + if ( step->_is_nil() ) + continue; + + CORBA::Long stamp = step->GetStamp(); + CORBA::Long id = step->GetID(); + fieldWriter.SetDtIt( int( stamp ), int( id )); + + // fill dblVals or intVals + for ( size_t iC = 0; iC < comps->length(); ++iC ) + if ( dataType == GEOM::FDT_Double ) + { + dblVals[ iC ].clear(); + dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 ); + } + else + { + intVals[ iC ].clear(); + intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 ); + } + switch ( dataType ) + { + case GEOM::FDT_Double: + { + GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step ); + if ( dblStep->_is_nil() ) continue; + GEOM::ListOfDouble_var vv = dblStep->GetValues(); + if ( vv->length() != subIds.size() * comps->length() ) + THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR ); + for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS ) + for ( size_t iC = 0; iC < comps->length(); ++iC ) + dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ]; + break; + } + case GEOM::FDT_Int: + { + GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step ); + if ( intStep->_is_nil() ) continue; + GEOM::ListOfLong_var vv = intStep->GetValues(); + if ( vv->length() != subIds.size() * comps->length() ) + THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR ); + for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS ) + for ( size_t iC = 0; iC < comps->length(); ++iC ) + intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ]; + break; + } + case GEOM::FDT_Bool: + { + GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step ); + if ( boolStep->_is_nil() ) continue; + GEOM::short_array_var vv = boolStep->GetValues(); + if ( vv->length() != subIds.size() * comps->length() ) + THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR ); + for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS ) + for ( size_t iC = 0; iC < comps->length(); ++iC ) + intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ]; + break; + } + default: continue; + } + + // pass values to fieldWriter + elemIt = fieldWriter.GetOrderedElems(); + if ( dataType == GEOM::FDT_Double ) + while ( elemIt->more() ) + { + const SMDS_MeshElement* e = elemIt->next(); + const int shapeID = e->getshapeId(); + if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() ) + for ( size_t iC = 0; iC < comps->length(); ++iC ) + fieldWriter.AddValue( noneDblValue ); + else + for ( size_t iC = 0; iC < comps->length(); ++iC ) + fieldWriter.AddValue( dblVals[ iC ][ shapeID ]); + } + else + while ( elemIt->more() ) + { + const SMDS_MeshElement* e = elemIt->next(); + const int shapeID = e->getshapeId(); + if ( shapeID < 1 || shapeID >= (int) intVals[0].size() ) + for ( size_t iC = 0; iC < comps->length(); ++iC ) + fieldWriter.AddValue( (double) noneIntValue ); + else + for ( size_t iC = 0; iC < comps->length(); ++iC ) + fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]); + } + + // write a step + fieldWriter.Perform(); + SMESH_ComputeErrorPtr res = fieldWriter.GetError(); + if ( res && res->IsKO() ) + { + if ( res->myComment.empty() ) + { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); } + else + { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); } + } + + } // loop on steps + } // loop on fields + + if ( !geomAssocFields || !geomAssocFields[0] ) + return; + + // write geomAssocFields + + std::vector< int > shapeDim( TopAbs_SHAPE + 1 ); + shapeDim[ TopAbs_COMPOUND ] = 3; + shapeDim[ TopAbs_COMPSOLID ] = 3; + shapeDim[ TopAbs_SOLID ] = 3; + shapeDim[ TopAbs_SHELL ] = 2; + shapeDim[ TopAbs_FACE ] = 2; + shapeDim[ TopAbs_WIRE ] = 1; + shapeDim[ TopAbs_EDGE ] = 1; + shapeDim[ TopAbs_VERTEX ] = 0; + shapeDim[ TopAbs_SHAPE ] = 3; + + for ( int iF = 0; geomAssocFields[ iF ]; ++iF ) + { + std::vector< std::string > compNames; + switch ( geomAssocFields[ iF ]) { + case 'v': case 'V': + fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false ); + compNames.push_back( "dim" ); + break; + case 'e': case 'E': + fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false ); + break; + case 'f': case 'F': + fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false ); + break; + case 's': case 'S': + fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false ); + break; + default: continue; + } + compNames.push_back( "id" ); + for ( size_t iC = 0; iC < compNames.size(); ++iC ) + fieldWriter.SetCompName( iC, compNames[ iC ].c_str() ); + + fieldWriter.SetDtIt( -1, -1 ); + + SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems(); + if ( !elemIt ) + continue; + + if ( compNames.size() == 2 ) // _vertices_ + while ( elemIt->more() ) + { + const SMDS_MeshElement* e = elemIt->next(); + const int shapeID = e->getshapeId(); + if ( shapeID < 1 ) + { + fieldWriter.AddValue( (double) -1 ); + fieldWriter.AddValue( (double) -1 ); + } + else + { + const TopoDS_Shape& S = meshDS->IndexToShape( shapeID ); + fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ])); + fieldWriter.AddValue( (double) shapeID ); + } + } + else + while ( elemIt->more() ) + { + const SMDS_MeshElement* e = elemIt->next(); + const int shapeID = e->getshapeId(); + if ( shapeID < 1 ) + fieldWriter.AddValue( (double) -1 ); + else + fieldWriter.AddValue( (double) shapeID ); + } + + // write a step + fieldWriter.Perform(); + SMESH_ComputeErrorPtr res = fieldWriter.GetError(); + if ( res && res->IsKO() ) + { + if ( res->myComment.empty() ) + { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); } + else + { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); } + } + + } // loop on geomAssocFields + +#undef METH } //================================================================================ @@ -2906,7 +4095,8 @@ void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart, SMESH_MeshPartDS partDS( meshPart ); _impl->ExportDAT(file,&partDS); - TPythonDump() << _this() << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )"; + TPythonDump() << SMESH::SMESH_Mesh_var(_this()) + << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )"; } //================================================================================ /*! @@ -2927,7 +4117,8 @@ void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart, SMESH_MeshPartDS partDS( meshPart ); _impl->ExportUNV(file, &partDS); - TPythonDump() << _this() << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )"; + TPythonDump() << SMESH::SMESH_Mesh_var(_this()) + << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )"; } //================================================================================ /*! @@ -2946,10 +4137,15 @@ void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart, PrepareForWriting(file); + CORBA::String_var name; + SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart ); + if ( !so->_is_nil() ) + name = so->GetName(); + SMESH_MeshPartDS partDS( meshPart ); - _impl->ExportSTL(file, isascii, &partDS); + _impl->ExportSTL( file, isascii, name.in(), &partDS ); - TPythonDump() << _this() << ".ExportPartToSTL( " + TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( " << meshPart<< ", r'" << file << "', " << isascii << ")"; } @@ -2961,7 +4157,8 @@ void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart, void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart, const char* file, - CORBA::Boolean overwrite) + CORBA::Boolean overwrite, + CORBA::Boolean groupElemsByType) throw (SALOME::SALOME_Exception) { #ifdef WITH_CGNS @@ -2971,10 +4168,21 @@ void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart, PrepareForWriting(file,overwrite); + std::string meshName(""); + SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart ); + if ( !so->_is_nil() ) + { + CORBA::String_var name = so->GetName(); + meshName = name.in(); + } + SMESH_TRY; + SMESH_MeshPartDS partDS( meshPart ); - _impl->ExportCGNS(file, &partDS); + _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType ); + + SMESH_CATCH( SMESH::throwCorbaException ); - TPythonDump() << _this() << ".ExportCGNS( " + TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( " << meshPart<< ", r'" << file << "', " << overwrite << ")"; #else THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR); @@ -3001,7 +4209,7 @@ void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart, SMESH_MeshPartDS partDS( meshPart ); _impl->ExportGMF(file, &partDS, withRequiredGroups); - TPythonDump() << _this() << ".ExportGMF( " + TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( " << meshPart<< ", r'" << file << "', " << withRequiredGroups << ")"; @@ -3009,22 +4217,19 @@ void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart, //============================================================================= /*! - * Return implementation of SALOME_MED::MESH interfaces + * Return computation progress [0.,1] */ //============================================================================= -SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception) +CORBA::Double SMESH_Mesh_i::GetComputeProgress() { - Unexpect aCatch(SALOME_SalomeException); - if ( _preMeshInfo ) - _preMeshInfo->FullLoadFromFile(); + SMESH_TRY; - SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this); - SALOME_MED::MESH_var aMesh = aMedMesh->_this(); - return aMesh._retn(); -} + return _impl->GetComputeProgress(); -//============================================================================= + SMESH_CATCH( SMESH::doNothing ); + return 0.; +} CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception) { @@ -3128,7 +4333,7 @@ CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception) return _impl->NbBiQuadQuadrangles(); } -CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception) +CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); if ( _preMeshInfo ) @@ -3137,6 +4342,15 @@ CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception) return _impl->NbPolygons(); } +CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order); + + return _impl->NbPolygons((SMDSAbs_ElementOrder)order); +} + CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception) { @@ -3334,7 +4548,7 @@ SMESH::long_array* SMESH_Mesh_i::GetIDs() //============================================================================= SMESH::long_array* SMESH_Mesh_i::GetElementsId() - throw (SALOME::SALOME_Exception) + throw (SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); if ( _preMeshInfo ) @@ -3387,12 +4601,9 @@ SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemTy int i = 0; - SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator(); - while ( i < nbElements && anIt->more() ) { - const SMDS_MeshElement* anElem = anIt->next(); - if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType ) - aResult[i++] = anElem->GetID(); - } + SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType ); + while ( i < nbElements && anIt->more() ) + aResult[i++] = anIt->next()->GetID(); aResult->length( i ); @@ -3413,14 +4624,14 @@ SMESH::long_array* SMESH_Mesh_i::GetNodesId() _preMeshInfo->FullLoadFromFile(); SMESH::long_array_var aResult = new SMESH::long_array(); - SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); + SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS(); - if ( aSMESHDS_Mesh == NULL ) + if ( aMeshDS == NULL ) return aResult._retn(); long nbNodes = NbNodes(); aResult->length( nbNodes ); - SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true); + SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator(); for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ ) aResult[i] = anIt->next()->GetID(); @@ -3436,7 +4647,7 @@ SMESH::long_array* SMESH_Mesh_i::GetNodesId() SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem ) throw (SALOME::SALOME_Exception) { - SMESH::ElementType type; + SMESH::ElementType type = SMESH::ALL; SMESH_TRY; if ( _preMeshInfo ) @@ -3468,6 +4679,25 @@ SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id ) return ( SMESH::EntityType ) e->GetEntityType(); } +//============================================================================= +/*! + * + */ +//============================================================================= + +SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id ) + throw (SALOME::SALOME_Exception) +{ + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + + const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id); + if ( !e ) + THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM ); + + return ( SMESH::GeometryType ) e->GetGeomType(); +} + //============================================================================= /*! * Returns ID of elements for given submesh @@ -3501,7 +4731,6 @@ SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID) return aResult._retn(); } - //============================================================================= /*! * Returns ID of nodes for given submesh @@ -3509,6 +4738,7 @@ SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID) * returns only nodes on shapes. */ //============================================================================= + SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, CORBA::Boolean all) throw (SALOME::SALOME_Exception) @@ -3555,7 +4785,7 @@ SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, return aResult._retn(); } - + //============================================================================= /*! * Returns type of elements for given submesh @@ -3565,7 +4795,7 @@ SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID) throw (SALOME::SALOME_Exception) { - SMESH::ElementType type; + SMESH::ElementType type = SMESH::ALL; SMESH_TRY; if ( _preMeshInfo ) @@ -3587,9 +4817,9 @@ SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID SMESH_CATCH( SMESH::throwCorbaException ); - return type; + return type; } - + //============================================================================= /*! @@ -3603,8 +4833,7 @@ CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() _preMeshInfo->FullLoadFromFile(); CORBA::LongLong pointeur = CORBA::LongLong(_impl); - if ( MYDEBUG ) - MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<FullLoadFromFile(); SMESH::double_array_var aResult = new SMESH::double_array(); - SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); - if ( aSMESHDS_Mesh == NULL ) + SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS(); + if ( aMeshDS == NULL ) return aResult._retn(); // find node - const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id); + const SMDS_MeshNode* aNode = aMeshDS->FindNode(id); if(!aNode) return aResult._retn(); @@ -3647,34 +4876,30 @@ SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id) */ //============================================================================= -SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id) +SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id, + SMESH::ElementType elemType) { if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); SMESH::long_array_var aResult = new SMESH::long_array(); - SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); - if ( aSMESHDS_Mesh == NULL ) + SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS(); + if ( aMeshDS == NULL ) return aResult._retn(); // find node - const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id); - if(!aNode) + const SMDS_MeshNode* aNode = aMeshDS->FindNode( id ); + if ( !aNode ) return aResult._retn(); // find inverse elements - SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator(); - TColStd_SequenceOfInteger IDs; - while(eIt->more()) { + SMDSAbs_ElementType type = SMDSAbs_ElementType( elemType ); + SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator( type ); + aResult->length( aNode->NbInverseElements( type )); + for( int i = 0; eIt->more(); ++i ) + { const SMDS_MeshElement* elem = eIt->next(); - IDs.Append(elem->GetID()); - } - if(IDs.Length()>0) { - aResult->length(IDs.Length()); - int i = 1; - for(; i<=IDs.Length(); i++) { - aResult[i-1] = IDs.Value(i); - } + aResult[ i ] = elem->GetID(); } return aResult._retn(); } @@ -3706,17 +4931,16 @@ SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID) case SMDS_TOP_EDGE: aNodePosition->shapeType = GEOM::EDGE; aNodePosition->params.length(1); - aNodePosition->params[0] = - static_cast( pos )->GetUParameter(); + aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter(); break; - case SMDS_TOP_FACE: + case SMDS_TOP_FACE: { + SMDS_FacePositionPtr fPos = pos; aNodePosition->shapeType = GEOM::FACE; aNodePosition->params.length(2); - aNodePosition->params[0] = - static_cast( pos )->GetUParameter(); - aNodePosition->params[1] = - static_cast( pos )->GetVParameter(); + aNodePosition->params[0] = fPos->GetUParameter(); + aNodePosition->params[1] = fPos->GetVParameter(); break; + } case SMDS_TOP_VERTEX: aNodePosition->shapeType = GEOM::VERTEX; break; @@ -3791,12 +5015,12 @@ CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id) if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); - if ( aSMESHDS_Mesh == NULL ) + SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS(); + if ( aMeshDS == NULL ) return -1; // try to find node - const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id); + const SMDS_MeshNode* aNode = aMeshDS->FindNode(id); if(aNode) { return aNode->getshapeId(); } @@ -3807,7 +5031,7 @@ CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id) //============================================================================= /*! - * For given element returns ID of result shape after + * For given element returns ID of result shape after * ::FindShape() from SMESH_MeshEditor * If there is not element for given ID - returns -1 */ @@ -3818,12 +5042,12 @@ CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id) if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); - if ( aSMESHDS_Mesh == NULL ) + SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS(); + if ( aMeshDS == NULL ) return -1; // try to find element - const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id); + const SMDS_MeshElement* elem = aMeshDS->FindElement(id); if(!elem) return -1; @@ -3848,10 +5072,10 @@ CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id) if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); - if ( aSMESHDS_Mesh == NULL ) return -1; + SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS(); + if ( aMeshDS == NULL ) return -1; // try to find element - const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id); + const SMDS_MeshElement* elem = aMeshDS->FindElement(id); if(!elem) return -1; return elem->NbNodes(); } @@ -3870,9 +5094,9 @@ CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long in if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); - if ( aSMESHDS_Mesh == NULL ) return -1; - const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id); + SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS(); + if ( aMeshDS == NULL ) return -1; + const SMDS_MeshElement* elem = aMeshDS->FindElement(id); if(!elem) return -1; if( index>=elem->NbNodes() || index<0 ) return -1; return elem->GetNode(index)->GetID(); @@ -3890,13 +5114,14 @@ SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id) _preMeshInfo->FullLoadFromFile(); SMESH::long_array_var aResult = new SMESH::long_array(); - if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() ) + if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) { - if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(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(); @@ -3914,13 +5139,13 @@ CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Lo if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); - if ( aSMESHDS_Mesh == NULL ) return false; + SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS(); + if ( aMeshDS == NULL ) return false; // try to find node - const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn); + const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn); if(!aNode) return false; // try to find element - const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide); + const SMDS_MeshElement* elem = aMeshDS->FindElement(ide); if(!elem) return false; return elem->IsMediumNode(aNode); @@ -3940,11 +5165,11 @@ CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn, if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); - if ( aSMESHDS_Mesh == NULL ) return false; + SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS(); + if ( aMeshDS == NULL ) return false; // try to find node - const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn); + const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn); if(!aNode) return false; SMESH_MesherHelper aHelper( *(_impl) ); @@ -3970,9 +5195,9 @@ CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id) if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); - if ( aSMESHDS_Mesh == NULL ) return -1; - const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id); + SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS(); + if ( aMeshDS == NULL ) return -1; + const SMDS_MeshElement* elem = aMeshDS->FindElement(id); if(!elem) return -1; return elem->NbEdges(); } @@ -3989,9 +5214,9 @@ CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id) if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); - if ( aSMESHDS_Mesh == NULL ) return -1; - const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id); + SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS(); + if ( aMeshDS == NULL ) return -1; + const SMDS_MeshElement* elem = aMeshDS->FindElement(id); if(!elem) return -1; return elem->NbFaces(); } @@ -4008,16 +5233,16 @@ SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId, _preMeshInfo->FullLoadFromFile(); SMESH::long_array_var aResult = new SMESH::long_array(); - if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() ) + if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) { - if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(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 )); const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex ); - for ( int i = 0; i < aResult->length(); ++i ) + for ( CORBA::ULong i = 0; i < aResult->length(); ++i ) aResult[ i ] = nn[ i ]->GetID(); } } @@ -4025,6 +5250,33 @@ SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId, return aResult._retn(); } +//======================================================================= +//function : GetFaceNormal +//purpose : Returns three components of normal of given mesh face. +//======================================================================= + +SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId, + CORBA::Boolean normalized) +{ + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + + SMESH::double_array_var aResult = new SMESH::double_array(); + + if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() ) + { + gp_XYZ normal; + if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized )) + { + aResult->length( 3 ); + aResult[ 0 ] = normal.X(); + aResult[ 1 ] = normal.Y(); + aResult[ 2 ] = normal.Z(); + } + } + return aResult._retn(); +} + //======================================================================= //function : FindElementByNodes //purpose : Returns an element based on all given nodes. @@ -4039,7 +5291,7 @@ CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes) if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() ) { vector< const SMDS_MeshNode * > nn( nodes.length() ); - for ( int i = 0; i < nodes.length(); ++i ) + for ( CORBA::ULong i = 0; i < nodes.length(); ++i ) if ( !( nn[i] = mesh->FindNode( nodes[i] ))) return elemID; @@ -4049,9 +5301,38 @@ CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes) _impl->NbVolumes( ORDER_QUADRATIC ))) elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true ); - if ( elem ) elemID = CORBA::Long( elem->GetID() ); + if ( elem ) elemID = CORBA::Long( elem->GetID() ); + } + return elemID; +} + +//================================================================================ +/*! + * \brief Return elements including all given nodes. + */ +//================================================================================ + +SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes, + SMESH::ElementType elemType) +{ + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + + SMESH::long_array_var result = new SMESH::long_array(); + + if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() ) + { + vector< const SMDS_MeshNode * > nn( nodes.length() ); + for ( CORBA::ULong i = 0; i < nodes.length(); ++i ) + nn[i] = mesh->FindNode( nodes[i] ); + + std::vector elems; + mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType ); + result->length( elems.size() ); + for ( size_t i = 0; i < elems.size(); ++i ) + result[i] = elems[i]->GetID(); } - return elemID; + return result._retn(); } //============================================================================= @@ -4065,9 +5346,9 @@ CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id) if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); - if ( aSMESHDS_Mesh == NULL ) return false; - const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id); + SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS(); + if ( aMeshDS == NULL ) return false; + const SMDS_MeshElement* elem = aMeshDS->FindElement(id); if(!elem) return false; return elem->IsPoly(); } @@ -4084,9 +5365,9 @@ CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id) if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); - if ( aSMESHDS_Mesh == NULL ) return false; - const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id); + SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS(); + if ( aMeshDS == NULL ) return false; + const SMDS_MeshElement* elem = aMeshDS->FindElement(id); if(!elem) return false; return elem->IsQuadratic(); } @@ -4103,7 +5384,7 @@ CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id) _preMeshInfo->FullLoadFromFile(); if ( const SMDS_BallElement* ball = - dynamic_cast( _impl->GetMeshDS()->FindElement( id ))) + SMDS_Mesh::DownCast( _impl->GetMeshDS()->FindElement( id ))) return ball->GetDiameter(); return 0; @@ -4121,11 +5402,11 @@ SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id) _preMeshInfo->FullLoadFromFile(); SMESH::double_array_var aResult = new SMESH::double_array(); - SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS(); - if ( aSMESHDS_Mesh == NULL ) + SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS(); + if ( aMeshDS == NULL ) return aResult._retn(); - const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id); + const SMDS_MeshElement* elem = aMeshDS->FindElement(id); if(!elem) return aResult._retn(); @@ -4177,6 +5458,7 @@ SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID, THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM ); SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups; + ::SMESH_MeshEditor::ElemFeatures elemType; // submesh by subshape id if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1; @@ -4184,12 +5466,14 @@ SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID, { // compute error SMESH_ComputeErrorPtr error = sm->GetComputeError(); - if ( error && !error->myBadElements.empty()) + if ( error && error->HasBadElems() ) { // sort bad elements by type vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ]; - list::iterator elemIt = error->myBadElements.begin(); - list::iterator elemEnd = error->myBadElements.end(); + const list& badElems = + static_cast( error.get() )->myBadElements; + list::const_iterator elemIt = badElems.begin(); + list::const_iterator elemEnd = badElems.end(); for ( ; elemIt != elemEnd; ++elemIt ) { const SMDS_MeshElement* elem = *elemIt; @@ -4209,7 +5493,7 @@ SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID, if ( elem ) { ::SMESH_MeshEditor editor( _impl ); - elem = editor.AddElement( nodes, elem->GetType(), elem->IsPoly() ); + elem = editor.AddElement( nodes, elemType.Init( elem )); } } if ( elem ) @@ -4231,10 +5515,10 @@ SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID, groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName ); if ( _gen_i->CanPublishInStudy( groups[ iG ] )) { + SMESH::SMESH_Mesh_var mesh = _this(); SALOMEDS::SObject_wrap aSO = - _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(), groups[ iG ], + _gen_i->PublishGroup( mesh, groups[ iG ], GEOM::GEOM_Object::_nil(), theGroupName); - aSO->_is_nil(); // avoid "unused variable" warning } SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]); if ( !grp_i ) continue; @@ -4257,14 +5541,14 @@ SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID, void SMESH_Mesh_i::CreateGroupServants() { - SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy(); + SMESH::SMESH_Mesh_var aMesh = _this(); set addedIDs; ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups(); 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 )) @@ -4283,9 +5567,9 @@ void SMESH_Mesh_i::CreateGroupServants() aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId ); } - SMESH::SMESH_GroupBase_var groupVar = - SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() ); + SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this(); _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar ); + aGroupImpl->Register(); // register CORBA object for persistence int nextId = _gen_i->RegisterObject( groupVar ); @@ -4293,10 +5577,8 @@ void SMESH_Mesh_i::CreateGroupServants() else { nextId = 0; } // avoid "unused variable" warning in release mode // publishing the groups in the study - if ( !aStudy->_is_nil() ) { - GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape ); - _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName()); - } + GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape ); + _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName()); } if ( !addedIDs.empty() ) { @@ -4306,11 +5588,22 @@ void SMESH_Mesh_i::CreateGroupServants() { map::iterator it = _mapGroups.find(*id); int i = std::distance( _mapGroups.begin(), it ); - TPythonDump() << it->second << " = " << _this() << ".GetGroups()[ "<< i << " ]"; + TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]"; } } } +//============================================================================= +/*! + * \brief Return true if all sub-meshes are computed OK - to update an icon + */ +//============================================================================= + +bool SMESH_Mesh_i::IsComputedOK() +{ + return _impl->IsComputedOK(); +} + //============================================================================= /*! * \brief Return groups cantained in _mapGroups by their IDs @@ -4340,17 +5633,59 @@ SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list& groupIDs) const */ //============================================================================= -SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo() +SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo() { - SALOME_MED::MedFileInfo_var res( _medFileInfo ); + SMESH::MedFileInfo_var res( _medFileInfo ); if ( !res.operator->() ) { - res = new SALOME_MED::MedFileInfo; + res = new SMESH::MedFileInfo; res->fileName = ""; res->fileSize = res->major = res->minor = res->release = -1; } return res._retn(); } +//======================================================================= +//function : FileInfoToString +//purpose : Persistence of file info +//======================================================================= + +std::string SMESH_Mesh_i::FileInfoToString() +{ + std::string s; + if ( &_medFileInfo.in() && _medFileInfo->fileName[0] ) + { + s = SMESH_Comment( _medFileInfo->fileSize ) + << " " << _medFileInfo->major + << " " << _medFileInfo->minor + << " " << _medFileInfo->release + << " " << _medFileInfo->fileName; + } + return s; +} + +//======================================================================= +//function : FileInfoFromString +//purpose : Persistence of file info +//======================================================================= + +void SMESH_Mesh_i::FileInfoFromString(const std::string& info) +{ + std::string size, major, minor, release, fileName; + std::istringstream is(info); + is >> size >> major >> minor >> release; + fileName = info.data() + ( size.size() + 1 + + major.size() + 1 + + minor.size() + 1 + + release.size()+ 1 ); + + _medFileInfo = new SMESH::MedFileInfo(); + _medFileInfo->fileName = fileName.c_str(); + _medFileInfo->fileSize = atoi( size.c_str() ); + _medFileInfo->major = atoi( major.c_str() ); + _medFileInfo->minor = atoi( minor.c_str() ); + _medFileInfo->release = atoi( release.c_str() ); +} + //============================================================================= /*! * \brief Pass names of mesh groups from study to mesh DS @@ -4363,10 +5698,6 @@ void SMESH_Mesh_i::checkGroupNames() if ( !nbGrp ) return; - SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy(); - if ( aStudy->_is_nil() ) - return; // nothing to do - SMESH::ListOfGroups* grpList = 0; // avoid dump of "GetGroups" { @@ -4379,7 +5710,7 @@ void SMESH_Mesh_i::checkGroupNames() SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ]; if ( !aGrp ) continue; - SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp ); + SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp ); if ( aGrpSO->_is_nil() ) continue; // correct name of the mesh group if necessary @@ -4405,10 +5736,10 @@ void SMESH_Mesh_i::SetParameters(const char* theParameters) * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol */ //============================================================================= + char* SMESH_Mesh_i::GetParameters() { - SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen(); - return CORBA::string_dup(gen->GetParameters(SMESH::SMESH_Mesh::_narrow(_this()))); + return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) ); } //============================================================================= @@ -4421,16 +5752,13 @@ SMESH::string_array* SMESH_Mesh_i::GetLastParameters() SMESH::string_array_var aResult = new SMESH::string_array(); SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen(); if(gen) { - char *aParameters = GetParameters(); - SALOMEDS::Study_var aStudy = gen->GetCurrentStudy(); - if(!aStudy->_is_nil()) { - SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters); - if(aSections->length() > 0) { - SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1]; - aResult->length(aVars.length()); - for(int i = 0;i < aVars.length();i++) - aResult[i] = CORBA::string_dup( aVars[i]); - } + CORBA::String_var aParameters = GetParameters(); + SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters); + if ( aSections->length() > 0 ) { + SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ]; + aResult->length( aVars.length() ); + for ( CORBA::ULong i = 0;i < aVars.length(); i++ ) + aResult[i] = CORBA::string_dup( aVars[i] ); } } return aResult._retn(); @@ -4455,6 +5783,8 @@ SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes() if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME; if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D; if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL; + if (_impl->NbNodes() && + nbTypes == 0 ) types[nbTypes++] = SMESH::NODE; types->length( nbTypes ); return types._retn(); @@ -4483,7 +5813,7 @@ bool SMESH_Mesh_i::IsMeshInfoCorrect() //============================================================================= /*! - * \brief Returns statistic of mesh elements + * \brief Returns number of mesh elements per each \a EntityType */ //============================================================================= @@ -4507,7 +5837,33 @@ SMESH::long_array* SMESH_Mesh_i::GetMeshInfo() //============================================================================= /*! - * \brief Collect statistic of mesh elements given by iterator + * \brief Returns number of mesh elements per each \a ElementType + */ +//============================================================================= + +SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType() +{ + SMESH::long_array_var aRes = new SMESH::long_array(); + aRes->length(SMESH::NB_ELEMENT_TYPES); + for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++) + aRes[ i ] = 0; + + const SMDS_MeshInfo* meshInfo = 0; + if ( _preMeshInfo ) + meshInfo = _preMeshInfo; + else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() ) + meshInfo = & meshDS->GetMeshInfo(); + + if (meshInfo) + for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++) + aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i); + + return aRes._retn(); +} + +//============================================================================= +/* + * Collect statistic of mesh elements given by iterator */ //============================================================================= @@ -4518,6 +5874,274 @@ void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr, while (theItr->more()) theInfo[ theItr->next()->GetEntityType() ]++; } +//============================================================================= +/* + * Returns mesh unstructed grid information. + */ +//============================================================================= + +SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream() +{ + SALOMEDS::TMPFile_var SeqFile; + if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) { + SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid(); + if(aGrid) { + vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New(); + aWriter->WriteToOutputStringOn(); + aWriter->SetInputData(aGrid); + aWriter->SetFileTypeToBinary(); + aWriter->Write(); + char* str = aWriter->GetOutputString(); + int size = aWriter->GetOutputStringLength(); + + //Allocate octet buffer of required size + CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size); + //Copy ostrstream content to the octet buffer + memcpy(OctetBuf, str, size); + //Create and return TMPFile + SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1); + aWriter->Delete(); + } + } + return SeqFile._retn(); +} + +//============================================================================= +namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj, + * SMESH::ElementType type) */ +{ + using namespace SMESH::Controls; + //----------------------------------------------------------------------------- + struct PredicateIterator : public SMDS_ElemIterator + { + SMDS_ElemIteratorPtr _elemIter; + PredicatePtr _predicate; + const SMDS_MeshElement* _elem; + SMDSAbs_ElementType _type; + + PredicateIterator( SMDS_ElemIteratorPtr iterator, + PredicatePtr predicate, + SMDSAbs_ElementType type): + _elemIter(iterator), _predicate(predicate), _type(type) + { + next(); + } + virtual bool more() + { + return _elem; + } + virtual const SMDS_MeshElement* next() + { + const SMDS_MeshElement* res = _elem; + _elem = 0; + while ( _elemIter->more() && !_elem ) + { + if ((_elem = _elemIter->next()) && + (( _type != SMDSAbs_All && _type != _elem->GetType() ) || + ( !_predicate->IsSatisfy( _elem->GetID() )))) + _elem = 0; + } + return res; + } + }; + + //----------------------------------------------------------------------------- + struct IDSourceIterator : public SMDS_ElemIterator + { + const CORBA::Long* _idPtr; + const CORBA::Long* _idEndPtr; + SMESH::long_array_var _idArray; + const SMDS_Mesh* _mesh; + const SMDSAbs_ElementType _type; + const SMDS_MeshElement* _elem; + + IDSourceIterator( const SMDS_Mesh* mesh, + const CORBA::Long* ids, + const int nbIds, + SMDSAbs_ElementType type): + _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 ) + { + if ( _idPtr && nbIds && _mesh ) + next(); + } + IDSourceIterator( const SMDS_Mesh* mesh, + SMESH::long_array* idArray, + SMDSAbs_ElementType type): + _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 ) + { + if ( idArray && _mesh ) + { + _idPtr = &_idArray[0]; + _idEndPtr = _idPtr + _idArray->length(); + next(); + } + } + virtual bool more() + { + return _elem; + } + virtual const SMDS_MeshElement* next() + { + const SMDS_MeshElement* res = _elem; + _elem = 0; + while ( _idPtr < _idEndPtr && !_elem ) + { + if ( _type == SMDSAbs_Node ) + { + _elem = _mesh->FindNode( *_idPtr++ ); + } + else if ((_elem = _mesh->FindElement( *_idPtr++ )) && + (_elem->GetType() != _type && _type != SMDSAbs_All )) + { + _elem = 0; + } + } + return res; + } + }; + //----------------------------------------------------------------------------- + + struct NodeOfElemIterator : public SMDS_ElemIterator + { + TColStd_MapOfInteger _checkedNodeIDs; + SMDS_ElemIteratorPtr _elemIter; + SMDS_ElemIteratorPtr _nodeIter; + const SMDS_MeshElement* _node; + + NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 ) + { + if ( _elemIter && _elemIter->more() ) + { + _nodeIter = _elemIter->next()->nodesIterator(); + next(); + } + } + virtual bool more() + { + return _node; + } + virtual const SMDS_MeshElement* next() + { + const SMDS_MeshElement* res = _node; + _node = 0; + while ( !_node && ( _elemIter->more() || _nodeIter->more() )) + { + if ( _nodeIter->more() ) + { + _node = _nodeIter->next(); + if ( !_checkedNodeIDs.Add( _node->GetID() )) + _node = 0; + } + else + { + _nodeIter = _elemIter->next()->nodesIterator(); + } + } + return res; + } + }; +} + +//============================================================================= +/* + * Return iterator on elements of given type in given object + */ +//============================================================================= + +SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject, + SMESH::ElementType theType) +{ + SMDS_ElemIteratorPtr elemIt; + bool typeOK = ( theType == SMESH::ALL ); + SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType ); + + SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh(); + SMESH_Mesh_i* mesh_i = SMESH::DownCast( meshVar ); + if ( !mesh_i ) return elemIt; + SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS(); + + if ( SMESH::DownCast( theObject )) + { + elemIt = meshDS->elementsIterator( elemType ); + typeOK = true; + } + else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast( theObject )) + { + SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() ); + if ( sm ) + { + elemIt = sm->GetElements(); + if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All ) + { + typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType ); + elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr(); + } + } + } + else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast( theObject )) + { + SMESHDS_GroupBase* groupDS = group_i->GetGroupDS(); + if ( groupDS && ( elemType == groupDS->GetType() || + elemType == SMDSAbs_Node || + elemType == SMDSAbs_All )) + { + elemIt = groupDS->GetElements(); + typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All ); + } + } + else if ( SMESH::Filter_i* filter_i = SMESH::DownCast( theObject )) + { + if ( filter_i->GetElementType() == theType || + filter_i->GetElementType() == SMESH::ALL || + elemType == SMDSAbs_Node || + elemType == SMDSAbs_All) + { + SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i(); + if ( pred_i && pred_i->GetPredicate() ) + { + SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() ); + SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType ); + SMDSAbs_ElementType iterType = elemType == SMDSAbs_Node ? filterType : elemType; + elemIt = SMDS_ElemIteratorPtr + ( new PredicateIterator( allElemIt, pred_i->GetPredicate(), iterType )); + typeOK = ( elemType == SMDSAbs_Node ? filterType == SMDSAbs_Node : elemIt->more() ); + } + } + } + else + { + SMESH::array_of_ElementType_var types = theObject->GetTypes(); + const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE ); + if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All ) + return elemIt; + SMDSAbs_ElementType iterType = isNodes ? SMDSAbs_Node : elemType; + if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject )) + { + int nbIds; + if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds )) + elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, iterType )); + } + else + { + SMESH::long_array_var ids = theObject->GetIDs(); + elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), iterType )); + } + typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All ); + } + + if ( elemIt && elemIt->more() && !typeOK ) + { + if ( elemType == SMDSAbs_Node ) + { + elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt )); + } + else + { + elemIt = SMDS_ElemIteratorPtr(); + } + } + return elemIt; +} //============================================================================= namespace // Finding concurrent hypotheses @@ -4542,17 +6166,17 @@ TopAbs_ShapeEnum shapeTypeByDim(const int theDim) //----------------------------------------------------------------------------- /*! - * \brief Internal structure used to find concurent submeshes + * \brief Internal structure used to find concurrent submeshes * - * It represents a pair < submesh, concurent dimension >, where - * 'concurrent dimension' is dimension of shape where the submesh can concurent + * It represents a pair < submesh, concurrent dimension >, where + * 'concurrent dimension' is dimension of shape where the submesh can concurrent * with another submesh. In other words, it is dimension of a hypothesis assigned * to submesh. */ class SMESH_DimHyp { public: - //! fileds + //! fields int _dim; //!< a dimension the algo can build (concurrent dimension) int _ownDim; //!< dimension of shape of _subMesh (>=_dim) TopTools_MapOfShape _shapeMap; @@ -4566,9 +6190,9 @@ class SMESH_DimHyp //----------------------------------------------------------------------------- //! Constructors - SMESH_DimHyp(const SMESH_subMesh* theSubMesh, - const int theDim, - const TopoDS_Shape& theShape) + SMESH_DimHyp(const SMESH_subMesh* theSubMesh, + const int theDim, + const TopoDS_Shape& theShape) { _subMesh = (SMESH_subMesh*)theSubMesh; SetShape( theDim, theShape ); @@ -4580,7 +6204,7 @@ class SMESH_DimHyp const TopoDS_Shape& theShape) { _dim = theDim; - _ownDim = (int)SMESH_Gen::GetShapeDim(theShape); + _ownDim = SMESH_Gen::GetShapeDim(theShape); if (_dim >= _ownDim) _shapeMap.Add( theShape ); else { @@ -4610,7 +6234,7 @@ class SMESH_DimHyp } return isShared; } - + //----------------------------------------------------------------------------- //! check algorithms static bool checkAlgo(const SMESHDS_Hypothesis* theA1, @@ -4624,7 +6248,7 @@ class SMESH_DimHyp return strcmp( theA1->GetName(), theA2->GetName() ) == 0; } - + //----------------------------------------------------------------------------- //! Check if sub-shape hypotheses are concurrent bool IsConcurrent(const SMESH_DimHyp* theOther) const @@ -4642,19 +6266,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(); @@ -4676,7 +6304,7 @@ class SMESH_DimHyp return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() ); } - + }; // end of SMESH_DimHyp //----------------------------------------------------------------------------- @@ -4684,7 +6312,7 @@ typedef list TDimHypList; //----------------------------------------------------------------------------- -void addDimHypInstance(const int theDim, +void addDimHypInstance(const int theDim, const TopoDS_Shape& theShape, const SMESH_Algo* theAlgo, const SMESH_subMesh* theSubMesh, @@ -4697,7 +6325,7 @@ void addDimHypInstance(const int theDim, dimHyp->_hypotheses.push_front(theAlgo); listOfdimHyp.push_back( dimHyp ); } - + SMESH_DimHyp* dimHyp = const_cast( listOfdimHyp.back() ); dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(), theHypList.begin(), theHypList.end() ); @@ -4756,7 +6384,7 @@ void unionLists(TListOfInt& theListOfId, if ( find_first_of( theListOfId.begin(), theListOfId.end(), otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() ) continue; - + // union two lists (from source into target) TListOfInt::iterator it2 = otherListOfId.begin(); for ( ; it2 != otherListOfId.end(); it2++ ) { @@ -4800,8 +6428,37 @@ void findCommonSubMesh (list& theSubMeshList, //theCommon.insert( theSubMesh ); } +//----------------------------------------------------------------------------- +bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists ) +{ + TListOfListOfInt::const_iterator listsIt = smLists.begin(); + for ( ; listsIt != smLists.end(); ++listsIt ) + { + const TListOfInt& smIDs = *listsIt; + if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() ) + return true; + } + return false; +} + } // namespace +//============================================================================= +/*! + * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh + */ +//============================================================================= + +CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID) +{ + TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order + if ( isSubMeshInList( submeshID, anOrder )) + return false; + + TListOfListOfInt allConurrent = findConcurrentSubMeshes(); + return isSubMeshInList( submeshID, allConurrent ); +} + //============================================================================= /*! * \brief Return submesh objects list in meshing order @@ -4815,14 +6472,37 @@ SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder() SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS(); if ( !aMeshDS ) return aResult._retn(); - - ::SMESH_Mesh& mesh = GetImpl(); - TListOfListOfInt anOrder = mesh.GetMeshOrder(); // is there already defined order? - if ( !anOrder.size() ) { + TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order + TListOfListOfInt allConurrent = findConcurrentSubMeshes(); + anOrder.splice( anOrder.end(), allConurrent ); + + int listIndx = 0; + TListOfListOfInt::iterator listIt = anOrder.begin(); + for(; listIt != anOrder.end(); listIt++, listIndx++ ) + unionLists( *listIt, anOrder, listIndx + 1 ); + + // convert submesh ids into interface instances + // and dump command into python + convertMeshOrder( anOrder, aResult, false ); + + return aResult._retn(); +} + +//============================================================================= +/*! + * \brief Finds concurrent sub-meshes + */ +//============================================================================= + +TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes() +{ + TListOfListOfInt anOrder; + ::SMESH_Mesh& mesh = GetImpl(); + { // collect submeshes and detect concurrent algorithms and hypothesises TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension - + map::iterator i_sm = _mapSubMesh.begin(); for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) { ::SMESH_subMesh* sm = (*i_sm).second; @@ -4857,7 +6537,7 @@ SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder() addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr ); } } // end iterations on submesh - + // iterate on created dimension-hypotheses and check for concurrents for ( int i = 0; i < 4; i++ ) { const TDimHypList& listOfDimHyp = dimHypListArr[i]; @@ -4882,10 +6562,10 @@ SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder() } } } - + removeDimHyps(dimHypListArr); - - // now, minimise the number of concurrent groups + + // now, minimize the number of concurrent groups // Here we assume that lists of submeshes can have same submesh // in case of multi-dimension algorithms, as result // list with common submesh has to be united into one list @@ -4894,11 +6574,8 @@ SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder() for(; listIt != anOrder.end(); listIt++, listIndx++ ) unionLists( *listIt, anOrder, listIndx + 1 ); } - // convert submesh ids into interface instances - // and dump command into python - convertMeshOrder( anOrder, aResult, false ); - return aResult._retn(); + return anOrder; } //============================================================================= @@ -4917,13 +6594,15 @@ SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder() ::SMESH_Mesh& mesh = GetImpl(); TPythonDump aPythonDump; // prevent dump of called methods - aPythonDump << "isDone = " << _this() << ".SetMeshOrder( [ "; + aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ "; TListOfListOfInt subMeshOrder; for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ ) { const SMESH::submesh_array& aSMArray = theSubMeshArray[i]; TListOfInt subMeshIds; + if ( i > 0 ) + aPythonDump << ", "; aPythonDump << "[ "; // Collect subMeshes which should be clear // do it list-by-list, because modification of submesh order @@ -4944,17 +6623,24 @@ SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder() 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 << " ])"; mesh.SetMeshOrder( subMeshOrder ); res = true; - + + SMESH::SMESH_Mesh_var me = _this(); + _gen_i->UpdateIcons( me ); + return res; } @@ -4983,11 +6669,12 @@ void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder, continue; if ( theIsDump ) aPythonDump << "[ "; - // convert shape indeces into interfaces + // convert shape indices into interfaces SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array(); aResSubSet->length(aSubOrder.size()); TListOfInt::const_iterator subIt = aSubOrder.begin(); - for( int j = 0; subIt != aSubOrder.end(); subIt++ ) { + int j; + for( j = 0; subIt != aSubOrder.end(); subIt++ ) { if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() ) continue; SMESH::SMESH_subMesh_var subMesh = @@ -5001,7 +6688,8 @@ void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder, } if ( theIsDump ) aPythonDump << " ]"; - theResOrder[ listIndx++ ] = aResSubSet; + if ( j > 1 ) + theResOrder[ listIndx++ ] = aResSubSet; } // correct number of lists theResOrder.length( listIndx ); @@ -5009,10 +6697,28 @@ void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder, if ( theIsDump ) { // finilise python dump aPythonDump << " ]"; - aPythonDump << " = " << _this() << ".GetMeshOrder()"; + aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()"; } } +namespace // utils used by SMESH_MeshPartDS +{ + /*! + * \brief Class used to access to protected data of SMDS_MeshInfo + */ + struct TMeshInfo : public SMDS_MeshInfo + { + void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); } + }; + /*! + * \brief Element holing its ID only + */ + struct TElemID : public SMDS_LinearEdge + { + TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); } + }; +} + //================================================================================ // // Implementation of SMESH_MeshPartDS @@ -5023,6 +6729,7 @@ SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart): SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh(); SMESH_Mesh_i* mesh_i = SMESH::DownCast( mesh ); + mesh_i->Load(); _meshDS = mesh_i->GetImpl().GetMeshDS(); SetPersistentId( _meshDS->GetPersistentId() ); @@ -5042,14 +6749,14 @@ SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart): SMESH::array_of_ElementType_var types = meshPart->GetTypes(); if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes { - for (int i=0; i < anIDs->length(); i++) - if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i])) + for ( CORBA::ULong i=0; i < anIDs->length(); i++ ) + if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] )) if ( _elements[ SMDSAbs_Node ].insert( n ).second ) tmpInfo.Add( n ); } else { - for (int i=0; i < anIDs->length(); i++) + for ( CORBA::ULong i=0; i < anIDs->length(); i++ ) if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i])) if ( _elements[ e->GetType() ].insert( e ).second ) { @@ -5065,6 +6772,8 @@ SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart): } myInfo = tmpInfo; + ShapeToMesh( _meshDS->ShapeToMesh() ); + _meshDS = 0; // to enforce iteration on _elements and _nodes } } @@ -5090,6 +6799,63 @@ SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & myInfo = tmpInfo; } // ------------------------------------------------------------------------------------- +const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const +{ + if ( _meshDS ) return _meshDS->FindElement( IDelem ); + + TElemID elem( IDelem ); + for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType ) + if ( !_elements[ iType ].empty() ) + { + TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem ); + if ( it != _elements[ iType ].end() ) + return *it; + } + 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 ); @@ -5101,7 +6867,7 @@ SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType SMDS_MeshElement::GeomFilter > TIter; - SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType ); + SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType ); return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(), _elements[type].end(), @@ -5119,7 +6885,7 @@ SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType SMDS_MeshElement::EntityFilter > TIter; - SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity ); + SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity ); return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(), _elements[type].end(), @@ -5146,10 +6912,10 @@ SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type } // ------------------------------------------------------------------------------------- #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \ - iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \ + iterType SMESH_MeshPartDS::methName() const \ { \ typedef SMDS_SetIterator TIter; \ - return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \ + return _meshDS ? _meshDS->methName() : iterType \ ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \ } // ------------------------------------------------------------------------------------- @@ -5162,5 +6928,3 @@ _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDS // END Implementation of SMESH_MeshPartDS // //================================================================================ - -