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=5669a0b223231e19dc0a3abc51ca077bb57a4232;hp=cf844162374e6285040eda9a199d0916670d2919;hb=fd1943809d016d0223da20a2a492b157cb17146a;hpb=9a54694a0ab1e5cbc558a35c4606ceea4f7af2ef diff --git a/src/SMESH_I/SMESH_Mesh_i.cxx b/src/SMESH_I/SMESH_Mesh_i.cxx index cf8441623..5669a0b22 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-2015 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,7 +26,9 @@ #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_EdgePosition.hxx" #include "SMDS_ElemIterator.hxx" #include "SMDS_FacePosition.hxx" @@ -38,11 +40,14 @@ #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" @@ -51,12 +56,9 @@ #include "SMESH_PythonDump.hxx" #include "SMESH_subMesh_i.hxx" -#include #include #include -#include #include -#include #include #include @@ -64,30 +66,25 @@ // OCCT Includes #include -#include -#include -#include -#include -#include -#include +#include #include -#include -#include #include #include #include #include #include -#include "SMESH_TryCatch.hxx" // include after OCCT headers! - // STL Includes #include -#include #include #include -#include +#include + +// to pass CORBA exception through SMESH_TRY +#define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; } + +#include "SMESH_TryCatch.hxx" // include after OCCT headers! #ifdef _DEBUG_ static int MYDEBUG = 0; @@ -112,11 +109,14 @@ SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA, : 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; } //============================================================================= @@ -134,10 +134,8 @@ SMESH_Mesh_i::~SMESH_Mesh_i() for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++) if (SMESH_GroupBase_i* aGroup = SMESH::DownCast(itGr->second)) { - // _impl->RemoveGroup() is called by ~SMESH_GroupBase_i() (PAL6331) - //_impl->RemoveGroup( aGroup->GetLocalID() ); - aGroup->myMeshServant = 0; aGroup->UnRegister(); + SMESH::SMESH_GroupBase_var( itGr->second ); } _mapGroups.clear(); @@ -147,18 +145,29 @@ SMESH_Mesh_i::~SMESH_Mesh_i() if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast( itSM->second )) { aSubMesh->UnRegister(); + SMESH::SMESH_subMesh_var( itSM->second ); } _mapSubMeshIor.clear(); - // destroy hypotheses + // destroy hypotheses. _mapHypo contains all hyps ever been assigned map::iterator itH; - for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) - if ( SMESH_Hypothesis_i* aHypo = SMESH::DownCast( itH->second )) - { - aHypo->UnRegister(); - } + for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) { + if ( SMESH_Hypothesis_i* hyp_i = SMESH::DownCast( itH->second )) + if ( SMESH_Hypothesis * smHyp = _impl->GetHypothesis( itH->first )) + if ( _impl->GetMeshDS()->IsUsedHypothesis( smHyp )) + hyp_i->UnRegister(); + + SMESH::SMESH_Hypothesis_var( itH->second ); // decref CORBA object + } _mapHypo.clear(); + // clear cashed shapes if no more meshes remain; (the cash is blame, + // together with publishing, of spent time increasing in issue 22874) + if ( _impl->NbMeshes() == 1 ) + _gen_i->GetShapeReader()->ClearClientBuffer(); + + delete _editor; _editor = NULL; + delete _previewEditor; _previewEditor = NULL; delete _impl; _impl = NULL; delete _preMeshInfo; _preMeshInfo = NULL; } @@ -184,7 +193,10 @@ void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject ) THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); } // to track changes of GEOM groups - addGeomGroupData( theShapeObject, _this() ); + SMESH::SMESH_Mesh_var mesh = _this(); + addGeomGroupData( theShapeObject, mesh ); + if ( !CORBA::is_nil( theShapeObject )) + _mainShapeTick = theShapeObject->GetTick(); } //================================================================================ @@ -267,14 +279,14 @@ void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception) try { _impl->Clear(); - CheckGeomGroupModif(); // issue 20145 + //CheckGeomGroupModif(); // issue 20145 } catch(SALOME_Exception & S_ex) { THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); } _impl->GetMeshDS()->Modified(); - TPythonDump() << _this() << ".Clear()"; + TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()"; } //================================================================================ @@ -298,7 +310,7 @@ void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID) } _impl->GetMeshDS()->Modified(); - TPythonDump() << _this() << ".ClearSubMesh( " << ShapeID << " )"; + TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )"; } //============================================================================= @@ -347,7 +359,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(); @@ -382,20 +394,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); } @@ -437,7 +442,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() ); } @@ -551,6 +556,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; @@ -566,31 +572,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); } @@ -601,19 +608,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 @@ -621,22 +626,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 ); - _mapHypo[hypId]->Register(); + const int hypId = anHyp->GetId(); + std::string error; + status = _impl->AddHypothesis( myLocSubShape, hypId, &error ); + if ( !SMESH_Hypothesis::IsStatusFatal(status) ) + { + _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp ); + anHyp->Register(); // assure there is a corresponding submesh if ( !_impl->IsMainShape( myLocSubShape )) { int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape ); if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() ) - createSubMesh( aSubShapeObject ); + SMESH::SMESH_subMesh_var( createSubMesh( aSubShape )); } } + else if ( anErrorText ) + { + *anErrorText = error; + } } catch(SALOME_Exception & S_ex) { @@ -651,30 +662,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); } @@ -686,17 +696,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; @@ -704,15 +712,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) { @@ -728,30 +739,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) { @@ -792,7 +805,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(); } @@ -802,20 +815,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 @@ -831,15 +843,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 )) { + subMesh = createSubMesh( aSubShape ); + if ( _gen_i->CanPublishInStudy( subMesh )) + { + SALOMEDS::Study_var study = _gen_i->GetCurrentStudy(); SALOMEDS::SObject_wrap aSO = - _gen_i->PublishSubMesh(_gen_i->GetCurrentStudy(), aMesh, - subMesh, aSubShapeObject, theName ); + _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 << "' )"; } } } @@ -859,11 +872,11 @@ void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh ) throw (SALOME::SALOME_Exception) { SMESH_TRY; - + if ( theSubMesh->_is_nil() ) return; - GEOM::GEOM_Object_var aSubShapeObject; + GEOM::GEOM_Object_var aSubShape; SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy(); if ( !aStudy->_is_nil() ) { // Remove submesh's SObject @@ -875,20 +888,20 @@ void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh ) anObj->ReferencedObject( aRef.inout() )) { CORBA::Object_var obj = aRef->GetObject(); - aSubShapeObject = GEOM::GEOM_Object::_narrow( obj ); + aSubShape = GEOM::GEOM_Object::_narrow( obj ); } - // if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617) - // aSubShapeObject = theSubMesh->GetSubShape(); + // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617) + // aSubShape = theSubMesh->GetSubShape(); 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(); @@ -903,7 +916,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 ) @@ -912,20 +925,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 ) ) { + 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(_gen_i->GetCurrentStudy(), _this(), - aNewGroup, GEOM::GEOM_Object::_nil(), theName); - if ( !aSO->_is_nil()) { + _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(); } - //============================================================================= /*! * @@ -935,7 +948,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 ) @@ -946,18 +959,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 ) ) { + 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(_gen_i->GetCurrentStudy(), _this(), - aNewGroup, theGeomObj, theName); - if ( !aSO->_is_nil()) { - // Update Python script - TPythonDump() << aSO << " = " << _this() << ".CreateGroupFromGEOM(" + _gen_i->PublishGroup( study, mesh, aNewGroup, theGeomObj, theName ); + if ( !aSO->_is_nil()) + TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( " << theElemType << ", '" << theName << "', " << theGeomObj << " )"; - } } } @@ -978,7 +991,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 ) @@ -1000,16 +1013,15 @@ SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType, 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(_gen_i->GetCurrentStudy(), _this(), aNewGroup, - GEOM::GEOM_Object::_nil(), theName); - if ( !aSO->_is_nil()) { - // Update Python script - pd << aSO << " = " << _this() << ".CreateGroupFromFilter(" + _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(); } @@ -1020,25 +1032,25 @@ SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType, //============================================================================= void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup ) - throw (SALOME::SALOME_Exception) + throw (SALOME::SALOME_Exception) { if ( theGroup->_is_nil() ) return; SMESH_TRY; - SMESH_GroupBase_i* aGroup = - dynamic_cast( SMESH_Gen_i::GetServant( theGroup ).in() ); + SMESH_GroupBase_i* aGroup = SMESH::DownCast( theGroup ); if ( !aGroup ) return; SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy(); - if ( !aStudy->_is_nil() ) { + if ( !aStudy->_is_nil() ) + { SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup ); - - if ( !aGroupSO->_is_nil() ) { + if ( !aGroupSO->_is_nil() ) + { // Update Python script - TPythonDump() << _this() << ".RemoveGroup( " << aGroupSO << " )"; + TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )"; // Remove group's SObject SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder(); @@ -1068,24 +1080,17 @@ void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup if ( theGroup->_is_nil() ) return; - SMESH_GroupBase_i* aGroup = - dynamic_cast( SMESH_Gen_i::GetServant( theGroup ).in() ); - if ( !aGroup ) - return; - - SMESH::long_array_var anIds = aGroup->GetListOfID(); - SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor(); - - TPythonDump pyDump; // Supress dump from RemoveNodes/Elements() and RemoveGroup() - // Remove contents - if ( aGroup->GetType() == SMESH::NODE ) - aMeshEditor->RemoveNodes( anIds ); - else - aMeshEditor->RemoveElements( anIds ); + SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup ); + SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() ); + while ( elemIt->more() ) + _impl->GetMeshDS()->RemoveElement( elemIt->next() ); + + TPythonDump pyDump; // Supress dump from RemoveGroup() // 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 ); @@ -1096,7 +1101,7 @@ void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup //================================================================================ /*! * \brief Get the list of groups existing in the mesh - * \retval SMESH::ListOfGroups * - list of groups + * \retval SMESH::ListOfGroups * - list of groups */ //================================================================================ @@ -1109,30 +1114,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(); } @@ -1149,14 +1151,14 @@ CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception) } //============================================================================= -/*! UnionGroups - * New group is created. All mesh elements that are - * present in initial groups are added to the new one +/*! + * New group including all mesh elements present in initial groups is created. */ //============================================================================= + SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1, SMESH::SMESH_GroupBase_ptr theGroup2, - const char* theName ) + const char* theName ) throw (SALOME::SALOME_Exception) { SMESH::SMESH_Group_var aResGrp; @@ -1165,10 +1167,12 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr the if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - if ( theGroup1->_is_nil() || theGroup2->_is_nil() || - theGroup1->GetType() != theGroup2->GetType() ) - return SMESH::SMESH_Group::_nil(); - + if ( theGroup1->_is_nil() || theGroup2->_is_nil() ) + THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group", + SALOME::BAD_PARAM); + if ( theGroup1->GetType() != theGroup2->GetType() ) + THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types", + SALOME::BAD_PARAM); TPythonDump pyDump; // Create Union @@ -1176,31 +1180,12 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr the if ( aResGrp->_is_nil() ) return SMESH::SMESH_Group::_nil(); - SMESH::long_array_var anIds1 = theGroup1->GetListOfID(); - SMESH::long_array_var anIds2 = theGroup2->GetListOfID(); - - TColStd_MapOfInteger aResMap; - - for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ ) - aResMap.Add( anIds1[ i1 ] ); - - for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ ) - aResMap.Add( anIds2[ i2 ] ); - - SMESH::long_array_var aResIds = new SMESH::long_array; - aResIds->length( aResMap.Extent() ); - - int resI = 0; - TColStd_MapIteratorOfMapOfInteger anIter( aResMap ); - for( ; anIter.More(); anIter.Next() ) - aResIds[ resI++ ] = anIter.Key(); - - aResGrp->Add( aResIds ); + aResGrp->AddFrom( theGroup1 ); + aResGrp->AddFrom( theGroup2 ); // Update Python script - pyDump << aResGrp << " = " << _this() << ".UnionGroups( " - << theGroup1 << ", " << theGroup2 << ", '" - << theName << "' )"; + pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) + << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )"; SMESH_CATCH( SMESH::throwCorbaException ); @@ -1209,72 +1194,62 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr the //============================================================================= /*! - \brief Union list of groups. New group is created. All mesh elements that are - present in initial groups are added to the new one. - \param theGroups list of groups - \param theName name of group to be created - \return pointer on the group -*/ + * \brief New group including all mesh elements present in initial groups is created. + * \param theGroups list of groups + * \param theName name of group to be created + * \return pointer to the new group + */ //============================================================================= + SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups, const char* theName ) throw (SALOME::SALOME_Exception) { + SMESH::SMESH_Group_var aResGrp; + if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); if ( !theName ) return SMESH::SMESH_Group::_nil(); - SMESH::SMESH_Group_var aResGrp; - SMESH_TRY; - vector< int > anIds; + // check types SMESH::ElementType aType = SMESH::ALL; for ( int g = 0, n = theGroups.length(); g < n; g++ ) { SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ]; if ( CORBA::is_nil( aGrp ) ) continue; - - // check type - SMESH::ElementType aCurrType = aGrp->GetType(); if ( aType == SMESH::ALL ) - aType = aCurrType; - else - { - if ( aType != aCurrType ) - return SMESH::SMESH_Group::_nil(); - } - - // unite ids - SMESH::long_array_var aCurrIds = aGrp->GetListOfID(); - for ( int i = 0, n = aCurrIds->length(); i < n; i++ ) - { - int aCurrId = aCurrIds[ i ]; - anIds.push_back( aCurrId ); - } + aType = aGrp->GetType(); + else if ( aType != aGrp->GetType() ) + THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types", + SALOME::BAD_PARAM); } + if ( aType == SMESH::ALL ) + return SMESH::SMESH_Group::_nil(); TPythonDump pyDump; - // Create group + // Create Union aResGrp = CreateGroup( aType, theName ); if ( aResGrp->_is_nil() ) return SMESH::SMESH_Group::_nil(); - // Create array of identifiers - SMESH::long_array_var aResIds = new SMESH::long_array; - aResIds->length( anIds.size() ); - - for ( size_t i = 0; iAdd( aResIds ); - - // Update Python script - pyDump << aResGrp << " = " << _this() << ".UnionListOfGroups( " - << &theGroups << ", '" << theName << "' )"; + pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ "; + for ( int g = 0, n = theGroups.length(); g < n; g++ ) + { + SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ]; + if ( !CORBA::is_nil( aGrp ) ) + { + aResGrp->AddFrom( aGrp ); + if ( g > 0 ) pyDump << ", "; + pyDump << aGrp; + } + } + pyDump << " ], '" << theName << "' )"; SMESH_CATCH( SMESH::throwCorbaException ); @@ -1282,11 +1257,12 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups } //============================================================================= -/*! IntersectGroups +/*! * New group is created. All mesh elements that are * present in both initial groups are added to the new one. */ //============================================================================= + SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1, SMESH::SMESH_GroupBase_ptr theGroup2, const char* theName ) @@ -1295,41 +1271,47 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr SMESH::SMESH_Group_var aResGrp; SMESH_TRY; + if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - if ( theGroup1->_is_nil() || theGroup2->_is_nil() || - theGroup1->GetType() != theGroup2->GetType() ) - return SMESH::SMESH_Group::_nil(); - + if ( theGroup1->_is_nil() || theGroup2->_is_nil() ) + THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group", + SALOME::BAD_PARAM); + if ( theGroup1->GetType() != theGroup2->GetType() ) + THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types", + SALOME::BAD_PARAM); TPythonDump pyDump; // Create Intersection aResGrp = CreateGroup( theGroup1->GetType(), theName ); if ( aResGrp->_is_nil() ) - return aResGrp; - - SMESH::long_array_var anIds1 = theGroup1->GetListOfID(); - SMESH::long_array_var anIds2 = theGroup2->GetListOfID(); - - TColStd_MapOfInteger aMap1; + return aResGrp._retn(); - for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ ) - aMap1.Add( anIds1[ i1 ] ); + SMESHDS_GroupBase* groupDS1 = 0; + if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 )) + groupDS1 = grp_i->GetGroupDS(); - TColStd_SequenceOfInteger aSeq; - for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ ) - if ( aMap1.Contains( anIds2[ i2 ] ) ) - aSeq.Append( anIds2[ i2 ] ); + SMESHDS_GroupBase* groupDS2 = 0; + if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 )) + groupDS2 = grp_i->GetGroupDS(); - SMESH::long_array_var aResIds = new SMESH::long_array; - aResIds->length( aSeq.Length() ); - for ( size_t resI = 0, resN = aSeq.Length(); resI < resN; resI++ ) - aResIds[ resI ] = aSeq( resI + 1 ); - aResGrp->Add( aResIds ); + SMESHDS_Group* resGroupDS = 0; + if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp )) + resGroupDS = dynamic_cast( grp_i->GetGroupDS() ); + if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() ) + { + SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements(); + while ( elemIt1->more() ) + { + const SMDS_MeshElement* e = elemIt1->next(); + if ( groupDS2->Contains( e )) + resGroupDS->SMDSGroup().Add( e ); + } + } // Update Python script - pyDump << aResGrp << " = " << _this() << ".IntersectGroups( " + pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "')"; SMESH_CATCH( SMESH::throwCorbaException ); @@ -1354,72 +1336,69 @@ SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups, SMESH::SMESH_Group_var aResGrp; SMESH_TRY; + if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); if ( !theName ) return SMESH::SMESH_Group::_nil(); - NCollection_DataMap< int, int > anIdToCount; + // check types and get SMESHDS_GroupBase's SMESH::ElementType aType = SMESH::ALL; + vector< SMESHDS_GroupBase* > groupVec; for ( int g = 0, n = theGroups.length(); g < n; g++ ) { SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ]; if ( CORBA::is_nil( aGrp ) ) continue; - - // check type - SMESH::ElementType aCurrType = aGrp->GetType(); if ( aType == SMESH::ALL ) - aType = aCurrType; - else - { - if ( aType != aCurrType ) - return SMESH::SMESH_Group::_nil(); - } + aType = aGrp->GetType(); + else if ( aType != aGrp->GetType() ) + THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types", + SALOME::BAD_PARAM); - // calculates number of occurance ids in groups - SMESH::long_array_var aCurrIds = aGrp->GetListOfID(); - for ( int i = 0, n = aCurrIds->length(); i < n; i++ ) - { - int aCurrId = aCurrIds[ i ]; - if ( !anIdToCount.IsBound( aCurrId ) ) - anIdToCount.Bind( aCurrId, 1 ); - else - anIdToCount( aCurrId ) = anIdToCount( aCurrId ) + 1; - } - } - - // create map of ids - int nbGrp = theGroups.length(); - vector< int > anIds; - NCollection_DataMap< int, int >::Iterator anIter( anIdToCount ); - for ( ; anIter.More(); anIter.Next() ) - { - int aCurrId = anIter.Key(); - int aCurrNb = anIter.Value(); - if ( aCurrNb == nbGrp ) - anIds.push_back( aCurrId ); + if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp )) + if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() ) + { + if ( grpDS->IsEmpty() ) + { + groupVec.clear(); + break; + } + groupVec.push_back( grpDS ); + } } + if ( aType == SMESH::ALL ) // all groups are nil + return SMESH::SMESH_Group::_nil(); TPythonDump pyDump; - // Create group + // Create a group aResGrp = CreateGroup( aType, theName ); - if ( aResGrp->_is_nil() ) - return SMESH::SMESH_Group::_nil(); - // Create array of identifiers - SMESH::long_array_var aResIds = new SMESH::long_array; - aResIds->length( anIds.size() ); + SMESHDS_Group* resGroupDS = 0; + if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp )) + resGroupDS = dynamic_cast( grp_i->GetGroupDS() ); + if ( !resGroupDS || groupVec.empty() ) + return aResGrp._retn(); + + // Fill the group + size_t i, nb = groupVec.size(); + SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements(); + while ( elemIt1->more() ) + { + const SMDS_MeshElement* e = elemIt1->next(); + bool inAll = true; + for ( i = 1; ( i < nb && inAll ); ++i ) + inAll = groupVec[i]->Contains( e ); - for ( size_t i = 0; iAdd( aResIds ); + if ( inAll ) + resGroupDS->SMDSGroup().Add( e ); + } // Update Python script - pyDump << aResGrp << " = " << _this() << ".IntersectListOfGroups( " - << &theGroups << ", '" << theName << "' )"; + pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() ) + << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )"; SMESH_CATCH( SMESH::throwCorbaException ); @@ -1427,11 +1406,12 @@ SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups, } //============================================================================= -/*! CutGroups +/*! * New group is created. All mesh elements that are present in - * main group but do not present in tool group are added to the new one + * a main group but is not present in a tool group are added to the new one */ //============================================================================= + SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1, SMESH::SMESH_GroupBase_ptr theGroup2, const char* theName ) @@ -1440,44 +1420,47 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGr SMESH::SMESH_Group_var aResGrp; SMESH_TRY; + if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - if ( theGroup1->_is_nil() || theGroup2->_is_nil() || - theGroup1->GetType() != theGroup2->GetType() ) - return SMESH::SMESH_Group::_nil(); - + if ( theGroup1->_is_nil() || theGroup2->_is_nil() ) + THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group", + SALOME::BAD_PARAM); + if ( theGroup1->GetType() != theGroup2->GetType() ) + THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types", + SALOME::BAD_PARAM); TPythonDump pyDump; - // Perform Cutting aResGrp = CreateGroup( theGroup1->GetType(), theName ); if ( aResGrp->_is_nil() ) - return aResGrp; - - SMESH::long_array_var anIds1 = theGroup1->GetListOfID(); - SMESH::long_array_var anIds2 = theGroup2->GetListOfID(); - - TColStd_MapOfInteger aMap2; - - for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ ) - aMap2.Add( anIds2[ i2 ] ); + return aResGrp._retn(); - TColStd_SequenceOfInteger aSeq; - for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ ) - if ( !aMap2.Contains( anIds1[ i1 ] ) ) - aSeq.Append( anIds1[ i1 ] ); + SMESHDS_GroupBase* groupDS1 = 0; + if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 )) + groupDS1 = grp_i->GetGroupDS(); - SMESH::long_array_var aResIds = new SMESH::long_array; - aResIds->length( aSeq.Length() ); + SMESHDS_GroupBase* groupDS2 = 0; + if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 )) + groupDS2 = grp_i->GetGroupDS(); - for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ ) - aResIds[ resI ] = aSeq( resI + 1 ); - aResGrp->Add( aResIds ); + SMESHDS_Group* resGroupDS = 0; + if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp )) + resGroupDS = dynamic_cast( grp_i->GetGroupDS() ); + if ( groupDS1 && groupDS2 && resGroupDS ) + { + SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements(); + while ( elemIt1->more() ) + { + const SMDS_MeshElement* e = elemIt1->next(); + if ( !groupDS2->Contains( e )) + resGroupDS->SMDSGroup().Add( e ); + } + } // Update Python script - pyDump << aResGrp << " = " << _this() << ".CutGroups( " - << theGroup1 << ", " << theGroup2 << ", '" - << theName << "' )"; + pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( " + << theGroup1 << ", " << theGroup2 << ", '" << theName << "')"; SMESH_CATCH( SMESH::throwCorbaException ); @@ -1503,89 +1486,82 @@ SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups, SMESH::SMESH_Group_var aResGrp; SMESH_TRY; + if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); if ( !theName ) return SMESH::SMESH_Group::_nil(); - set< int > aToolIds; + // check types and get SMESHDS_GroupBase's SMESH::ElementType aType = SMESH::ALL; - int g, n; - // iterate through tool groups - for ( g = 0, n = theToolGroups.length(); g < n; g++ ) + vector< SMESHDS_GroupBase* > toolGroupVec; + vector< SMDS_ElemIteratorPtr > mainIterVec; + + for ( int g = 0, n = theMainGroups.length(); g < n; g++ ) { - SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ]; + SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ]; if ( CORBA::is_nil( aGrp ) ) continue; - - // check type - SMESH::ElementType aCurrType = aGrp->GetType(); if ( aType == SMESH::ALL ) - aType = aCurrType; - else - { - if ( aType != aCurrType ) - return SMESH::SMESH_Group::_nil(); - } - - // unite tool ids - SMESH::long_array_var aCurrIds = aGrp->GetListOfID(); - for ( int i = 0, n = aCurrIds->length(); i < n; i++ ) - { - int aCurrId = aCurrIds[ i ]; - aToolIds.insert( aCurrId ); - } + aType = aGrp->GetType(); + else if ( aType != aGrp->GetType() ) + THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types", + SALOME::BAD_PARAM); + if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp )) + if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() ) + if ( !grpDS->IsEmpty() ) + mainIterVec.push_back( grpDS->GetElements() ); } + if ( aType == SMESH::ALL ) // all main groups are nil + return SMESH::SMESH_Group::_nil(); + if ( mainIterVec.empty() ) // all main groups are empty + return aResGrp._retn(); - vector< int > anIds; // result - - // Iterate through main group - for ( g = 0, n = theMainGroups.length(); g < n; g++ ) + for ( int g = 0, n = theToolGroups.length(); g < n; g++ ) { - SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ]; + SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ]; if ( CORBA::is_nil( aGrp ) ) continue; - - // check type - SMESH::ElementType aCurrType = aGrp->GetType(); - if ( aType == SMESH::ALL ) - aType = aCurrType; - else - { - if ( aType != aCurrType ) - return SMESH::SMESH_Group::_nil(); - } - - // unite tool ids - SMESH::long_array_var aCurrIds = aGrp->GetListOfID(); - for ( int i = 0, n = aCurrIds->length(); i < n; i++ ) - { - int aCurrId = aCurrIds[ i ]; - if ( !aToolIds.count( aCurrId ) ) - anIds.push_back( aCurrId ); - } + if ( aType != aGrp->GetType() ) + THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types", + SALOME::BAD_PARAM); + if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp )) + if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() ) + toolGroupVec.push_back( grpDS ); } TPythonDump pyDump; - // Create group + // Create a group aResGrp = CreateGroup( aType, theName ); - if ( aResGrp->_is_nil() ) - return SMESH::SMESH_Group::_nil(); - // Create array of identifiers - SMESH::long_array_var aResIds = new SMESH::long_array; - aResIds->length( anIds.size() ); + SMESHDS_Group* resGroupDS = 0; + if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp )) + resGroupDS = dynamic_cast( grp_i->GetGroupDS() ); + if ( !resGroupDS ) + return aResGrp._retn(); + + // Fill the group + size_t i, nb = toolGroupVec.size(); + SMDS_ElemIteratorPtr mainElemIt + ( new SMDS_IteratorOnIterators + < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec )); + while ( mainElemIt->more() ) + { + const SMDS_MeshElement* e = mainElemIt->next(); + bool isIn = false; + for ( i = 0; ( i < nb && !isIn ); ++i ) + isIn = toolGroupVec[i]->Contains( e ); - for (int i=0; iAdd( aResIds ); + if ( !isIn ) + resGroupDS->SMDSGroup().Add( e ); + } // Update Python script - pyDump << aResGrp << " = " << _this() << ".CutListOfGroups( " - << &theMainGroups << ", " << &theToolGroups << ", '" - << theName << "' )"; + pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() ) + << ".CutListOfGroups( " << theMainGroups << ", " + << theToolGroups << ", '" << theName << "' )"; SMESH_CATCH( SMESH::throwCorbaException ); @@ -1687,8 +1663,9 @@ SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups, } // Update Python script - pyDump << aResGrp << " = " << _this() << ".CreateDimGroup( " - << &theGroups << ", " << theElemType << ", '" << theName << "' )"; + pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this()) + << ".CreateDimGroup( " + << theGroups << ", " << theElemType << ", '" << theName << "' )"; SMESH_CATCH( SMESH::throwCorbaException ); @@ -1707,7 +1684,7 @@ 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::Study_var study = _gen_i->GetCurrentStudy(); SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study, theGeomObj ); if ( groupSO->_is_nil() ) return; @@ -1727,7 +1704,10 @@ void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj, for ( int 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(); } //================================================================================ @@ -1785,8 +1765,8 @@ 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 ); } @@ -1801,22 +1781,176 @@ 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; + + if ( mainGO->GetType() == GEOM_GROUP || + mainGO->GetTick() == _mainShapeTick ) + { + CheckGeomGroupModif(); + return; + } + + GEOM_Client* geomClient = _gen_i->GetShapeReader(); + if ( !geomClient ) return; + GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine(); + if ( geomGen->_is_nil() ) return; + + CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO ); + geomClient->RemoveShapeFromBuffer( ior.in() ); + + // Update data taking into account that + // all sub-shapes change but IDs of sub-shapes remain (except for geom groups) + + _impl->Clear(); + TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO ); + if ( newShape.IsNull() ) + return; + + _mainShapeTick = mainGO->GetTick(); + + SMESHDS_Mesh * meshDS = _impl->GetMeshDS(); + + // store data of groups on geometry + vector< TGroupOnGeomData > groupsData; + const set& 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 */ @@ -1864,7 +1998,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(); @@ -1984,12 +2118,12 @@ 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 @@ -2069,14 +2203,13 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase if ( theGroup->_is_nil() ) return aGroup._retn(); - SMESH_GroupBase_i* aGroupToRem = - dynamic_cast( SMESH_Gen_i::GetServant( theGroup ).in() ); + SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast( theGroup ); if ( !aGroupToRem ) return aGroup._retn(); const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup )); - int anId = aGroupToRem->GetLocalID(); + const int anId = aGroupToRem->GetLocalID(); if ( !_impl->ConvertToStandalone( anId ) ) return aGroup._retn(); removeGeomGroupData( theGroup ); @@ -2084,10 +2217,11 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId ); // remove old instance of group from own map + { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object _mapGroups.erase( anId ); SALOMEDS::StudyBuilder_var builder; - SALOMEDS::SObject_wrap aGroupSO; + SALOMEDS::SObject_wrap aGroupSO; SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy(); if ( !aStudy->_is_nil() ) { builder = aStudy->NewBuilder(); @@ -2101,8 +2235,8 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase 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 ) @@ -2128,7 +2262,9 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase _gen_i->RegisterObject( aGroup ); CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup ); - builder->SetIOR( aGroupSO, ior.in() ); + builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register(); + //aGroup->Register(); + aGroupToRem->UnRegister(); SMESH_CATCH( SMESH::throwCorbaException ); @@ -2144,21 +2280,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 ); @@ -2180,7 +2318,6 @@ SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID) return SMESH::SMESH_subMesh::_duplicate( (*it).second ); } - //============================================================================= /*! * @@ -2194,12 +2331,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 ); @@ -2224,7 +2362,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); @@ -2250,7 +2397,10 @@ SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType 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 ); @@ -2268,12 +2418,14 @@ SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType else aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId ); - aGroup = SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() ); + aGroup = aGroupImpl->_this(); _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup ); + aGroupImpl->Register(); // register CORBA object for persistence int nextId = _gen_i->RegisterObject( aGroup ); - if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId); + 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() ) { @@ -2296,14 +2448,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(); } } @@ -2474,11 +2627,13 @@ SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor() _preMeshInfo->FullLoadFromFile(); // Create MeshEditor - SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, false ); - aMeshEdVar = aMeshEditor->_this(); + if ( !_editor ) + _editor = new SMESH_MeshEditor_i( this, false ); + aMeshEdVar = _editor->_this(); // Update Python script - TPythonDump() << aMeshEditor << " = " << _this() << ".GetMeshEditor()"; + TPythonDump() << _editor << " = " + << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()"; SMESH_CATCH( SMESH::throwCorbaException ); @@ -2500,8 +2655,9 @@ SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer() if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, true ); - aMeshEdVar = aMeshEditor->_this(); + if ( !_previewEditor ) + _previewEditor = new SMESH_MeshEditor_i( this, true ); + aMeshEdVar = _previewEditor->_this(); SMESH_CATCH( SMESH::throwCorbaException ); @@ -2569,7 +2725,7 @@ void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOM _impl->SetAutoColor(theAutoColor); TPythonDump pyDump; // not to dump group->SetColor() from below code - pyDump<<_this()<<".SetAutoColor( "< aReservedColors; map::iterator it = _mapGroups.begin(); @@ -2612,44 +2768,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 existance and access rights"; } + aFile.remove(); + } + + if ( !msg.empty() ) + { + msg << "."; + THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM); } } @@ -2692,7 +2840,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(); @@ -2709,18 +2858,23 @@ 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); + 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 ); } //================================================================================ @@ -2765,7 +2919,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); } @@ -2786,7 +2941,7 @@ void SMESH_Mesh_i::ExportDAT (const char *file) // Update Python script // check names of groups checkGroupNames(); - TPythonDump() << _this() << ".ExportDAT( r'" << file << "' )"; + TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )"; // Perform Export PrepareForWriting(file); @@ -2809,7 +2964,7 @@ void SMESH_Mesh_i::ExportUNV (const char *file) // Update Python script // check names of groups checkGroupNames(); - TPythonDump() << _this() << ".ExportUNV( r'" << file << "' )"; + TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )"; // Perform Export PrepareForWriting(file); @@ -2832,7 +2987,8 @@ void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii) // Update Python script // check names of groups checkGroupNames(); - TPythonDump() << _this() << ".ExportSTL( r'" << file << "', " << isascii << " )"; + TPythonDump() << SMESH::SMESH_Mesh_var(_this()) + << ".ExportSTL( r'" << file << "', " << isascii << " )"; // Perform Export PrepareForWriting(file); @@ -2845,33 +3001,362 @@ void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii) */ //================================================================================ -void SMESH_Mesh_i::ExportPartToMED(::SMESH::SMESH_IDSource_ptr meshPart, - const char* file, - CORBA::Boolean auto_groups, - ::SMESH::MED_VERSION version, - ::CORBA::Boolean overwrite) +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) { - Unexpect aCatch(SALOME_SalomeException); + SMESH_TRY; if ( _preMeshInfo ) _preMeshInfo->FullLoadFromFile(); - PrepareForWriting(file, overwrite); + // 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"; - 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; + 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; } - SMESH_MeshPartDS partDS( meshPart ); - _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, &partDS ); - TPythonDump() << _this() << ".ExportPartToMED( " << meshPart << ", r'" << file << "', " - << auto_groups << ", " << version << ", " << overwrite << " )"; + // 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 : "" ) << "'" << " )"; + + SMESH_CATCH( SMESH::throwCorbaException ); +} + +//================================================================================ +/*! + * Write GEOM fields to MED file + */ +//================================================================================ + +void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter, + SMESHDS_Mesh* meshDS, + const GEOM::ListOfFields& fields, + const char* geomAssocFields) +{ +#define METH "SMESH_Mesh_i::exportMEDFields() " + + if (( fields.length() < 1 ) && + ( !geomAssocFields || !geomAssocFields[0] )) + return; + + std::vector< double > dblVals( meshDS->MaxShapeIndex()+1 ); + std::vector< int > intVals( meshDS->MaxShapeIndex()+1 ); + std::vector< int > subIdsByDim[ 4 ]; + const double noneDblValue = 0.; + const double noneIntValue = 0; + + for ( size_t iF = 0; iF < fields.length(); ++iF ) + { + // set field data + + int dim = fields[ iF ]->GetDimension(); + SMDSAbs_ElementType elemType; + TopAbs_ShapeEnum shapeType; + switch ( dim ) { + case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break; + case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break; + case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break; + case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break; + default: + continue; // skip fields on whole shape + } + GEOM::field_data_type dataType = fields[ iF ]->GetDataType(); + if ( dataType == GEOM::FDT_String ) + continue; + GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps(); + if ( stepIDs->length() < 1 ) + continue; + GEOM::string_array_var comps = fields[ iF ]->GetComponents(); + if ( comps->length() < 1 ) + continue; + CORBA::String_var name = fields[ iF ]->GetName(); + + if ( !fieldWriter.Set( meshDS, + name.in(), + elemType, + comps->length(), + /*isIntData=*/false ))//( dataType == GEOM::FDT_Int ))) + continue; + + for ( size_t iC = 0; iC < comps->length(); ++iC ) + fieldWriter.SetCompName( iC, comps[ iC ].in() ); + + // find sub-shape IDs + + std::vector< int >& subIds = subIdsByDim[ dim ]; + if ( subIds.empty() ) + for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id ) + if ( meshDS->IndexToShape( id ).ShapeType() == shapeType ) + subIds.push_back( id ); + + // write steps + + SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems(); + if ( !elemIt ) + continue; + + for ( size_t iS = 0; iS < stepIDs->length(); ++iS ) + { + GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]); + if ( step->_is_nil() ) + continue; + + CORBA::Long stamp = step->GetStamp(); + CORBA::Long id = step->GetID(); + fieldWriter.SetDtIt( int( stamp ), int( id )); + + // fill dblVals or intVals + 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() ) + THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR ); + for ( size_t i = 0; i < vv->length(); ++i ) + dblVals[ subIds[ i ]] = vv[ i ]; + 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() ) + THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR ); + for ( size_t i = 0; i < vv->length(); ++i ) + intVals[ subIds[ i ]] = (int) vv[ i ]; + 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() ) + THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR ); + for ( size_t i = 0; i < vv->length(); ++i ) + intVals[ subIds[ i ]] = (int) vv[ i ]; + 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 >= dblVals.size() ) + fieldWriter.AddValue( noneDblValue ); + else + fieldWriter.AddValue( dblVals[ shapeID ]); + } + else + while ( elemIt->more() ) + { + const SMDS_MeshElement* e = elemIt->next(); + const int shapeID = e->getshapeId(); + if ( shapeID < 1 || shapeID >= intVals.size() ) + fieldWriter.AddValue( (double) noneIntValue ); + else + fieldWriter.AddValue( (double) intVals[ shapeID ]); + } + + // write a step + fieldWriter.Perform(); + SMESH_ComputeErrorPtr res = fieldWriter.GetError(); + if ( res && res->IsKO() ) + { + if ( res->myComment.empty() ) + { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); } + else + { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); } + } + + } // loop on steps + } // loop on fields + + if ( !geomAssocFields || !geomAssocFields[0] ) + return; + + // write geomAssocFields + + std::vector< int > shapeDim( TopAbs_SHAPE + 1 ); + shapeDim[ TopAbs_COMPOUND ] = 3; + shapeDim[ TopAbs_COMPSOLID ] = 3; + shapeDim[ TopAbs_SOLID ] = 3; + shapeDim[ TopAbs_SHELL ] = 2; + shapeDim[ TopAbs_FACE ] = 2; + shapeDim[ TopAbs_WIRE ] = 1; + shapeDim[ TopAbs_EDGE ] = 1; + shapeDim[ TopAbs_VERTEX ] = 0; + shapeDim[ TopAbs_SHAPE ] = 3; + + for ( int iF = 0; geomAssocFields[ iF ]; ++iF ) + { + std::vector< std::string > compNames; + switch ( geomAssocFields[ iF ]) { + case 'v': case 'V': + fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false ); + compNames.push_back( "dim" ); + break; + case 'e': case 'E': + fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false ); + break; + case 'f': case 'F': + fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false ); + break; + case 's': case 'S': + fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false ); + break; + default: continue; + } + compNames.push_back( "id" ); + for ( size_t iC = 0; iC < compNames.size(); ++iC ) + fieldWriter.SetCompName( iC, compNames[ iC ].c_str() ); + + fieldWriter.SetDtIt( -1, -1 ); + + SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems(); + if ( !elemIt ) + continue; + + if ( compNames.size() == 2 ) // _vertices_ + while ( elemIt->more() ) + { + const SMDS_MeshElement* e = elemIt->next(); + const int shapeID = e->getshapeId(); + if ( shapeID < 1 ) + { + fieldWriter.AddValue( (double) -1 ); + fieldWriter.AddValue( (double) -1 ); + } + else + { + const TopoDS_Shape& S = meshDS->IndexToShape( shapeID ); + fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ])); + fieldWriter.AddValue( (double) shapeID ); + } + } + else + while ( elemIt->more() ) + { + const SMDS_MeshElement* e = elemIt->next(); + const int shapeID = e->getshapeId(); + if ( shapeID < 1 ) + fieldWriter.AddValue( (double) -1 ); + else + fieldWriter.AddValue( (double) shapeID ); + } + + // write a step + fieldWriter.Perform(); + SMESH_ComputeErrorPtr res = fieldWriter.GetError(); + if ( res && res->IsKO() ) + { + if ( res->myComment.empty() ) + { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); } + else + { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); } + } + + } // loop on geomAssocFields + +#undef METH } //================================================================================ @@ -2893,7 +3378,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 << "' )"; } //================================================================================ /*! @@ -2914,7 +3400,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 << "' )"; } //================================================================================ /*! @@ -2936,7 +3423,7 @@ void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart, SMESH_MeshPartDS partDS( meshPart ); _impl->ExportSTL(file, isascii, &partDS); - TPythonDump() << _this() << ".ExportPartToSTL( " + TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( " << meshPart<< ", r'" << file << "', " << isascii << ")"; } @@ -2961,7 +3448,7 @@ void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart, SMESH_MeshPartDS partDS( meshPart ); _impl->ExportCGNS(file, &partDS); - TPythonDump() << _this() << ".ExportCGNS( " + TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( " << meshPart<< ", r'" << file << "', " << overwrite << ")"; #else THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR); @@ -2988,7 +3475,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 << ")"; @@ -2996,22 +3483,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) { @@ -3088,6 +3572,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); @@ -3312,7 +3805,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 ) @@ -3365,12 +3858,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 ); @@ -3446,6 +3936,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 @@ -3479,7 +3988,6 @@ SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID) return aResult._retn(); } - //============================================================================= /*! * Returns ID of nodes for given submesh @@ -3487,6 +3995,7 @@ SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID) * returns only nodes on shapes. */ //============================================================================= + SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, CORBA::Boolean all) throw (SALOME::SALOME_Exception) @@ -3642,17 +4151,11 @@ SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id) // 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(); } @@ -4003,6 +4506,33 @@ SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId, return aResult._retn(); } +//======================================================================= +//function : GetElemFaceNodes +//purpose : Returns three components of normal of given mesh face. +//======================================================================= + +SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId, + CORBA::Boolean normalized) +{ + if ( _preMeshInfo ) + _preMeshInfo->FullLoadFromFile(); + + SMESH::double_array_var aResult = new SMESH::double_array(); + + if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() ) + { + gp_XYZ normal; + if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized )) + { + aResult->length( 3 ); + aResult[ 0 ] = normal.X(); + aResult[ 1 ] = normal.Y(); + aResult[ 2 ] = normal.Z(); + } + } + return aResult._retn(); +} + //======================================================================= //function : FindElementByNodes //purpose : Returns an element based on all given nodes. @@ -4021,7 +4551,7 @@ CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes) 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 ))) @@ -4138,6 +4668,95 @@ 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; + + // 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->myBadElements.empty()) + { + // sort bad elements by type + vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ]; + list::iterator elemIt = error->myBadElements.begin(); + list::iterator elemEnd = error->myBadElements.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, elem->GetType(), elem->IsPoly() ); + } + } + 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(); +} //============================================================================= /*! @@ -4147,7 +4766,8 @@ SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id) void SMESH_Mesh_i::CreateGroupServants() { - SALOMEDS::Study_var 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(); @@ -4173,18 +4793,19 @@ void SMESH_Mesh_i::CreateGroupServants() aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId ); } - SMESH::SMESH_GroupBase_var groupVar = - SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() ); + SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this(); _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar ); + aGroupImpl->Register(); // register CORBA object for persistence int nextId = _gen_i->RegisterObject( groupVar ); - 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() ) @@ -4195,7 +4816,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 << " ]"; } } } @@ -4229,11 +4850,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; } @@ -4285,9 +4906,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 ); } //============================================================================= @@ -4295,10 +4915,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()) ); } //============================================================================= @@ -4311,9 +4931,9 @@ SMESH::string_array* SMESH_Mesh_i::GetLastParameters() SMESH::string_array_var aResult = new SMESH::string_array(); SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen(); if(gen) { - char *aParameters = GetParameters(); - SALOMEDS::Study_var aStudy = gen->GetCurrentStudy(); - if(!aStudy->_is_nil()) { + 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]; @@ -4373,7 +4993,7 @@ bool SMESH_Mesh_i::IsMeshInfoCorrect() //============================================================================= /*! - * \brief Returns statistic of mesh elements + * \brief Returns number of mesh elements per each \a EntityType */ //============================================================================= @@ -4397,7 +5017,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 */ //============================================================================= @@ -4408,6 +5054,263 @@ 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 ) + { + _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 (( _elemIter->more() || _nodeIter->more() ) && !_node ) + { + 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 = false; + 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 ) + { + 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 && ( groupDS->GetType() == elemType || elemType == SMDSAbs_Node )) + { + elemIt = groupDS->GetElements(); + typeOK = ( groupDS->GetType() == elemType ); + } + } + else if ( SMESH::Filter_i* filter_i = SMESH::DownCast( theObject )) + { + if ( filter_i->GetElementType() == theType || elemType == SMDSAbs_Node ) + { + 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 ); + } + } + } + else + { + SMESH::array_of_ElementType_var types = theObject->GetTypes(); + const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE ); + if ( isNodes && elemType != SMDSAbs_Node ) + 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 )); + } + + 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 @@ -4456,9 +5359,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 ); @@ -4470,7 +5373,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 { @@ -4690,8 +5593,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 @@ -4705,14 +5637,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; @@ -4784,11 +5739,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; } //============================================================================= @@ -4807,13 +5759,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 @@ -4877,7 +5831,8 @@ void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder, 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 = @@ -4891,7 +5846,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 ); @@ -4899,7 +5855,7 @@ void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder, if ( theIsDump ) { // finilise python dump aPythonDump << " ]"; - aPythonDump << " = " << _this() << ".GetMeshOrder()"; + aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()"; } }