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=2b11922915c2f77addce88e7b2b928751be0ccb2;hp=afe7656491c7ebdf32d3ab5f312796866f3377d8;hb=88a6b8d690a5410a9097c2f924d4a63be6db5e77;hpb=1067ffa6e7e5c394e3a1b17219d8b355a57607cd diff --git a/src/SMESH_I/SMESH_Mesh_i.cxx b/src/SMESH_I/SMESH_Mesh_i.cxx index afe765649..2b1192291 100644 --- a/src/SMESH_I/SMESH_Mesh_i.cxx +++ b/src/SMESH_I/SMESH_Mesh_i.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2016 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,21 +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" @@ -49,25 +58,18 @@ #include "SMESH_PythonDump.hxx" #include "SMESH_subMesh_i.hxx" -#include -#include -#include +#include +#include #include -#include #include + #include +#include // OCCT Includes #include -#include -#include -#include -#include -#include -#include +#include #include -#include -#include #include #include #include @@ -76,10 +78,15 @@ // 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; @@ -92,10 +99,6 @@ using SMESH::TPythonDump; int SMESH_Mesh_i::_idGenerator = 0; -//To disable automatic genericobj management, the following line should be commented. -//Otherwise, it should be uncommented. Refer to KERNEL_SRC/src/SALOMEDSImpl/SALOMEDSImpl_AttributeIOR.cxx -#define WITHGENERICOBJ - //============================================================================= /*! * Constructor @@ -104,15 +107,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 ) + CORBA::Long studyId ) : 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++; + _studyId = studyId; + _editor = NULL; + _previewEditor = NULL; + _preMeshInfo = NULL; + _mainShapeTick = 0; } //============================================================================= @@ -123,52 +128,47 @@ SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA, SMESH_Mesh_i::~SMESH_Mesh_i() { - MESSAGE("~SMESH_Mesh_i"); - -#ifdef WITHGENERICOBJ // destroy groups map::iterator itGr; - for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++) { - if ( CORBA::is_nil( itGr->second )) - continue; - SMESH_GroupBase_i* aGroup = dynamic_cast(SMESH_Gen_i::GetServant(itGr->second).in()); - if (aGroup) { - // this method is called from destructor of group (PAL6331) - //_impl->RemoveGroup( aGroup->GetLocalID() ); - aGroup->myMeshServant = 0; + for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++) + if (SMESH_GroupBase_i* aGroup = SMESH::DownCast(itGr->second)) + { aGroup->UnRegister(); + SMESH::SMESH_GroupBase_var( itGr->second ); } - } _mapGroups.clear(); // destroy submeshes map::iterator itSM; - for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ ) { - if ( CORBA::is_nil( itSM->second )) - continue; - SMESH_subMesh_i* aSubMesh = dynamic_cast(SMESH_Gen_i::GetServant(itSM->second).in()); - if (aSubMesh) { + for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ ) + 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 ( CORBA::is_nil( itH->second )) - continue; - SMESH_Hypothesis_i* aHypo = dynamic_cast(SMESH_Gen_i::GetServant(itH->second).in()); - if (aHypo) { - aHypo->UnRegister(); - } + 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(); -#endif - delete _impl; _impl = NULL; + // 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(); - if ( _preMeshInfo ) delete _preMeshInfo; _preMeshInfo = NULL; + delete _editor; _editor = NULL; + delete _previewEditor; _previewEditor = NULL; + delete _impl; _impl = NULL; + delete _preMeshInfo; _preMeshInfo = NULL; } //============================================================================= @@ -192,7 +192,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(); } //================================================================================ @@ -228,7 +231,25 @@ 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::Study_var study = _gen_i->GetCurrentStudy(); + if ( study->_is_nil() ) break; + SALOMEDS::SObject_wrap so = study->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); @@ -271,16 +292,17 @@ 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); } - TPythonDump() << _this() << ".Clear()"; + + TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()"; } //================================================================================ @@ -302,6 +324,9 @@ void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID) catch(SALOME_Exception & S_ex) { THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); } + _impl->GetMeshDS()->Modified(); + + TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )"; } //============================================================================= @@ -323,6 +348,8 @@ static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus) res = SMESH::DRS_WARN_RENUMBER; break; case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM: res = SMESH::DRS_WARN_SKIP_ELEM; break; + case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING: + res = SMESH::DRS_WARN_DESCENDING; break; case DriverMED_R_SMESHDS_Mesh::DRS_FAIL: default: res = SMESH::DRS_FAIL; break; @@ -348,7 +375,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(); @@ -383,20 +410,13 @@ SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName ) int major, minor, release; if( !MED::getMEDVersion( theFileName, major, minor, release ) ) major = minor = release = -1; - _medFileInfo = new SALOME_MED::MedFileInfo(); + _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); } @@ -438,7 +458,7 @@ SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileNa char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits) { string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version), - nbDigits); + nbDigits); return CORBA::string_dup( ver.c_str() ); } @@ -453,11 +473,15 @@ char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nb int SMESH_Mesh_i::ImportUNVFile( const char* theFileName ) throw ( SALOME::SALOME_Exception ) { + SMESH_TRY; + // Read mesh with name = into SMESH_Mesh _impl->UNVToMesh( theFileName ); CreateGroupServants(); + SMESH_CATCH( SMESH::throwCorbaException ); + return 1; } @@ -471,12 +495,36 @@ int SMESH_Mesh_i::ImportUNVFile( const char* theFileName ) int SMESH_Mesh_i::ImportSTLFile( const char* theFileName ) throw ( SALOME::SALOME_Exception ) { + SMESH_TRY; + // Read mesh with name = into SMESH_Mesh - _impl->STLToMesh( theFileName ); + std::string name = _impl->STLToMesh( theFileName ); + if ( !name.empty() ) + { + SALOMEDS::Study_var study = _gen_i->GetCurrentStudy(); + SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( study, _this() ); + _gen_i->SetName( meshSO, name.c_str() ); + } + + SMESH_CATCH( SMESH::throwCorbaException ); return 1; } +//================================================================================ +/*! + * \brief Function used in SMESH_CATCH by ImportGMFFile() + */ +//================================================================================ + +namespace +{ + SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText) + { + return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText ); + } +} + //================================================================================ /*! * \brief Imports data from a GMF file and returns an error description @@ -488,29 +536,16 @@ SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName, throw (SALOME::SALOME_Exception) { SMESH_ComputeErrorPtr error; - try { - error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups ); - } - catch ( std::bad_alloc& exc ) { - error = SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, "std::bad_alloc raised" ); - } - catch ( Standard_OutOfMemory& exc ) { - error = SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, "Standard_OutOfMemory raised" ); - } - catch (Standard_Failure& ex) { - error = SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, ex.DynamicType()->Name() ); - if ( ex.GetMessageString() && strlen( ex.GetMessageString() )) - error->myComment += string(": ") + ex.GetMessageString(); - } - catch ( SALOME_Exception& S_ex ) { - error = SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, S_ex.what() ); - } - catch ( std::exception& exc ) { - error = SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, exc.what() ); - } - catch (...) { - error = SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, "Unknown exception" ); - } + +#undef SMESH_CAUGHT +#define SMESH_CAUGHT error = + SMESH_TRY; + + error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups ); + + SMESH_CATCH( exceptionToComputeError ); +#undef SMESH_CAUGHT +#define SMESH_CAUGHT CreateGroupServants(); @@ -531,7 +566,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 ); @@ -543,6 +578,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; @@ -558,31 +594,32 @@ 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 ); + 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 ); - + { + SALOMEDS::Study_var study = _gen_i->GetCurrentStudy(); + _gen_i->AddHypothesisToShape( study, mesh, aSubShape, anHyp ); + } 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); } @@ -593,19 +630,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 @@ -613,24 +648,28 @@ SMESH_Hypothesis::Hypothesis_Status TopoDS_Shape myLocSubShape; //use PseudoShape in case if mesh has no shape if(HasShapeToMesh()) - myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject); + 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 ); -#ifdef WITHGENERICOBJ - _mapHypo[hypId]->Register(); -#endif + 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) { @@ -645,30 +684,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 << " )"; + { + SALOMEDS::Study_var study = _gen_i->GetCurrentStudy(); + _gen_i->RemoveHypothesisFromShape( study, mesh, aSubShape, anHyp ); } - 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); } @@ -680,17 +718,15 @@ 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); SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK; @@ -698,15 +734,18 @@ SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject, { 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) { @@ -722,30 +761,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) { @@ -786,7 +827,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(); } @@ -796,20 +837,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 @@ -825,15 +865,16 @@ SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShap // create a new subMesh object servant if there is none for the shape if ( subMesh->_is_nil() ) - subMesh = createSubMesh( aSubShapeObject ); - if ( _gen_i->CanPublishInStudy( subMesh )) { - SALOMEDS::SObject_var aSO = - _gen_i->PublishSubMesh(_gen_i->GetCurrentStudy(), aMesh, - subMesh, aSubShapeObject, theName ); + subMesh = createSubMesh( aSubShape ); + if ( _gen_i->CanPublishInStudy( subMesh )) + { + SALOMEDS::Study_var study = _gen_i->GetCurrentStudy(); + SALOMEDS::SObject_wrap aSO = + _gen_i->PublishSubMesh( study, aMesh, subMesh, aSubShape, theName ); if ( !aSO->_is_nil()) { // Update Python script - TPythonDump() << aSO << " = " << _this() << ".GetSubMesh( " - << aSubShapeObject << ", '" << theName << "' )"; + TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( " + << aSubShape << ", '" << theName << "' )"; } } } @@ -850,36 +891,43 @@ SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShap //============================================================================= void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh ) - throw (SALOME::SALOME_Exception) + throw (SALOME::SALOME_Exception) { - if(MYDEBUG) MESSAGE("SMESH_Mesh_i::RemoveSubMesh"); + SMESH_TRY; + if ( theSubMesh->_is_nil() ) return; - GEOM::GEOM_Object_var aSubShapeObject; - SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy(); + GEOM::GEOM_Object_var aSubShape; + SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy(); if ( !aStudy->_is_nil() ) { // Remove submesh's SObject - SALOMEDS::SObject_var anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh ); + SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh ); if ( !anSO->_is_nil() ) { long aTag = SMESH_Gen_i::GetRefOnShapeTag(); - SALOMEDS::SObject_var anObj, aRef; - if ( anSO->FindSubObject( aTag, anObj ) && anObj->ReferencedObject( aRef ) ) - aSubShapeObject = GEOM::GEOM_Object::_narrow( aRef->GetObject() ); - -// if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617) -// aSubShapeObject = theSubMesh->GetSubShape(); + 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(); - aStudy->NewBuilder()->RemoveObjectWithChildren( anSO ); + SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder(); + builder->RemoveObjectWithChildren( anSO ); // Update Python script - TPythonDump() << _this() << ".RemoveSubMesh( " << anSO << " )"; + TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )"; } } - if ( removeSubMesh( theSubMesh, aSubShapeObject.in() )) + if ( removeSubMesh( theSubMesh, aSubShape.in() )) if ( _preMeshInfo ) _preMeshInfo->ForgetOrLoad(); + + SMESH_CATCH( SMESH::throwCorbaException ); } //============================================================================= @@ -890,7 +938,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 ) @@ -899,20 +947,20 @@ 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 ) ) { - SALOMEDS::SObject_var aSO = - _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(), - aNewGroup, GEOM::GEOM_Object::_nil(), theName); - if ( !aSO->_is_nil()) { + if ( _gen_i->CanPublishInStudy( aNewGroup ) ) + { + SMESH::SMESH_Mesh_var mesh = _this(); + SALOMEDS::Study_var study = _gen_i->GetCurrentStudy(); + SALOMEDS::SObject_wrap aSO = + _gen_i->PublishGroup( study, 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(); } - //============================================================================= /*! * @@ -922,7 +970,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 ) @@ -933,18 +981,18 @@ 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, aShape )); - if ( _gen_i->CanPublishInStudy( aNewGroup ) ) { - SALOMEDS::SObject_var aSO = - _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(), - aNewGroup, theGeomObj, theName); - if ( !aSO->_is_nil()) { - // Update Python script - TPythonDump() << aSO << " = " << _this() << ".CreateGroupFromGEOM(" + if ( _gen_i->CanPublishInStudy( aNewGroup ) ) + { + SMESH::SMESH_Mesh_var mesh = _this(); + SALOMEDS::Study_var study = _gen_i->GetCurrentStudy(); + SALOMEDS::SObject_wrap aSO = + _gen_i->PublishGroup( study, mesh, aNewGroup, theGeomObj, theName ); + if ( !aSO->_is_nil()) + TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( " << theElemType << ", '" << theName << "', " << theGeomObj << " )"; - } } } @@ -965,7 +1013,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 ) @@ -987,16 +1035,15 @@ SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType, if ( _gen_i->CanPublishInStudy( aNewGroup ) ) { - SALOMEDS::SObject_var 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(" + SMESH::SMESH_Mesh_var mesh = _this(); + SALOMEDS::Study_var study = _gen_i->GetCurrentStudy(); + SALOMEDS::SObject_wrap aSO = + _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName ); + + if ( !aSO->_is_nil()) + pd << aSO << " = " << mesh << ".CreateGroupFromFilter( " << theElemType << ", '" << theName << "', " << theFilter << " )"; - } } - return aNewGroup._retn(); } @@ -1007,31 +1054,37 @@ 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_GroupBase_i* aGroup = - dynamic_cast( SMESH_Gen_i::GetServant( theGroup ).in() ); + SMESH_TRY; + + SMESH_GroupBase_i* aGroup = SMESH::DownCast( theGroup ); if ( !aGroup ) return; - SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy(); - if ( !aStudy->_is_nil() ) { - SALOMEDS::SObject_var aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup ); - - if ( !aGroupSO->_is_nil() ) { + SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy(); + if ( !aStudy->_is_nil() ) + { + SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup ); + if ( !aGroupSO->_is_nil() ) + { // Update Python script - TPythonDump() << _this() << ".RemoveGroup( " << aGroupSO << " )"; + TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )"; // Remove group's SObject - aStudy->NewBuilder()->RemoveObjectWithChildren( aGroupSO ); + SALOMEDS::StudyBuilder_var builder = aStudy->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() ); + + SMESH_CATCH( SMESH::throwCorbaException ); } //============================================================================= @@ -1043,39 +1096,68 @@ void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup ) void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup ) throw (SALOME::SALOME_Exception) { + SMESH_TRY; if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); if ( theGroup->_is_nil() ) return; - SMESH_GroupBase_i* aGroup = - dynamic_cast( SMESH_Gen_i::GetServant( theGroup ).in() ); - if ( !aGroup ) - return; + 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 ); + } + + // 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 ); - SMESH::long_array_var anIds = aGroup->GetListOfID(); - SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor(); + TPythonDump pyDump; // Suppress dump from RemoveGroup() - TPythonDump pyDump; // Supress dump from RemoveNodes/Elements() and RemoveGroup() + // Remove group + RemoveGroup( theGroup ); // Remove contents - if ( aGroup->GetType() == SMESH::NODE ) - aMeshEditor->RemoveNodes( anIds ); - else - aMeshEditor->RemoveElements( anIds ); + for ( size_t i = 0; i < elems.size(); ++i ) + { + 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 << _this() << ".RemoveGroupWithContents( " << theGroup << " )"; + pyDump << SMESH::SMESH_Mesh_var(_this()) + << ".RemoveGroupWithContents( " << theGroup << " )"; - // Remove group - RemoveGroup( 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 */ //================================================================================ @@ -1088,30 +1170,27 @@ SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception) // Python Dump TPythonDump aPythonDump; - if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []" + if ( !_mapGroups.empty() ) + { aPythonDump << "[ "; - - try { - aList->length( _mapGroups.size() ); - int i = 0; - map::iterator it = _mapGroups.begin(); - for ( ; it != _mapGroups.end(); it++ ) { - if ( CORBA::is_nil( it->second )) continue; - aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second ); - // Python Dump - if (i > 1) aPythonDump << ", "; - aPythonDump << it->second; + try { + aList->length( _mapGroups.size() ); + int i = 0; + map::iterator it = _mapGroups.begin(); + for ( ; it != _mapGroups.end(); it++ ) { + if ( CORBA::is_nil( it->second )) continue; + aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second ); + // Python Dump + if (i > 1) aPythonDump << ", "; + aPythonDump << it->second; + } + aList->length( i ); } - aList->length( i ); - } - catch(SALOME_Exception & S_ex) { - THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); + catch(SALOME_Exception & S_ex) { + THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); + } + aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()"; } - - // Update Python script - if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []" - aPythonDump << " ] = " << _this() << ".GetGroups()"; - return aList._retn(); } @@ -1128,204 +1207,170 @@ 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; + + SMESH_TRY; if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - try - { - if ( theGroup1->_is_nil() || theGroup2->_is_nil() || - theGroup1->GetType() != theGroup2->GetType() ) - return SMESH::SMESH_Group::_nil(); - - // Create Union - SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName ); - 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() ); + 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; - int resI = 0; - TColStd_MapIteratorOfMapOfInteger anIter( aResMap ); - for( ; anIter.More(); anIter.Next() ) - aResIds[ resI++ ] = anIter.Key(); + // Create Union + aResGrp = CreateGroup( theGroup1->GetType(), theName ); + if ( aResGrp->_is_nil() ) + return SMESH::SMESH_Group::_nil(); - aResGrp->Add( aResIds ); + aResGrp->AddFrom( theGroup1 ); + aResGrp->AddFrom( theGroup2 ); - // Clear python lines, created by CreateGroup() and Add() - SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy(); - _gen_i->RemoveLastFromPythonScript(aStudy->StudyId()); - _gen_i->RemoveLastFromPythonScript(aStudy->StudyId()); + // Update Python script + pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) + << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )"; - // Update Python script - TPythonDump() << aResGrp << " = " << _this() << ".UnionGroups( " - << theGroup1 << ", " << theGroup2 << ", '" - << theName << "' )"; + SMESH_CATCH( SMESH::throwCorbaException ); - return aResGrp._retn(); - } - catch( ... ) - { - return SMESH::SMESH_Group::_nil(); - } + return aResGrp._retn(); } //============================================================================= /*! - \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) + throw (SALOME::SALOME_Exception) { + SMESH::SMESH_Group_var aResGrp; + if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); if ( !theName ) return SMESH::SMESH_Group::_nil(); - try + SMESH_TRY; + + // check types + SMESH::ElementType aType = SMESH::ALL; + for ( int g = 0, n = theGroups.length(); g < n; g++ ) { - vector< int > anIds; - 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; + SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ]; + if ( CORBA::is_nil( aGrp ) ) + continue; + if ( aType == SMESH::ALL ) + 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(); - // check type - SMESH::ElementType aCurrType = aGrp->GetType(); - if ( aType == SMESH::ALL ) - aType = aCurrType; - else - { - if ( aType != aCurrType ) - return SMESH::SMESH_Group::_nil(); - } + TPythonDump pyDump; - // 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 ); - } - } + // Create Union + aResGrp = CreateGroup( aType, theName ); + if ( aResGrp->_is_nil() ) + return SMESH::SMESH_Group::_nil(); - // Create group - SMESH::SMESH_Group_var 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() ); - - //NCollection_Map< int >::Iterator anIter( anIds ); - for ( int i = 0; iAddFrom( aGrp ); + if ( g > 0 ) pyDump << ", "; + pyDump << aGrp; } - aResGrp->Add( aResIds ); - - // Clear python lines, created by CreateGroup() and Add() - SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy(); - _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() ); - _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() ); + } + pyDump << " ], '" << theName << "' )"; - // Update Python script - - TPythonDump() << aResGrp << " = " << _this() << ".UnionListOfGroups( " - << &theGroups << ", '" << theName << "' )"; + SMESH_CATCH( SMESH::throwCorbaException ); - return aResGrp._retn(); - } - catch( ... ) - { - return SMESH::SMESH_Group::_nil(); - } + return aResGrp._retn(); } //============================================================================= -/*! 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 ) + const char* theName ) throw (SALOME::SALOME_Exception) { + 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 - SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName ); + 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; - - for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ ) - aMap1.Add( anIds1[ i1 ] ); - - TColStd_SequenceOfInteger aSeq; - - for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ ) - if ( aMap1.Contains( anIds2[ i2 ] ) ) - aSeq.Append( anIds2[ i2 ] ); - - SMESH::long_array_var aResIds = new SMESH::long_array; - aResIds->length( aSeq.Length() ); + return aResGrp._retn(); - for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ ) - aResIds[ resI ] = aSeq( resI + 1 ); + SMESHDS_GroupBase* groupDS1 = 0; + if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 )) + groupDS1 = grp_i->GetGroupDS(); - aResGrp->Add( aResIds ); + SMESHDS_GroupBase* groupDS2 = 0; + if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 )) + groupDS2 = grp_i->GetGroupDS(); - // Clear python lines, created by CreateGroup() and Add() - SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy(); - _gen_i->RemoveLastFromPythonScript(aStudy->StudyId()); - _gen_i->RemoveLastFromPythonScript(aStudy->StudyId()); + 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 - TPythonDump() << aResGrp << " = " << _this() << ".IntersectGroups( " - << theGroup1 << ", " << theGroup2 << ", '" << theName << "')"; + pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( " + << theGroup1 << ", " << theGroup2 << ", '" << theName << "')"; + + SMESH_CATCH( SMESH::throwCorbaException ); return aResGrp._retn(); } @@ -1344,143 +1389,136 @@ SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups, 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(); - try + // 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++ ) { - NCollection_DataMap< int, int > anIdToCount; - 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(); - } - - // calculates number of occurance ids in groups - SMESH::long_array_var aCurrIds = aGrp->GetListOfID(); - for ( int i = 0, n = aCurrIds->length(); i < n; i++ ) + SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ]; + if ( CORBA::is_nil( aGrp ) ) + continue; + if ( aType == SMESH::ALL ) + aType = aGrp->GetType(); + else if ( aType != aGrp->GetType() ) + THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): 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() ) { - int aCurrId = aCurrIds[ i ]; - if ( !anIdToCount.IsBound( aCurrId ) ) - anIdToCount.Bind( aCurrId, 1 ); - else - anIdToCount( aCurrId ) = anIdToCount( aCurrId ) + 1; + if ( grpDS->IsEmpty() ) + { + groupVec.clear(); + break; + } + groupVec.push_back( grpDS ); } - } - - // 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 ); - } - - // Create group - SMESH::SMESH_Group_var 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() ); - - //NCollection_Map< int >::Iterator aListIter( anIds ); - for ( int i = 0; iAdd( aResIds ); + } + if ( aType == SMESH::ALL ) // all groups are nil + return SMESH::SMESH_Group::_nil(); - // Clear python lines, created by CreateGroup() and Add() - SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy(); - _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() ); - _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() ); + TPythonDump pyDump; - // Update Python script - - TPythonDump() << aResGrp << " = " << _this() << ".IntersectListOfGroups( " - << &theGroups << ", '" << theName << "' )"; + // Create a group + aResGrp = CreateGroup( aType, theName ); + 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(); - } - catch( ... ) + + // Fill the group + size_t i, nb = groupVec.size(); + SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements(); + while ( elemIt1->more() ) { - return SMESH::SMESH_Group::_nil(); + const SMDS_MeshElement* e = elemIt1->next(); + bool inAll = true; + for ( i = 1; ( i < nb && inAll ); ++i ) + inAll = groupVec[i]->Contains( e ); + + if ( inAll ) + resGroupDS->SMDSGroup().Add( e ); } + + // Update Python script + pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() ) + << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )"; + + SMESH_CATCH( SMESH::throwCorbaException ); + + return aResGrp._retn(); } //============================================================================= -/*! 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 ) throw (SALOME::SALOME_Exception) { + 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 - SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName ); + 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 ] ); - - TColStd_SequenceOfInteger aSeq; - for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ ) - if ( !aMap2.Contains( anIds1[ i1 ] ) ) - aSeq.Append( anIds1[ i1 ] ); - - SMESH::long_array_var aResIds = new SMESH::long_array; - aResIds->length( aSeq.Length() ); + return aResGrp._retn(); - for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ ) - aResIds[ resI ] = aSeq( resI + 1 ); + SMESHDS_GroupBase* groupDS1 = 0; + if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 )) + groupDS1 = grp_i->GetGroupDS(); - aResGrp->Add( aResIds ); + SMESHDS_GroupBase* groupDS2 = 0; + if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 )) + groupDS2 = grp_i->GetGroupDS(); - // Clear python lines, created by CreateGroup() and Add() - SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy(); - _gen_i->RemoveLastFromPythonScript(aStudy->StudyId()); - _gen_i->RemoveLastFromPythonScript(aStudy->StudyId()); + 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 - TPythonDump() << aResGrp << " = " << _this() << ".CutGroups( " - << theGroup1 << ", " << theGroup2 << ", '" - << theName << "' )"; + pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( " + << theGroup1 << ", " << theGroup2 << ", '" << theName << "')"; + + SMESH_CATCH( SMESH::throwCorbaException ); return aResGrp._retn(); } @@ -1501,124 +1539,142 @@ SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups, 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(); - try + // check types and get SMESHDS_GroupBase's + SMESH::ElementType aType = SMESH::ALL; + vector< SMESHDS_GroupBase* > toolGroupVec; + vector< SMDS_ElemIteratorPtr > mainIterVec; + + for ( int g = 0, n = theMainGroups.length(); g < n; g++ ) { - set< int > aToolIds; - SMESH::ElementType aType = SMESH::ALL; - int g, n; - // iterate through tool groups - for ( g = 0, n = theToolGroups.length(); g < n; g++ ) - { - SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ]; - if ( CORBA::is_nil( aGrp ) ) - continue; + SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ]; + if ( CORBA::is_nil( aGrp ) ) + continue; + if ( aType == SMESH::ALL ) + 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(); - // check type - SMESH::ElementType aCurrType = aGrp->GetType(); - if ( aType == SMESH::ALL ) - aType = aCurrType; - else - { - if ( aType != aCurrType ) - return SMESH::SMESH_Group::_nil(); - } + for ( int g = 0, n = theToolGroups.length(); g < n; g++ ) + { + SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ]; + if ( CORBA::is_nil( aGrp ) ) + continue; + 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 ); + } - // 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 ); - } - } + TPythonDump pyDump; - vector< int > anIds; // result + // Create a group + aResGrp = CreateGroup( aType, theName ); - // Iterate through main group - for ( g = 0, n = theMainGroups.length(); g < n; g++ ) - { - SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ]; - if ( CORBA::is_nil( aGrp ) ) - continue; + 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(); - // check type - SMESH::ElementType aCurrType = aGrp->GetType(); - if ( aType == SMESH::ALL ) - aType = aCurrType; - else - { - if ( aType != aCurrType ) - return SMESH::SMESH_Group::_nil(); - } + // 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 ); - // 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 ( !isIn ) + resGroupDS->SMDSGroup().Add( e ); + } - // Create group - SMESH::SMESH_Group_var 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 (int i=0; iAdd( aResIds ); + // Update Python script + pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() ) + << ".CutListOfGroups( " << theMainGroups << ", " + << theToolGroups << ", '" << theName << "' )"; - // Clear python lines, created by CreateGroup() and Add() - SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy(); - _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() ); - _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() ); + SMESH_CATCH( SMESH::throwCorbaException ); - // Update Python script + return aResGrp._retn(); +} - TPythonDump() << aResGrp << " = " << _this() << ".CutListOfGroups( " - << &theMainGroups << ", " << &theToolGroups << ", '" - << theName << "' )"; - - 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; } - catch( ... ) + bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners, + bool & toStopChecking ) { - return SMESH::SMESH_Group::_nil(); + 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 + * 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; + + SMESH_TRY; if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); @@ -1629,141 +1685,154 @@ SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups, SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType; - try - { - // Create map of nodes from all groups + 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; + + aResGrp = CreateGroup( theElemType, theName ); + if ( aResGrp->_is_nil() ) + return SMESH::SMESH_Group::_nil(); + + SMESHDS_GroupBase* groupBaseDS = + 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_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; + + SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL ); + if ( !elIt ) continue; - set< int > aNodeMap; - - for ( int g = 0, n = theGroups.length(); g < n; g++ ) + if ( theElemType == SMESH::NODE ) // get all nodes of elements { - SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ]; - if ( CORBA::is_nil( aGrp ) ) - continue; - - SMESH::ElementType aType = aGrp->GetType(); - if ( aType == SMESH::ALL ) - continue; - else if ( aType == SMESH::NODE ) - { - SMESH::long_array_var aCurrIds = aGrp->GetListOfID(); - for ( int i = 0, n = aCurrIds->length(); i < n; i++ ) - { - int aCurrId = aCurrIds[ i ]; - const SMDS_MeshNode* aNode = aMeshDS->FindNode( aCurrId ); - if ( aNode ) - aNodeMap.insert( aNode->GetID() ); - } + while ( elIt->more() ) { + const SMDS_MeshElement* el = elIt->next(); + SMDS_ElemIteratorPtr nIt = el->nodesIterator(); + while ( nIt->more() ) + resGroupCore.Add( nIt->next() ); } - else + } + // get elements of theElemType based on nodes of every element of group + else if ( theUnderlyingOnly ) + { + while ( elIt->more() ) { - SMESH::long_array_var aCurrIds = aGrp->GetListOfID(); - for ( int i = 0, n = aCurrIds->length(); i < n; i++ ) + const SMDS_MeshElement* el = elIt->next(); // an element of ref group + TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() ); + TIDSortedElemSet checkedElems; + SMDS_NodeIteratorPtr nIt = el->nodeIterator(); + while ( nIt->more() ) { - int aCurrId = aCurrIds[ i ]; - const SMDS_MeshElement* anElem = aMeshDS->FindElement( aCurrId ); - if ( !anElem ) - continue; - SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator(); - while( aNodeIter->more() ) + 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_MeshNode* aNode = - dynamic_cast( aNodeIter->next() ); - if ( aNode ) - aNodeMap.insert( aNode->GetID() ); + 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(); + for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked ) + if ( elNodes.count( nIt2->next() ) && + isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking )) + { + resGroupCore.Add( elOfType ); + break; + } } } } } - - // Get result identifiers - - vector< int > aResultIds; - if ( theElemType == SMESH::NODE ) - { - //NCollection_Map< int >::Iterator aNodeIter( aNodeMap ); - set::iterator iter = aNodeMap.begin(); - for ( ; iter != aNodeMap.end(); iter++ ) - aResultIds.push_back( *iter); - } + // get all nodes of elements of groups else { - // Create list of elements of given dimension constructed on the nodes - vector< int > anElemList; - //NCollection_Map< int >::Iterator aNodeIter( aNodeMap ); - //for ( ; aNodeIter.More(); aNodeIter.Next() ) - set::iterator iter = aNodeMap.begin(); - for ( ; iter != aNodeMap.end(); iter++ ) + while ( elIt->more() ) { - const SMDS_MeshElement* aNode = - dynamic_cast( aMeshDS->FindNode( *iter ) ); - if ( !aNode ) - continue; - - SMDS_ElemIteratorPtr anElemIter = aNode->elementsIterator( anElemType ); - while( anElemIter->more() ) + const SMDS_MeshElement* el = elIt->next(); // an element of group + SMDS_NodeIteratorPtr nIt = el->nodeIterator(); + while ( nIt->more() ) { - const SMDS_MeshElement* anElem = - dynamic_cast( anElemIter->next() ); - if ( anElem && anElem->GetType() == anElemType ) - anElemList.push_back( anElem->GetID() ); + 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 whether all nodes of elements are present in nodes map - for (int i=0; i< anElemList.size(); i++) + // check nodes of elements of theElemType around n + SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType ); + while ( elOfTypeIt->more() ) { - const SMDS_MeshElement* anElem = aMeshDS->FindElement( anElemList[i] ); - if ( !anElem ) + const SMDS_MeshElement* elOfType = elOfTypeIt->next(); + vector::reference isChecked = isElemChecked[ elOfType->GetID() ]; + if ( isChecked ) continue; - - bool isOk = true; - SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator(); - while( aNodeIter->more() ) + 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 SMDS_MeshNode* aNode = - dynamic_cast( aNodeIter->next() ); - if ( !aNode || !aNodeMap.count( aNode->GetID() ) ) + const int nID = nIt->next()->GetID(); + if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] && + isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking )) { - isOk = false; + resGroupCore.Add( elOfType ); break; } - } - if ( isOk ) - aResultIds.push_back( anElem->GetID() ); + } } } + } - // Create group - - SMESH::SMESH_Group_var aResGrp = CreateGroup( theElemType, 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( aResultIds.size() ); - - for (int i=0; i< aResultIds.size(); i++) - aResIds[ i ] = aResultIds[i]; - aResGrp->Add( aResIds ); - - // Remove strings corresponding to group creation - SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy(); - _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() ); - _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() ); + // Update Python script + pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this()) + << ".CreateDimGroup( " + << theGroups << ", " << theElemType << ", '" << theName << "', " + << nbCoNoStr << ", " << theUnderlyingOnly << ")"; - // Update Python script - - TPythonDump() << aResGrp << " = " << _this() << ".CreateDimGroup( " - << &theGroups << ", " << theElemType << ", '" << theName << "' )"; + SMESH_CATCH( SMESH::throwCorbaException ); - return aResGrp._retn(); - } - catch( ... ) - { - return SMESH::SMESH_Group::_nil(); - } + return aResGrp._retn(); } //================================================================================ @@ -1778,13 +1847,13 @@ 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_var groupSO = _gen_i->ObjectToSObject( study, theGeomObj ); + SALOMEDS::Study_var study = _gen_i->GetCurrentStudy(); + SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study, theGeomObj ); if ( groupSO->_is_nil() ) return; // group indices GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine(); - GEOM::GEOM_IGroupOperations_var groupOp = + GEOM::GEOM_IGroupOperations_wrap groupOp = geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() ); GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj ); @@ -1795,10 +1864,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(); } //================================================================================ @@ -1832,7 +1904,7 @@ TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData) // get geom group SALOMEDS::Study_var study = _gen_i->GetCurrentStudy(); if ( study->_is_nil() ) return newShape; // means "not changed" - SALOMEDS::SObject_var groupSO = study->FindObjectID( groupData._groupEntry.c_str() ); + SALOMEDS::SObject_wrap groupSO = study->FindObjectID( groupData._groupEntry.c_str() ); if ( !groupSO->_is_nil() ) { CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO ); @@ -1842,10 +1914,10 @@ TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData) // get indices of group items set curIndices; GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine(); - GEOM::GEOM_IGroupOperations_var groupOp = + 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 ) + GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup ); + for ( CORBA::ULong i = 0; i < ids->length(); ++i ) curIndices.insert( ids[i] ); if ( groupData._indices == curIndices ) @@ -1856,10 +1928,10 @@ TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData) GEOM_Client* geomClient = _gen_i->GetShapeReader(); if ( !geomClient ) return newShape; - TCollection_AsciiString groupIOR = geomGen->GetStringFromIOR( geomGroup ); - geomClient->RemoveShapeFromBuffer( groupIOR ); + 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 @@ -1872,22 +1944,182 @@ 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; + int _shapeID; + SMDSAbs_ElementType _type; + std::string _name; + Quantity_Color _color; + }; +} + +//============================================================================= +/*! + * \brief Update data if geometry changes + * + * Issue 0022501 + */ +//============================================================================= + +void SMESH_Mesh_i::CheckGeomModif() +{ + if ( !_impl->HasShapeToMesh() ) return; + + SALOMEDS::Study_var study = _gen_i->GetCurrentStudy(); + if ( study->_is_nil() ) return; + + GEOM::GEOM_Object_var mainGO = _gen_i->ShapeToGeomObject( _impl->GetShapeToMesh() ); + //if ( mainGO->_is_nil() ) return; + + // Update after group modification + + if ( mainGO->_is_nil() || /* shape was removed from GEOM_Client by newGroupShape() + called by other mesh (IPAL52735) */ + mainGO->GetType() == GEOM_GROUP || + mainGO->GetTick() == _mainShapeTick ) + { + CheckGeomGroupModif(); + return; + } + + // Update after shape transformation like Translate + + GEOM_Client* geomClient = _gen_i->GetShapeReader(); + if ( !geomClient ) return; + GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine(); + if ( geomGen->_is_nil() ) return; + + CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO ); + geomClient->RemoveShapeFromBuffer( ior.in() ); + + // Update data taking into account that + // all sub-shapes change but IDs of sub-shapes remain (except for geom groups) + + _impl->Clear(); + TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO ); + if ( newShape.IsNull() ) + return; + + _mainShapeTick = mainGO->GetTick(); + + SMESHDS_Mesh * meshDS = _impl->GetMeshDS(); + + // store data of groups on geometry + vector< TGroupOnGeomData > groupsData; + const set& groups = meshDS->GetGroups(); + groupsData.reserve( groups.size() ); + set::const_iterator g = groups.begin(); + for ( ; g != groups.end(); ++g ) + if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g )) + { + TGroupOnGeomData data; + data._oldID = group->GetID(); + data._shapeID = meshDS->ShapeToIndex( group->GetShape() ); + data._type = group->GetType(); + data._name = group->GetStoreName(); + data._color = group->GetColor(); + groupsData.push_back( data ); + } + // store assigned hypotheses + vector< pair< int, THypList > > ids2Hyps; + const ShapeToHypothesis & hyps = meshDS->GetHypotheses(); + for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() ) + { + const TopoDS_Shape& s = s2hyps.Key(); + const THypList& hyps = s2hyps.ChangeValue(); + ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps )); + } + + // change shape to mesh + int oldNbSubShapes = meshDS->MaxShapeIndex(); + _impl->ShapeToMesh( TopoDS_Shape() ); + _impl->ShapeToMesh( newShape ); + + // re-add shapes of geom groups + list::iterator data = _geomGroupData.begin(); + for ( ; data != _geomGroupData.end(); ++data ) + { + TopoDS_Shape newShape = newGroupShape( *data ); + if ( !newShape.IsNull() ) + { + if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape + { + TopoDS_Compound compound; + BRep_Builder().MakeCompound( compound ); + BRep_Builder().Add( compound, newShape ); + newShape = compound; + } + _impl->GetSubMesh( newShape ); + } + } + if ( oldNbSubShapes != meshDS->MaxShapeIndex() ) + THROW_SALOME_CORBA_EXCEPTION( "SMESH_Mesh_i::CheckGeomModif() bug", + SALOME::INTERNAL_ERROR ); + + // re-assign hypotheses + for ( size_t i = 0; i < ids2Hyps.size(); ++i ) + { + const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first ); + const THypList& hyps = ids2Hyps[i].second; + THypList::const_iterator h = hyps.begin(); + for ( ; h != hyps.end(); ++h ) + _impl->AddHypothesis( s, (*h)->GetID() ); + } + + // restore groups + for ( size_t i = 0; i < groupsData.size(); ++i ) + { + const TGroupOnGeomData& data = groupsData[i]; + + map::iterator i2g = _mapGroups.find( data._oldID ); + if ( i2g == _mapGroups.end() ) continue; + + SMESH_GroupBase_i* gr_i = SMESH::DownCast( i2g->second ); + if ( !gr_i ) continue; + + int id; + SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), id, + meshDS->IndexToShape( data._shapeID )); + if ( !g ) + { + _mapGroups.erase( i2g ); + } + else + { + g->GetGroupDS()->SetColor( data._color ); + gr_i->changeLocalId( id ); + _mapGroups[ id ] = i2g->second; + if ( data._oldID != id ) + _mapGroups.erase( i2g ); + } + } + + // update _mapSubMesh + map::iterator i_sm = _mapSubMesh.begin(); + for ( ; i_sm != _mapSubMesh.end(); ++i_sm ) + i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first )); + } + //============================================================================= /*! * \brief Update objects depending on changed geom groups - * + * * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation * issue 0020210: Update of a smesh group after modification of the associated geom group */ @@ -1935,7 +2167,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(); @@ -2044,9 +2276,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 are 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 ) @@ -2055,15 +2289,15 @@ void SMESH_Mesh_i::CheckGeomGroupModif() list& hyps = indS_hyps->second; int oldID = geom._index; int newID = meshDS->ShapeToIndex( geom._shape ); - if ( !newID ) - continue; if ( oldID == 1 ) { // main shape newID = 1; geom._shape = newShape; } + if ( !newID ) + 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; @@ -2084,10 +2318,10 @@ void SMESH_Mesh_i::CheckGeomGroupModif() if ( _mapGroups.find( oldID ) == _mapGroups.end() ) continue; // get group name - SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] ); - CORBA::String_var name = groupSO->GetName(); + SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] ); + CORBA::String_var name = groupSO->GetName(); // update - SMESH_GroupBase_i* group_i = SMESH::DownCast(_mapGroups[oldID] ); + 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 ); @@ -2101,7 +2335,7 @@ void SMESH_Mesh_i::CheckGeomGroupModif() // Update icons CORBA::Long newNbEntities = NbNodes() + NbElements(); - list< SALOMEDS::SObject_var > soToUpdateIcons; + list< SALOMEDS::SObject_wrap > soToUpdateIcons; if ( newNbEntities != nbEntities ) { // Add all SObjects with icons to soToUpdateIcons @@ -2116,7 +2350,7 @@ void SMESH_Mesh_i::CheckGeomGroupModif() soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second )); } - list< SALOMEDS::SObject_var >::iterator so = soToUpdateIcons.begin(); + list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin(); for ( ; so != soToUpdateIcons.end(); ++so ) _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" ); } @@ -2128,24 +2362,25 @@ void SMESH_Mesh_i::CheckGeomGroupModif() //============================================================================= SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup ) + throw (SALOME::SALOME_Exception) { + SMESH::SMESH_Group_var aGroup; + + SMESH_TRY; + if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - SMESH::SMESH_Group_var aGroup; if ( theGroup->_is_nil() ) return aGroup._retn(); - Unexpect aCatch(SALOME_SalomeException); - - 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 ); @@ -2153,25 +2388,26 @@ 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_var aGroupSO; - SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy(); - if ( !aStudy->_is_nil() ) { - builder = aStudy->NewBuilder(); + SALOMEDS::SObject_wrap aGroupSO; + SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy(); + if ( !aStudy->_is_nil() ) { + builder = aStudy->NewBuilder(); aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup ); - if ( !aGroupSO->_is_nil() ) { - + if ( !aGroupSO->_is_nil() ) + { // remove reference to geometry - SALOMEDS::ChildIterator_var chItr = aStudy->NewChildIterator(aGroupSO); + SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO); for ( ; chItr->More(); chItr->Next() ) // Remove group's child SObject builder->RemoveObject( chItr->Value() ); // 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 ) @@ -2180,28 +2416,28 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase const int isEmpty = ( elemTypes->length() == 0 ); if ( !isEmpty ) { - SALOMEDS::GenericAttribute_var anAttr = + SALOMEDS::GenericAttribute_wrap anAttr = builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" ); - SALOMEDS::AttributePixMap_var pm = SALOMEDS::AttributePixMap::_narrow( anAttr ); + SALOMEDS::AttributePixMap_wrap pm = anAttr; pm->SetPixMap( "ICON_SMESH_TREE_GROUP" ); } } } } - // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i - SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl ); - aGroupImpl->Register(); - // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i - // remember new group in own map aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() ); _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup ); // register CORBA object for persistence - /*int nextId =*/ _gen_i->RegisterObject( aGroup ); + _gen_i->RegisterObject( aGroup ); + + CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup ); + builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register(); + //aGroup->Register(); + aGroupToRem->UnRegister(); - builder->SetIOR( aGroupSO, _gen_i->GetORB()->object_to_string( aGroup ) ); + SMESH_CATCH( SMESH::throwCorbaException ); return aGroup._retn(); } @@ -2215,21 +2451,23 @@ 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()); + const int subMeshId = mySubMesh->GetId(); + + SMESH_subMesh_i * subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId); + SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this(); - _mapSubMesh[subMeshId] = mySubMesh; - _mapSubMesh_i[subMeshId] = subMeshServant; - _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate(subMesh); + _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); + if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); } + else { nextId = 0; } // avoid "unused variable" warning // to track changes of GEOM groups addGeomGroupData( theSubShapeObject, subMesh ); @@ -2251,7 +2489,6 @@ SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID) return SMESH::SMESH_subMesh::_duplicate( (*it).second ); } - //============================================================================= /*! * @@ -2265,12 +2502,13 @@ 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()) + if ( _mapSubMesh.find( subMeshId ) != _mapSubMesh.end()) { - TopoDS_Shape S = _mapSubMesh[ shapeId ]->GetSubShape(); + TopoDS_Shape S = _mapSubMesh[ subMeshId ]->GetSubShape(); if ( !S.IsNull() ) { list hyps = _impl->GetHypothesisList( S ); @@ -2295,7 +2533,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); @@ -2316,12 +2563,15 @@ SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType 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 ); @@ -2339,17 +2589,14 @@ SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType else aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId ); - // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i - SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl ); - aGroupImpl->Register(); - // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i - - 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); + if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); } + else { nextId = 0; } // avoid "unused variable" warning in release mode // to track changes of GEOM groups if ( !theShape.IsNull() ) { @@ -2372,14 +2619,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(); } } @@ -2390,57 +2638,57 @@ void SMESH_Mesh_i::removeGroup( const int theId ) //============================================================================= SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet) -throw(SALOME::SALOME_Exception) + throw(SALOME::SALOME_Exception) { + SMESH::log_array_var aLog; + + SMESH_TRY; if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - SMESH::log_array_var aLog; - try{ - list < SMESHDS_Command * >logDS = _impl->GetLog(); - aLog = new SMESH::log_array; - int indexLog = 0; - int lg = logDS.size(); - SCRUTE(lg); - aLog->length(lg); - list < SMESHDS_Command * >::iterator its = logDS.begin(); - while(its != logDS.end()){ - SMESHDS_Command *com = *its; - int comType = com->GetType(); - //SCRUTE(comType); - int lgcom = com->GetNumber(); - //SCRUTE(lgcom); - const list < int >&intList = com->GetIndexes(); - int inum = intList.size(); - //SCRUTE(inum); - list < int >::const_iterator ii = intList.begin(); - const list < double >&coordList = com->GetCoords(); - int rnum = coordList.size(); - //SCRUTE(rnum); - list < double >::const_iterator ir = coordList.begin(); - aLog[indexLog].commandType = comType; - aLog[indexLog].number = lgcom; - aLog[indexLog].coords.length(rnum); - aLog[indexLog].indexes.length(inum); - for(int i = 0; i < rnum; i++){ - aLog[indexLog].coords[i] = *ir; - //MESSAGE(" "<logDS = _impl->GetLog(); + aLog = new SMESH::log_array; + int indexLog = 0; + int lg = logDS.size(); + SCRUTE(lg); + aLog->length(lg); + list < SMESHDS_Command * >::iterator its = logDS.begin(); + while(its != logDS.end()){ + SMESHDS_Command *com = *its; + int comType = com->GetType(); + //SCRUTE(comType); + int lgcom = com->GetNumber(); + //SCRUTE(lgcom); + const list < int >&intList = com->GetIndexes(); + int inum = intList.size(); + //SCRUTE(inum); + list < int >::const_iterator ii = intList.begin(); + const list < double >&coordList = com->GetCoords(); + int rnum = coordList.size(); + //SCRUTE(rnum); + list < double >::const_iterator ir = coordList.begin(); + aLog[indexLog].commandType = comType; + aLog[indexLog].number = lgcom; + aLog[indexLog].coords.length(rnum); + aLog[indexLog].indexes.length(inum); + for(int i = 0; i < rnum; i++){ + aLog[indexLog].coords[i] = *ir; + //MESSAGE(" "<ClearLog(); - } - catch(SALOME_Exception & S_ex){ - THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); + for(int i = 0; i < inum; i++){ + aLog[indexLog].indexes[i] = *ii; + //MESSAGE(" "<ClearLog(); + + SMESH_CATCH( SMESH::throwCorbaException ); + return aLog._retn(); } @@ -2453,8 +2701,9 @@ throw(SALOME::SALOME_Exception) void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception) { - if(MYDEBUG) MESSAGE("SMESH_Mesh_i::ClearLog"); + SMESH_TRY; _impl->ClearLog(); + SMESH_CATCH( SMESH::throwCorbaException ); } //============================================================================= @@ -2465,7 +2714,6 @@ void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception) CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception) { - if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetId"); return _id; } @@ -2541,18 +2789,26 @@ void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl) //============================================================================= SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor() + throw (SALOME::SALOME_Exception) { + SMESH::SMESH_MeshEditor_var aMeshEdVar; + + SMESH_TRY; if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); // Create MeshEditor - SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, false ); - SMESH::SMESH_MeshEditor_var aMesh = 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()"; - return aMesh._retn(); + SMESH_CATCH( SMESH::throwCorbaException ); + + return aMeshEdVar._retn(); } //============================================================================= @@ -2562,13 +2818,21 @@ SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor() //============================================================================= SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer() + throw (SALOME::SALOME_Exception) { + SMESH::SMESH_MeshEditor_var aMeshEdVar; + + SMESH_TRY; if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, true ); - SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this(); - return aMesh._retn(); + if ( !_previewEditor ) + _previewEditor = new SMESH_MeshEditor_i( this, true ); + aMeshEdVar = _previewEditor->_this(); + + SMESH_CATCH( SMESH::throwCorbaException ); + + return aMeshEdVar._retn(); } //================================================================================ @@ -2632,7 +2896,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(); @@ -2675,44 +2939,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 ); + 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); } } @@ -2731,25 +2987,23 @@ string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file, // Perform Export PrepareForWriting(file, overwrite); string aMeshName = "Mesh"; - SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy(); + SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy(); if ( !aStudy->_is_nil() ) { - SALOMEDS::SObject_var aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() ); + SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() ); if ( !aMeshSO->_is_nil() ) { CORBA::String_var name = aMeshSO->GetName(); aMeshName = name; // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes if ( !aStudy->GetProperties()->IsLocked() ) { - SALOMEDS::GenericAttribute_var anAttr; + SALOMEDS::GenericAttribute_wrap anAttr; SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder(); - SALOMEDS::AttributeExternalFileDef_var aFileName; anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef"); - aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr); + SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr; ASSERT(!aFileName->_is_nil()); aFileName->SetValue(file); - SALOMEDS::AttributeFileType_var aFileType; anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType"); - aFileType = SALOMEDS::AttributeFileType::_narrow(anAttr); + SALOMEDS::AttributeFileType_wrap aFileType = anAttr; ASSERT(!aFileType->_is_nil()); aFileType->SetValue("FICHIERMED"); } @@ -2757,7 +3011,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(); @@ -2774,18 +3029,24 @@ string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file, void SMESH_Mesh_i::ExportToMEDX (const char* file, CORBA::Boolean auto_groups, SMESH::MED_VERSION theVersion, - CORBA::Boolean overwrite) + CORBA::Boolean overwrite, + CORBA::Boolean autoDimension) throw(SALOME::SALOME_Exception) { - Unexpect aCatch(SALOME_SalomeException); + //MESSAGE("SMESH::MED_VERSION:"<< theVersion); + SMESH_TRY; if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); string aMeshName = prepareMeshNameAndGroups(file, overwrite); - TPythonDump() << _this() << ".ExportToMEDX( r'" - << file << "', " << auto_groups << ", " << theVersion << ", " << overwrite << " )"; + _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion, 0, autoDimension ); + + TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportToMEDX( r'" + << file << "', " << auto_groups << ", " + << theVersion << ", " << overwrite << ", " + << autoDimension << " )"; - _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion ); + SMESH_CATCH( SMESH::throwCorbaException ); } //================================================================================ @@ -2799,6 +3060,7 @@ void SMESH_Mesh_i::ExportToMED (const char* file, SMESH::MED_VERSION theVersion) throw(SALOME::SALOME_Exception) { + //MESSAGE("SMESH::MED_VERSION:"<< theVersion); ExportToMEDX(file,auto_groups,theVersion,true); } @@ -2812,7 +3074,8 @@ void SMESH_Mesh_i::ExportMED (const char* file, CORBA::Boolean auto_groups) throw(SALOME::SALOME_Exception) { - ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true); + //MESSAGE("SMESH::MED_VERSION:"<< SMESH::MED_LATEST); + ExportToMEDX(file,auto_groups,SMESH::MED_LATEST,true); } //================================================================================ @@ -2830,7 +3093,8 @@ void SMESH_Mesh_i::ExportSAUV (const char* file, _preMeshInfo->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); } @@ -2851,92 +3115,449 @@ 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); + _impl->ExportDAT(file); +} + +//================================================================================ +/*! + * \brief Export a mesh to an UNV file + */ +//================================================================================ + +void SMESH_Mesh_i::ExportUNV (const char *file) + throw(SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + + // Update Python script + // check names of groups + checkGroupNames(); + TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )"; + + // Perform Export + PrepareForWriting(file); + _impl->ExportUNV(file); +} + +//================================================================================ +/*! + * \brief Export a mesh to an STL file + */ +//================================================================================ + +void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii) + throw(SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + + // Update Python script + // check names of groups + checkGroupNames(); + TPythonDump() << SMESH::SMESH_Mesh_var(_this()) + << ".ExportSTL( r'" << file << "', " << isascii << " )"; + + CORBA::String_var name; + SALOMEDS::Study_var study = _gen_i->GetCurrentStudy(); + SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( study, _this() ); + if ( !so->_is_nil() ) + name = so->GetName(); + + // Perform Export + PrepareForWriting( file ); + _impl->ExportSTL( file, isascii, name.in() ); +} + +//================================================================================ +/*! + * \brief Export a part of mesh to a med file + */ +//================================================================================ + +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, + const GEOM::ListOfFields& fields, + const char* geomAssocFields) + throw (SALOME::SALOME_Exception) +{ + 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(); + + // write mesh + + string aMeshName = "Mesh"; + SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0); + if ( CORBA::is_nil( meshPart ) || + SMESH::DownCast< SMESH_Mesh_i* >( meshPart )) + { + aMeshName = prepareMeshNameAndGroups(file, overwrite); + _impl->ExportMED( file, aMeshName.c_str(), auto_groups, + version, 0, autoDimension, /*addODOnVertices=*/have0dField); + meshDS = _impl->GetMeshDS(); + } + else + { + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + + PrepareForWriting(file, overwrite); + + 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; + } + } + SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart ); + _impl->ExportMED( file, aMeshName.c_str(), auto_groups, + version, partDS, autoDimension, /*addODOnVertices=*/have0dField); + 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; + } + TPythonDump() << _this() << ".ExportPartToMED( " + << meshPart << ", r'" << file << "', " + << auto_groups << ", " << version << ", " << overwrite << ", " + << autoDimension << ", " << goList + << ", '" << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )"; - // Perform Export - PrepareForWriting(file); - _impl->ExportDAT(file); + SMESH_CATCH( SMESH::throwCorbaException ); } //================================================================================ /*! - * \brief Export a mesh to an UNV file + * Write GEOM fields to MED file */ //================================================================================ -void SMESH_Mesh_i::ExportUNV (const char *file) - throw(SALOME::SALOME_Exception) +void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter, + SMESHDS_Mesh* meshDS, + const GEOM::ListOfFields& fields, + const char* geomAssocFields) { - Unexpect aCatch(SALOME_SalomeException); - if ( _preMeshInfo ) - _preMeshInfo->FullLoadFromFile(); +#define METH "SMESH_Mesh_i::exportMEDFields() " - // Update Python script - // check names of groups - checkGroupNames(); - TPythonDump() << _this() << ".ExportUNV( r'" << file << "' )"; + if (( fields.length() < 1 ) && + ( !geomAssocFields || !geomAssocFields[0] )) + return; - // Perform Export - PrepareForWriting(file); - _impl->ExportUNV(file); -} + 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; -//================================================================================ -/*! - * \brief Export a mesh to an STL file - */ -//================================================================================ + 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(); -void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii) - throw(SALOME::SALOME_Exception) -{ - Unexpect aCatch(SALOME_SalomeException); - if ( _preMeshInfo ) - _preMeshInfo->FullLoadFromFile(); + if ( !fieldWriter.Set( meshDS, + name.in(), + elemType, + comps->length(), + /*isIntData=*/false ))//( dataType == GEOM::FDT_Int ))) + continue; - // Update Python script - // check names of groups - checkGroupNames(); - TPythonDump() << _this() << ".ExportSTL( r'" << file << "', " << isascii << " )"; + for ( size_t iC = 0; iC < comps->length(); ++iC ) + fieldWriter.SetCompName( iC, comps[ iC ].in() ); - // Perform Export - PrepareForWriting(file); - _impl->ExportSTL(file, isascii); -} + dblVals.resize( comps->length() ); + intVals.resize( comps->length() ); -//================================================================================ -/*! - * \brief Export a part of mesh to a med file - */ -//================================================================================ + // find sub-shape IDs -void SMESH_Mesh_i::ExportPartToMED(::SMESH::SMESH_IDSource_ptr meshPart, - const char* file, - CORBA::Boolean auto_groups, - ::SMESH::MED_VERSION version, - ::CORBA::Boolean overwrite) - throw (SALOME::SALOME_Exception) -{ - Unexpect aCatch(SALOME_SalomeException); - if ( _preMeshInfo ) - _preMeshInfo->FullLoadFromFile(); + 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 ); - PrepareForWriting(file, overwrite); + // write steps - string aMeshName = "Mesh"; - SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy(); - if ( !aStudy->_is_nil() ) { - SALOMEDS::SObject_var SO = _gen_i->ObjectToSObject( aStudy, meshPart ); - if ( !SO->_is_nil() ) { - CORBA::String_var name = SO->GetName(); - aMeshName = name; + 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; } - } - SMESH_MeshPartDS partDS( meshPart ); - _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, &partDS ); + 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; - TPythonDump() << _this() << ".ExportPartToMED( " << meshPart << ", r'" << file << "', " - << auto_groups << ", " << version << ", " << overwrite << " )"; + 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 } //================================================================================ @@ -2958,7 +3579,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 << "' )"; } //================================================================================ /*! @@ -2979,7 +3601,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 << "' )"; } //================================================================================ /*! @@ -2998,10 +3621,16 @@ void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart, PrepareForWriting(file); + CORBA::String_var name; + SALOMEDS::Study_var study = _gen_i->GetCurrentStudy(); + SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( study, 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 << ")"; } @@ -3013,7 +3642,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 @@ -3023,10 +3653,22 @@ void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart, PrepareForWriting(file,overwrite); + std::string meshName(""); + SALOMEDS::Study_var study = _gen_i->GetCurrentStudy(); + SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( study, 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 ); - TPythonDump() << _this() << ".ExportCGNS( " + SMESH_CATCH( SMESH::throwCorbaException ); + + TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( " << meshPart<< ", r'" << file << "', " << overwrite << ")"; #else THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR); @@ -3053,7 +3695,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 << ")"; @@ -3061,22 +3703,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) { @@ -3153,6 +3792,15 @@ CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception) return _impl->NbTriangles(); } +CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception) +{ + Unexpect aCatch(SALOME_SalomeException); + if ( _preMeshInfo ) + return _preMeshInfo->NbBiQuadTriangles(); + + return _impl->NbBiQuadTriangles(); +} + CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); @@ -3171,7 +3819,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 ) @@ -3180,6 +3828,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) { @@ -3377,7 +4034,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 ) @@ -3430,12 +4087,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 ); @@ -3456,14 +4110,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(); @@ -3479,10 +4133,17 @@ 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::ALL; + SMESH_TRY; + if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - return ( SMESH::ElementType )_impl->GetElementType( id, iselem ); + type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem ); + + SMESH_CATCH( SMESH::throwCorbaException ); + + return type; } //============================================================================= @@ -3504,6 +4165,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 @@ -3512,11 +4192,12 @@ SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id ) SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID) throw (SALOME::SALOME_Exception) { + SMESH::long_array_var aResult = new SMESH::long_array(); + + SMESH_TRY; if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - SMESH::long_array_var aResult = new SMESH::long_array(); - SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID); if(!SM) return aResult._retn(); @@ -3531,10 +4212,11 @@ SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID) aResult[i++] = eIt->next()->GetID(); } + SMESH_CATCH( SMESH::throwCorbaException ); + return aResult._retn(); } - //============================================================================= /*! * Returns ID of nodes for given submesh @@ -3542,15 +4224,17 @@ 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) { + SMESH::long_array_var aResult = new SMESH::long_array(); + + SMESH_TRY; if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - SMESH::long_array_var aResult = new SMESH::long_array(); - SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID); if(!SM) return aResult._retn(); @@ -3583,6 +4267,8 @@ SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) aResult[i++] = *itElem; + SMESH_CATCH( SMESH::throwCorbaException ); + return aResult._retn(); } @@ -3595,6 +4281,9 @@ 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::ALL; + + SMESH_TRY; if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); @@ -3609,7 +4298,12 @@ SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID SMDS_ElemIteratorPtr eIt = SDSM->GetElements(); const SMDS_MeshElement* anElem = eIt->next(); - return ( SMESH::ElementType ) anElem->GetType(); + + type = ( SMESH::ElementType ) anElem->GetType(); + + SMESH_CATCH( SMESH::throwCorbaException ); + + return type; } @@ -3625,8 +4319,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(); @@ -3675,28 +4368,22 @@ SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id) _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); + 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()) { + aResult->length( aNode->NbInverseElements() ); + 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(); } @@ -3728,17 +4415,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; @@ -3755,6 +4441,52 @@ SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID) return aNodePosition; } +//============================================================================= +/*! + * \brief Return position of an element on shape + */ +//============================================================================= + +SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID) +{ + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + + SMESH::ElementPosition anElementPosition; + anElementPosition.shapeID = 0; + anElementPosition.shapeType = GEOM::SHAPE; + + SMESHDS_Mesh* mesh = _impl->GetMeshDS(); + if ( !mesh ) return anElementPosition; + + if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) ) + { + anElementPosition.shapeID = anElem->getshapeId(); + const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() ); + if ( !aSp.IsNull() ) { + switch ( aSp.ShapeType() ) { + case TopAbs_EDGE: + anElementPosition.shapeType = GEOM::EDGE; + break; + case TopAbs_FACE: + anElementPosition.shapeType = GEOM::FACE; + break; + case TopAbs_VERTEX: + anElementPosition.shapeType = GEOM::VERTEX; + break; + case TopAbs_SOLID: + anElementPosition.shapeType = GEOM::SOLID; + break; + case TopAbs_SHELL: + anElementPosition.shapeType = GEOM::SHELL; + break; + default:; + } + } + } + return anElementPosition; +} + //============================================================================= /*! * If given element is node returns IDs of shape from position @@ -3767,12 +4499,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(); } @@ -3794,16 +4526,15 @@ 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; - //SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor(); ::SMESH_MeshEditor aMeshEditor(_impl); int index = aMeshEditor.FindShape( elem ); if(index>0) @@ -3825,10 +4556,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(); } @@ -3847,9 +4578,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(); @@ -3867,9 +4598,9 @@ 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 ) @@ -3891,13 +4622,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); @@ -3917,11 +4648,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) ); @@ -3947,9 +4678,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(); } @@ -3966,37 +4697,64 @@ 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(); } //======================================================================= //function : GetElemFaceNodes -//purpose : Returns nodes of given face (counted from zero) for given element. +//purpose : Returns nodes of given face (counted from zero) for given element. +//======================================================================= + +SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId, + CORBA::Short faceIndex) +{ + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + + SMESH::long_array_var aResult = new SMESH::long_array(); + if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) + { + if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) ) + { + SMDS_VolumeTool vtool( elem ); + if ( faceIndex < vtool.NbFaces() ) + { + aResult->length( vtool.NbFaceNodes( faceIndex )); + const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex ); + for ( CORBA::ULong i = 0; i < aResult->length(); ++i ) + aResult[ i ] = nn[ i ]->GetID(); + } + } + } + return aResult._retn(); +} + +//======================================================================= +//function : GetElemFaceNodes +//purpose : Returns three components of normal of given mesh face. //======================================================================= -SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId, - CORBA::Short faceIndex) +SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId, + CORBA::Boolean normalized) { if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - SMESH::long_array_var aResult = new SMESH::long_array(); - if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() ) + SMESH::double_array_var aResult = new SMESH::double_array(); + + if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() ) { - if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) ) + gp_XYZ normal; + if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized )) { - SMDS_VolumeTool vtool( elem ); - if ( faceIndex < vtool.NbFaces() ) - { - aResult->length( vtool.NbFaceNodes( faceIndex )); - const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex ); - for ( int i = 0; i < aResult->length(); ++i ) - aResult[ i ] = nn[ i ]->GetID(); - } + aResult->length( 3 ); + aResult[ 0 ] = normal.X(); + aResult[ 1 ] = normal.Y(); + aResult[ 2 ] = normal.Z(); } } return aResult._retn(); @@ -4016,11 +4774,11 @@ 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; - const SMDS_MeshElement* elem = mesh->FindElement( nn ); + const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false ); if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) || _impl->NbFaces ( ORDER_QUADRATIC ) || _impl->NbVolumes( ORDER_QUADRATIC ))) @@ -4031,6 +4789,35 @@ CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes) 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 result._retn(); +} + //============================================================================= /*! * Returns true if given element is polygon @@ -4042,9 +4829,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(); } @@ -4061,9 +4848,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(); } @@ -4080,7 +4867,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; @@ -4098,11 +4885,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(); @@ -4137,6 +4924,98 @@ SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id) return aResult._retn(); } +//================================================================================ +/*! + * \brief Create a group of elements preventing computation of a sub-shape + */ +//================================================================================ + +SMESH::ListOfGroups* +SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID, + const char* theGroupName ) + throw ( SALOME::SALOME_Exception ) +{ + Unexpect aCatch(SALOME_SalomeException); + + if ( !theGroupName || strlen( theGroupName) == 0 ) + 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; + if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID )) + { + // compute error + SMESH_ComputeErrorPtr error = sm->GetComputeError(); + if ( error && error->HasBadElems() ) + { + // sort bad elements by type + vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ]; + 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; + if ( !elem ) continue; + + if ( elem->GetID() < 1 ) + { + // elem is a temporary element, make a real element + vector< const SMDS_MeshNode* > nodes; + SMDS_NodeIteratorPtr nIt = elem->nodeIterator(); + while ( nIt->more() && elem ) + { + nodes.push_back( nIt->next() ); + if ( nodes.back()->GetID() < 1 ) + elem = 0; // a temporary element on temporary nodes + } + if ( elem ) + { + ::SMESH_MeshEditor editor( _impl ); + elem = editor.AddElement( nodes, elemType.Init( elem )); + } + } + if ( elem ) + elemsByType[ elem->GetType() ].push_back( elem ); + } + + // how many groups to create? + int nbTypes = 0; + for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i ) + nbTypes += int( !elemsByType[ i ].empty() ); + groups->length( nbTypes ); + + // create groups + for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i ) + { + vector< const SMDS_MeshElement* >& elems = elemsByType[ i ]; + if ( elems.empty() ) continue; + + groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName ); + if ( _gen_i->CanPublishInStudy( groups[ iG ] )) + { + SALOMEDS::Study_var study = _gen_i->GetCurrentStudy(); + SMESH::SMESH_Mesh_var mesh = _this(); + SALOMEDS::SObject_wrap aSO = + _gen_i->PublishGroup( study, mesh, groups[ iG ], + GEOM::GEOM_Object::_nil(), theGroupName); + } + SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]); + if ( !grp_i ) continue; + + if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() )) + for ( size_t iE = 0; iE < elems.size(); ++iE ) + grpDS->SMDSGroup().Add( elems[ iE ]); + } + } + } + + return groups._retn(); +} //============================================================================= /*! @@ -4146,7 +5025,8 @@ SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id) void SMESH_Mesh_i::CreateGroupServants() { - SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy(); + SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy(); + SMESH::SMESH_Mesh_var aMesh = _this(); set addedIDs; ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups(); @@ -4172,22 +5052,19 @@ void SMESH_Mesh_i::CreateGroupServants() aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId ); } - // To ensure correct mapping of servant and correct reference counting in GenericObj_i - SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl ); - aGroupImpl->Register(); - - 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 ); - if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId); + if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); } + 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()); + _gen_i->PublishGroup( aStudy, aMesh, groupVar, shapeVar, group->GetName()); } } if ( !addedIDs.empty() ) @@ -4198,7 +5075,7 @@ 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 << " ]"; } } } @@ -4232,11 +5109,11 @@ 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; } @@ -4255,7 +5132,7 @@ void SMESH_Mesh_i::checkGroupNames() if ( !nbGrp ) return; - SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy(); + SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy(); if ( aStudy->_is_nil() ) return; // nothing to do @@ -4271,7 +5148,7 @@ void SMESH_Mesh_i::checkGroupNames() SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ]; if ( !aGrp ) continue; - SALOMEDS::SObject_var aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp ); + SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp ); if ( aGrpSO->_is_nil() ) continue; // correct name of the mesh group if necessary @@ -4288,9 +5165,8 @@ void SMESH_Mesh_i::checkGroupNames() //============================================================================= void SMESH_Mesh_i::SetParameters(const char* theParameters) { - // SMESH_Gen_i::GetSMESHGen()->UpdateParameters(SMESH::SMESH_Mesh::_narrow(_this()), - // CORBA::string_dup(theParameters)); - SMESH_Gen_i::GetSMESHGen()->UpdateParameters(theParameters); + SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(), + theParameters ); } //============================================================================= @@ -4298,10 +5174,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()) ); } //============================================================================= @@ -4314,15 +5190,15 @@ 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_ptr aStudy = gen->GetCurrentStudy(); - if(!aStudy->_is_nil()) { + CORBA::String_var 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]); + 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] ); } } } @@ -4348,6 +5224,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(); @@ -4376,7 +5254,7 @@ bool SMESH_Mesh_i::IsMeshInfoCorrect() //============================================================================= /*! - * \brief Returns statistic of mesh elements + * \brief Returns number of mesh elements per each \a EntityType */ //============================================================================= @@ -4400,7 +5278,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 */ //============================================================================= @@ -4411,6 +5315,267 @@ 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 octect buffer of required size + CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size); + //Copy ostrstream content to the octect 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; + + PredicateIterator( SMDS_ElemIteratorPtr iterator, + PredicatePtr predicate): + _elemIter(iterator), _predicate(predicate) + { + next(); + } + virtual bool more() + { + return _elem; + } + virtual const SMDS_MeshElement* next() + { + const SMDS_MeshElement* res = _elem; + _elem = 0; + while ( _elemIter->more() && !_elem ) + { + _elem = _elemIter->next(); + if ( _elem && ( !_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 || + 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 ); + elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() )); + typeOK = ( filterType == elemType || elemType == SMDSAbs_All ); + } + } + } + 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; + 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, elemType )); + } + else + { + SMESH::long_array_var ids = theObject->GetIDs(); + elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType )); + } + 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 @@ -4435,10 +5600,10 @@ 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. */ @@ -4459,9 +5624,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 ); @@ -4473,7 +5638,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 { @@ -4555,7 +5720,7 @@ class SMESH_DimHyp if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt ) nbSame++; // the submeshes are concurrent if their algorithms has different parameters - return nbSame != theOther->_hypotheses.size() - 1; + return nbSame != (int)theOther->_hypotheses.size() - 1; } // Return true if algorithm of this SMESH_DimHyp is used if no @@ -4693,8 +5858,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 @@ -4708,14 +5902,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; @@ -4778,7 +5995,7 @@ 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 @@ -4787,11 +6004,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; } //============================================================================= @@ -4810,13 +6024,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 @@ -4876,11 +6092,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 = @@ -4894,7 +6111,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 ); @@ -4902,10 +6120,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 @@ -4916,6 +6152,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() ); @@ -4935,14 +6172,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 ) { @@ -4958,6 +6195,8 @@ SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart): } myInfo = tmpInfo; + ShapeToMesh( _meshDS->ShapeToMesh() ); + _meshDS = 0; // to enforce iteration on _elements and _nodes } } @@ -4983,6 +6222,21 @@ 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; +} +// ------------------------------------------------------------------------------------- SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const { if ( _meshDS ) return _meshDS->elementGeomIterator( geomType ); @@ -4994,7 +6248,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(), @@ -5012,7 +6266,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(), @@ -5039,10 +6293,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() )); \ } // -------------------------------------------------------------------------------------