X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMESH_I%2FSMESH_Gen_i.cxx;h=411b111ee4c6616d82b11f8c1ee11b6e71e36445;hp=e90e690f759e238dc86f9f8847267c5f93d74fbe;hb=45953e0114b2bc6a1f40c6fdf74edb19d72c781e;hpb=0635c9fc80f67d1e5dc0e94ec85f487286a92070 diff --git a/src/SMESH_I/SMESH_Gen_i.cxx b/src/SMESH_I/SMESH_Gen_i.cxx index e90e690f7..411b111ee 100644 --- a/src/SMESH_I/SMESH_Gen_i.cxx +++ b/src/SMESH_I/SMESH_Gen_i.cxx @@ -1,29 +1,28 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2013 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// 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. +// 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. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : SMESH_Gen_i.cxx // Author : Paul RASCLE, EDF // Module : SMESH -// + #include #include #include @@ -46,14 +45,9 @@ #include #include -#include "Utils_CorbaException.hxx" - -#include "utilities.h" -#include -#include - #ifdef WNT #include + #include #else #include #endif @@ -70,51 +64,72 @@ #define UnLoadLib( handle ) dlclose( handle ); #endif -#include - #include "SMESH_Gen_i.hxx" -#include "SMESH_Mesh_i.hxx" -#include "SMESH_Hypothesis_i.hxx" -#include "SMESH_Algo_i.hxx" -#include "SMESH_Group_i.hxx" -#include "SMESH_PythonDump.hxx" +#include "SMESH_version.h" +#include "DriverMED_W_SMESHDS_Mesh.h" +#include "DriverMED_R_SMESHDS_Mesh.h" +#ifdef WITH_CGNS +#include "DriverCGNS_Read.hxx" +#endif +#include "MED_Factory.hxx" +#include "SMDS_EdgePosition.hxx" +#include "SMDS_FacePosition.hxx" +#include "SMDS_PolyhedralVolumeOfNodes.hxx" +#include "SMDS_SetIterator.hxx" +#include "SMDS_SpacePosition.hxx" +#include "SMDS_VertexPosition.hxx" #include "SMESHDS_Document.hxx" #include "SMESHDS_Group.hxx" #include "SMESHDS_GroupOnGeom.hxx" -#include "SMESH_Mesh.hxx" -#include "SMESH_Hypothesis.hxx" +#include "SMESH_Algo_i.hxx" +#include "SMESH_File.hxx" #include "SMESH_Group.hxx" +#include "SMESH_Group_i.hxx" +#include "SMESH_Hypothesis.hxx" +#include "SMESH_Hypothesis_i.hxx" +#include "SMESH_Mesh.hxx" #include "SMESH_MeshEditor.hxx" - -#include "SMDS_EdgePosition.hxx" -#include "SMDS_FacePosition.hxx" -#include "SMDS_VertexPosition.hxx" -#include "SMDS_SpacePosition.hxx" -#include "SMDS_PolyhedralVolumeOfNodes.hxx" +#include "SMESH_Mesh_i.hxx" +#include "SMESH_PreMeshInfo.hxx" +#include "SMESH_PythonDump.hxx" +#include "memoire.h" #include CORBA_SERVER_HEADER(SMESH_Group) #include CORBA_SERVER_HEADER(SMESH_Filter) #include CORBA_SERVER_HEADER(SMESH_MeshEditor) -#include "DriverMED_W_SMESHDS_Mesh.h" -#include "DriverMED_R_SMESHDS_Mesh.h" -#include "SALOMEDS_Tool.hxx" -#include "SALOME_NamingService.hxx" -#include "SALOME_LifeCycleCORBA.hxx" -#include "Utils_SINGLETON.hxx" -#include "OpUtil.hxx" +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include CORBA_CLIENT_HEADER(SALOME_ModuleCatalog) +#include CORBA_CLIENT_HEADER(SALOME_Session) -#include "GEOM_Client.hxx" -#include "Utils_ExceptHandlers.hxx" +// helpers about SALOME::GenericObj +#include +#include +#include #include +#include +#include +#include using namespace std; using SMESH::TPythonDump; +using SMESH::TVar; #define NUM_TMP_FILES 2 @@ -150,9 +165,9 @@ PortableServer::ServantBase_var SMESH_Gen_i::GetServant( CORBA::Object_ptr theOb try { PortableServer::Servant aServant = GetPOA()->reference_to_servant( theObject ); return aServant; - } + } catch (...) { - INFOS( "GetServant - Unknown exception was caught!!!" ); + INFOS( "GetServant - Unknown exception was caught!!!" ); return NULL; } } @@ -167,16 +182,16 @@ PortableServer::ServantBase_var SMESH_Gen_i::GetServant( CORBA::Object_ptr theOb CORBA::Object_var SMESH_Gen_i::SObjectToObject( SALOMEDS::SObject_ptr theSObject ) { - SALOMEDS::GenericAttribute_var anAttr; + SALOMEDS::GenericAttribute_wrap anAttr; CORBA::Object_var anObj; if ( !theSObject->_is_nil() ) { try { - if( theSObject->FindAttribute( anAttr, "AttributeIOR" ) ) { - SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow( anAttr ); - CORBA::String_var aValue = anIOR->Value(); - if( strcmp( aValue, "" ) != 0 ) - anObj = GetORB()->string_to_object( aValue ); - } + if( theSObject->FindAttribute( anAttr.inout(), "AttributeIOR" ) ) { + SALOMEDS::AttributeIOR_wrap anIOR = anAttr; + CORBA::String_var aValue = anIOR->Value(); + if( strcmp( aValue, "" ) != 0 ) + anObj = GetORB()->string_to_object( aValue ); + } } catch( ... ) { INFOS( "SObjectToObject - Unknown exception was caught!!!" ); @@ -189,7 +204,7 @@ CORBA::Object_var SMESH_Gen_i::SObjectToObject( SALOMEDS::SObject_ptr theSObject /*! * GetNS [ static ] * - * Get SALOME_NamingService object + * Get SALOME_NamingService object */ //============================================================================= @@ -209,7 +224,7 @@ SALOME_NamingService* SMESH_Gen_i::GetNS() * * Get SALOME_LifeCycleCORBA object */ -//============================================================================= +//============================================================================= SALOME_LifeCycleCORBA* SMESH_Gen_i::GetLCC() { if ( myLCC == NULL ) { myLCC = new SALOME_LifeCycleCORBA( GetNS() ); @@ -224,14 +239,14 @@ SALOME_LifeCycleCORBA* SMESH_Gen_i::GetLCC() { * * Get GEOM::GEOM_Gen reference */ -//============================================================================= -GEOM::GEOM_Gen_ptr SMESH_Gen_i::GetGeomEngine() { +//============================================================================= +GEOM::GEOM_Gen_var SMESH_Gen_i::GetGeomEngine() { //CCRT GEOM::GEOM_Gen_var aGeomEngine = //CCRT GEOM::GEOM_Gen::_narrow( GetLCC()->FindOrLoad_Component("FactoryServer","GEOM") ); //CCRT return aGeomEngine._retn(); if(CORBA::is_nil(myGeomGen)) { - Engines::Component_ptr temp=GetLCC()->FindOrLoad_Component("FactoryServer","GEOM"); + Engines::EngineComponent_ptr temp=GetLCC()->FindOrLoad_Component("FactoryServer","GEOM"); myGeomGen=GEOM::GEOM_Gen::_narrow(temp); } return myGeomGen; @@ -252,16 +267,16 @@ SMESH_Gen_i::SMESH_Gen_i() //============================================================================= /*! - * SMESH_Gen_i::SMESH_Gen_i + * SMESH_Gen_i::SMESH_Gen_i * * Standard constructor, used with Container */ //============================================================================= SMESH_Gen_i::SMESH_Gen_i( CORBA::ORB_ptr orb, - PortableServer::POA_ptr poa, - PortableServer::ObjectId* contId, - const char* instanceName, + PortableServer::POA_ptr poa, + PortableServer::ObjectId* contId, + const char* instanceName, const char* interfaceName ) : Engines_Component_i( orb, poa, contId, instanceName, interfaceName ) { @@ -269,16 +284,40 @@ SMESH_Gen_i::SMESH_Gen_i( CORBA::ORB_ptr orb, myOrb = CORBA::ORB::_duplicate(orb); myPoa = PortableServer::POA::_duplicate(poa); - + _thisObj = this ; _id = myPoa->activate_object( _thisObj ); - + myIsEmbeddedMode = false; myShapeReader = NULL; // shape reader mySMESHGen = this; + myIsHistoricalPythonDump = true; + myToForgetMeshDataOnHypModif = false; // set it in standalone mode only //OSD::SetSignal( true ); + + // 0020605: EDF 1190 SMESH: Display performance. 80 seconds for 52000 cells. + // find out mode (embedded or standalone) here else + // meshes created before calling SMESH_Client::GetSMESHGen(), which calls + // SMESH_Gen_i::SetEmbeddedMode(), have wrong IsEmbeddedMode flag + if ( SALOME_NamingService* ns = GetNS() ) + { + CORBA::Object_var obj = ns->Resolve( "/Kernel/Session" ); + SALOME::Session_var session = SALOME::Session::_narrow( obj ) ; + if ( !session->_is_nil() ) + { + CORBA::String_var str_host = session->getHostname(); + CORBA::Long s_pid = session->getPID(); + string my_host = Kernel_Utils::GetHostname(); +#ifdef WNT + long my_pid = (long)_getpid(); +#else + long my_pid = (long) getpid(); +#endif + SetEmbeddedMode( s_pid == my_pid && my_host == str_host.in() ); + } + } } //============================================================================= @@ -291,7 +330,7 @@ SMESH_Gen_i::SMESH_Gen_i( CORBA::ORB_ptr orb, SMESH_Gen_i::~SMESH_Gen_i() { - INFOS( "SMESH_Gen_i::~SMESH_Gen_i" ); + MESSAGE( "SMESH_Gen_i::~SMESH_Gen_i" ); // delete hypothesis creators map::iterator itHyp; @@ -308,10 +347,10 @@ SMESH_Gen_i::~SMESH_Gen_i() } myStudyContextMap.clear(); // delete shape reader - if ( !myShapeReader ) + if ( myShapeReader ) delete myShapeReader; } - + //============================================================================= /*! * SMESH_Gen_i::createHypothesis @@ -349,7 +388,7 @@ SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::createHypothesis(const char* theHypName } else { - //try to use new format + //try to use new format #ifdef WNT aPlatformLibName = new char[ libNameLen + 5 ]; aPlatformLibName[0] = '\0'; @@ -435,7 +474,8 @@ SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::createHypothesis(const char* theHypName // activate the CORBA servant of hypothesis hypothesis_i = SMESH::SMESH_Hypothesis::_narrow( myHypothesis_i->_this() ); int nextId = RegisterObject( hypothesis_i ); - if(MYDEBUG) MESSAGE( "Add hypo to map with id = "<< nextId ); + if(MYDEBUG) { MESSAGE( "Add hypo to map with id = "<< nextId ); } + else { nextId = 0; } // avoid "unused variable" warning in release mode return hypothesis_i._retn(); } @@ -458,12 +498,14 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::createMesh() // create a new mesh object servant, store it in a map in study context SMESH_Mesh_i* meshServant = new SMESH_Mesh_i( GetPOA(), this, GetCurrentStudyID() ); // create a new mesh object + MESSAGE("myIsEmbeddedMode " << myIsEmbeddedMode); meshServant->SetImpl( myGen.CreateMesh( GetCurrentStudyID(), myIsEmbeddedMode )); // activate the CORBA servant of Mesh SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( meshServant->_this() ); int nextId = RegisterObject( mesh ); - if(MYDEBUG) MESSAGE( "Add mesh to map with id = "<< nextId); + if(MYDEBUG) { MESSAGE( "Add mesh to map with id = "<< nextId); } + else { nextId = 0; } // avoid "unused variable" warning in release mode return mesh._retn(); } catch (SALOME_Exception& S_ex) { @@ -482,7 +524,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::createMesh() GEOM_Client* SMESH_Gen_i::GetShapeReader() { // create shape reader if necessary - if ( !myShapeReader ) + if ( !myShapeReader ) myShapeReader = new GEOM_Client(GetContainerRef()); ASSERT( myShapeReader ); return myShapeReader; @@ -515,6 +557,7 @@ void SMESH_Gen_i::SetGeomEngine( GEOM::GEOM_Gen_ptr geomcompo ) void SMESH_Gen_i::SetEmbeddedMode( CORBA::Boolean theMode ) { myIsEmbeddedMode = theMode; + MESSAGE("myIsEmbeddedMode " << myIsEmbeddedMode); if ( !myIsEmbeddedMode ) { //PAL10867: disable signals catching with "noexcepthandler" option @@ -559,25 +602,41 @@ CORBA::Boolean SMESH_Gen_i::IsEmbeddedMode() void SMESH_Gen_i::SetCurrentStudy( SALOMEDS::Study_ptr theStudy ) { - //if(MYDEBUG) - //MESSAGE( "SMESH_Gen_i::SetCurrentStudy" ); + setCurrentStudy( theStudy ); +} + +void SMESH_Gen_i::setCurrentStudy( SALOMEDS::Study_ptr theStudy, + bool theStudyIsBeingClosed) +{ + int curStudyId = GetCurrentStudyID(); myCurrentStudy = SALOMEDS::Study::_duplicate( theStudy ); // create study context, if it doesn't exist and set current study int studyId = GetCurrentStudyID(); - if(MYDEBUG) MESSAGE( "SMESH_Gen_i::SetCurrentStudy: study Id = " << studyId ); - if ( myStudyContextMap.find( studyId ) == myStudyContextMap.end() ) { - myStudyContextMap[ studyId ] = new StudyContext; - } + if ( myStudyContextMap.find( studyId ) == myStudyContextMap.end() ) + myStudyContextMap[ studyId ] = new StudyContext; // myCurrentStudy may be nil - if ( !CORBA::is_nil( myCurrentStudy ) ) { - SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder(); - if( !myCurrentStudy->FindComponent( "GEOM" )->_is_nil() ) - aStudyBuilder->LoadWith( myCurrentStudy->FindComponent( "GEOM" ), GetGeomEngine() ); - - // set current study for geom engine - //if ( !CORBA::is_nil( GetGeomEngine() ) ) - // GetGeomEngine()->GetCurrentStudy( myCurrentStudy->StudyId() ); + if ( !theStudyIsBeingClosed && !CORBA::is_nil( myCurrentStudy ) ) { + SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder(); + SALOMEDS::SComponent_wrap GEOM_var = myCurrentStudy->FindComponent( "GEOM" ); + if( !GEOM_var->_is_nil() ) + aStudyBuilder->LoadWith( GEOM_var, GetGeomEngine() ); + // NPAL16168, issue 0020210 + // Let meshes update their data depending on GEOM groups that could change + if ( curStudyId != studyId ) + { + CORBA::String_var compDataType = ComponentDataType(); + SALOMEDS::SComponent_wrap me = myCurrentStudy->FindComponent( compDataType.in() ); + if ( !me->_is_nil() ) { + SALOMEDS::ChildIterator_wrap anIter = myCurrentStudy->NewChildIterator( me ); + for ( ; anIter->More(); anIter->Next() ) { + SALOMEDS::SObject_wrap so = anIter->Value(); + CORBA::Object_var ior = SObjectToObject( so ); + if ( SMESH_Mesh_i* mesh = SMESH::DownCast( ior )) + mesh->CheckGeomGroupModif(); + } + } + } } } @@ -597,7 +656,7 @@ SALOMEDS::Study_ptr SMESH_Gen_i::GetCurrentStudy() //============================================================================= /*! - * SMESH_Gen_i::GetCurrentStudyContext + * SMESH_Gen_i::GetCurrentStudyContext * * Get current study context */ @@ -613,7 +672,7 @@ StudyContext* SMESH_Gen_i::GetCurrentStudyContext() //============================================================================= /*! - * SMESH_Gen_i::CreateHypothesis + * SMESH_Gen_i::CreateHypothesis * * Create hypothesis/algorothm of given type and publish it in the study */ @@ -629,7 +688,7 @@ SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::CreateHypothesis( const char* theHypNam // Publish hypothesis/algorithm in the study if ( CanPublishInStudy( hyp ) ) { - SALOMEDS::SObject_var aSO = PublishHypothesis( myCurrentStudy, hyp ); + SALOMEDS::SObject_wrap aSO = PublishHypothesis( myCurrentStudy, hyp ); if ( !aSO->_is_nil() ) { // Update Python script TPythonDump() << aSO << " = " << this << ".CreateHypothesis('" @@ -693,9 +752,11 @@ SMESH_Gen_i::GetHypothesisParameterValues (const char* theHypType, // check local shape SMESH::ListOfHypothesis_var aHypList = theMesh->GetHypothesisList( theGeom ); int nbLocalHyps = aHypList->length(); - for ( int i = 0; i < nbLocalHyps; i++ ) - if ( strcmp( theHypType, aHypList[i]->GetName() ) == 0 ) // FOUND local! + for ( int i = 0; i < nbLocalHyps; i++ ) { + CORBA::String_var hypName = aHypList[i]->GetName(); + if ( strcmp( theHypType, hypName.in() ) == 0 ) // FOUND local! return SMESH::SMESH_Hypothesis::_duplicate( aHypList[i] ); + } // check super shapes TopTools_ListIteratorOfListOfShape itShape( mesh->GetAncestors( shape )); while ( nbLocalHyps == 0 && itShape.More() ) { @@ -711,7 +772,7 @@ SMESH_Gen_i::GetHypothesisParameterValues (const char* theHypType, } } - // let the temporary hypothesis find out some how parameter values by mesh + // let the temporary hypothesis find out somehow parameter values by mesh if ( hyp->SetParametersByMesh( mesh, shape )) return SMESH::SMESH_Hypothesis::_duplicate( tmpHyp ); } @@ -724,6 +785,7 @@ SMESH_Gen_i::GetHypothesisParameterValues (const char* theHypType, ::SMESH_Hypothesis::TDefaults dflts; dflts._elemLength = diagonal / myGen.GetBoundaryBoxSegmentation(); dflts._nbSegments = myGen.GetDefaultNbSegments(); + dflts._shape = &shape; // let the temporary hypothesis initialize it's values if ( hyp->SetParametersByDefaults( dflts, mesh )) return SMESH::SMESH_Hypothesis::_duplicate( tmpHyp ); @@ -755,12 +817,69 @@ void SMESH_Gen_i::SetBoundaryBoxSegmentation( CORBA::Long theNbSegments ) void SMESH_Gen_i::SetDefaultNbSegments(CORBA::Long theNbSegments) throw ( SALOME::SALOME_Exception ) { - if ( theNbSegments ) + if ( theNbSegments > 0 ) myGen.SetDefaultNbSegments( int(theNbSegments) ); else THROW_SALOME_CORBA_EXCEPTION( "non-positive number of segments", SALOME::BAD_PARAM ); } +//============================================================================= +/*! + Set an option value +*/ +//============================================================================= + +void SMESH_Gen_i::SetOption(const char* name, const char* value) +{ + if ( name && value && strlen( value ) > 0 ) + { + string msgToGUI; + if ( strcmp(name, "historical_python_dump") == 0 ) + { + myIsHistoricalPythonDump = ( value[0] == '1' || toupper(value[0]) == 'T' ); // 1 || true + msgToGUI = "preferences/SMESH/historical_python_dump/"; + msgToGUI += myIsHistoricalPythonDump ? "true" : "false"; + } + else if ( strcmp(name, "forget_mesh_on_hyp_modif") == 0 ) + { + myToForgetMeshDataOnHypModif = ( value[0] == '1' || toupper(value[0]) == 'T' ); // 1 || true + msgToGUI = "preferences/SMESH/forget_mesh_on_hyp_modif/"; + msgToGUI += myToForgetMeshDataOnHypModif ? "true" : "false"; + } + + // update preferences in case if SetOption() is invoked from python console + if ( !msgToGUI.empty() ) + { + CORBA::Object_var obj = SMESH_Gen_i::GetNS()->Resolve( "/Kernel/Session" ); + SALOME::Session_var session = SALOME::Session::_narrow( obj ); + if ( !CORBA::is_nil( session ) ) + session->emitMessageOneWay(msgToGUI.c_str()); + } + } +} + +//============================================================================= +/*! + Return an option value +*/ +//============================================================================= + +char* SMESH_Gen_i::GetOption(const char* name) +{ + if ( name ) + { + if ( strcmp(name, "historical_python_dump") == 0 ) + { + return CORBA::string_dup( myIsHistoricalPythonDump ? "true" : "false" ); + } + if ( strcmp(name, "forget_mesh_on_hyp_modif") == 0 ) + { + return CORBA::string_dup( myToForgetMeshDataOnHypModif ? "true" : "false" ); + } + } + return CORBA::string_dup( "" ); +} + //============================================================================= /*! * SMESH_Gen_i::CreateMesh @@ -785,7 +904,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMesh( GEOM::GEOM_Object_ptr theShapeObj if ( CanPublishInStudy( mesh ) ) { SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder(); aStudyBuilder->NewCommand(); // There is a transaction - SALOMEDS::SObject_var aSO = PublishMesh( myCurrentStudy, mesh.in() ); + SALOMEDS::SObject_wrap aSO = PublishMesh( myCurrentStudy, mesh.in() ); aStudyBuilder->CommitCommand(); if ( !aSO->_is_nil() ) { // Update Python script @@ -816,7 +935,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateEmptyMesh() if ( CanPublishInStudy( mesh ) ) { SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder(); aStudyBuilder->NewCommand(); // There is a transaction - SALOMEDS::SObject_var aSO = PublishMesh( myCurrentStudy, mesh.in() ); + SALOMEDS::SObject_wrap aSO = PublishMesh( myCurrentStudy, mesh.in() ); aStudyBuilder->CommitCommand(); if ( !aSO->_is_nil() ) { // Update Python script @@ -847,11 +966,11 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromUNV( const char* theFileName if ( CanPublishInStudy( aMesh ) ) { SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder(); aStudyBuilder->NewCommand(); // There is a transaction - SALOMEDS::SObject_var aSO = PublishMesh( myCurrentStudy, aMesh.in(), aFileName.c_str() ); + SALOMEDS::SObject_wrap aSO = PublishMesh( myCurrentStudy, aMesh.in(), aFileName.c_str() ); aStudyBuilder->CommitCommand(); if ( !aSO->_is_nil() ) { // Update Python script - TPythonDump() << aSO << " = smeshgen.CreateMeshesFromUNV('" << theFileName << "')"; + TPythonDump() << aSO << " = " << this << ".CreateMeshesFromUNV(r'" << theFileName << "')"; } } @@ -860,8 +979,9 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromUNV( const char* theFileName aServant->ImportUNVFile( theFileName ); // Dump creation of groups - aServant->GetGroups(); + SMESH::ListOfGroups_var groups = aServant->GetGroups(); + aServant->GetImpl().GetMeshDS()->Modified(); return aMesh._retn(); } @@ -873,13 +993,18 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromUNV( const char* theFileName */ //============================================================================= -SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char* theFileName, - SMESH::DriverMED_ReadStatus& theStatus) - throw ( SALOME::SALOME_Exception ) +SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMEDorSAUV( const char* theFileName, + SMESH::DriverMED_ReadStatus& theStatus, + const char* theCommandNameForPython, + const char* theFileNameForPython) { - Unexpect aCatch(SALOME_SalomeException); - if(MYDEBUG) MESSAGE( "SMESH_Gen_i::CreateMeshFromMED" ); - +#ifdef WIN32 + char bname[ _MAX_FNAME ]; + _splitpath( theFileNameForPython, NULL, NULL, bname, NULL ); + string aFileName = bname; +#else + string aFileName = basename( theFileNameForPython ); +#endif // Retrieve mesh names from the file DriverMED_R_SMESHDS_Mesh myReader; myReader.SetFile( theFileName ); @@ -894,61 +1019,110 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char* theFileName, // Python Dump TPythonDump aPythonDump; aPythonDump << "(["; - //TCollection_AsciiString aStr ("(["); if (theStatus == SMESH::DRS_OK) { SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder(); aStudyBuilder->NewCommand(); // There is a transaction aResult->length( aNames.size() ); int i = 0; - + // Iterate through all meshes and create mesh objects for ( list::iterator it = aNames.begin(); it != aNames.end(); it++ ) { // Python Dump - //if (i > 0) aStr += ", "; if (i > 0) aPythonDump << ", "; // create mesh SMESH::SMESH_Mesh_var mesh = createMesh(); - + // publish mesh in the study - SALOMEDS::SObject_var aSO; + SALOMEDS::SObject_wrap aSO; if ( CanPublishInStudy( mesh ) ) - aSO = PublishMesh( myCurrentStudy, mesh.in(), (*it).c_str() ); + // little trick: for MED file theFileName and theFileNameForPython are the same, but they are different for SAUV + // - as names of meshes are stored in MED file, we use them for data publishing + // - as mesh name is not stored in UNV file, we use file name as name of mesh when publishing data + aSO = PublishMesh( myCurrentStudy, mesh.in(), ( theFileName == theFileNameForPython ) ? (*it).c_str() : aFileName.c_str() ); if ( !aSO->_is_nil() ) { // Python Dump aPythonDump << aSO; - //aStr += aSO->GetID(); } else { // Python Dump aPythonDump << "mesh_" << i; -// aStr += "mesh_"; -// aStr += TCollection_AsciiString(i); } // Read mesh data (groups are published automatically by ImportMEDFile()) SMESH_Mesh_i* meshServant = dynamic_cast( GetServant( mesh ).in() ); ASSERT( meshServant ); SMESH::DriverMED_ReadStatus status1 = - meshServant->ImportMEDFile( theFileName, (*it).c_str() ); + meshServant->ImportMEDFile( theFileName, (*it).c_str() ); if (status1 > theStatus) - theStatus = status1; + theStatus = status1; aResult[i++] = SMESH::SMESH_Mesh::_duplicate( mesh ); + meshServant->GetImpl().GetMeshDS()->Modified(); } aStudyBuilder->CommitCommand(); } // Update Python script - aPythonDump << "], status) = " << this << ".CreateMeshesFromMED('" << theFileName << "')"; + aPythonDump << "], status) = " << this << "." << theCommandNameForPython << "(r'" << theFileNameForPython << "')"; } // Dump creation of groups for ( int i = 0; i < aResult->length(); ++i ) - aResult[ i ]->GetGroups(); + SMESH::ListOfGroups_var groups = aResult[ i ]->GetGroups(); return aResult._retn(); } +SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char* theFileName, + SMESH::DriverMED_ReadStatus& theStatus) + throw ( SALOME::SALOME_Exception ) +{ + Unexpect aCatch(SALOME_SalomeException); + if(MYDEBUG) MESSAGE( "SMESH_Gen_i::CreateMeshFromMED" ); + SMESH::mesh_array* result = CreateMeshesFromMEDorSAUV(theFileName, theStatus, "CreateMeshesFromMED", theFileName); + return result; +} + +//============================================================================= +/*! + * SMESH_Gen_i::CreateMeshFromSAUV + * + * Create mesh and import data from SAUV file + */ +//============================================================================= + +SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromSAUV( const char* theFileName, + SMESH::DriverMED_ReadStatus& theStatus) + throw ( SALOME::SALOME_Exception ) +{ + Unexpect aCatch(SALOME_SalomeException); + if(MYDEBUG) MESSAGE( "SMESH_Gen_i::CreateMeshFromSAUV" ); + std::string sauvfilename(theFileName); + std::string medfilename(theFileName); + medfilename += ".med"; + std::string cmd; +#ifdef WNT + cmd = "%PYTHONBIN% "; +#else + cmd = "python "; +#endif + cmd += "-c \""; + cmd += "from medutilities import convert ; convert(r'" + sauvfilename + "', 'GIBI', 'MED', 1, r'" + medfilename + "')"; + cmd += "\""; + system(cmd.c_str()); + SMESH::mesh_array* result = CreateMeshesFromMEDorSAUV(medfilename.c_str(), theStatus, "CreateMeshesFromSAUV", sauvfilename.c_str()); +#ifdef WNT + cmd = "%PYTHONBIN% "; +#else + cmd = "python "; +#endif + cmd += "-c \""; + cmd += "from medutilities import my_remove ; my_remove(r'" + medfilename + "')"; + cmd += "\""; + system(cmd.c_str()); + return result; +} + //============================================================================= /*! * SMESH_Gen_i::CreateMeshFromSTL @@ -964,26 +1138,163 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromSTL( const char* theFileName if(MYDEBUG) MESSAGE( "SMESH_Gen_i::CreateMeshesFromSTL" ); SMESH::SMESH_Mesh_var aMesh = createMesh(); - string aFileName; + //string aFileName; +#ifdef WIN32 + char bname[ _MAX_FNAME ]; + _splitpath( theFileName, NULL, NULL, bname, NULL ); + string aFileName = bname; +#else + string aFileName = basename( theFileName ); +#endif // publish mesh in the study if ( CanPublishInStudy( aMesh ) ) { SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder(); aStudyBuilder->NewCommand(); // There is a transaction - SALOMEDS::SObject_var aSO = PublishInStudy + SALOMEDS::SObject_wrap aSO = PublishInStudy ( myCurrentStudy, SALOMEDS::SObject::_nil(), aMesh.in(), aFileName.c_str() ); aStudyBuilder->CommitCommand(); if ( !aSO->_is_nil() ) { // Update Python script - TPythonDump() << aSO << " = " << this << ".CreateMeshesFromSTL('" << theFileName << "')"; + TPythonDump() << aSO << " = " << this << ".CreateMeshesFromSTL(r'" << theFileName << "')"; } } SMESH_Mesh_i* aServant = dynamic_cast( GetServant( aMesh ).in() ); ASSERT( aServant ); aServant->ImportSTLFile( theFileName ); + aServant->GetImpl().GetMeshDS()->Modified(); + return aMesh._retn(); +} + +//================================================================================ +/*! + * \brief Create meshes and import data from the CGSN file + */ +//================================================================================ + +SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromCGNS( const char* theFileName, + SMESH::DriverMED_ReadStatus& theStatus) + throw ( SALOME::SALOME_Exception ) +{ + Unexpect aCatch(SALOME_SalomeException); + + SMESH::mesh_array_var aResult = new SMESH::mesh_array(); + +#ifdef WITH_CGNS + // Retrieve nb meshes from the file + DriverCGNS_Read myReader; + myReader.SetFile( theFileName ); + Driver_Mesh::Status aStatus; + int nbMeshes = myReader.GetNbMeshes(aStatus); + theStatus = (SMESH::DriverMED_ReadStatus)aStatus; + + aResult->length( nbMeshes ); + + { // open a new scope to make aPythonDump die before PythonDump in SMESH_Mesh::GetGroups() + + // Python Dump + TPythonDump aPythonDump; + aPythonDump << "(["; + + if (theStatus == SMESH::DRS_OK) + { + SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder(); + aStudyBuilder->NewCommand(); // There is a transaction + + int i = 0; + + // Iterate through all meshes and create mesh objects + for ( ; i < nbMeshes; ++i ) + { + // Python Dump + if (i > 0) aPythonDump << ", "; + + // create mesh + SMESH::SMESH_Mesh_var mesh = createMesh(); + aResult[i] = SMESH::SMESH_Mesh::_duplicate( mesh ); + + // Read mesh data (groups are published automatically by ImportMEDFile()) + SMESH_Mesh_i* meshServant = dynamic_cast( GetServant( mesh ).in() ); + ASSERT( meshServant ); + string meshName; + SMESH::DriverMED_ReadStatus status1 = + meshServant->ImportCGNSFile( theFileName, i, meshName ); + if (status1 > theStatus) + theStatus = status1; + + meshServant->GetImpl().GetMeshDS()->Modified(); + // publish mesh in the study + SALOMEDS::SObject_wrap aSO; + if ( CanPublishInStudy( mesh ) ) + aSO = PublishMesh( myCurrentStudy, mesh.in(), meshName.c_str() ); + + // Python Dump + if ( !aSO->_is_nil() ) { + aPythonDump << aSO; + } + else { + aPythonDump << "mesh_" << i; + } + } + aStudyBuilder->CommitCommand(); + } + + aPythonDump << "], status) = " << this << ".CreateMeshesFromCGNS(r'" << theFileName << "')"; + } + // Dump creation of groups + for ( int i = 0; i < aResult->length(); ++i ) + SMESH::ListOfGroups_var groups = aResult[ i ]->GetGroups(); +#else + THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR); +#endif + + return aResult._retn(); +} + +//================================================================================ +/*! + * \brief Create a mesh and import data from a GMF file + */ +//================================================================================ + +SMESH::SMESH_Mesh_ptr +SMESH_Gen_i::CreateMeshesFromGMF( const char* theFileName, + CORBA::Boolean theMakeRequiredGroups, + SMESH::ComputeError_out theError) + throw ( SALOME::SALOME_Exception ) +{ + Unexpect aCatch(SALOME_SalomeException); + + SMESH::SMESH_Mesh_var aMesh = createMesh(); +#ifdef WIN32 + char bname[ _MAX_FNAME ]; + _splitpath( theFileName, NULL, NULL, bname, NULL ); + string aFileName = bname; +#else + string aFileName = basename( theFileName ); +#endif + // publish mesh in the study + if ( CanPublishInStudy( aMesh ) ) { + SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder(); + aStudyBuilder->NewCommand(); // There is a transaction + SALOMEDS::SObject_wrap aSO = PublishInStudy + ( myCurrentStudy, SALOMEDS::SObject::_nil(), aMesh.in(), aFileName.c_str() ); + aStudyBuilder->CommitCommand(); + if ( !aSO->_is_nil() ) { + // Update Python script + TPythonDump() << "("<< aSO << ", error) = " << this << ".CreateMeshesFromGMF(r'" + << theFileName << "', " + << theMakeRequiredGroups << " )"; + } + } + SMESH_Mesh_i* aServant = dynamic_cast( GetServant( aMesh ).in() ); + ASSERT( aServant ); + theError = aServant->ImportGMFFile( theFileName, theMakeRequiredGroups ); + aServant->GetImpl().GetMeshDS()->Modified(); return aMesh._retn(); } + //============================================================================= /*! * SMESH_Gen_i::IsReadyToCompute @@ -1000,7 +1311,7 @@ CORBA::Boolean SMESH_Gen_i::IsReadyToCompute( SMESH::SMESH_Mesh_ptr theMesh, if(MYDEBUG) MESSAGE( "SMESH_Gen_i::IsReadyToCompute" ); if ( CORBA::is_nil( theShapeObject ) ) - THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", + THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", SALOME::BAD_PARAM ); if ( CORBA::is_nil( theMesh ) ) @@ -1036,16 +1347,16 @@ SALOMEDS::SObject_ptr SMESH_Gen_i::GetAlgoSO(const ::SMESH_Algo* algo) if ( algo ) { if ( !myCurrentStudy->_is_nil() ) { // find algo in the study - SALOMEDS::SComponent_var father = SALOMEDS::SComponent::_narrow - ( myCurrentStudy->FindComponent( ComponentDataType() ) ); + CORBA::String_var compDataType = ComponentDataType(); + SALOMEDS::SComponent_wrap father = myCurrentStudy->FindComponent( compDataType.in() ); if ( !father->_is_nil() ) { - SALOMEDS::ChildIterator_var itBig = myCurrentStudy->NewChildIterator( father ); + SALOMEDS::ChildIterator_wrap itBig = myCurrentStudy->NewChildIterator( father ); for ( ; itBig->More(); itBig->Next() ) { - SALOMEDS::SObject_var gotBranch = itBig->Value(); + SALOMEDS::SObject_wrap gotBranch = itBig->Value(); if ( gotBranch->Tag() == GetAlgorithmsRootTag() ) { - SALOMEDS::ChildIterator_var algoIt = myCurrentStudy->NewChildIterator( gotBranch ); + SALOMEDS::ChildIterator_wrap algoIt = myCurrentStudy->NewChildIterator( gotBranch ); for ( ; algoIt->More(); algoIt->Next() ) { - SALOMEDS::SObject_var algoSO = algoIt->Value(); + SALOMEDS::SObject_wrap algoSO = algoIt->Value(); CORBA::Object_var algoIOR = SObjectToObject( algoSO ); if ( !CORBA::is_nil( algoIOR )) { SMESH_Hypothesis_i* impl = SMESH::DownCast( algoIOR ); @@ -1068,7 +1379,7 @@ SALOMEDS::SObject_ptr SMESH_Gen_i::GetAlgoSO(const ::SMESH_Algo* algo) */ //================================================================================ -SMESH::compute_error_array* SMESH_Gen_i::GetComputeErrors( SMESH::SMESH_Mesh_ptr theMesh, +SMESH::compute_error_array* SMESH_Gen_i::GetComputeErrors( SMESH::SMESH_Mesh_ptr theMesh, GEOM::GEOM_Object_ptr theSubObject ) throw ( SALOME::SALOME_Exception ) { @@ -1090,7 +1401,7 @@ SMESH::compute_error_array* SMESH_Gen_i::GetComputeErrors( SMESH::SMESH_Mesh_ptr shape = GeomObjectToShape( theSubObject ); else shape = SMESH_Mesh::PseudoShape(); - + ::SMESH_Mesh& mesh = meshServant->GetImpl(); error_array->length( mesh.GetMeshDS()->MaxShapeIndex() ); @@ -1103,8 +1414,8 @@ SMESH::compute_error_array* SMESH_Gen_i::GetComputeErrors( SMESH::SMESH_Mesh_ptr while ( smIt->more() ) { sm = smIt->next(); - if ( sm->GetSubShape().ShapeType() == TopAbs_VERTEX ) - break; + // if ( sm->GetSubShape().ShapeType() == TopAbs_VERTEX ) + // break; SMESH_ComputeErrorPtr error = sm->GetComputeError(); if ( error && !error->IsOK() && error->myAlgo ) { @@ -1112,11 +1423,14 @@ SMESH::compute_error_array* SMESH_Gen_i::GetComputeErrors( SMESH::SMESH_Mesh_ptr errStruct.code = -( error->myName < 0 ? error->myName + 1: error->myName ); // -1 -> 0 errStruct.comment = error->myComment.c_str(); errStruct.subShapeID = sm->GetId(); - SALOMEDS::SObject_var algoSO = GetAlgoSO( error->myAlgo ); - if ( !algoSO->_is_nil() ) - errStruct.algoName = algoSO->GetName(); - else + SALOMEDS::SObject_wrap algoSO = GetAlgoSO( error->myAlgo ); + if ( !algoSO->_is_nil() ) { + CORBA::String_var algoName = algoSO->GetName(); + errStruct.algoName = algoName; + } + else { errStruct.algoName = error->myAlgo->GetName(); + } errStruct.hasBadMesh = !error->myBadElements.empty(); } } @@ -1130,7 +1444,6 @@ SMESH::compute_error_array* SMESH_Gen_i::GetComputeErrors( SMESH::SMESH_Mesh_ptr return error_array._retn(); } -// //================================================================================ /*! * \brief Return mesh elements preventing computation of a subshape @@ -1216,6 +1529,40 @@ SMESH_Gen_i::GetBadInputElements( SMESH::SMESH_Mesh_ptr theMesh, return result._retn(); } +//================================================================================ +/*! + * \brief Create a group of elements preventing computation of a sub-shape + */ +//================================================================================ + +SMESH::ListOfGroups* +SMESH_Gen_i::MakeGroupsOfBadInputElements( SMESH::SMESH_Mesh_ptr theMesh, + CORBA::Short theSubShapeID, + const char* theGroupName ) + throw ( SALOME::SALOME_Exception ) +{ + Unexpect aCatch(SALOME_SalomeException); + + SMESH::ListOfGroups_var groups; + + if ( CORBA::is_nil( theMesh ) ) + THROW_SALOME_CORBA_EXCEPTION( "bad Mesh reference",SALOME::BAD_PARAM ); + + try { + if ( SMESH_Mesh_i* meshServant = SMESH::DownCast( theMesh )) + { + groups = meshServant->MakeGroupsOfBadInputElements( theSubShapeID, theGroupName ); + TPythonDump() << groups << " = " << this + << ".MakeGroupsOfBadInputElements( " + << theMesh << ", " << theSubShapeID << ", '" << theGroupName << "' )"; + } + } + catch ( SALOME_Exception& S_ex ) { + INFOS( "catch exception "<< S_ex.what() ); + } + return groups._retn(); +} + //================================================================================ /*! * \brief Returns errors of hypotheses definintion @@ -1225,7 +1572,7 @@ SMESH_Gen_i::GetBadInputElements( SMESH::SMESH_Mesh_ptr theMesh, */ //================================================================================ -SMESH::algo_error_array* SMESH_Gen_i::GetAlgoState( SMESH::SMESH_Mesh_ptr theMesh, +SMESH::algo_error_array* SMESH_Gen_i::GetAlgoState( SMESH::SMESH_Mesh_ptr theMesh, GEOM::GEOM_Object_ptr theSubObject ) throw ( SALOME::SALOME_Exception ) { @@ -1248,7 +1595,7 @@ SMESH::algo_error_array* SMESH_Gen_i::GetAlgoState( SMESH::SMESH_Mesh_ptr theMes myLocShape = GeomObjectToShape( theSubObject ); else myLocShape = SMESH_Mesh::PseudoShape(); - + ::SMESH_Mesh& myLocMesh = meshServant->GetImpl(); list< ::SMESH_Gen::TAlgoStateError > error_list; list< ::SMESH_Gen::TAlgoStateError >::iterator error; @@ -1264,9 +1611,11 @@ SMESH::algo_error_array* SMESH_Gen_i::GetAlgoState( SMESH::SMESH_Mesh_ptr theMes errStruct.algoDim = error->_algoDim; errStruct.isGlobalAlgo = error->_isGlobalAlgo; errStruct.algoName = ""; - SALOMEDS::SObject_var algoSO = GetAlgoSO( error->_algo ); - if ( !algoSO->_is_nil() ) - errStruct.algoName = algoSO->GetName(); + SALOMEDS::SObject_wrap algoSO = GetAlgoSO( error->_algo ); + if ( !algoSO->_is_nil() ) { + CORBA::String_var algoName = algoSO->GetName(); + errStruct.algoName = algoName.in(); + } } } } @@ -1285,7 +1634,7 @@ SMESH::algo_error_array* SMESH_Gen_i::GetAlgoState( SMESH::SMESH_Mesh_ptr theMes //============================================================================= SMESH::long_array* SMESH_Gen_i::GetSubShapesId( GEOM::GEOM_Object_ptr theMainShapeObject, - const SMESH::object_array& theListOfSubShapeObject ) + const SMESH::object_array& theListOfSubShapeObject ) throw ( SALOME::SALOME_Exception ) { Unexpect aCatch(SALOME_SalomeException); @@ -1301,47 +1650,47 @@ SMESH::long_array* SMESH_Gen_i::GetSubShapesId( GEOM::GEOM_Object_ptr theMainSha try { TopoDS_Shape myMainShape = GeomObjectToShape(theMainShapeObject); - TopTools_IndexedMapOfShape myIndexToShape; + TopTools_IndexedMapOfShape myIndexToShape; TopExp::MapShapes(myMainShape,myIndexToShape); for ( int i = 0; i < theListOfSubShapeObject.length(); i++ ) - { - GEOM::GEOM_Object_var aShapeObject - = GEOM::GEOM_Object::_narrow(theListOfSubShapeObject[i]); - if ( CORBA::is_nil( aShapeObject ) ) - THROW_SALOME_CORBA_EXCEPTION ("bad shape object reference", \ - SALOME::BAD_PARAM ); - - TopoDS_Shape locShape = GeomObjectToShape(aShapeObject); - for (TopExp_Explorer exp(locShape,TopAbs_FACE); exp.More(); exp.Next()) - { - const TopoDS_Face& F = TopoDS::Face(exp.Current()); - setId.insert(myIndexToShape.FindIndex(F)); - if(MYDEBUG) SCRUTE(myIndexToShape.FindIndex(F)); - } - for (TopExp_Explorer exp(locShape,TopAbs_EDGE); exp.More(); exp.Next()) - { - const TopoDS_Edge& E = TopoDS::Edge(exp.Current()); - setId.insert(myIndexToShape.FindIndex(E)); - if(MYDEBUG) SCRUTE(myIndexToShape.FindIndex(E)); - } - for (TopExp_Explorer exp(locShape,TopAbs_VERTEX); exp.More(); exp.Next()) - { - const TopoDS_Vertex& V = TopoDS::Vertex(exp.Current()); - setId.insert(myIndexToShape.FindIndex(V)); - if(MYDEBUG) SCRUTE(myIndexToShape.FindIndex(V)); - } - } + { + GEOM::GEOM_Object_var aShapeObject + = GEOM::GEOM_Object::_narrow(theListOfSubShapeObject[i]); + if ( CORBA::is_nil( aShapeObject ) ) + THROW_SALOME_CORBA_EXCEPTION ("bad shape object reference", \ + SALOME::BAD_PARAM ); + + TopoDS_Shape locShape = GeomObjectToShape(aShapeObject); + for (TopExp_Explorer exp(locShape,TopAbs_FACE); exp.More(); exp.Next()) + { + const TopoDS_Face& F = TopoDS::Face(exp.Current()); + setId.insert(myIndexToShape.FindIndex(F)); + if(MYDEBUG) SCRUTE(myIndexToShape.FindIndex(F)); + } + for (TopExp_Explorer exp(locShape,TopAbs_EDGE); exp.More(); exp.Next()) + { + const TopoDS_Edge& E = TopoDS::Edge(exp.Current()); + setId.insert(myIndexToShape.FindIndex(E)); + if(MYDEBUG) SCRUTE(myIndexToShape.FindIndex(E)); + } + for (TopExp_Explorer exp(locShape,TopAbs_VERTEX); exp.More(); exp.Next()) + { + const TopoDS_Vertex& V = TopoDS::Vertex(exp.Current()); + setId.insert(myIndexToShape.FindIndex(V)); + if(MYDEBUG) SCRUTE(myIndexToShape.FindIndex(V)); + } + } shapesId->length(setId.size()); set::iterator iind; int i=0; for (iind = setId.begin(); iind != setId.end(); iind++) - { - if(MYDEBUG) SCRUTE((*iind)); - shapesId[i] = (*iind); - if(MYDEBUG) SCRUTE(shapesId[i]); - i++; - } + { + if(MYDEBUG) SCRUTE((*iind)); + shapesId[i] = (*iind); + if(MYDEBUG) SCRUTE(shapesId[i]); + i++; + } } catch (SALOME_Exception& S_ex) { @@ -1363,11 +1712,12 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh, GEOM::GEOM_Object_ptr theShapeObject ) throw ( SALOME::SALOME_Exception ) { + MEMOSTAT; Unexpect aCatch(SALOME_SalomeException); if(MYDEBUG) MESSAGE( "SMESH_Gen_i::Compute" ); if ( CORBA::is_nil( theShapeObject ) && theMesh->HasShapeToMesh()) - THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", + THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", SALOME::BAD_PARAM ); if ( CORBA::is_nil( theMesh ) ) @@ -1381,6 +1731,7 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh, try { // get mesh servant SMESH_Mesh_i* meshServant = dynamic_cast( GetServant( theMesh ).in() ); + meshServant->Load(); ASSERT( meshServant ); if ( meshServant ) { // NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation" @@ -1393,7 +1744,13 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh, myLocShape = SMESH_Mesh::PseudoShape(); // call implementation compute ::SMESH_Mesh& myLocMesh = meshServant->GetImpl(); - return myGen.Compute( myLocMesh, myLocShape); +#ifdef WITH_SMESH_CANCEL_COMPUTE + myGen.PrepareCompute( myLocMesh, myLocShape); +#endif + bool ok = myGen.Compute( myLocMesh, myLocShape); + meshServant->CreateGroupServants(); // algos can create groups (issue 0020918) + myLocMesh.GetMeshDS()->Modified(); + return ok; } } catch ( std::bad_alloc ) { @@ -1410,23 +1767,46 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh, //============================================================================= /*! - * SMESH_Gen_i::Precompute + * SMESH_Gen_i::CancelCompute * - * Compute mesh as preview till indicated dimension on shape + * Cancel Compute mesh on a shape */ //============================================================================= -SMESH::MeshPreviewStruct* SMESH_Gen_i::Precompute( SMESH::SMESH_Mesh_ptr theMesh, - GEOM::GEOM_Object_ptr theShapeObject, - SMESH::Dimension theDimension, - SMESH::long_array& theShapesId) - throw ( SALOME::SALOME_Exception ) +void SMESH_Gen_i::CancelCompute( SMESH::SMESH_Mesh_ptr theMesh, + GEOM::GEOM_Object_ptr theShapeObject ) { - Unexpect aCatch(SALOME_SalomeException); - if(MYDEBUG) MESSAGE( "SMESH_Gen_i::Precompute" ); - +#ifdef WITH_SMESH_CANCEL_COMPUTE + SMESH_Mesh_i* meshServant = dynamic_cast( GetServant( theMesh ).in() ); + ::SMESH_Mesh& myLocMesh = meshServant->GetImpl(); + TopoDS_Shape myLocShape; + if(theMesh->HasShapeToMesh()) + myLocShape = GeomObjectToShape( theShapeObject ); + else + myLocShape = SMESH_Mesh::PseudoShape(); + myGen.CancelCompute( myLocMesh, myLocShape); +#endif +} + +//============================================================================= +/*! + * SMESH_Gen_i::Precompute + * + * Compute mesh as preview till indicated dimension on shape + */ +//============================================================================= + +SMESH::MeshPreviewStruct* SMESH_Gen_i::Precompute( SMESH::SMESH_Mesh_ptr theMesh, + GEOM::GEOM_Object_ptr theShapeObject, + SMESH::Dimension theDimension, + SMESH::long_array& theShapesId) + throw ( SALOME::SALOME_Exception ) +{ + Unexpect aCatch(SALOME_SalomeException); + if(MYDEBUG) MESSAGE( "SMESH_Gen_i::Precompute" ); + if ( CORBA::is_nil( theShapeObject ) && theMesh->HasShapeToMesh()) - THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", + THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", SALOME::BAD_PARAM ); if ( CORBA::is_nil( theMesh ) ) @@ -1437,6 +1817,7 @@ SMESH::MeshPreviewStruct* SMESH_Gen_i::Precompute( SMESH::SMESH_Mesh_ptr theMesh try { // get mesh servant SMESH_Mesh_i* meshServant = dynamic_cast( GetServant( theMesh ).in() ); + meshServant->Load(); ASSERT( meshServant ); if ( meshServant ) { // NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation" @@ -1446,140 +1827,140 @@ SMESH::MeshPreviewStruct* SMESH_Gen_i::Precompute( SMESH::SMESH_Mesh_ptr theMesh if(theMesh->HasShapeToMesh()) myLocShape = GeomObjectToShape( theShapeObject ); else - return result._retn();; + return result._retn();; // call implementation compute ::SMESH_Mesh& myLocMesh = meshServant->GetImpl(); TSetOfInt shapeIds; ::MeshDimension aDim = (MeshDimension)theDimension; - if ( myGen.Compute( myLocMesh, myLocShape, false, aDim, &shapeIds ) ) + if ( myGen.Compute( myLocMesh, myLocShape, false, false, aDim, &shapeIds ) ) { - int nbShapeId = shapeIds.size(); - theShapesId.length( nbShapeId ); - // iterates on shapes and collect mesh entities into mesh preview - TSetOfInt::const_iterator idIt = shapeIds.begin(); - TSetOfInt::const_iterator idEnd = shapeIds.end(); - std::map< int, int > mapOfShIdNb; - std::set< SMESH_TLink > setOfEdge; - std::list< SMDSAbs_ElementType > listOfElemType; - typedef map TNode2LocalIDMap; - typedef TNode2LocalIDMap::iterator TNodeLocalID; - TNode2LocalIDMap mapNode2LocalID; - list< TNodeLocalID > connectivity; - int i, nbConnNodes = 0; - std::set< const SMESH_subMesh* > setOfVSubMesh; - // iterates on shapes - for ( ; idIt != idEnd; idIt++ ) - { - if ( mapOfShIdNb.find( *idIt ) != mapOfShIdNb.end() ) - continue; - SMESH_subMesh* sm = myLocMesh.GetSubMeshContaining(*idIt); - if ( !sm || !sm->IsMeshComputed() ) - continue; - - const TopoDS_Shape& aSh = sm->GetSubShape(); - const int shDim = myGen.GetShapeDim( aSh ); - if ( shDim < 1 || shDim > theDimension ) - continue; - - mapOfShIdNb[ *idIt ] = 0; - theShapesId[ mapOfShIdNb.size() - 1 ] = *idIt; - - SMESHDS_SubMesh* smDS = sm->GetSubMeshDS(); - if ( !smDS ) continue; - - if ( theDimension == SMESH::DIM_2D ) - { - SMDS_ElemIteratorPtr faceIt = smDS->GetElements(); - while ( faceIt->more() ) - { - const SMDS_MeshElement* face = faceIt->next(); - int aNbNode = face->NbNodes(); - if ( aNbNode > 4 ) - aNbNode /= 2; // do not take into account additional middle nodes - - SMDS_MeshNode* node1 = (SMDS_MeshNode*)face->GetNode( 1 ); - for ( int nIndx = 1; nIndx <= aNbNode; nIndx++ ) - { - SMDS_MeshNode* node2 = (SMDS_MeshNode*)face->GetNode( nIndx < aNbNode ? nIndx+1 : 1 ); - if ( setOfEdge.insert( SMESH_TLink ( node1, node2 ) ).second ) - { - listOfElemType.push_back( SMDSAbs_Edge ); - connectivity.push_back - ( mapNode2LocalID.insert( make_pair( node1, ++nbConnNodes)).first ); - connectivity.push_back - ( mapNode2LocalID.insert( make_pair( node2, ++nbConnNodes)).first ); - } - node1 = node2; - } - } - } - else if ( theDimension == SMESH::DIM_1D ) - { - SMDS_NodeIteratorPtr nodeIt = smDS->GetNodes(); - while ( nodeIt->more() ) - { - listOfElemType.push_back( SMDSAbs_Node ); - connectivity.push_back - ( mapNode2LocalID.insert( make_pair( nodeIt->next(), ++nbConnNodes)).first ); - } - // add corner nodes by first vertex from edge - SMESH_subMeshIteratorPtr edgeSmIt = - sm->getDependsOnIterator(/*includeSelf*/false, - /*complexShapeFirst*/false); - while ( edgeSmIt->more() ) - { - SMESH_subMesh* vertexSM = edgeSmIt->next(); - // check that vertex is not already treated - if ( !setOfVSubMesh.insert( vertexSM ).second ) - continue; - if ( vertexSM->GetSubShape().ShapeType() != TopAbs_VERTEX ) - continue; - - const SMESHDS_SubMesh* vertexSmDS = vertexSM->GetSubMeshDS(); - SMDS_NodeIteratorPtr nodeIt = vertexSmDS->GetNodes(); - while ( nodeIt->more() ) - { - listOfElemType.push_back( SMDSAbs_Node ); - connectivity.push_back - ( mapNode2LocalID.insert( make_pair( nodeIt->next(), ++nbConnNodes)).first ); - } - } - } - } - - // fill node coords and assign local ids to the nodes - int nbNodes = mapNode2LocalID.size(); - result->nodesXYZ.length( nbNodes ); - TNodeLocalID node2ID = mapNode2LocalID.begin(); - for ( i = 0; i < nbNodes; ++i, ++node2ID ) { - node2ID->second = i; - const SMDS_MeshNode* node = (const SMDS_MeshNode*) node2ID->first; - result->nodesXYZ[i].x = node->X(); - result->nodesXYZ[i].y = node->Y(); - result->nodesXYZ[i].z = node->Z(); - } - // fill connectivity - result->elementConnectivities.length( nbConnNodes ); - list< TNodeLocalID >::iterator connIt = connectivity.begin(); - for ( i = 0; i < nbConnNodes; ++i, ++connIt ) { - result->elementConnectivities[i] = (*connIt)->second; - } - - // fill element types - result->elementTypes.length( listOfElemType.size() ); - std::list< SMDSAbs_ElementType >::const_iterator typeIt = listOfElemType.begin(); - std::list< SMDSAbs_ElementType >::const_iterator typeEnd = listOfElemType.end(); - for ( i = 0; typeIt != typeEnd; ++i, ++typeIt ) + int nbShapeId = shapeIds.size(); + theShapesId.length( nbShapeId ); + // iterates on shapes and collect mesh entities into mesh preview + TSetOfInt::const_iterator idIt = shapeIds.begin(); + TSetOfInt::const_iterator idEnd = shapeIds.end(); + std::map< int, int > mapOfShIdNb; + std::set< SMESH_TLink > setOfEdge; + std::list< SMDSAbs_ElementType > listOfElemType; + typedef map TNode2LocalIDMap; + typedef TNode2LocalIDMap::iterator TNodeLocalID; + TNode2LocalIDMap mapNode2LocalID; + list< TNodeLocalID > connectivity; + int i, nbConnNodes = 0; + std::set< const SMESH_subMesh* > setOfVSubMesh; + // iterates on shapes + for ( ; idIt != idEnd; idIt++ ) + { + if ( mapOfShIdNb.find( *idIt ) != mapOfShIdNb.end() ) + continue; + SMESH_subMesh* sm = myLocMesh.GetSubMeshContaining(*idIt); + if ( !sm || !sm->IsMeshComputed() ) + continue; + + const TopoDS_Shape& aSh = sm->GetSubShape(); + const int shDim = myGen.GetShapeDim( aSh ); + if ( shDim < 1 || shDim > theDimension ) + continue; + + mapOfShIdNb[ *idIt ] = 0; + theShapesId[ mapOfShIdNb.size() - 1 ] = *idIt; + + SMESHDS_SubMesh* smDS = sm->GetSubMeshDS(); + if ( !smDS ) continue; + + if ( theDimension == SMESH::DIM_2D ) + { + SMDS_ElemIteratorPtr faceIt = smDS->GetElements(); + while ( faceIt->more() ) + { + const SMDS_MeshElement* face = faceIt->next(); + int aNbNode = face->NbNodes(); + if ( aNbNode > 4 ) + aNbNode /= 2; // do not take into account additional middle nodes + + SMDS_MeshNode* node1 = (SMDS_MeshNode*)face->GetNode( 0 ); + for ( int nIndx = 0; nIndx < aNbNode; nIndx++ ) + { + SMDS_MeshNode* node2 = (SMDS_MeshNode*)face->GetNode( nIndx+1 < aNbNode ? nIndx+1 : 0 ); + if ( setOfEdge.insert( SMESH_TLink ( node1, node2 ) ).second ) + { + listOfElemType.push_back( SMDSAbs_Edge ); + connectivity.push_back + ( mapNode2LocalID.insert( make_pair( node1, ++nbConnNodes)).first ); + connectivity.push_back + ( mapNode2LocalID.insert( make_pair( node2, ++nbConnNodes)).first ); + } + node1 = node2; + } + } + } + else if ( theDimension == SMESH::DIM_1D ) + { + SMDS_NodeIteratorPtr nodeIt = smDS->GetNodes(); + while ( nodeIt->more() ) + { + listOfElemType.push_back( SMDSAbs_Node ); + connectivity.push_back + ( mapNode2LocalID.insert( make_pair( nodeIt->next(), ++nbConnNodes)).first ); + } + // add corner nodes by first vertex from edge + SMESH_subMeshIteratorPtr edgeSmIt = + sm->getDependsOnIterator(/*includeSelf*/false, + /*complexShapeFirst*/false); + while ( edgeSmIt->more() ) + { + SMESH_subMesh* vertexSM = edgeSmIt->next(); + // check that vertex is not already treated + if ( !setOfVSubMesh.insert( vertexSM ).second ) + continue; + if ( vertexSM->GetSubShape().ShapeType() != TopAbs_VERTEX ) + continue; + + const SMESHDS_SubMesh* vertexSmDS = vertexSM->GetSubMeshDS(); + SMDS_NodeIteratorPtr nodeIt = vertexSmDS->GetNodes(); + while ( nodeIt->more() ) + { + listOfElemType.push_back( SMDSAbs_Node ); + connectivity.push_back + ( mapNode2LocalID.insert( make_pair( nodeIt->next(), ++nbConnNodes)).first ); + } + } + } + } + + // fill node coords and assign local ids to the nodes + int nbNodes = mapNode2LocalID.size(); + result->nodesXYZ.length( nbNodes ); + TNodeLocalID node2ID = mapNode2LocalID.begin(); + for ( i = 0; i < nbNodes; ++i, ++node2ID ) { + node2ID->second = i; + const SMDS_MeshNode* node = (const SMDS_MeshNode*) node2ID->first; + result->nodesXYZ[i].x = node->X(); + result->nodesXYZ[i].y = node->Y(); + result->nodesXYZ[i].z = node->Z(); + } + // fill connectivity + result->elementConnectivities.length( nbConnNodes ); + list< TNodeLocalID >::iterator connIt = connectivity.begin(); + for ( i = 0; i < nbConnNodes; ++i, ++connIt ) { + result->elementConnectivities[i] = (*connIt)->second; + } + + // fill element types + result->elementTypes.length( listOfElemType.size() ); + std::list< SMDSAbs_ElementType >::const_iterator typeIt = listOfElemType.begin(); + std::list< SMDSAbs_ElementType >::const_iterator typeEnd = listOfElemType.end(); + for ( i = 0; typeIt != typeEnd; ++i, ++typeIt ) { - SMDSAbs_ElementType elemType = *typeIt; - result->elementTypes[i].SMDS_ElementType = (SMESH::ElementType)elemType; - result->elementTypes[i].isPoly = false; - result->elementTypes[i].nbNodesInElement = elemType == SMDSAbs_Edge ? 2 : 1; - } - - // correct number of shapes - theShapesId.length( mapOfShIdNb.size() ); + SMDSAbs_ElementType elemType = *typeIt; + result->elementTypes[i].SMDS_ElementType = (SMESH::ElementType)elemType; + result->elementTypes[i].isPoly = false; + result->elementTypes[i].nbNodesInElement = elemType == SMDSAbs_Edge ? 2 : 1; + } + + // correct number of shapes + theShapesId.length( mapOfShIdNb.size() ); } } } @@ -1595,13 +1976,100 @@ SMESH::MeshPreviewStruct* SMESH_Gen_i::Precompute( SMESH::SMESH_Mesh_ptr theMesh return result._retn(); } + +//============================================================================= +/*! + * SMESH_Gen_i::Evaluate + * + * Evaluate mesh on a shape + */ +//============================================================================= + +SMESH::long_array* SMESH_Gen_i::Evaluate(SMESH::SMESH_Mesh_ptr theMesh, + GEOM::GEOM_Object_ptr theShapeObject) +// SMESH::long_array& theNbElems) + throw ( SALOME::SALOME_Exception ) +{ + Unexpect aCatch(SALOME_SalomeException); + if(MYDEBUG) MESSAGE( "SMESH_Gen_i::Evaluate" ); + + if ( CORBA::is_nil( theShapeObject ) && theMesh->HasShapeToMesh()) + THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", + SALOME::BAD_PARAM ); + + if ( CORBA::is_nil( theMesh ) ) + THROW_SALOME_CORBA_EXCEPTION( "bad Mesh reference", + SALOME::BAD_PARAM ); + + SMESH::long_array_var nbels = new SMESH::long_array; + nbels->length(SMESH::Entity_Last); + int i = SMESH::Entity_Node; + for (; i < SMESH::Entity_Last; i++) + nbels[i] = 0; + + // Update Python script + TPythonDump() << "theNbElems = " << this << ".Evaluate( " + << theMesh << ", " << theShapeObject << ")"; + + try { + // get mesh servant + SMESH_Mesh_i* meshServant = dynamic_cast( GetServant( theMesh ).in() ); + ASSERT( meshServant ); + if ( meshServant ) { + // NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation" + meshServant->CheckGeomGroupModif(); + // get local TopoDS_Shape + TopoDS_Shape myLocShape; + if(theMesh->HasShapeToMesh()) + myLocShape = GeomObjectToShape( theShapeObject ); + else + myLocShape = SMESH_Mesh::PseudoShape(); + // call implementation compute + ::SMESH_Mesh& myLocMesh = meshServant->GetImpl(); + MapShapeNbElems aResMap; + /*CORBA::Boolean ret =*/ myGen.Evaluate( myLocMesh, myLocShape, aResMap); + MapShapeNbElemsItr anIt = aResMap.begin(); + for(; anIt!=aResMap.end(); anIt++) { + const vector& aVec = (*anIt).second; + for(i = SMESH::Entity_Node; i < aVec.size(); i++) { + int nbElem = aVec[i]; + if ( nbElem < 0 ) // algo failed, check that it has reported a message + { + SMESH_subMesh* sm = anIt->first; + SMESH_ComputeErrorPtr& error = sm->GetComputeError(); + const SMESH_Algo* algo = myGen.GetAlgo( myLocMesh, sm->GetSubShape()); + if ( (algo && !error.get()) || error->IsOK() ) + error.reset( new SMESH_ComputeError( COMPERR_ALGO_FAILED,"Failed to evaluate",algo)); + } + else + { + nbels[i] += aVec[i]; + } + } + } + return nbels._retn(); + } + } + catch ( std::bad_alloc ) { + INFOS( "Evaluate(): lack of memory" ); + } + catch ( SALOME_Exception& S_ex ) { + INFOS( "Evaluate(): catch exception "<< S_ex.what() ); + } + catch ( ... ) { + INFOS( "Evaluate(): unknown exception " ); + } + + return nbels._retn(); +} + //================================================================================ /*! * \brief Return geometrical object the given element is built on * \param theMesh - the mesh the element is in * \param theElementID - the element ID * \param theGeomName - the name of the result geom object if it is not yet published - * \retval GEOM::GEOM_Object_ptr - the found or just published geom object + * \retval GEOM::GEOM_Object_ptr - the found or just published geom object (no need to UnRegister()) */ //================================================================================ @@ -1612,32 +2080,35 @@ SMESH_Gen_i::GetGeometryByMeshElement( SMESH::SMESH_Mesh_ptr theMesh, throw ( SALOME::SALOME_Exception ) { Unexpect aCatch(SALOME_SalomeException); - - GEOM::GEOM_Object_var geom = FindGeometryByMeshElement(theMesh, theElementID); + + GEOM::GEOM_Object_wrap geom = FindGeometryByMeshElement(theMesh, theElementID); if ( !geom->_is_nil() ) { GEOM::GEOM_Object_var mainShape = theMesh->GetShapeToMesh(); GEOM::GEOM_Gen_ptr geomGen = GetGeomEngine(); // try to find the corresponding SObject - SALOMEDS::SObject_var SObj = ObjectToSObject( myCurrentStudy, geom.in() ); + SALOMEDS::SObject_wrap SObj = ObjectToSObject( myCurrentStudy, geom.in() ); if ( SObj->_is_nil() ) // submesh can be not found even if published { // try to find published submesh GEOM::ListOfLong_var list = geom->GetSubShapeIndices(); if ( !geom->IsMainShape() && list->length() == 1 ) { - SALOMEDS::SObject_var mainSO = ObjectToSObject( myCurrentStudy, mainShape ); - SALOMEDS::ChildIterator_var it; - if ( !mainSO->_is_nil() ) + SALOMEDS::SObject_wrap mainSO = ObjectToSObject( myCurrentStudy, mainShape ); + SALOMEDS::ChildIterator_wrap it; + if ( !mainSO->_is_nil() ) { it = myCurrentStudy->NewChildIterator( mainSO ); + } if ( !it->_is_nil() ) { - for ( it->InitEx(true); SObj->_is_nil() && it->More(); it->Next() ) { - GEOM::GEOM_Object_var subGeom = - GEOM::GEOM_Object::_narrow( SObjectToObject( it->Value() )); + for ( it->InitEx(true); it->More(); it->Next() ) { + SALOMEDS::SObject_wrap so = it->Value(); + CORBA::Object_var obj = SObjectToObject( so ); + GEOM::GEOM_Object_var subGeom = GEOM::GEOM_Object::_narrow( obj ); if ( !subGeom->_is_nil() ) { GEOM::ListOfLong_var subList = subGeom->GetSubShapeIndices(); if ( subList->length() == 1 && list[0] == subList[0] ) { - SObj = it->Value(); + SObj = so; geom = subGeom; + break; } } } @@ -1648,8 +2119,12 @@ SMESH_Gen_i::GetGeometryByMeshElement( SMESH::SMESH_Mesh_ptr theMesh, SObj = geomGen->AddInStudy( myCurrentStudy, geom, theGeomName, mainShape ); // return only published geometry - if ( !SObj->_is_nil() ) - return geom._retn(); + if ( !SObj->_is_nil() ) { + //return geom._retn(); -- servant of geom must be UnRegister()ed; + CORBA::Object_var obj = SObjectToObject( SObj ); + GEOM::GEOM_Object_var go = GEOM::GEOM_Object::_narrow( obj ); + return go._retn(); + } } return GEOM::GEOM_Object::_nil(); } @@ -1659,7 +2134,7 @@ SMESH_Gen_i::GetGeometryByMeshElement( SMESH::SMESH_Mesh_ptr theMesh, * \brief Return geometrical object the given element is built on. * \param theMesh - the mesh the element is in * \param theElementID - the element ID - * \retval GEOM::GEOM_Object_ptr - the found geom object + * \retval GEOM::GEOM_Object_ptr - the found or created (UnRegister()!) geom object */ //================================================================================ @@ -1689,14 +2164,16 @@ SMESH_Gen_i::FindGeometryByMeshElement( SMESH::SMESH_Mesh_ptr theMesh, GEOM::GEOM_Object_var geom = ShapeToGeomObject( meshDS->IndexToShape( shapeID )); if ( geom->_is_nil() ) { // try to find a published sub-shape - SALOMEDS::SObject_var mainSO = ObjectToSObject( myCurrentStudy, mainShape ); - SALOMEDS::ChildIterator_var it; - if ( !mainSO->_is_nil() ) + SALOMEDS::SObject_wrap mainSO = ObjectToSObject( myCurrentStudy, mainShape ); + SALOMEDS::ChildIterator_wrap it; + if ( !mainSO->_is_nil() ) { it = myCurrentStudy->NewChildIterator( mainSO ); + } if ( !it->_is_nil() ) { for ( it->InitEx(true); it->More(); it->Next() ) { - GEOM::GEOM_Object_var subGeom = - GEOM::GEOM_Object::_narrow( SObjectToObject( it->Value() )); + SALOMEDS::SObject_wrap so = it->Value(); + CORBA::Object_var obj = SObjectToObject( so ); + GEOM::GEOM_Object_var subGeom = GEOM::GEOM_Object::_narrow( obj ); if ( !subGeom->_is_nil() ) { GEOM::ListOfLong_var subList = subGeom->GetSubShapeIndices(); if ( subList->length() == 1 && shapeID == subList[0] ) { @@ -1709,14 +2186,17 @@ SMESH_Gen_i::FindGeometryByMeshElement( SMESH::SMESH_Mesh_ptr theMesh, } if ( geom->_is_nil() ) { // explode - GEOM::GEOM_IShapesOperations_var op = + GEOM::GEOM_IShapesOperations_wrap op = geomGen->GetIShapesOperations( GetCurrentStudyID() ); if ( !op->_is_nil() ) geom = op->GetSubShape( mainShape, shapeID ); } + else { + geom->Register(); + } if ( !geom->_is_nil() ) { GeomObjectToShape( geom ); // let geom client remember the found shape - return geom._retn(); + return geom._retn(); } } } @@ -1733,16 +2213,16 @@ SMESH_Gen_i::FindGeometryByMeshElement( SMESH::SMESH_Mesh_ptr theMesh, //================================================================================ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::Concatenate(const SMESH::mesh_array& theMeshesArray, - CORBA::Boolean theUniteIdenticalGroups, - CORBA::Boolean theMergeNodesAndElements, - CORBA::Double theMergeTolerance) + CORBA::Boolean theUniteIdenticalGroups, + CORBA::Boolean theMergeNodesAndElements, + CORBA::Double theMergeTolerance) throw ( SALOME::SALOME_Exception ) { return ConcatenateCommon(theMeshesArray, - theUniteIdenticalGroups, - theMergeNodesAndElements, - theMergeTolerance, - false); + theUniteIdenticalGroups, + theMergeNodesAndElements, + theMergeTolerance, + false); } //================================================================================ @@ -1756,8 +2236,8 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::Concatenate(const SMESH::mesh_array& theMeshe SMESH::SMESH_Mesh_ptr SMESH_Gen_i::ConcatenateWithGroups(const SMESH::mesh_array& theMeshesArray, - CORBA::Boolean theUniteIdenticalGroups, - CORBA::Boolean theMergeNodesAndElements, + CORBA::Boolean theUniteIdenticalGroups, + CORBA::Boolean theMergeNodesAndElements, CORBA::Double theMergeTolerance) throw ( SALOME::SALOME_Exception ) { @@ -1765,7 +2245,7 @@ SMESH_Gen_i::ConcatenateWithGroups(const SMESH::mesh_array& theMeshesArray, theUniteIdenticalGroups, theMergeNodesAndElements, theMergeTolerance, - true); + true); } //================================================================================ @@ -1778,10 +2258,10 @@ SMESH_Gen_i::ConcatenateWithGroups(const SMESH::mesh_array& theMeshesArray, SMESH::SMESH_Mesh_ptr SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray, - CORBA::Boolean theUniteIdenticalGroups, - CORBA::Boolean theMergeNodesAndElements, + CORBA::Boolean theUniteIdenticalGroups, + CORBA::Boolean theMergeNodesAndElements, CORBA::Double theMergeTolerance, - CORBA::Boolean theCommonGroups) + CORBA::Boolean theCommonGroups) throw ( SALOME::SALOME_Exception ) { typedef map TIDsMap; @@ -1789,16 +2269,18 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray, typedef map< pair, TListOfNewGroups > TGroupsMap; typedef std::set TGroups; - TPythonDump aPythonDump; // prevent dump of called methods + TPythonDump* pPythonDump = new TPythonDump; + TPythonDump& aPythonDump = *pPythonDump; // prevent dump of called methods // create mesh SMESH::SMESH_Mesh_var aNewMesh = CreateEmptyMesh(); - + + SMESHDS_Mesh* aNewMeshDS = 0; if ( !aNewMesh->_is_nil() ) { SMESH_Mesh_i* aNewImpl = dynamic_cast( GetServant( aNewMesh ).in() ); if ( aNewImpl ) { ::SMESH_Mesh& aLocMesh = aNewImpl->GetImpl(); - SMESHDS_Mesh* aNewMeshDS = aLocMesh.GetMeshDS(); + aNewMeshDS = aLocMesh.GetMeshDS(); TGroupsMap aGroupsMap; TListOfNewGroups aListOfNewGroups; @@ -1807,240 +2289,281 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray, // loop on meshes for ( int i = 0; i < theMeshesArray.length(); i++) { - SMESH::SMESH_Mesh_var anInitMesh = theMeshesArray[i]; - if ( !anInitMesh->_is_nil() ) { - SMESH_Mesh_i* anInitImpl = dynamic_cast( GetServant( anInitMesh ).in() ); - if ( anInitImpl ) { - ::SMESH_Mesh& aInitLocMesh = anInitImpl->GetImpl(); - SMESHDS_Mesh* anInitMeshDS = aInitLocMesh.GetMeshDS(); - - TIDsMap nodesMap; - TIDsMap elemsMap; - - // loop on elements of mesh - SMDS_ElemIteratorPtr itElems = anInitMeshDS->elementsIterator(); - const SMDS_MeshElement* anElem = 0; - const SMDS_MeshElement* aNewElem = 0; - int anElemNbNodes = 0; - - int anNbNodes = 0; - int anNbEdges = 0; - int anNbFaces = 0; - int anNbVolumes = 0; - - SMESH::long_array_var anIDsNodes = new SMESH::long_array(); - SMESH::long_array_var anIDsEdges = new SMESH::long_array(); - SMESH::long_array_var anIDsFaces = new SMESH::long_array(); - SMESH::long_array_var anIDsVolumes = new SMESH::long_array(); - - if( theCommonGroups ) { - anIDsNodes->length( anInitMeshDS->NbNodes() ); - anIDsEdges->length( anInitMeshDS->NbEdges() ); - anIDsFaces->length( anInitMeshDS->NbFaces() ); - anIDsVolumes->length( anInitMeshDS->NbVolumes() ); - } - - for ( int j = 0; itElems->more(); j++) { - anElem = itElems->next(); - SMDSAbs_ElementType anElemType = anElem->GetType(); - anElemNbNodes = anElem->NbNodes(); - std::vector aNodesArray (anElemNbNodes); - - // loop on nodes of element - const SMDS_MeshNode* aNode = 0; - const SMDS_MeshNode* aNewNode = 0; - SMDS_ElemIteratorPtr itNodes = anElem->nodesIterator(); - - for ( int k = 0; itNodes->more(); k++) { - aNode = static_cast(itNodes->next()); - if ( nodesMap.find(aNode->GetID()) == nodesMap.end() ) { - aNewNode = aNewMeshDS->AddNode(aNode->X(), aNode->Y(), aNode->Z()); - nodesMap.insert( make_pair(aNode->GetID(), aNewNode->GetID()) ); - if( theCommonGroups ) - anIDsNodes[anNbNodes++] = aNewNode->GetID(); - } - else - aNewNode = aNewMeshDS->FindNode( nodesMap.find(aNode->GetID())->second ); - aNodesArray[k] = aNewNode; - }//nodes loop - - // creates a corresponding element on existent nodes in new mesh - if ( anElem->IsPoly() && anElemType == SMDSAbs_Volume ) - { - const SMDS_PolyhedralVolumeOfNodes* aVolume = - dynamic_cast (anElem); - if ( aVolume ) { - aNewElem = aNewMeshDS->AddPolyhedralVolume(aNodesArray, - aVolume->GetQuanities()); - elemsMap.insert(make_pair(anElem->GetID(), aNewElem->GetID())); - if( theCommonGroups ) - anIDsVolumes[anNbVolumes++] = aNewElem->GetID(); - } - } - else { - - aNewElem = aNewEditor.AddElement(aNodesArray, - anElemType, - anElem->IsPoly()); - elemsMap.insert(make_pair(anElem->GetID(), aNewElem->GetID())); - if( theCommonGroups ) { - if( anElemType == SMDSAbs_Edge ) - anIDsEdges[anNbEdges++] = aNewElem->GetID(); - else if( anElemType == SMDSAbs_Face ) - anIDsFaces[anNbFaces++] = aNewElem->GetID(); - else if( anElemType == SMDSAbs_Volume ) - anIDsVolumes[anNbVolumes++] = aNewElem->GetID(); - } - } - }//elems loop - - aListOfGroups = anInitImpl->GetGroups(); - SMESH::SMESH_GroupBase_ptr aGroup; - - // loop on groups of mesh - SMESH::long_array_var anInitIDs = new SMESH::long_array(); - SMESH::long_array_var anNewIDs = new SMESH::long_array(); - SMESH::SMESH_Group_var aNewGroup; - - SMESH::ElementType aGroupType; - CORBA::String_var aGroupName; - if ( theCommonGroups ) { - for(aGroupType=SMESH::NODE;aGroupType<=SMESH::VOLUME;aGroupType=(SMESH::ElementType)(aGroupType+1)) { - string str = "Gr"; - SALOMEDS::SObject_var aMeshSObj = ObjectToSObject( myCurrentStudy, anInitMesh ); - if(aMeshSObj) - str += aMeshSObj->GetName(); - str += "_"; - - int anLen = 0; - - switch(aGroupType) { - case SMESH::NODE: - str += "Nodes"; - anIDsNodes->length(anNbNodes); - anLen = anNbNodes; - break; - case SMESH::EDGE: - str += "Edges"; - anIDsEdges->length(anNbEdges); - anLen = anNbEdges; - break; - case SMESH::FACE: - str += "Faces"; - anIDsFaces->length(anNbFaces); - anLen = anNbFaces; - break; - case SMESH::VOLUME: - str += "Volumes"; - anIDsVolumes->length(anNbVolumes); - anLen = anNbVolumes; - break; - default: - break; - } - - if(anLen) { - aGroupName = str.c_str(); - - // add a new group in the mesh - aNewGroup = aNewImpl->CreateGroup(aGroupType, aGroupName); - - switch(aGroupType) { - case SMESH::NODE: - aNewGroup->Add( anIDsNodes ); - break; - case SMESH::EDGE: - aNewGroup->Add( anIDsEdges ); - break; - case SMESH::FACE: - aNewGroup->Add( anIDsFaces ); - break; - case SMESH::VOLUME: - aNewGroup->Add( anIDsVolumes ); - break; - default: - break; - } - - aListOfNewGroups.clear(); - aListOfNewGroups.push_back(aNewGroup); - aGroupsMap.insert(make_pair( make_pair(aGroupName, aGroupType), aListOfNewGroups )); - } - } - } - - // check that current group name and type don't have identical ones in union mesh - for (int i = 0; i < aListOfGroups->length(); i++) { - aGroup = aListOfGroups[i]; - aListOfNewGroups.clear(); - aGroupType = aGroup->GetType(); - aGroupName = aGroup->GetName(); - - TGroupsMap::iterator anIter = aGroupsMap.find(make_pair(aGroupName, aGroupType)); - - // convert a list of IDs - anInitIDs = aGroup->GetListOfID(); - anNewIDs->length(anInitIDs->length()); - if ( aGroupType == SMESH::NODE ) - for (int j = 0; j < anInitIDs->length(); j++) { - anNewIDs[j] = nodesMap.find(anInitIDs[j])->second; - } - else - for (int j = 0; j < anInitIDs->length(); j++) { - anNewIDs[j] = elemsMap.find(anInitIDs[j])->second; - } - - // check that current group name and type don't have identical ones in union mesh - if ( anIter == aGroupsMap.end() ) { - // add a new group in the mesh - aNewGroup = aNewImpl->CreateGroup(aGroupType, aGroupName); - // add elements into new group - aNewGroup->Add( anNewIDs ); - - aListOfNewGroups.push_back(aNewGroup); - aGroupsMap.insert(make_pair( make_pair(aGroupName, aGroupType), aListOfNewGroups )); - } - - else if ( theUniteIdenticalGroups ) { - // unite identical groups - TListOfNewGroups& aNewGroups = anIter->second; - aNewGroups.front()->Add( anNewIDs ); - } - - else { - // rename identical groups - aNewGroup = aNewImpl->CreateGroup(aGroupType, aGroupName); - aNewGroup->Add( anNewIDs ); - - TListOfNewGroups& aNewGroups = anIter->second; - string aNewGroupName; - if (aNewGroups.size() == 1) { - aNewGroupName = string(aGroupName) + "_1"; - aNewGroups.front()->SetName(aNewGroupName.c_str()); - } - char aGroupNum[128]; - sprintf(aGroupNum, "%u", aNewGroups.size()+1); - aNewGroupName = string(aGroupName) + "_" + string(aGroupNum); - aNewGroup->SetName(aNewGroupName.c_str()); - aNewGroups.push_back(aNewGroup); - } - }//groups loop - } - } + SMESH::SMESH_Mesh_var anInitMesh = theMeshesArray[i]; + if ( !anInitMesh->_is_nil() ) { + SMESH_Mesh_i* anInitImpl = dynamic_cast( GetServant( anInitMesh ).in() ); + if ( anInitImpl ) { + ::SMESH_Mesh& aInitLocMesh = anInitImpl->GetImpl(); + aInitLocMesh.Load(); + SMESHDS_Mesh* anInitMeshDS = aInitLocMesh.GetMeshDS(); + + TIDsMap nodesMap; + TIDsMap elemsMap; + + // loop on elements of mesh + SMDS_ElemIteratorPtr itElems = anInitMeshDS->elementsIterator(); + const SMDS_MeshElement* anElem = 0; + const SMDS_MeshElement* aNewElem = 0; + int anElemNbNodes = 0; + + int anNbNodes = 0; + int anNbEdges = 0; + int anNbFaces = 0; + int anNbVolumes = 0; + int aNbBalls = 0; + + SMESH::long_array_var anIDsNodes = new SMESH::long_array(); + SMESH::long_array_var anIDsEdges = new SMESH::long_array(); + SMESH::long_array_var anIDsFaces = new SMESH::long_array(); + SMESH::long_array_var anIDsVolumes = new SMESH::long_array(); + SMESH::long_array_var anIDsBalls = new SMESH::long_array(); + + if( theCommonGroups ) { + anIDsNodes->length( anInitMeshDS->NbNodes() ); + anIDsEdges->length( anInitMeshDS->NbEdges() ); + anIDsFaces->length( anInitMeshDS->NbFaces() ); + anIDsVolumes->length( anInitMeshDS->NbVolumes() ); + anIDsBalls->length( anInitMeshDS->NbBalls() ); + } + + for ( int j = 0; itElems->more(); j++) { + anElem = itElems->next(); + SMDSAbs_ElementType anElemType = anElem->GetType(); + anElemNbNodes = anElem->NbNodes(); + std::vector aNodesArray (anElemNbNodes); + + // loop on nodes of element + const SMDS_MeshNode* aNode = 0; + const SMDS_MeshNode* aNewNode = 0; + SMDS_ElemIteratorPtr itNodes = anElem->nodesIterator(); + + for ( int k = 0; itNodes->more(); k++) { + aNode = static_cast(itNodes->next()); + if ( nodesMap.find(aNode->GetID()) == nodesMap.end() ) { + aNewNode = aNewMeshDS->AddNode(aNode->X(), aNode->Y(), aNode->Z()); + nodesMap.insert( make_pair(aNode->GetID(), aNewNode->GetID()) ); + if( theCommonGroups ) + anIDsNodes[anNbNodes++] = aNewNode->GetID(); + } + else + aNewNode = aNewMeshDS->FindNode( nodesMap.find(aNode->GetID())->second ); + aNodesArray[k] = aNewNode; + }//nodes loop + + // creates a corresponding element on existent nodes in new mesh + switch ( anElem->GetEntityType() ) { + case SMDSEntity_Polyhedra: + if ( const SMDS_VtkVolume* aVolume = + dynamic_cast (anElem)) + { + aNewElem = aNewMeshDS->AddPolyhedralVolume(aNodesArray, + aVolume->GetQuantities()); + elemsMap.insert(make_pair(anElem->GetID(), aNewElem->GetID())); + if( theCommonGroups ) + anIDsVolumes[anNbVolumes++] = aNewElem->GetID(); + } + break; + case SMDSEntity_Ball: + if ( const SMDS_BallElement* aBall = + dynamic_cast (anElem)) + { + aNewElem = aNewEditor.AddElement(aNodesArray, SMDSAbs_Ball, + /*isPoly=*/false, /*id=*/0, + aBall->GetDiameter() ); + elemsMap.insert(make_pair(anElem->GetID(), aNewElem->GetID())); + if( theCommonGroups ) + anIDsBalls[aNbBalls++] = aNewElem->GetID(); + } + break; + default: + { + aNewElem = aNewEditor.AddElement(aNodesArray, + anElemType, + anElem->IsPoly()); + elemsMap.insert(make_pair(anElem->GetID(), aNewElem->GetID())); + if( theCommonGroups ) { + if( anElemType == SMDSAbs_Edge ) + anIDsEdges[anNbEdges++] = aNewElem->GetID(); + else if( anElemType == SMDSAbs_Face ) + anIDsFaces[anNbFaces++] = aNewElem->GetID(); + else if( anElemType == SMDSAbs_Volume ) + anIDsVolumes[anNbVolumes++] = aNewElem->GetID(); + } + } + } + } //elems loop + + // copy orphan nodes + SMDS_NodeIteratorPtr itNodes = anInitMeshDS->nodesIterator(); + while ( itNodes->more() ) + { + const SMDS_MeshNode* aNode = itNodes->next(); + if ( aNode->NbInverseElements() == 0 ) + { + const SMDS_MeshNode* aNewNode = + aNewMeshDS->AddNode(aNode->X(), aNode->Y(), aNode->Z()); + nodesMap.insert( make_pair(aNode->GetID(), aNewNode->GetID()) ); + if( theCommonGroups ) + anIDsNodes[anNbNodes++] = aNewNode->GetID(); + } + } + + + aListOfGroups = anInitImpl->GetGroups(); + SMESH::SMESH_GroupBase_ptr aGroup; + + // loop on groups of mesh + SMESH::long_array_var anInitIDs = new SMESH::long_array(); + SMESH::long_array_var anNewIDs = new SMESH::long_array(); + SMESH::SMESH_Group_var aNewGroup; + + SMESH::ElementType aGroupType; + CORBA::String_var aGroupName; + if ( theCommonGroups ) { + for(aGroupType=SMESH::NODE;aGroupType<=SMESH::BALL;aGroupType=(SMESH::ElementType)(aGroupType+1)) { + string str = "Gr"; + SALOMEDS::SObject_wrap aMeshSObj = ObjectToSObject( myCurrentStudy, anInitMesh ); + if(aMeshSObj) + str += aMeshSObj->GetName(); + str += "_"; + + int anLen = 0; + + switch(aGroupType) { + case SMESH::NODE: + str += "Nodes"; + anIDsNodes->length(anNbNodes); + anLen = anNbNodes; + break; + case SMESH::EDGE: + str += "Edges"; + anIDsEdges->length(anNbEdges); + anLen = anNbEdges; + break; + case SMESH::FACE: + str += "Faces"; + anIDsFaces->length(anNbFaces); + anLen = anNbFaces; + break; + case SMESH::VOLUME: + str += "Volumes"; + anIDsVolumes->length(anNbVolumes); + anLen = anNbVolumes; + break; + case SMESH::BALL: + str += "Balls"; + anIDsBalls->length(aNbBalls); + anLen = aNbBalls; + break; + default: + break; + } + + if(anLen) { + aGroupName = str.c_str(); + + // add a new group in the mesh + aNewGroup = aNewImpl->CreateGroup(aGroupType, aGroupName); + + switch(aGroupType) { + case SMESH::NODE: + aNewGroup->Add( anIDsNodes ); + break; + case SMESH::EDGE: + aNewGroup->Add( anIDsEdges ); + break; + case SMESH::FACE: + aNewGroup->Add( anIDsFaces ); + break; + case SMESH::VOLUME: + aNewGroup->Add( anIDsVolumes ); + break; + case SMESH::BALL: + aNewGroup->Add( anIDsBalls ); + break; + default: + break; + } + + aListOfNewGroups.clear(); + aListOfNewGroups.push_back(aNewGroup); + aGroupsMap.insert(make_pair( make_pair(aGroupName, aGroupType), aListOfNewGroups )); + } + } + } + + // check that current group name and type don't have identical ones in union mesh + for (int iG = 0; iG < aListOfGroups->length(); iG++) { + aGroup = aListOfGroups[iG]; + aListOfNewGroups.clear(); + aGroupType = aGroup->GetType(); + aGroupName = aGroup->GetName(); + + TGroupsMap::iterator anIter = aGroupsMap.find(make_pair(aGroupName, aGroupType)); + + // convert a list of IDs + anInitIDs = aGroup->GetListOfID(); + anNewIDs->length(anInitIDs->length()); + if ( aGroupType == SMESH::NODE ) + for (int j = 0; j < anInitIDs->length(); j++) { + anNewIDs[j] = nodesMap.find(anInitIDs[j])->second; + } + else + for (int j = 0; j < anInitIDs->length(); j++) { + anNewIDs[j] = elemsMap.find(anInitIDs[j])->second; + } + + // check that current group name and type don't have identical ones in union mesh + if ( anIter == aGroupsMap.end() ) { + // add a new group in the mesh + aNewGroup = aNewImpl->CreateGroup(aGroupType, aGroupName); + // add elements into new group + aNewGroup->Add( anNewIDs ); + + aListOfNewGroups.push_back(aNewGroup); + aGroupsMap.insert(make_pair( make_pair(aGroupName, aGroupType), aListOfNewGroups )); + } + + else if ( theUniteIdenticalGroups ) { + // unite identical groups + TListOfNewGroups& aNewGroups = anIter->second; + aNewGroups.front()->Add( anNewIDs ); + } + + else { + // rename identical groups + aNewGroup = aNewImpl->CreateGroup(aGroupType, aGroupName); + aNewGroup->Add( anNewIDs ); + + TListOfNewGroups& aNewGroups = anIter->second; + string aNewGroupName; + if (aNewGroups.size() == 1) { + aNewGroupName = string(aGroupName) + "_1"; + aNewGroups.front()->SetName(aNewGroupName.c_str()); + } + char aGroupNum[128]; + sprintf(aGroupNum, "%u", aNewGroups.size()+1); + aNewGroupName = string(aGroupName) + "_" + string(aGroupNum); + aNewGroup->SetName(aNewGroupName.c_str()); + aNewGroups.push_back(aNewGroup); + } + }//groups loop + } + } }//meshes loop if (theMergeNodesAndElements) { - // merge nodes - set aMeshNodes; // no input nodes - SMESH_MeshEditor::TListOfListOfNodes aGroupsOfNodes; - aNewEditor.FindCoincidentNodes( aMeshNodes, theMergeTolerance, aGroupsOfNodes ); - aNewEditor.MergeNodes( aGroupsOfNodes ); - // merge elements - aNewEditor.MergeEqualElements(); + // merge nodes + TIDSortedNodeSet aMeshNodes; // no input nodes + SMESH_MeshEditor::TListOfListOfNodes aGroupsOfNodes; + aNewEditor.FindCoincidentNodes( aMeshNodes, theMergeTolerance, aGroupsOfNodes ); + aNewEditor.MergeNodes( aGroupsOfNodes ); + // merge elements + aNewEditor.MergeEqualElements(); } } } - + // Update Python script aPythonDump << aNewMesh << " = " << this; if( !theCommonGroups ) @@ -2054,12 +2577,309 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray, } aPythonDump << "], "; aPythonDump << theUniteIdenticalGroups << ", " - << theMergeNodesAndElements << ", " - << theMergeTolerance << ")"; + << theMergeNodesAndElements << ", " + << TVar( theMergeTolerance ) << ")"; + + delete pPythonDump; // enable python dump from GetGroups() + + // 0020577: EDF 1164 SMESH: Bad dump of concatenate with create common groups + if ( !aNewMesh->_is_nil() ) + { + SMESH::ListOfGroups_var groups = aNewMesh->GetGroups(); + } + + // IPAL21468 Change icon of compound because it need not be computed. + SALOMEDS::SObject_wrap aMeshSObj = ObjectToSObject( myCurrentStudy, aNewMesh ); + SetPixMap( aMeshSObj, "ICON_SMESH_TREE_MESH" ); + if (aNewMeshDS) + aNewMeshDS->Modified(); return aNewMesh._retn(); } +//================================================================================ +/*! + * \brief Create a mesh by copying a part of another mesh + * \param meshPart - a part of mesh to copy + * \param toCopyGroups - to create in the new mesh groups + * the copied elements belongs to + * \param toKeepIDs - to preserve IDs of the copied elements or not + * \retval SMESH::SMESH_Mesh_ptr - the new mesh + */ +//================================================================================ + +SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CopyMesh(SMESH::SMESH_IDSource_ptr meshPart, + const char* meshName, + CORBA::Boolean toCopyGroups, + CORBA::Boolean toKeepIDs) +{ + Unexpect aCatch(SALOME_SalomeException); + + TPythonDump* pyDump = new TPythonDump; // prevent dump from CreateMesh() + + // 1. Get source mesh + + if ( CORBA::is_nil( meshPart )) + THROW_SALOME_CORBA_EXCEPTION( "bad IDSource", SALOME::BAD_PARAM ); + + SMESH::SMESH_Mesh_var srcMesh = meshPart->GetMesh(); + SMESH_Mesh_i* srcMesh_i = SMESH::DownCast( srcMesh ); + if ( !srcMesh_i ) + THROW_SALOME_CORBA_EXCEPTION( "bad mesh of IDSource", SALOME::BAD_PARAM ); + + SMESHDS_Mesh* srcMeshDS = srcMesh_i->GetImpl().GetMeshDS(); + + // 2. Make a new mesh + + SMESH::SMESH_Mesh_var newMesh = CreateMesh(GEOM::GEOM_Object::_nil()); + SMESH_Mesh_i* newMesh_i = SMESH::DownCast( newMesh ); + if ( !newMesh_i ) + THROW_SALOME_CORBA_EXCEPTION( "can't create a mesh", SALOME::INTERNAL_ERROR ); + SALOMEDS::SObject_wrap meshSO = ObjectToSObject(myCurrentStudy, newMesh ); + if ( !meshSO->_is_nil() ) + { + SetName( meshSO, meshName, "Mesh" ); + SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED"); + } + SMESHDS_Mesh* newMeshDS = newMesh_i->GetImpl().GetMeshDS(); + ::SMESH_MeshEditor editor( &newMesh_i->GetImpl() ); + + // 3. Get elements to copy + + SMDS_ElemIteratorPtr srcElemIt; SMDS_NodeIteratorPtr srcNodeIt; + TIDSortedElemSet srcElems; + SMESH::array_of_ElementType_var srcElemTypes = meshPart->GetTypes(); + if ( SMESH::DownCast( meshPart )) + { + srcElemIt = srcMeshDS->elementsIterator(); + srcNodeIt = srcMeshDS->nodesIterator(); + } + else + { + SMESH::long_array_var ids = meshPart->GetIDs(); + if ( srcElemTypes->length() == 1 && srcElemTypes[0] == SMESH::NODE ) // group of nodes + { + for (int i=0; i < ids->length(); i++) + if ( const SMDS_MeshElement * elem = srcMeshDS->FindNode( ids[i] )) + srcElems.insert( elem ); + } + else + { + for (int i=0; i < ids->length(); i++) + if ( const SMDS_MeshElement * elem = srcMeshDS->FindElement( ids[i] )) + srcElems.insert( elem ); + } + if ( srcElems.empty() ) + return newMesh._retn(); + + typedef SMDS_SetIterator< SMDS_pElement, TIDSortedElemSet::const_iterator > ElIter; + srcElemIt = SMDS_ElemIteratorPtr( new ElIter( srcElems.begin(), srcElems.end() )); + } + + // 4. Copy elements + + typedef map TE2EMap; + TE2EMap e2eMapByType[ SMDSAbs_NbElementTypes ]; + TE2EMap& n2nMap = e2eMapByType[ SMDSAbs_Node ]; + int iN; + const SMDS_MeshNode *nSrc, *nTgt; + vector< const SMDS_MeshNode* > nodes; + while ( srcElemIt->more() ) + { + const SMDS_MeshElement * elem = srcElemIt->next(); + // find / add nodes + nodes.resize( elem->NbNodes()); + SMDS_ElemIteratorPtr nIt = elem->nodesIterator(); + if ( toKeepIDs ) { + for ( iN = 0; nIt->more(); ++iN ) + { + nSrc = static_cast( nIt->next() ); + nTgt = newMeshDS->FindNode( nSrc->GetID()); + if ( !nTgt ) + nTgt = newMeshDS->AddNodeWithID( nSrc->X(), nSrc->Y(), nSrc->Z(), nSrc->GetID()); + nodes[ iN ] = nTgt; + } + } + else { + for ( iN = 0; nIt->more(); ++iN ) + { + nSrc = static_cast( nIt->next() ); + TE2EMap::iterator n2n = n2nMap.insert( make_pair( nSrc, SMDS_pNode(0) )).first; + if ( !n2n->second ) + n2n->second = newMeshDS->AddNode( nSrc->X(), nSrc->Y(), nSrc->Z() ); + nodes[ iN ] = (const SMDS_MeshNode*) n2n->second; + } + } + // add elements + if ( elem->GetType() != SMDSAbs_Node ) + { + int ID = toKeepIDs ? elem->GetID() : 0; + const SMDS_MeshElement * newElem; + switch ( elem->GetEntityType() ) { + case SMDSEntity_Polyhedra: + newElem = editor.GetMeshDS()-> + AddPolyhedralVolumeWithID( nodes, + static_cast(elem)->GetQuantities(), + ID); + break; + case SMDSEntity_Ball: + newElem = editor.AddElement( nodes, SMDSAbs_Ball, false, ID, + static_cast(elem)->GetDiameter()); + break; + default: + newElem = editor.AddElement( nodes,elem->GetType(),elem->IsPoly(),ID); + + if ( toCopyGroups && !toKeepIDs ) + e2eMapByType[ elem->GetType() ].insert( make_pair( elem, newElem )); + } + } + } // while ( srcElemIt->more() ) + + // 4(b). Copy free nodes + + if ( srcNodeIt && srcMeshDS->NbNodes() != newMeshDS->NbNodes() ) + { + while ( srcNodeIt->more() ) + { + nSrc = srcNodeIt->next(); + if ( nSrc->NbInverseElements() == 0 ) + { + if ( toKeepIDs ) + nTgt = newMeshDS->AddNodeWithID( nSrc->X(), nSrc->Y(), nSrc->Z(), nSrc->GetID()); + else + n2nMap[ nSrc ] = newMeshDS->AddNode( nSrc->X(), nSrc->Y(), nSrc->Z() ); + } + } + } + + // 5. Copy groups + + int nbNewGroups = 0; + if ( toCopyGroups ) + { + SMESH_Mesh::GroupIteratorPtr gIt = srcMesh_i->GetImpl().GetGroups(); + while ( gIt->more() ) + { + SMESH_Group* group = gIt->next(); + const SMESHDS_GroupBase* groupDS = group->GetGroupDS(); + + // Check group type. We copy nodal groups containing nodes of copied element + SMDSAbs_ElementType groupType = groupDS->GetType(); + if ( groupType != SMDSAbs_Node && + newMeshDS->GetMeshInfo().NbElements( groupType ) == 0 ) + continue; // group type differs from types of meshPart + + // Find copied elements in the group + vector< const SMDS_MeshElement* > groupElems; + SMDS_ElemIteratorPtr eIt = groupDS->GetElements(); + if ( toKeepIDs ) + { + const SMDS_MeshElement* foundElem; + if ( groupType == SMDSAbs_Node ) + { + while ( eIt->more() ) + if (( foundElem = newMeshDS->FindNode( eIt->next()->GetID() ))) + groupElems.push_back( foundElem ); + } + else + { + while ( eIt->more() ) + if (( foundElem = newMeshDS->FindElement( eIt->next()->GetID() ))) + groupElems.push_back( foundElem ); + } + } + else + { + TE2EMap & e2eMap = e2eMapByType[ groupDS->GetType() ]; + if ( e2eMap.empty() ) continue; + int minID = e2eMap.begin()->first->GetID(); + int maxID = e2eMap.rbegin()->first->GetID(); + TE2EMap::iterator e2e; + while ( eIt->more() && groupElems.size() < e2eMap.size()) + { + const SMDS_MeshElement* e = eIt->next(); + if ( e->GetID() < minID || e->GetID() > maxID ) continue; + if ((e2e = e2eMap.find( e )) != e2eMap.end()) + groupElems.push_back( e2e->second ); + } + } + // Make a new group + if ( !groupElems.empty() ) + { + SMESH::SMESH_Group_var newGroupObj = + newMesh->CreateGroup( SMESH::ElementType(groupType), group->GetName() ); + if ( SMESH_GroupBase_i* newGroup_i = SMESH::DownCast( newGroupObj)) + { + SMESHDS_GroupBase * newGroupDS = newGroup_i->GetGroupDS(); + SMDS_MeshGroup& smdsGroup = ((SMESHDS_Group*)newGroupDS)->SMDSGroup(); + for ( unsigned i = 0; i < groupElems.size(); ++i ) + smdsGroup.Add( groupElems[i] ); + + nbNewGroups++; + } + } + } + } + + newMeshDS->Modified(); + + *pyDump << newMesh << " = " << this + << ".CopyMesh( " << meshPart << ", " + << "'" << meshName << "', " + << toCopyGroups << ", " + << toKeepIDs << ")"; + + delete pyDump; pyDump = 0; // allow dump in GetGroups() + + if ( nbNewGroups > 0 ) // dump created groups + SMESH::ListOfGroups_var groups = newMesh->GetGroups(); + + return newMesh._retn(); +} + +//================================================================================ +/*! + * SMESH_Gen_i::GetMEDVersion + * + * Get MED version of the file by its name + */ +//================================================================================ +CORBA::Boolean SMESH_Gen_i::GetMEDVersion(const char* theFileName, + SMESH::MED_VERSION& theVersion) +{ + theVersion = SMESH::MED_V2_1; + MED::EVersion aVersion = MED::GetVersionId( theFileName ); + switch( aVersion ) { + case MED::eV2_1 : theVersion = SMESH::MED_V2_1; return true; + case MED::eV2_2 : theVersion = SMESH::MED_V2_2; return true; + case MED::eVUnknown : return false; + } + return false; +} + +//================================================================================ +/*! + * SMESH_Gen_i::GetMeshNames + * + * Get names of meshes defined in file with the specified name + */ +//================================================================================ +SMESH::string_array* SMESH_Gen_i::GetMeshNames(const char* theFileName) +{ + SMESH::string_array_var aResult = new SMESH::string_array(); + MED::PWrapper aMed = MED::CrWrapper( theFileName ); + MED::TErr anErr; + MED::TInt aNbMeshes = aMed->GetNbMeshes( &anErr ); + if( anErr >= 0 ) { + aResult->length( aNbMeshes ); + for( MED::TInt i = 0; i < aNbMeshes; i++ ) { + MED::PMeshInfo aMeshInfo = aMed->GetPMeshInfo( i+1 ); + aResult[i] = CORBA::string_dup( aMeshInfo->GetName().c_str() ); + } + } + return aResult._retn(); +} + //============================================================================= /*! * SMESH_Gen_i::Save @@ -2076,7 +2896,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, // ASSERT( theComponent->GetStudy()->StudyId() == myCurrentStudy->StudyId() ) // san -- in case differs from theComponent's study, // use that of the component - if ( myCurrentStudy->_is_nil() || + if ( myCurrentStudy->_is_nil() || theComponent->GetStudy()->StudyId() != myCurrentStudy->StudyId() ) SetCurrentStudy( theComponent->GetStudy() ); @@ -2097,7 +2917,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, aFileSeq->length( NUM_TMP_FILES ); TCollection_AsciiString aStudyName( "" ); - if ( isMultiFile ) + if ( isMultiFile ) aStudyName = ( (char*)SALOMEDS_Tool::GetNameFromPath( myCurrentStudy->URL() ).c_str() ); // Set names of temporary files @@ -2136,15 +2956,50 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, DriverMED_W_SMESHDS_Mesh myWriter; myWriter.SetFile( meshfile.ToCString() ); + // IMP issue 20918 + // SetStoreName() to groups before storing hypotheses to let them refer to + // groups using "store name", which is "Group " + { + SALOMEDS::ChildIterator_wrap itBig = myCurrentStudy->NewChildIterator( theComponent ); + for ( ; itBig->More(); itBig->Next() ) { + SALOMEDS::SObject_wrap gotBranch = itBig->Value(); + if ( gotBranch->Tag() > GetAlgorithmsRootTag() ) { + CORBA::Object_var anObject = SObjectToObject( gotBranch ); + if ( !CORBA::is_nil( anObject ) ) { + SMESH::SMESH_Mesh_var myMesh = SMESH::SMESH_Mesh::_narrow( anObject ) ; + if ( !myMesh->_is_nil() ) { + myMesh->Load(); // load from study file if not yet done + TPythonDump pd; // not to dump GetGroups() + SMESH::ListOfGroups_var groups = myMesh->GetGroups(); + pd << ""; // to avoid optimizing pd out + for ( int i = 0; i < groups->length(); ++i ) + { + SMESH_GroupBase_i* grImpl = SMESH::DownCast( groups[i]); + if ( grImpl ) + { + CORBA::String_var objStr = GetORB()->object_to_string( grImpl->_this() ); + int anId = myStudyContext->findId( string( objStr.in() ) ); + char grpName[ 30 ]; + sprintf( grpName, "Group %d", anId ); + SMESHDS_GroupBase* aGrpBaseDS = grImpl->GetGroupDS(); + aGrpBaseDS->SetStoreName( grpName ); + } + } + } + } + } + } + } + // Write data // ---> create HDF file aFile = new HDFfile( (char*) filename.ToCString() ); aFile->CreateOnDisk(); // --> iterator for top-level objects - SALOMEDS::ChildIterator_var itBig = myCurrentStudy->NewChildIterator( theComponent ); + SALOMEDS::ChildIterator_wrap itBig = myCurrentStudy->NewChildIterator( theComponent ); for ( ; itBig->More(); itBig->Next() ) { - SALOMEDS::SObject_var gotBranch = itBig->Value(); + SALOMEDS::SObject_wrap gotBranch = itBig->Value(); // --> hypotheses root branch (only one for the study) if ( gotBranch->Tag() == GetHypothesisRootTag() ) { @@ -2153,9 +3008,9 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, aTopGroup->CreateOnDisk(); // iterator for all hypotheses - SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( gotBranch ); + SALOMEDS::ChildIterator_wrap it = myCurrentStudy->NewChildIterator( gotBranch ); for ( ; it->More(); it->Next() ) { - SALOMEDS::SObject_var mySObject = it->Value(); + SALOMEDS::SObject_wrap mySObject = it->Value(); CORBA::Object_var anObject = SObjectToObject( mySObject ); if ( !CORBA::is_nil( anObject ) ) { SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow( anObject ); @@ -2222,9 +3077,9 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, aTopGroup->CreateOnDisk(); // iterator for all algorithms - SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( gotBranch ); + SALOMEDS::ChildIterator_wrap it = myCurrentStudy->NewChildIterator( gotBranch ); for ( ; it->More(); it->Next() ) { - SALOMEDS::SObject_var mySObject = it->Value(); + SALOMEDS::SObject_wrap mySObject = it->Value(); CORBA::Object_var anObject = SObjectToObject( mySObject ); if ( !CORBA::is_nil( anObject ) ) { SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow( anObject ); @@ -2319,25 +3174,41 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, aDataset->WriteOnDisk( ( char* )( strHasData.c_str() ) ); aDataset->CloseOnDisk(); - // ouv : NPAL12872 + // ouv : NPAL12872 // for each mesh open the HDF group basing on its auto color parameter - char meshAutoColorName[ 30 ]; - sprintf( meshAutoColorName, "AutoColorMesh %d", id ); - int anAutoColor[1]; - anAutoColor[0] = myImpl->GetAutoColor(); - aSize[ 0 ] = 1; - aDataset = new HDFdataset( meshAutoColorName, aTopGroup, HDF_INT32, aSize, 1 ); - aDataset->CreateOnDisk(); - aDataset->WriteOnDisk( anAutoColor ); - aDataset->CloseOnDisk(); + char meshAutoColorName[ 30 ]; + sprintf( meshAutoColorName, "AutoColorMesh %d", id ); + int anAutoColor[1]; + anAutoColor[0] = myImpl->GetAutoColor(); + aSize[ 0 ] = 1; + aDataset = new HDFdataset( meshAutoColorName, aTopGroup, HDF_INT32, aSize, 1 ); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk( anAutoColor ); + aDataset->CloseOnDisk(); + + // issue 0020693. Store _isModified flag + int isModified = myLocMesh.GetIsModified(); + aSize[ 0 ] = 1; + aDataset = new HDFdataset( "_isModified", aTopGroup, HDF_INT32, aSize, 1 ); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk( &isModified ); + aDataset->CloseOnDisk(); + + // issue 20918. Store Persistent Id of SMESHDS_Mesh + int meshPersistentId = mySMESHDSMesh->GetPersistentId(); + aSize[ 0 ] = 1; + aDataset = new HDFdataset( "meshPersistentId", aTopGroup, HDF_INT32, aSize, 1 ); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk( &meshPersistentId ); + aDataset->CloseOnDisk(); // write reference on a shape if exists - SALOMEDS::SObject_var myRef; + SALOMEDS::SObject_wrap myRef; bool shapeRefFound = false; - bool found = gotBranch->FindSubObject( GetRefOnShapeTag(), myRef ); + bool found = gotBranch->FindSubObject( GetRefOnShapeTag(), myRef.inout() ); if ( found ) { - SALOMEDS::SObject_var myShape; - bool ok = myRef->ReferencedObject( myShape ); + SALOMEDS::SObject_wrap myShape; + bool ok = myRef->ReferencedObject( myShape.inout() ); if ( ok ) { shapeRefFound = (! CORBA::is_nil( myShape->GetObject() )); string myRefOnObject = myShape->GetID(); @@ -2352,8 +3223,8 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, } // write applied hypotheses if exist - SALOMEDS::SObject_var myHypBranch; - found = gotBranch->FindSubObject( GetRefOnAppliedHypothesisTag(), myHypBranch ); + SALOMEDS::SObject_wrap myHypBranch; + found = gotBranch->FindSubObject( GetRefOnAppliedHypothesisTag(), myHypBranch.inout() ); if ( found && !shapeRefFound && hasShape) { // remove applied hyps myCurrentStudy->NewBuilder()->RemoveObjectWithChildren( myHypBranch ); } @@ -2361,16 +3232,16 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, aGroup = new HDFgroup( "Applied Hypotheses", aTopGroup ); aGroup->CreateOnDisk(); - SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( myHypBranch ); + SALOMEDS::ChildIterator_wrap it = myCurrentStudy->NewChildIterator( myHypBranch ); int hypNb = 0; for ( ; it->More(); it->Next() ) { - SALOMEDS::SObject_var mySObject = it->Value(); - SALOMEDS::SObject_var myRefOnHyp; - bool ok = mySObject->ReferencedObject( myRefOnHyp ); + SALOMEDS::SObject_wrap mySObject = it->Value(); + SALOMEDS::SObject_wrap myRefOnHyp; + bool ok = mySObject->ReferencedObject( myRefOnHyp.inout() ); if ( ok ) { // san - it is impossible to recover applied hypotheses // using their entries within Load() method, - // for there are no AttributeIORs in the study when Load() is working. + // for there are no AttributeIORs in the study when Load() is working. // Hence, it is better to store persistent IDs of hypotheses as references to them //string myRefOnObject = myRefOnHyp->GetID(); @@ -2395,8 +3266,9 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, } // write applied algorithms if exist - SALOMEDS::SObject_var myAlgoBranch; - found = gotBranch->FindSubObject( GetRefOnAppliedAlgorithmsTag(), myAlgoBranch ); + SALOMEDS::SObject_wrap myAlgoBranch; + found = gotBranch->FindSubObject( GetRefOnAppliedAlgorithmsTag(), + myAlgoBranch.inout() ); if ( found && !shapeRefFound && hasShape) { // remove applied algos myCurrentStudy->NewBuilder()->RemoveObjectWithChildren( myAlgoBranch ); } @@ -2404,16 +3276,16 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, aGroup = new HDFgroup( "Applied Algorithms", aTopGroup ); aGroup->CreateOnDisk(); - SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( myAlgoBranch ); + SALOMEDS::ChildIterator_wrap it = myCurrentStudy->NewChildIterator( myAlgoBranch ); int algoNb = 0; for ( ; it->More(); it->Next() ) { - SALOMEDS::SObject_var mySObject = it->Value(); - SALOMEDS::SObject_var myRefOnAlgo; - bool ok = mySObject->ReferencedObject( myRefOnAlgo ); + SALOMEDS::SObject_wrap mySObject = it->Value(); + SALOMEDS::SObject_wrap myRefOnAlgo; + bool ok = mySObject->ReferencedObject( myRefOnAlgo.inout() ); if ( ok ) { // san - it is impossible to recover applied algorithms // using their entries within Load() method, - // for there are no AttributeIORs in the study when Load() is working. + // for there are no AttributeIORs in the study when Load() is working. // Hence, it is better to store persistent IDs of algorithms as references to them //string myRefOnObject = myRefOnAlgo->GetID(); @@ -2440,18 +3312,18 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, // --> submesh objects sub-branches for ( int i = GetSubMeshOnVertexTag(); i <= GetSubMeshOnCompoundTag(); i++ ) { - SALOMEDS::SObject_var mySubmeshBranch; - found = gotBranch->FindSubObject( i, mySubmeshBranch ); + SALOMEDS::SObject_wrap mySubmeshBranch; + found = gotBranch->FindSubObject( i, mySubmeshBranch.inout() ); if ( found ) // check if there is shape reference in submeshes { bool hasShapeRef = false; - SALOMEDS::ChildIterator_var itSM = + SALOMEDS::ChildIterator_wrap itSM = myCurrentStudy->NewChildIterator( mySubmeshBranch ); for ( ; itSM->More(); itSM->Next() ) { - SALOMEDS::SObject_var mySubRef, myShape, mySObject = itSM->Value(); - if ( mySObject->FindSubObject( GetRefOnShapeTag(), mySubRef )) - mySubRef->ReferencedObject( myShape ); + SALOMEDS::SObject_wrap mySubRef, myShape, mySObject = itSM->Value(); + if ( mySObject->FindSubObject( GetRefOnShapeTag(), mySubRef.inout() )) + mySubRef->ReferencedObject( myShape.inout() ); if ( !CORBA::is_nil( myShape ) && !CORBA::is_nil( myShape->GetObject() )) hasShapeRef = true; else @@ -2502,9 +3374,9 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, aGroup->CreateOnDisk(); // iterator for all submeshes of given type - SALOMEDS::ChildIterator_var itSM = myCurrentStudy->NewChildIterator( mySubmeshBranch ); + SALOMEDS::ChildIterator_wrap itSM = myCurrentStudy->NewChildIterator( mySubmeshBranch ); for ( ; itSM->More(); itSM->Next() ) { - SALOMEDS::SObject_var mySObject = itSM->Value(); + SALOMEDS::SObject_wrap mySObject = itSM->Value(); CORBA::Object_var anSubObject = SObjectToObject( mySObject ); if ( !CORBA::is_nil( anSubObject )) { @@ -2519,9 +3391,9 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, aSubGroup->CreateOnDisk(); // write reference on a shape, already checked if it exists - SALOMEDS::SObject_var mySubRef, myShape; - if ( mySObject->FindSubObject( GetRefOnShapeTag(), mySubRef )) - mySubRef->ReferencedObject( myShape ); + SALOMEDS::SObject_wrap mySubRef, myShape; + if ( mySObject->FindSubObject( GetRefOnShapeTag(), mySubRef.inout() )) + mySubRef->ReferencedObject( myShape.inout() ); string myRefOnObject = myShape->GetID(); if ( myRefOnObject.length() > 0 ) { aSize[ 0 ] = myRefOnObject.length() + 1; @@ -2532,18 +3404,19 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, } // write applied hypotheses if exist - SALOMEDS::SObject_var mySubHypBranch; - found = mySObject->FindSubObject( GetRefOnAppliedHypothesisTag(), mySubHypBranch ); + SALOMEDS::SObject_wrap mySubHypBranch; + found = mySObject->FindSubObject( GetRefOnAppliedHypothesisTag(), + mySubHypBranch.inout() ); if ( found ) { aSubSubGroup = new HDFgroup( "Applied Hypotheses", aSubGroup ); aSubSubGroup->CreateOnDisk(); - SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( mySubHypBranch ); + SALOMEDS::ChildIterator_wrap it = myCurrentStudy->NewChildIterator( mySubHypBranch ); int hypNb = 0; for ( ; it->More(); it->Next() ) { - SALOMEDS::SObject_var mySubSObject = it->Value(); - SALOMEDS::SObject_var myRefOnHyp; - bool ok = mySubSObject->ReferencedObject( myRefOnHyp ); + SALOMEDS::SObject_wrap mySubSObject = it->Value(); + SALOMEDS::SObject_wrap myRefOnHyp; + bool ok = mySubSObject->ReferencedObject( myRefOnHyp.inout() ); if ( ok ) { //string myRefOnObject = myRefOnHyp->GetID(); CORBA::Object_var anObject = SObjectToObject( myRefOnHyp ); @@ -2567,18 +3440,20 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, } // write applied algorithms if exist - SALOMEDS::SObject_var mySubAlgoBranch; - found = mySObject->FindSubObject( GetRefOnAppliedAlgorithmsTag(), mySubAlgoBranch ); + SALOMEDS::SObject_wrap mySubAlgoBranch; + found = mySObject->FindSubObject( GetRefOnAppliedAlgorithmsTag(), + mySubAlgoBranch.inout() ); if ( found ) { aSubSubGroup = new HDFgroup( "Applied Algorithms", aSubGroup ); aSubSubGroup->CreateOnDisk(); - SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( mySubAlgoBranch ); + SALOMEDS::ChildIterator_wrap it = + myCurrentStudy->NewChildIterator( mySubAlgoBranch ); int algoNb = 0; for ( ; it->More(); it->Next() ) { - SALOMEDS::SObject_var mySubSObject = it->Value(); - SALOMEDS::SObject_var myRefOnAlgo; - bool ok = mySubSObject->ReferencedObject( myRefOnAlgo ); + SALOMEDS::SObject_wrap mySubSObject = it->Value(); + SALOMEDS::SObject_wrap myRefOnAlgo; + bool ok = mySubSObject->ReferencedObject( myRefOnAlgo.inout() ); if ( ok ) { //string myRefOnObject = myRefOnAlgo->GetID(); CORBA::Object_var anObject = SObjectToObject( myRefOnAlgo ); @@ -2598,347 +3473,395 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, //} } } - aSubSubGroup->CloseOnDisk(); + aSubSubGroup->CloseOnDisk(); + } + // close submesh HDF group + aSubGroup->CloseOnDisk(); + } + } + // close container of submeshes by type HDF group + aGroup->CloseOnDisk(); + } + } + // All sub-meshes will be stored in MED file + // .. will NOT (PAL 12992) + //if ( shapeRefFound ) + //myWriter.AddAllSubMeshes(); + + // store submesh order if any + const TListOfListOfInt& theOrderIds = myLocMesh.GetMeshOrder(); + if ( theOrderIds.size() ) { + char order_list[ 30 ]; + strcpy( order_list, "Mesh Order" ); + // count number of submesh ids + int nbIDs = 0; + TListOfListOfInt::const_iterator idIt = theOrderIds.begin(); + for ( ; idIt != theOrderIds.end(); idIt++ ) + nbIDs += (*idIt).size(); + // number of values = number of IDs + + // number of lists (for separators) - 1 + int* smIDs = new int [ nbIDs + theOrderIds.size() - 1 ]; + idIt = theOrderIds.begin(); + for ( int i = 0; idIt != theOrderIds.end(); idIt++ ) { + const TListOfInt& idList = *idIt; + if (idIt != theOrderIds.begin()) // not first list + smIDs[ i++ ] = -1/* *idList.size()*/; // separator between lists + // dump submesh ids from current list + TListOfInt::const_iterator id_smId = idList.begin(); + for( ; id_smId != idList.end(); id_smId++ ) + smIDs[ i++ ] = *id_smId; + } + // write HDF group + aSize[ 0 ] = nbIDs + theOrderIds.size() - 1; + + aDataset = new HDFdataset( order_list, aTopGroup, HDF_INT32, aSize, 1 ); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk( smIDs ); + aDataset->CloseOnDisk(); + // + delete[] smIDs; + } + + // groups root sub-branch + SALOMEDS::SObject_wrap myGroupsBranch; + for ( int i = GetNodeGroupsTag(); i <= GetBallElementsGroupsTag(); i++ ) { + found = gotBranch->FindSubObject( i, myGroupsBranch.inout() ); + if ( found ) { + char name_group[ 30 ]; + if ( i == GetNodeGroupsTag() ) + strcpy( name_group, "Groups of Nodes" ); + else if ( i == GetEdgeGroupsTag() ) + strcpy( name_group, "Groups of Edges" ); + else if ( i == GetFaceGroupsTag() ) + strcpy( name_group, "Groups of Faces" ); + else if ( i == GetVolumeGroupsTag() ) + strcpy( name_group, "Groups of Volumes" ); + else if ( i == Get0DElementsGroupsTag() ) + strcpy( name_group, "Groups of 0D Elements" ); + else if ( i == GetBallElementsGroupsTag() ) + strcpy( name_group, "Groups of Balls" ); + + aGroup = new HDFgroup( name_group, aTopGroup ); + aGroup->CreateOnDisk(); + + SALOMEDS::ChildIterator_wrap it = myCurrentStudy->NewChildIterator( myGroupsBranch ); + for ( ; it->More(); it->Next() ) { + SALOMEDS::SObject_wrap mySObject = it->Value(); + CORBA::Object_var aSubObject = SObjectToObject( mySObject ); + if ( !CORBA::is_nil( aSubObject ) ) { + SMESH_GroupBase_i* myGroupImpl = + dynamic_cast( GetServant( aSubObject ).in() ); + if ( !myGroupImpl ) + continue; + SMESHDS_GroupBase* aGrpBaseDS = myGroupImpl->GetGroupDS(); + if ( !aGrpBaseDS ) + continue; + + CORBA::String_var objStr = GetORB()->object_to_string( aSubObject ); + int anId = myStudyContext->findId( string( objStr.in() ) ); + + // For each group, create a dataset named "Group " + // and store the group's user name into it + const char* grpName = aGrpBaseDS->GetStoreName(); + char* aUserName = myGroupImpl->GetName(); + aSize[ 0 ] = strlen( aUserName ) + 1; + + aDataset = new HDFdataset( grpName, aGroup, HDF_STRING, aSize, 1 ); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk( aUserName ); + aDataset->CloseOnDisk(); + + // ouv : NPAL12872 + // For each group, create a dataset named "Group Color" + // and store the group's color into it + char grpColorName[ 30 ]; + sprintf( grpColorName, "ColorGroup %d", anId ); + SALOMEDS::Color aColor = myGroupImpl->GetColor(); + double anRGB[3]; + anRGB[ 0 ] = aColor.R; + anRGB[ 1 ] = aColor.G; + anRGB[ 2 ] = aColor.B; + aSize[ 0 ] = 3; + aDataset = new HDFdataset( grpColorName, aGroup, HDF_FLOAT64, aSize, 1 ); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk( anRGB ); + aDataset->CloseOnDisk(); + + // Pass SMESHDS_Group to MED writer + SMESHDS_Group* aGrpDS = dynamic_cast( aGrpBaseDS ); + if ( aGrpDS ) + myWriter.AddGroup( aGrpDS ); + + // write reference on a shape if exists + SMESHDS_GroupOnGeom* aGeomGrp = + dynamic_cast( aGrpBaseDS ); + if ( aGeomGrp ) { + SALOMEDS::SObject_wrap mySubRef, myShape; + if (mySObject->FindSubObject( GetRefOnShapeTag(), mySubRef.inout() ) && + mySubRef->ReferencedObject( myShape.inout() ) && + !CORBA::is_nil( myShape->GetObject() )) + { + string myRefOnObject = myShape->GetID(); + if ( myRefOnObject.length() > 0 ) { + char aRefName[ 30 ]; + sprintf( aRefName, "Ref on shape %d", anId); + aSize[ 0 ] = myRefOnObject.length() + 1; + aDataset = new HDFdataset(aRefName, aGroup, HDF_STRING, aSize, 1); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk( ( char* )( myRefOnObject.c_str() ) ); + aDataset->CloseOnDisk(); + } + } + else // shape ref is invalid: + { + // save a group on geometry as ordinary group + myWriter.AddGroup( aGeomGrp ); + } + } + else if ( SMESH_GroupOnFilter_i* aFilterGrp_i = + dynamic_cast( myGroupImpl )) + { + std::string str = aFilterGrp_i->FilterToString(); + std::string hdfGrpName = "Filter " + SMESH_Comment(anId); + aSize[ 0 ] = str.length() + 1; + aDataset = new HDFdataset( hdfGrpName.c_str(), aGroup, HDF_STRING, aSize, 1); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk( ( char* )( str.c_str() ) ); + aDataset->CloseOnDisk(); + } + } + } + aGroup->CloseOnDisk(); + } + } // loop on groups + + if ( strcmp( strHasData.c_str(), "1" ) == 0 ) + { + // Flush current mesh information into MED file + myWriter.Perform(); + + // save info on nb of elements + SMESH_PreMeshInfo::SaveToFile( myImpl, id, aFile ); + + // maybe a shape was deleted in the study + if ( !shapeRefFound && !mySMESHDSMesh->ShapeToMesh().IsNull() && hasShape) { + TopoDS_Shape nullShape; + myLocMesh.ShapeToMesh( nullShape ); // remove shape referring data + } + + if ( !mySMESHDSMesh->SubMeshes().empty() ) + { + // Store submeshes + // ---------------- + aGroup = new HDFgroup( "Submeshes", aTopGroup ); + aGroup->CreateOnDisk(); + + // each element belongs to one or none submesh, + // so for each node/element, we store a submesh ID + + // Make maps of submesh IDs of elements sorted by element IDs + typedef int TElemID; + typedef int TSubMID; + map< TElemID, TSubMID > eId2smId, nId2smId; + map< TElemID, TSubMID >::iterator hint; // insertion to map is done before hint + const map& aSubMeshes = mySMESHDSMesh->SubMeshes(); + map::const_iterator itSubM ( aSubMeshes.begin() ); + SMDS_NodeIteratorPtr itNode; + SMDS_ElemIteratorPtr itElem; + for ( itSubM = aSubMeshes.begin(); itSubM != aSubMeshes.end() ; itSubM++ ) + { + TSubMID aSubMeID = itSubM->first; + SMESHDS_SubMesh* aSubMesh = itSubM->second; + if ( aSubMesh->IsComplexSubmesh() ) + continue; // submesh containing other submeshs + // nodes + hint = nId2smId.begin(); // optimize insertion basing on increasing order of elem Ids in submesh + for ( itNode = aSubMesh->GetNodes(); itNode->more(); ++hint) + hint = nId2smId.insert( hint, make_pair( itNode->next()->GetID(), aSubMeID )); + // elements + hint = eId2smId.begin(); + for ( itElem = aSubMesh->GetElements(); itElem->more(); ++hint) + hint = eId2smId.insert( hint, make_pair( itElem->next()->GetID(), aSubMeID )); + } + + // Care of elements that are not on submeshes + if ( mySMESHDSMesh->NbNodes() != nId2smId.size() ) { + for ( itNode = mySMESHDSMesh->nodesIterator(); itNode->more(); ) + /* --- stl_map.h says : */ + /* A %map relies on unique keys and thus a %pair is only inserted if its */ + /* first element (the key) is not already present in the %map. */ + nId2smId.insert( make_pair( itNode->next()->GetID(), 0 )); + } + int nbElems = mySMESHDSMesh->NbEdges() + mySMESHDSMesh->NbFaces() + mySMESHDSMesh->NbVolumes(); + if ( nbElems != eId2smId.size() ) { + for ( itElem = mySMESHDSMesh->elementsIterator(); itElem->more(); ) + eId2smId.insert( make_pair( itElem->next()->GetID(), 0 )); + } + + // Store submesh IDs + for ( int isNode = 0; isNode < 2; ++isNode ) + { + map< TElemID, TSubMID >& id2smId = isNode ? nId2smId : eId2smId; + if ( id2smId.empty() ) continue; + map< TElemID, TSubMID >::const_iterator id_smId = id2smId.begin(); + // make and fill array of submesh IDs + int* smIDs = new int [ id2smId.size() ]; + for ( int i = 0; id_smId != id2smId.end(); ++id_smId, ++i ) + smIDs[ i ] = id_smId->second; + // write HDF group + aSize[ 0 ] = id2smId.size(); + string aDSName( isNode ? "Node Submeshes" : "Element Submeshes"); + aDataset = new HDFdataset( (char*)aDSName.c_str(), aGroup, HDF_INT32, aSize, 1 ); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk( smIDs ); + aDataset->CloseOnDisk(); + // + delete[] smIDs; + } + + aGroup->CloseOnDisk(); + + // Store node positions on sub-shapes (SMDS_Position): + // ---------------------------------------------------- + + aGroup = new HDFgroup( "Node Positions", aTopGroup ); + aGroup->CreateOnDisk(); + + // in aGroup, create 5 datasets to contain: + // "Nodes on Edges" - ID of node on edge + // "Edge positions" - U parameter on node on edge + // "Nodes on Faces" - ID of node on face + // "Face U positions" - U parameter of node on face + // "Face V positions" - V parameter of node on face + + // Find out nb of nodes on edges and faces + // Collect corresponing sub-meshes + int nbEdgeNodes = 0, nbFaceNodes = 0; + list aEdgeSM, aFaceSM; + // loop on SMESHDS_SubMesh'es + for ( itSubM = aSubMeshes.begin(); itSubM != aSubMeshes.end() ; itSubM++ ) + { + SMESHDS_SubMesh* aSubMesh = (*itSubM).second; + if ( aSubMesh->IsComplexSubmesh() ) + continue; // submesh containing other submeshs + int nbNodes = aSubMesh->NbNodes(); + if ( nbNodes == 0 ) continue; + + int aShapeID = (*itSubM).first; + if ( aShapeID < 1 || aShapeID > mySMESHDSMesh->MaxShapeIndex() ) + continue; + int aShapeType = mySMESHDSMesh->IndexToShape( aShapeID ).ShapeType(); + // write only SMDS_FacePosition and SMDS_EdgePosition + switch ( aShapeType ) { + case TopAbs_FACE: + nbFaceNodes += nbNodes; + aFaceSM.push_back( aSubMesh ); + break; + case TopAbs_EDGE: + nbEdgeNodes += nbNodes; + aEdgeSM.push_back( aSubMesh ); + break; + default: + continue; + } + } + // Treat positions on edges or faces + for ( int onFace = 0; onFace < 2; onFace++ ) + { + // Create arrays to store in datasets + int iNode = 0, nbNodes = ( onFace ? nbFaceNodes : nbEdgeNodes ); + if (!nbNodes) continue; + int* aNodeIDs = new int [ nbNodes ]; + double* aUPos = new double [ nbNodes ]; + double* aVPos = ( onFace ? new double[ nbNodes ] : 0 ); + + // Fill arrays + // loop on sub-meshes + list * pListSM = ( onFace ? &aFaceSM : &aEdgeSM ); + list::iterator itSM = pListSM->begin(); + for ( ; itSM != pListSM->end(); itSM++ ) + { + SMESHDS_SubMesh* aSubMesh = (*itSM); + + SMDS_NodeIteratorPtr itNode = aSubMesh->GetNodes(); + // loop on nodes in aSubMesh + while ( itNode->more() ) + { + //node ID + const SMDS_MeshNode* node = itNode->next(); + aNodeIDs [ iNode ] = node->GetID(); + + // Position + const SMDS_PositionPtr pos = node->GetPosition(); + if ( onFace ) { // on FACE + const SMDS_FacePosition* fPos = + dynamic_cast( pos ); + if ( fPos ) { + aUPos[ iNode ] = fPos->GetUParameter(); + aVPos[ iNode ] = fPos->GetVParameter(); + iNode++; + } + else + nbNodes--; + } + else { // on EDGE + const SMDS_EdgePosition* ePos = + dynamic_cast( pos ); + if ( ePos ) { + aUPos[ iNode ] = ePos->GetUParameter(); + iNode++; + } + else + nbNodes--; + } + } // loop on nodes in aSubMesh + } // loop on sub-meshes + + // Write datasets + if ( nbNodes ) + { + aSize[ 0 ] = nbNodes; + // IDS + string aDSName( onFace ? "Nodes on Faces" : "Nodes on Edges"); + aDataset = new HDFdataset( (char*)aDSName.c_str(), aGroup, HDF_INT32, aSize, 1 ); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk( aNodeIDs ); + aDataset->CloseOnDisk(); + + // U Positions + aDSName = ( onFace ? "Face U positions" : "Edge positions"); + aDataset = new HDFdataset( (char*)aDSName.c_str(), aGroup, HDF_FLOAT64, aSize, 1); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk( aUPos ); + aDataset->CloseOnDisk(); + // V Positions + if ( onFace ) { + aDataset = new HDFdataset( "Face V positions", aGroup, HDF_FLOAT64, aSize, 1); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk( aVPos ); + aDataset->CloseOnDisk(); } - // close submesh HDF group - aSubGroup->CloseOnDisk(); } - } - // close container of submeshes by type HDF group + delete [] aNodeIDs; + delete [] aUPos; + if ( aVPos ) delete [] aVPos; + + } // treat positions on edges or faces + + // close "Node Positions" group aGroup->CloseOnDisk(); - } - } - // All sub-meshes will be stored in MED file - // .. will NOT (PAL 12992) - //if ( shapeRefFound ) - //myWriter.AddAllSubMeshes(); - // groups root sub-branch - SALOMEDS::SObject_var myGroupsBranch; - for ( int i = GetNodeGroupsTag(); i <= GetVolumeGroupsTag(); i++ ) { - found = gotBranch->FindSubObject( i, myGroupsBranch ); - if ( found ) { - char name_group[ 30 ]; - if ( i == GetNodeGroupsTag() ) - strcpy( name_group, "Groups of Nodes" ); - else if ( i == GetEdgeGroupsTag() ) - strcpy( name_group, "Groups of Edges" ); - else if ( i == GetFaceGroupsTag() ) - strcpy( name_group, "Groups of Faces" ); - else if ( i == GetVolumeGroupsTag() ) - strcpy( name_group, "Groups of Volumes" ); - - aGroup = new HDFgroup( name_group, aTopGroup ); - aGroup->CreateOnDisk(); - - SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( myGroupsBranch ); - for ( ; it->More(); it->Next() ) { - SALOMEDS::SObject_var mySObject = it->Value(); - CORBA::Object_var aSubObject = SObjectToObject( mySObject ); - if ( !CORBA::is_nil( aSubObject ) ) { - SMESH_GroupBase_i* myGroupImpl = - dynamic_cast( GetServant( aSubObject ).in() ); - if ( !myGroupImpl ) - continue; - - CORBA::String_var objStr = GetORB()->object_to_string( aSubObject ); - int anId = myStudyContext->findId( string( objStr.in() ) ); - - // For each group, create a dataset named "Group " - // and store the group's user name into it - char grpName[ 30 ]; - sprintf( grpName, "Group %d", anId ); - char* aUserName = myGroupImpl->GetName(); - aSize[ 0 ] = strlen( aUserName ) + 1; - - aDataset = new HDFdataset( grpName, aGroup, HDF_STRING, aSize, 1 ); - aDataset->CreateOnDisk(); - aDataset->WriteOnDisk( aUserName ); - aDataset->CloseOnDisk(); - - // ouv : NPAL12872 - // For each group, create a dataset named "Group Color" - // and store the group's color into it - char grpColorName[ 30 ]; - sprintf( grpColorName, "ColorGroup %d", anId ); - SALOMEDS::Color aColor = myGroupImpl->GetColor(); - double anRGB[3]; - anRGB[ 0 ] = aColor.R; - anRGB[ 1 ] = aColor.G; - anRGB[ 2 ] = aColor.B; - aSize[ 0 ] = 3; - aDataset = new HDFdataset( grpColorName, aGroup, HDF_FLOAT64, aSize, 1 ); - aDataset->CreateOnDisk(); - aDataset->WriteOnDisk( anRGB ); - aDataset->CloseOnDisk(); - - // Store the group contents into MED file - if ( myLocMesh.GetGroup( myGroupImpl->GetLocalID() ) ) { - - if(MYDEBUG) MESSAGE( "VSR - SMESH_Gen_i::Save(): saving group with StoreName = " - << grpName << " to MED file" ); - SMESHDS_GroupBase* aGrpBaseDS = - myLocMesh.GetGroup( myGroupImpl->GetLocalID() )->GetGroupDS(); - aGrpBaseDS->SetStoreName( grpName ); - - // Pass SMESHDS_Group to MED writer - SMESHDS_Group* aGrpDS = dynamic_cast( aGrpBaseDS ); - if ( aGrpDS ) - myWriter.AddGroup( aGrpDS ); - - // write reference on a shape if exists - SMESHDS_GroupOnGeom* aGeomGrp = - dynamic_cast( aGrpBaseDS ); - if ( aGeomGrp ) { - SALOMEDS::SObject_var mySubRef, myShape; - if (mySObject->FindSubObject( GetRefOnShapeTag(), mySubRef ) && - mySubRef->ReferencedObject( myShape ) && - !CORBA::is_nil( myShape->GetObject() )) - { - string myRefOnObject = myShape->GetID(); - if ( myRefOnObject.length() > 0 ) { - char aRefName[ 30 ]; - sprintf( aRefName, "Ref on shape %d", anId); - aSize[ 0 ] = myRefOnObject.length() + 1; - aDataset = new HDFdataset(aRefName, aGroup, HDF_STRING, aSize, 1); - aDataset->CreateOnDisk(); - aDataset->WriteOnDisk( ( char* )( myRefOnObject.c_str() ) ); - aDataset->CloseOnDisk(); - } - } - else // shape ref is invalid: - { - // save a group on geometry as ordinary group - myWriter.AddGroup( aGeomGrp ); - } - } - } - } - } - aGroup->CloseOnDisk(); - } - } // loop on groups - - if ( strcmp( strHasData.c_str(), "1" ) == 0 ) - { - // Flush current mesh information into MED file - myWriter.Perform(); - - // maybe a shape was deleted in the study - if ( !shapeRefFound && !mySMESHDSMesh->ShapeToMesh().IsNull() && hasShape) { - TopoDS_Shape nullShape; - myLocMesh.ShapeToMesh( nullShape ); // remove shape referring data - } - - if ( !mySMESHDSMesh->SubMeshes().empty() ) - { - // Store submeshes - // ---------------- - aGroup = new HDFgroup( "Submeshes", aTopGroup ); - aGroup->CreateOnDisk(); - - // each element belongs to one or none submesh, - // so for each node/element, we store a submesh ID - - // Make maps of submesh IDs of elements sorted by element IDs - typedef int TElemID; - typedef int TSubMID; - map< TElemID, TSubMID > eId2smId, nId2smId; - map< TElemID, TSubMID >::iterator hint; // insertion to map is done before hint - const map& aSubMeshes = mySMESHDSMesh->SubMeshes(); - map::const_iterator itSubM ( aSubMeshes.begin() ); - SMDS_NodeIteratorPtr itNode; - SMDS_ElemIteratorPtr itElem; - for ( itSubM = aSubMeshes.begin(); itSubM != aSubMeshes.end() ; itSubM++ ) - { - TSubMID aSubMeID = itSubM->first; - SMESHDS_SubMesh* aSubMesh = itSubM->second; - if ( aSubMesh->IsComplexSubmesh() ) - continue; // submesh containing other submeshs - // nodes - hint = nId2smId.begin(); // optimize insertion basing on increasing order of elem Ids in submesh - for ( itNode = aSubMesh->GetNodes(); itNode->more(); ++hint) - hint = nId2smId.insert( hint, make_pair( itNode->next()->GetID(), aSubMeID )); - // elements - hint = eId2smId.begin(); - for ( itElem = aSubMesh->GetElements(); itElem->more(); ++hint) - hint = eId2smId.insert( hint, make_pair( itElem->next()->GetID(), aSubMeID )); - } - - // Care of elements that are not on submeshes - if ( mySMESHDSMesh->NbNodes() != nId2smId.size() ) { - for ( itNode = mySMESHDSMesh->nodesIterator(); itNode->more(); ) - /* --- stl_map.h says : */ - /* A %map relies on unique keys and thus a %pair is only inserted if its */ - /* first element (the key) is not already present in the %map. */ - nId2smId.insert( make_pair( itNode->next()->GetID(), 0 )); - } - int nbElems = mySMESHDSMesh->NbEdges() + mySMESHDSMesh->NbFaces() + mySMESHDSMesh->NbVolumes(); - if ( nbElems != eId2smId.size() ) { - for ( itElem = mySMESHDSMesh->elementsIterator(); itElem->more(); ) - eId2smId.insert( make_pair( itElem->next()->GetID(), 0 )); - } - - // Store submesh IDs - for ( int isNode = 0; isNode < 2; ++isNode ) - { - map< TElemID, TSubMID >& id2smId = isNode ? nId2smId : eId2smId; - if ( id2smId.empty() ) continue; - map< TElemID, TSubMID >::const_iterator id_smId = id2smId.begin(); - // make and fill array of submesh IDs - int* smIDs = new int [ id2smId.size() ]; - for ( int i = 0; id_smId != id2smId.end(); ++id_smId, ++i ) - smIDs[ i ] = id_smId->second; - // write HDF group - aSize[ 0 ] = id2smId.size(); - string aDSName( isNode ? "Node Submeshes" : "Element Submeshes"); - aDataset = new HDFdataset( (char*)aDSName.c_str(), aGroup, HDF_INT32, aSize, 1 ); - aDataset->CreateOnDisk(); - aDataset->WriteOnDisk( smIDs ); - aDataset->CloseOnDisk(); - // - delete smIDs; - } - - // Store node positions on sub-shapes (SMDS_Position): - // ---------------------------------------------------- - - aGroup = new HDFgroup( "Node Positions", aTopGroup ); - aGroup->CreateOnDisk(); - - // in aGroup, create 5 datasets to contain: - // "Nodes on Edges" - ID of node on edge - // "Edge positions" - U parameter on node on edge - // "Nodes on Faces" - ID of node on face - // "Face U positions" - U parameter of node on face - // "Face V positions" - V parameter of node on face - - // Find out nb of nodes on edges and faces - // Collect corresponing sub-meshes - int nbEdgeNodes = 0, nbFaceNodes = 0; - list aEdgeSM, aFaceSM; - // loop on SMESHDS_SubMesh'es - for ( itSubM = aSubMeshes.begin(); itSubM != aSubMeshes.end() ; itSubM++ ) - { - SMESHDS_SubMesh* aSubMesh = (*itSubM).second; - if ( aSubMesh->IsComplexSubmesh() ) - continue; // submesh containing other submeshs - int nbNodes = aSubMesh->NbNodes(); - if ( nbNodes == 0 ) continue; - - int aShapeID = (*itSubM).first; - int aShapeType = mySMESHDSMesh->IndexToShape( aShapeID ).ShapeType(); - // write only SMDS_FacePosition and SMDS_EdgePosition - switch ( aShapeType ) { - case TopAbs_FACE: - nbFaceNodes += nbNodes; - aFaceSM.push_back( aSubMesh ); - break; - case TopAbs_EDGE: - nbEdgeNodes += nbNodes; - aEdgeSM.push_back( aSubMesh ); - break; - default: - continue; - } - } - // Treat positions on edges or faces - for ( int onFace = 0; onFace < 2; onFace++ ) - { - // Create arrays to store in datasets - int iNode = 0, nbNodes = ( onFace ? nbFaceNodes : nbEdgeNodes ); - if (!nbNodes) continue; - int* aNodeIDs = new int [ nbNodes ]; - double* aUPos = new double [ nbNodes ]; - double* aVPos = ( onFace ? new double[ nbNodes ] : 0 ); - - // Fill arrays - // loop on sub-meshes - list * pListSM = ( onFace ? &aFaceSM : &aEdgeSM ); - list::iterator itSM = pListSM->begin(); - for ( ; itSM != pListSM->end(); itSM++ ) - { - SMESHDS_SubMesh* aSubMesh = (*itSM); - - SMDS_NodeIteratorPtr itNode = aSubMesh->GetNodes(); - // loop on nodes in aSubMesh - while ( itNode->more() ) - { - //node ID - const SMDS_MeshNode* node = itNode->next(); - aNodeIDs [ iNode ] = node->GetID(); - - // Position - const SMDS_PositionPtr pos = node->GetPosition(); - if ( onFace ) { // on FACE - const SMDS_FacePosition* fPos = - dynamic_cast( pos.get() ); - if ( fPos ) { - aUPos[ iNode ] = fPos->GetUParameter(); - aVPos[ iNode ] = fPos->GetVParameter(); - iNode++; - } - else - nbNodes--; - } - else { // on EDGE - const SMDS_EdgePosition* ePos = - dynamic_cast( pos.get() ); - if ( ePos ) { - aUPos[ iNode ] = ePos->GetUParameter(); - iNode++; - } - else - nbNodes--; - } - } // loop on nodes in aSubMesh - } // loop on sub-meshes - - // Write datasets - if ( nbNodes ) - { - aSize[ 0 ] = nbNodes; - // IDS - string aDSName( onFace ? "Nodes on Faces" : "Nodes on Edges"); - aDataset = new HDFdataset( (char*)aDSName.c_str(), aGroup, HDF_INT32, aSize, 1 ); - aDataset->CreateOnDisk(); - aDataset->WriteOnDisk( aNodeIDs ); - aDataset->CloseOnDisk(); - - // U Positions - aDSName = ( onFace ? "Face U positions" : "Edge positions"); - aDataset = new HDFdataset( (char*)aDSName.c_str(), aGroup, HDF_FLOAT64, aSize, 1); - aDataset->CreateOnDisk(); - aDataset->WriteOnDisk( aUPos ); - aDataset->CloseOnDisk(); - // V Positions - if ( onFace ) { - aDataset = new HDFdataset( "Face V positions", aGroup, HDF_FLOAT64, aSize, 1); - aDataset->CreateOnDisk(); - aDataset->WriteOnDisk( aVPos ); - aDataset->CloseOnDisk(); - } - } - delete [] aNodeIDs; - delete [] aUPos; - if ( aVPos ) delete [] aVPos; - - } // treat positions on edges or faces - - // close "Node Positions" group - aGroup->CloseOnDisk(); - - } // if ( there are submeshes in SMESHDS_Mesh ) - } // if ( hasData ) - - // close mesh HDF group - aTopGroup->CloseOnDisk(); - } - } + } // if ( there are submeshes in SMESHDS_Mesh ) + } // if ( hasData ) + + // close mesh HDF group + aTopGroup->CloseOnDisk(); + } + } } } } - + // close HDF file aFile->CloseOnDisk(); delete aFile; @@ -2947,7 +3870,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, aStreamFile = SALOMEDS_Tool::PutFilesToStream( tmpDir.ToCString(), aFileSeq.in(), isMultiFile ); // Remove temporary files and directory - if ( !isMultiFile ) + if ( !isMultiFile ) SALOMEDS_Tool::RemoveTemporaryFiles( tmpDir.ToCString(), aFileSeq.in(), true ); INFOS( "SMESH_Gen_i::Save() completed" ); @@ -2963,8 +3886,8 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, //============================================================================= SALOMEDS::TMPFile* SMESH_Gen_i::SaveASCII( SALOMEDS::SComponent_ptr theComponent, - const char* theURL, - bool isMultiFile ) { + const char* theURL, + bool isMultiFile ) { if(MYDEBUG) MESSAGE( "SMESH_Gen_i::SaveASCII" ); SALOMEDS::TMPFile_var aStreamFile = Save( theComponent, theURL, isMultiFile ); return aStreamFile._retn(); @@ -2974,12 +3897,12 @@ SALOMEDS::TMPFile* SMESH_Gen_i::SaveASCII( SALOMEDS::SComponent_ptr theComponent int size = aStreamFile.in().length(); _CORBA_Octet* buffer = new _CORBA_Octet[size*3+1]; for ( int i = 0; i < size; i++ ) - sprintf( (char*)&(buffer[i*3]), "|%02x", (char*)(aStreamFile[i]) ); + sprintf( (char*)&(buffer[i*3]), "|%02x", aStreamFile[i] ); buffer[size * 3] = '\0'; SALOMEDS::TMPFile_var anAsciiStreamFile = new SALOMEDS::TMPFile(size*3, size*3, buffer, 1); - + return anAsciiStreamFile._retn(); } @@ -3000,34 +3923,9 @@ void SMESH_Gen_i::loadGeomData( SALOMEDS::SComponent_ptr theCompRoot ) if ( aStudy->_is_nil() ) return; - SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder(); + SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder(); aStudyBuilder->LoadWith( theCompRoot, GetGeomEngine() ); } -//============================================================================= -/*! - * \brief Creates SMDS_Position according to shape type - */ -//============================================================================= - -class PositionCreator { -public: - SMDS_PositionPtr MakePosition(const TopAbs_ShapeEnum type) { - return (this->*myFuncTable[ type ])(); - } - PositionCreator() { - myFuncTable.resize( (size_t) TopAbs_SHAPE, & PositionCreator::defaultPosition ); - myFuncTable[ TopAbs_FACE ] = & PositionCreator::facePosition; - myFuncTable[ TopAbs_EDGE ] = & PositionCreator::edgePosition; - myFuncTable[ TopAbs_VERTEX ] = & PositionCreator::vertexPosition; - } -private: - SMDS_PositionPtr edgePosition() const { return SMDS_PositionPtr( new SMDS_EdgePosition ); } - SMDS_PositionPtr facePosition() const { return SMDS_PositionPtr( new SMDS_FacePosition ); } - SMDS_PositionPtr vertexPosition() const { return SMDS_PositionPtr( new SMDS_VertexPosition); } - SMDS_PositionPtr defaultPosition() const { return SMDS_SpacePosition::originSpacePosition(); } - typedef SMDS_PositionPtr (PositionCreator:: * FmakePos)() const; - vector myFuncTable; -}; //============================================================================= /*! @@ -3038,13 +3936,13 @@ private: //============================================================================= bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, - const SALOMEDS::TMPFile& theStream, - const char* theURL, - bool isMultiFile ) + const SALOMEDS::TMPFile& theStream, + const char* theURL, + bool isMultiFile ) { INFOS( "SMESH_Gen_i::Load" ); - if ( myCurrentStudy->_is_nil() || + if ( myCurrentStudy->_is_nil() || theComponent->GetStudy()->StudyId() != myCurrentStudy->StudyId() ) SetCurrentStudy( theComponent->GetStudy() ); @@ -3060,18 +3958,18 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, // Get temporary files location TCollection_AsciiString tmpDir = isMultiFile ? TCollection_AsciiString( ( char* )theURL ) : ( char* )SALOMEDS_Tool::GetTmpDir().c_str(); - - INFOS( "THE URL++++++++++++++" ) - INFOS( theURL ); - INFOS( "THE TMP PATH+++++++++" ); - INFOS( tmpDir ); + + INFOS( "THE URL++++++++++++++" ); + INFOS( theURL ); + INFOS( "THE TMP PATH+++++++++" ); + INFOS( tmpDir ); // Convert the stream into sequence of files to process SALOMEDS::ListOfFileNames_var aFileSeq = SALOMEDS_Tool::PutStreamToFiles( theStream, tmpDir.ToCString(), - isMultiFile ); + isMultiFile ); TCollection_AsciiString aStudyName( "" ); - if ( isMultiFile ) + if ( isMultiFile ) aStudyName = ( (char*)SALOMEDS_Tool::GetNameFromPath( myCurrentStudy->URL() ).c_str() ); // Set names of temporary files @@ -3097,8 +3995,10 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, return false; } - DriverMED_R_SMESHDS_Mesh myReader; - myReader.SetFile( meshfile.ToCString() ); + TPythonDump pd; // prevent dump during loading + + // DriverMED_R_SMESHDS_Mesh myReader; + // myReader.SetFile( meshfile.ToCString() ); // For PAL13473 ("Repetitive mesh") implementation. // New dependencies between SMESH objects are established: @@ -3114,99 +4014,99 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, list< pair< SMESH_Mesh_i*, HDFgroup* > > meshGroupList; // get total number of top-level groups - int aNbGroups = aFile->nInternalObjects(); + int aNbGroups = aFile->nInternalObjects(); if ( aNbGroups > 0 ) { // --> in first turn we should read&create hypotheses if ( aFile->ExistInternalObject( "Hypotheses" ) ) { // open hypotheses root HDF group - aTopGroup = new HDFgroup( "Hypotheses", aFile ); + aTopGroup = new HDFgroup( "Hypotheses", aFile ); aTopGroup->OpenOnDisk(); // get number of hypotheses - int aNbObjects = aTopGroup->nInternalObjects(); + int aNbObjects = aTopGroup->nInternalObjects(); for ( int j = 0; j < aNbObjects; j++ ) { - // try to identify hypothesis - char hypGrpName[ HDF_NAME_MAX_LEN+1 ]; + // try to identify hypothesis + char hypGrpName[ HDF_NAME_MAX_LEN+1 ]; aTopGroup->InternalObjectIndentify( j, hypGrpName ); - if ( string( hypGrpName ).substr( 0, 10 ) == string( "Hypothesis" ) ) { - // open hypothesis group - aGroup = new HDFgroup( hypGrpName, aTopGroup ); - aGroup->OpenOnDisk(); - - // --> get hypothesis id - int id = atoi( string( hypGrpName ).substr( 10 ).c_str() ); - string hypname; - string libname; - string hypdata; - - // get number of datasets - int aNbSubObjects = aGroup->nInternalObjects(); - for ( int k = 0; k < aNbSubObjects; k++ ) { - // identify dataset - char name_of_subgroup[ HDF_NAME_MAX_LEN+1 ]; - aGroup->InternalObjectIndentify( k, name_of_subgroup ); - // --> get hypothesis name - if ( strcmp( name_of_subgroup, "Name" ) == 0 ) { - aDataset = new HDFdataset( name_of_subgroup, aGroup ); - aDataset->OpenOnDisk(); - size = aDataset->GetSize(); - char* hypname_str = new char[ size ]; - aDataset->ReadFromDisk( hypname_str ); - hypname = string( hypname_str ); - delete [] hypname_str; - aDataset->CloseOnDisk(); - } - // --> get hypothesis plugin library name - if ( strcmp( name_of_subgroup, "LibName" ) == 0 ) { - aDataset = new HDFdataset( name_of_subgroup, aGroup ); - aDataset->OpenOnDisk(); - size = aDataset->GetSize(); - char* libname_str = new char[ size ]; - aDataset->ReadFromDisk( libname_str ); - if(MYDEBUG) SCRUTE( libname_str ); - libname = string( libname_str ); - delete [] libname_str; - aDataset->CloseOnDisk(); - } - // --> get hypothesis data - if ( strcmp( name_of_subgroup, "Data" ) == 0 ) { - aDataset = new HDFdataset( name_of_subgroup, aGroup ); - aDataset->OpenOnDisk(); - size = aDataset->GetSize(); - char* hypdata_str = new char[ size ]; - aDataset->ReadFromDisk( hypdata_str ); - hypdata = string( hypdata_str ); - delete [] hypdata_str; - aDataset->CloseOnDisk(); - } - } - // close hypothesis HDF group - aGroup->CloseOnDisk(); - - // --> restore hypothesis from data - if ( id > 0 && !hypname.empty()/* && !hypdata.empty()*/ ) { // VSR : persistent data can be empty - if(MYDEBUG) MESSAGE("VSR - load hypothesis : id = " << id << + if ( string( hypGrpName ).substr( 0, 10 ) == string( "Hypothesis" ) ) { + // open hypothesis group + aGroup = new HDFgroup( hypGrpName, aTopGroup ); + aGroup->OpenOnDisk(); + + // --> get hypothesis id + int id = atoi( string( hypGrpName ).substr( 10 ).c_str() ); + string hypname; + string libname; + string hypdata; + + // get number of datasets + int aNbSubObjects = aGroup->nInternalObjects(); + for ( int k = 0; k < aNbSubObjects; k++ ) { + // identify dataset + char name_of_subgroup[ HDF_NAME_MAX_LEN+1 ]; + aGroup->InternalObjectIndentify( k, name_of_subgroup ); + // --> get hypothesis name + if ( strcmp( name_of_subgroup, "Name" ) == 0 ) { + aDataset = new HDFdataset( name_of_subgroup, aGroup ); + aDataset->OpenOnDisk(); + size = aDataset->GetSize(); + char* hypname_str = new char[ size ]; + aDataset->ReadFromDisk( hypname_str ); + hypname = string( hypname_str ); + delete [] hypname_str; + aDataset->CloseOnDisk(); + } + // --> get hypothesis plugin library name + if ( strcmp( name_of_subgroup, "LibName" ) == 0 ) { + aDataset = new HDFdataset( name_of_subgroup, aGroup ); + aDataset->OpenOnDisk(); + size = aDataset->GetSize(); + char* libname_str = new char[ size ]; + aDataset->ReadFromDisk( libname_str ); + if(MYDEBUG) SCRUTE( libname_str ); + libname = string( libname_str ); + delete [] libname_str; + aDataset->CloseOnDisk(); + } + // --> get hypothesis data + if ( strcmp( name_of_subgroup, "Data" ) == 0 ) { + aDataset = new HDFdataset( name_of_subgroup, aGroup ); + aDataset->OpenOnDisk(); + size = aDataset->GetSize(); + char* hypdata_str = new char[ size ]; + aDataset->ReadFromDisk( hypdata_str ); + hypdata = string( hypdata_str ); + delete [] hypdata_str; + aDataset->CloseOnDisk(); + } + } + // close hypothesis HDF group + aGroup->CloseOnDisk(); + + // --> restore hypothesis from data + if ( id > 0 && !hypname.empty()/* && !hypdata.empty()*/ ) { // VSR : persistent data can be empty + if(MYDEBUG) MESSAGE("VSR - load hypothesis : id = " << id << ", name = " << hypname.c_str() << ", persistent string = " << hypdata.c_str()); SMESH::SMESH_Hypothesis_var myHyp; - try { // protect persistence mechanism against exceptions - myHyp = this->createHypothesis( hypname.c_str(), libname.c_str() ); - } - catch (...) { - INFOS( "Exception during hypothesis creation" ); - } + try { // protect persistence mechanism against exceptions + myHyp = this->createHypothesis( hypname.c_str(), libname.c_str() ); + } + catch (...) { + INFOS( "Exception during hypothesis creation" ); + } - SMESH_Hypothesis_i* myImpl = dynamic_cast( GetServant( myHyp ).in() ); - if ( myImpl ) { - // myImpl->LoadFrom( hypdata.c_str() ); + SMESH_Hypothesis_i* myImpl = dynamic_cast( GetServant( myHyp ).in() ); + if ( myImpl ) { + // myImpl->LoadFrom( hypdata.c_str() ); hypDataList.push_back( make_pair( myImpl, hypdata )); - string iorString = GetORB()->object_to_string( myHyp ); - int newId = myStudyContext->findId( iorString ); - myStudyContext->mapOldToNew( id, newId ); - } - else - if(MYDEBUG) MESSAGE( "VSR - SMESH_Gen::Load - can't get servant" ); + CORBA::String_var iorString = GetORB()->object_to_string( myHyp ); + int newId = myStudyContext->findId( iorString.in() ); + myStudyContext->mapOldToNew( id, newId ); + } + else + if(MYDEBUG) MESSAGE( "VSR - SMESH_Gen::Load - can't get servant" ); } } } @@ -3218,95 +4118,95 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, // --> then we should read&create algorithms if ( aFile->ExistInternalObject( "Algorithms" ) ) { // open algorithms root HDF group - aTopGroup = new HDFgroup( "Algorithms", aFile ); + aTopGroup = new HDFgroup( "Algorithms", aFile ); aTopGroup->OpenOnDisk(); // get number of algorithms - int aNbObjects = aTopGroup->nInternalObjects(); + int aNbObjects = aTopGroup->nInternalObjects(); for ( int j = 0; j < aNbObjects; j++ ) { - // try to identify algorithm - char hypGrpName[ HDF_NAME_MAX_LEN+1 ]; + // try to identify algorithm + char hypGrpName[ HDF_NAME_MAX_LEN+1 ]; aTopGroup->InternalObjectIndentify( j, hypGrpName ); - if ( string( hypGrpName ).substr( 0, 9 ) == string( "Algorithm" ) ) { - // open algorithm group - aGroup = new HDFgroup( hypGrpName, aTopGroup ); - aGroup->OpenOnDisk(); - - // --> get algorithm id - int id = atoi( string( hypGrpName ).substr( 9 ).c_str() ); - string hypname; - string libname; - string hypdata; - - // get number of datasets - int aNbSubObjects = aGroup->nInternalObjects(); - for ( int k = 0; k < aNbSubObjects; k++ ) { - // identify dataset - char name_of_subgroup[ HDF_NAME_MAX_LEN+1 ]; - aGroup->InternalObjectIndentify( k, name_of_subgroup ); - // --> get algorithm name - if ( strcmp( name_of_subgroup, "Name" ) == 0 ) { - aDataset = new HDFdataset( name_of_subgroup, aGroup ); - aDataset->OpenOnDisk(); - size = aDataset->GetSize(); - char* hypname_str = new char[ size ]; - aDataset->ReadFromDisk( hypname_str ); - hypname = string( hypname_str ); - delete [] hypname_str; - aDataset->CloseOnDisk(); - } - // --> get algorithm plugin library name - if ( strcmp( name_of_subgroup, "LibName" ) == 0 ) { - aDataset = new HDFdataset( name_of_subgroup, aGroup ); - aDataset->OpenOnDisk(); - size = aDataset->GetSize(); - char* libname_str = new char[ size ]; - aDataset->ReadFromDisk( libname_str ); - if(MYDEBUG) SCRUTE( libname_str ); - libname = string( libname_str ); - delete [] libname_str; - aDataset->CloseOnDisk(); - } - // --> get algorithm data - if ( strcmp( name_of_subgroup, "Data" ) == 0 ) { - aDataset = new HDFdataset( name_of_subgroup, aGroup ); - aDataset->OpenOnDisk(); - size = aDataset->GetSize(); - char* hypdata_str = new char[ size ]; - aDataset->ReadFromDisk( hypdata_str ); - if(MYDEBUG) SCRUTE( hypdata_str ); - hypdata = string( hypdata_str ); - delete [] hypdata_str; - aDataset->CloseOnDisk(); - } - } - // close algorithm HDF group - aGroup->CloseOnDisk(); - - // --> restore algorithm from data - if ( id > 0 && !hypname.empty()/* && !hypdata.empty()*/ ) { // VSR : persistent data can be empty - if(MYDEBUG) MESSAGE("VSR - load algo : id = " << id << + if ( string( hypGrpName ).substr( 0, 9 ) == string( "Algorithm" ) ) { + // open algorithm group + aGroup = new HDFgroup( hypGrpName, aTopGroup ); + aGroup->OpenOnDisk(); + + // --> get algorithm id + int id = atoi( string( hypGrpName ).substr( 9 ).c_str() ); + string hypname; + string libname; + string hypdata; + + // get number of datasets + int aNbSubObjects = aGroup->nInternalObjects(); + for ( int k = 0; k < aNbSubObjects; k++ ) { + // identify dataset + char name_of_subgroup[ HDF_NAME_MAX_LEN+1 ]; + aGroup->InternalObjectIndentify( k, name_of_subgroup ); + // --> get algorithm name + if ( strcmp( name_of_subgroup, "Name" ) == 0 ) { + aDataset = new HDFdataset( name_of_subgroup, aGroup ); + aDataset->OpenOnDisk(); + size = aDataset->GetSize(); + char* hypname_str = new char[ size ]; + aDataset->ReadFromDisk( hypname_str ); + hypname = string( hypname_str ); + delete [] hypname_str; + aDataset->CloseOnDisk(); + } + // --> get algorithm plugin library name + if ( strcmp( name_of_subgroup, "LibName" ) == 0 ) { + aDataset = new HDFdataset( name_of_subgroup, aGroup ); + aDataset->OpenOnDisk(); + size = aDataset->GetSize(); + char* libname_str = new char[ size ]; + aDataset->ReadFromDisk( libname_str ); + if(MYDEBUG) SCRUTE( libname_str ); + libname = string( libname_str ); + delete [] libname_str; + aDataset->CloseOnDisk(); + } + // --> get algorithm data + if ( strcmp( name_of_subgroup, "Data" ) == 0 ) { + aDataset = new HDFdataset( name_of_subgroup, aGroup ); + aDataset->OpenOnDisk(); + size = aDataset->GetSize(); + char* hypdata_str = new char[ size ]; + aDataset->ReadFromDisk( hypdata_str ); + if(MYDEBUG) SCRUTE( hypdata_str ); + hypdata = string( hypdata_str ); + delete [] hypdata_str; + aDataset->CloseOnDisk(); + } + } + // close algorithm HDF group + aGroup->CloseOnDisk(); + + // --> restore algorithm from data + if ( id > 0 && !hypname.empty()/* && !hypdata.empty()*/ ) { // VSR : persistent data can be empty + if(MYDEBUG) MESSAGE("VSR - load algo : id = " << id << ", name = " << hypname.c_str() << ", persistent string = " << hypdata.c_str()); SMESH::SMESH_Hypothesis_var myHyp; - try { // protect persistence mechanism against exceptions - myHyp = this->createHypothesis( hypname.c_str(), libname.c_str() ); - } - catch (...) { - INFOS( "Exception during hypothesis creation" ); - } + try { // protect persistence mechanism against exceptions + myHyp = this->createHypothesis( hypname.c_str(), libname.c_str() ); + } + catch (...) { + INFOS( "Exception during hypothesis creation" ); + } - SMESH_Hypothesis_i* myImpl = dynamic_cast( GetServant( myHyp ).in() ); - if ( myImpl ) { - //myImpl->LoadFrom( hypdata.c_str() ); + SMESH_Hypothesis_i* myImpl = dynamic_cast( GetServant( myHyp ).in() ); + if ( myImpl ) { + //myImpl->LoadFrom( hypdata.c_str() ); hypDataList.push_back( make_pair( myImpl, hypdata )); - string iorString = GetORB()->object_to_string( myHyp ); - int newId = myStudyContext->findId( iorString ); - myStudyContext->mapOldToNew( id, newId ); - } - else - if(MYDEBUG) MESSAGE( "VSR - SMESH_Gen::Load - can't get servant" ); + CORBA::String_var iorString = GetORB()->object_to_string( myHyp ); + int newId = myStudyContext->findId( iorString.in() ); + myStudyContext->mapOldToNew( id, newId ); + } + else + if(MYDEBUG) MESSAGE( "VSR - SMESH_Gen::Load - can't get servant" ); } } } @@ -3322,44 +4222,45 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, aFile->InternalObjectIndentify( i, meshName ); if ( string( meshName ).substr( 0, 4 ) == string( "Mesh" ) ) { - // --> get mesh id - int id = atoi( string( meshName ).substr( 4 ).c_str() ); - if ( id <= 0 ) - continue; - - // open mesh HDF group - aTopGroup = new HDFgroup( meshName, aFile ); - aTopGroup->OpenOnDisk(); - - // get number of child HDF objects - int aNbObjects = aTopGroup->nInternalObjects(); - if ( aNbObjects > 0 ) { - // create mesh - if(MYDEBUG) MESSAGE( "VSR - load mesh : id = " << id ); - SMESH::SMESH_Mesh_var myNewMesh = this->createMesh(); - SMESH_Mesh_i* myNewMeshImpl = dynamic_cast( GetServant( myNewMesh ).in() ); + // --> get mesh id + int id = atoi( string( meshName ).substr( 4 ).c_str() ); + if ( id <= 0 ) + continue; + + // open mesh HDF group + aTopGroup = new HDFgroup( meshName, aFile ); + aTopGroup->OpenOnDisk(); + + // get number of child HDF objects + int aNbObjects = aTopGroup->nInternalObjects(); + if ( aNbObjects > 0 ) { + // create mesh + if(MYDEBUG) MESSAGE( "VSR - load mesh : id = " << id ); + SMESH::SMESH_Mesh_var myNewMesh = this->createMesh(); + SMESH_Mesh_i* myNewMeshImpl = dynamic_cast( GetServant( myNewMesh ).in() ); if ( !myNewMeshImpl ) - continue; + continue; meshGroupList.push_back( make_pair( myNewMeshImpl, aTopGroup )); - string iorString = GetORB()->object_to_string( myNewMesh ); - int newId = myStudyContext->findId( iorString ); - myStudyContext->mapOldToNew( id, newId ); - - // ouv : NPAL12872 - // try to read and set auto color flag - char aMeshAutoColorName[ 30 ]; - sprintf( aMeshAutoColorName, "AutoColorMesh %d", id); - if( aTopGroup->ExistInternalObject( aMeshAutoColorName ) ) - { - aDataset = new HDFdataset( aMeshAutoColorName, aTopGroup ); - aDataset->OpenOnDisk(); - size = aDataset->GetSize(); - int* anAutoColor = new int[ size ]; - aDataset->ReadFromDisk( anAutoColor ); - aDataset->CloseOnDisk(); - myNewMeshImpl->SetAutoColor( (bool)anAutoColor[0] ); - } + CORBA::String_var iorString = GetORB()->object_to_string( myNewMesh ); + int newId = myStudyContext->findId( iorString.in() ); + myStudyContext->mapOldToNew( id, newId ); + + // ouv : NPAL12872 + // try to read and set auto color flag + char aMeshAutoColorName[ 30 ]; + sprintf( aMeshAutoColorName, "AutoColorMesh %d", id); + if( aTopGroup->ExistInternalObject( aMeshAutoColorName ) ) + { + aDataset = new HDFdataset( aMeshAutoColorName, aTopGroup ); + aDataset->OpenOnDisk(); + size = aDataset->GetSize(); + int* anAutoColor = new int[ size ]; + aDataset->ReadFromDisk( anAutoColor ); + aDataset->CloseOnDisk(); + myNewMeshImpl->GetImpl().SetAutoColor( (bool)anAutoColor[0] ); + delete [] anAutoColor; + } // try to read and set reference to shape GEOM::GEOM_Object_var aShapeObject; @@ -3372,7 +4273,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, aDataset->ReadFromDisk( refFromFile ); aDataset->CloseOnDisk(); if ( strlen( refFromFile ) > 0 ) { - SALOMEDS::SObject_var shapeSO = myCurrentStudy->FindObjectID( refFromFile ); + SALOMEDS::SObject_wrap shapeSO = myCurrentStudy->FindObjectID( refFromFile ); // Make sure GEOM data are loaded first //loadGeomData( shapeSO->GetFatherComponent() ); @@ -3384,11 +4285,24 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, myNewMeshImpl->SetShape( aShapeObject ); } } + delete [] refFromFile; } + // issue 20918. Restore Persistent Id of SMESHDS_Mesh + if( aTopGroup->ExistInternalObject( "meshPersistentId" ) ) + { + aDataset = new HDFdataset( "meshPersistentId", aTopGroup ); + aDataset->OpenOnDisk(); + size = aDataset->GetSize(); + int* meshPersistentId = new int[ size ]; + aDataset->ReadFromDisk( meshPersistentId ); + aDataset->CloseOnDisk(); + myNewMeshImpl->GetImpl().GetMeshDS()->SetPersistentId( *meshPersistentId ); + delete [] meshPersistentId; + } } } - } + } // reading MESHes // As all object that can be referred by hypothesis are created, // we can restore hypothesis data @@ -3408,15 +4322,15 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, { aTopGroup = meshi_group->second; SMESH_Mesh_i* myNewMeshImpl = meshi_group->first; - ::SMESH_Mesh& myLocMesh = myNewMeshImpl->GetImpl(); - SMESHDS_Mesh* mySMESHDSMesh = myLocMesh.GetMeshDS(); + //::SMESH_Mesh& myLocMesh = myNewMeshImpl->GetImpl(); + //SMESHDS_Mesh* mySMESHDSMesh = myLocMesh.GetMeshDS(); GEOM::GEOM_Object_var aShapeObject = myNewMeshImpl->GetShapeToMesh(); bool hasData = false; // get mesh old id - string iorString = GetORB()->object_to_string( myNewMeshImpl->_this() ); - int newId = myStudyContext->findId( iorString ); + CORBA::String_var iorString = GetORB()->object_to_string( myNewMeshImpl->_this() ); + int newId = myStudyContext->findId( iorString.in() ); int id = myStudyContext->getOldId( newId ); // try to find mesh data dataset @@ -3430,19 +4344,21 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, aDataset->CloseOnDisk(); if ( strcmp( strHasData, "1") == 0 ) { // read mesh data from MED file - myReader.SetMesh( mySMESHDSMesh ); - myReader.SetMeshId( id ); - myReader.Perform(); + // myReader.SetMesh( mySMESHDSMesh ); + // myReader.SetMeshId( id ); + // myReader.Perform(); hasData = true; } + delete [] strHasData; } - // try to get applied algorithms + // Try to get applied ALGORITHMS (mesh is not cleared by algo addition because + // nodes and elements are not yet put into sub-meshes) if ( aTopGroup->ExistInternalObject( "Applied Algorithms" ) ) { aGroup = new HDFgroup( "Applied Algorithms", aTopGroup ); aGroup->OpenOnDisk(); // get number of applied algorithms - int aNbSubObjects = aGroup->nInternalObjects(); + int aNbSubObjects = aGroup->nInternalObjects(); if(MYDEBUG) MESSAGE( "VSR - number of applied algos " << aNbSubObjects ); for ( int j = 0; j < aNbSubObjects; j++ ) { char name_dataset[ HDF_NAME_MAX_LEN+1 ]; @@ -3455,12 +4371,11 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, char* refFromFile = new char[ size ]; aDataset->ReadFromDisk( refFromFile ); aDataset->CloseOnDisk(); - // san - it is impossible to recover applied algorithms using their entries within Load() method - - //SALOMEDS::SObject_var hypSO = myCurrentStudy->FindObjectID( refFromFile ); + //SALOMEDS::SObject_wrap hypSO = myCurrentStudy->FindObjectID( refFromFile ); //CORBA::Object_var hypObject = SObjectToObject( hypSO ); int id = atoi( refFromFile ); + delete [] refFromFile; string anIOR = myStudyContext->getIORbyOldId( id ); if ( !anIOR.empty() ) { CORBA::Object_var hypObject = GetORB()->string_to_object( anIOR.c_str() ); @@ -3481,7 +4396,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, aGroup = new HDFgroup( "Applied Hypotheses", aTopGroup ); aGroup->OpenOnDisk(); // get number of applied hypotheses - int aNbSubObjects = aGroup->nInternalObjects(); + int aNbSubObjects = aGroup->nInternalObjects(); for ( int j = 0; j < aNbSubObjects; j++ ) { char name_dataset[ HDF_NAME_MAX_LEN+1 ]; aGroup->InternalObjectIndentify( j, name_dataset ); @@ -3493,12 +4408,11 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, char* refFromFile = new char[ size ]; aDataset->ReadFromDisk( refFromFile ); aDataset->CloseOnDisk(); - // san - it is impossible to recover applied hypotheses using their entries within Load() method - - //SALOMEDS::SObject_var hypSO = myCurrentStudy->FindObjectID( refFromFile ); + //SALOMEDS::SObject_wrap hypSO = myCurrentStudy->FindObjectID( refFromFile ); //CORBA::Object_var hypObject = SObjectToObject( hypSO ); int id = atoi( refFromFile ); + delete [] refFromFile; string anIOR = myStudyContext->getIORbyOldId( id ); if ( !anIOR.empty() ) { CORBA::Object_var hypObject = GetORB()->string_to_object( anIOR.c_str() ); @@ -3514,7 +4428,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, aGroup->CloseOnDisk(); } - // --> try to find submeshes containers for each type of submesh + // --> try to find SUB-MESHES containers for each type of submesh for ( int j = GetSubMeshOnVertexTag(); j <= GetSubMeshOnCompoundTag(); j++ ) { char name_meshgroup[ 30 ]; if ( j == GetSubMeshOnVertexTag() ) @@ -3539,7 +4453,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, aGroup->OpenOnDisk(); // get number of submeshes - int aNbSubMeshes = aGroup->nInternalObjects(); + int aNbSubMeshes = aGroup->nInternalObjects(); for ( int k = 0; k < aNbSubMeshes; k++ ) { // identify submesh char name_submeshgroup[ HDF_NAME_MAX_LEN+1 ]; @@ -3566,7 +4480,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, aDataset->ReadFromDisk( refFromFile ); aDataset->CloseOnDisk(); if ( strlen( refFromFile ) > 0 ) { - SALOMEDS::SObject_var subShapeSO = myCurrentStudy->FindObjectID( refFromFile ); + SALOMEDS::SObject_wrap subShapeSO = myCurrentStudy->FindObjectID( refFromFile ); CORBA::Object_var subShapeObject = SObjectToObject( subShapeSO ); if ( !CORBA::is_nil( subShapeObject ) ) { aSubShapeObject = GEOM::GEOM_Object::_narrow( subShapeObject ); @@ -3585,28 +4499,13 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, if ( aSubMesh->_is_nil() ) continue; - // VSR: Get submesh data from MED convertor - // int anInternalSubmeshId = aSubMesh->GetId(); // this is not a persistent ID, it's an internal one computed from sub-shape - // if (myNewMeshImpl->_mapSubMesh.find(anInternalSubmeshId) != myNewMeshImpl->_mapSubMesh.end()) { - // if(MYDEBUG) MESSAGE("VSR - SMESH_Gen_i::Load(): loading from MED file submesh with ID = " << - // subid << " for subshape # " << anInternalSubmeshId); - // SMESHDS_SubMesh* aSubMeshDS = - // myNewMeshImpl->_mapSubMesh[anInternalSubmeshId]->CreateSubMeshDS(); - // if ( !aSubMeshDS ) { - // if(MYDEBUG) MESSAGE("VSR - SMESH_Gen_i::Load(): FAILED to create a submesh for subshape # " << - // anInternalSubmeshId << " in current mesh!"); - // } - // else - // myReader.GetSubMesh( aSubMeshDS, subid ); - // } - // try to get applied algorithms if ( aSubGroup->ExistInternalObject( "Applied Algorithms" ) ) { // open "applied algorithms" HDF group aSubSubGroup = new HDFgroup( "Applied Algorithms", aSubGroup ); aSubSubGroup->OpenOnDisk(); // get number of applied algorithms - int aNbSubObjects = aSubSubGroup->nInternalObjects(); + int aNbSubObjects = aSubSubGroup->nInternalObjects(); for ( int l = 0; l < aNbSubObjects; l++ ) { char name_dataset[ HDF_NAME_MAX_LEN+1 ]; aSubSubGroup->InternalObjectIndentify( l, name_dataset ); @@ -3619,8 +4518,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, aDataset->ReadFromDisk( refFromFile ); aDataset->CloseOnDisk(); - //SALOMEDS::SObject_var hypSO = myCurrentStudy->FindObjectID( refFromFile ); - //CORBA::Object_var hypObject = SObjectToObject( hypSO ); int id = atoi( refFromFile ); string anIOR = myStudyContext->getIORbyOldId( id ); if ( !anIOR.empty() ) { @@ -3643,7 +4540,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, aSubSubGroup = new HDFgroup( "Applied Hypotheses", aSubGroup ); aSubSubGroup->OpenOnDisk(); // get number of applied hypotheses - int aNbSubObjects = aSubSubGroup->nInternalObjects(); + int aNbSubObjects = aSubSubGroup->nInternalObjects(); for ( int l = 0; l < aNbSubObjects; l++ ) { char name_dataset[ HDF_NAME_MAX_LEN+1 ]; aSubSubGroup->InternalObjectIndentify( l, name_dataset ); @@ -3656,8 +4553,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, aDataset->ReadFromDisk( refFromFile ); aDataset->CloseOnDisk(); - //SALOMEDS::SObject_var hypSO = myCurrentStudy->FindObjectID( refFromFile ); - //CORBA::Object_var hypObject = SObjectToObject( hypSO ); int id = atoi( refFromFile ); string anIOR = myStudyContext->getIORbyOldId( id ); if ( !anIOR.empty() ) { @@ -3670,222 +4565,21 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, } } } - // close "applied hypotheses" HDF group + // close "APPLIED HYPOTHESES" hdf group aSubSubGroup->CloseOnDisk(); } - // close submesh HDF group + // close SUB-MESH hdf group aSubGroup->CloseOnDisk(); } } - // close submeshes containers HDF group + // close SUB-MESHES containers hdf group aGroup->CloseOnDisk(); } } - if(hasData) { - - // Read sub-meshes from MED - // ------------------------- - if(MYDEBUG) MESSAGE("Create all sub-meshes"); - bool submeshesInFamilies = ( ! aTopGroup->ExistInternalObject( "Submeshes" )); - if ( submeshesInFamilies ) - { - // old way working before fix of PAL 12992 - myReader.CreateAllSubMeshes(); - } - else - { - // open a group - aGroup = new HDFgroup( "Submeshes", aTopGroup ); - aGroup->OpenOnDisk(); - - int maxID = mySMESHDSMesh->MaxShapeIndex(); - vector< SMESHDS_SubMesh * > subMeshes( maxID + 1, (SMESHDS_SubMesh*) 0 ); - vector< TopAbs_ShapeEnum > smType ( maxID + 1, TopAbs_SHAPE ); - - PositionCreator aPositionCreator; - - SMDS_NodeIteratorPtr nIt = mySMESHDSMesh->nodesIterator(); - SMDS_ElemIteratorPtr eIt = mySMESHDSMesh->elementsIterator(); - for ( int isNode = 0; isNode < 2; ++isNode ) - { - string aDSName( isNode ? "Node Submeshes" : "Element Submeshes"); - if ( aGroup->ExistInternalObject( (char*) aDSName.c_str() )) - { - aDataset = new HDFdataset( (char*) aDSName.c_str(), aGroup ); - aDataset->OpenOnDisk(); - // read submesh IDs for all elements sorted by ID - int nbElems = aDataset->GetSize(); - int* smIDs = new int [ nbElems ]; - aDataset->ReadFromDisk( smIDs ); - aDataset->CloseOnDisk(); - - // get elements sorted by ID - TIDSortedElemSet elemSet; - if ( isNode ) - while ( nIt->more() ) elemSet.insert( nIt->next() ); - else - while ( eIt->more() ) elemSet.insert( eIt->next() ); - ASSERT( elemSet.size() == nbElems ); - - // add elements to submeshes - TIDSortedElemSet::iterator iE = elemSet.begin(); - for ( int i = 0; i < nbElems; ++i, ++iE ) - { - int smID = smIDs[ i ]; - if ( smID == 0 ) continue; - ASSERT( smID <= maxID ); - const SMDS_MeshElement* elem = *iE; - // get or create submesh - SMESHDS_SubMesh* & sm = subMeshes[ smID ]; - if ( ! sm ) { - sm = mySMESHDSMesh->NewSubMesh( smID ); - smType[ smID ] = mySMESHDSMesh->IndexToShape( smID ).ShapeType(); - } - // add - if ( isNode ) { - SMDS_PositionPtr pos = aPositionCreator.MakePosition( smType[ smID ]); - pos->SetShapeId( smID ); - SMDS_MeshNode* node = const_cast( static_cast( elem )); - node->SetPosition( pos ); - sm->AddNode( node ); - } else { - sm->AddElement( elem ); - } - } - delete [] smIDs; - } - } - } // end reading submeshes - - // Read node positions on sub-shapes (SMDS_Position) - - if ( aTopGroup->ExistInternalObject( "Node Positions" )) - { - // There are 5 datasets to read: - // "Nodes on Edges" - ID of node on edge - // "Edge positions" - U parameter on node on edge - // "Nodes on Faces" - ID of node on face - // "Face U positions" - U parameter of node on face - // "Face V positions" - V parameter of node on face - const char* aEid_DSName = "Nodes on Edges"; - const char* aEu_DSName = "Edge positions"; - const char* aFu_DSName = "Face U positions"; - //char* aFid_DSName = "Nodes on Faces"; - //char* aFv_DSName = "Face V positions"; - - // data to retrieve - int nbEids = 0, nbFids = 0; - int *aEids = 0, *aFids = 0; - double *aEpos = 0, *aFupos = 0, *aFvpos = 0; - - // open a group - aGroup = new HDFgroup( "Node Positions", aTopGroup ); - aGroup->OpenOnDisk(); - - // loop on 5 data sets - int aNbObjects = aGroup->nInternalObjects(); - for ( int i = 0; i < aNbObjects; i++ ) - { - // identify dataset - char aDSName[ HDF_NAME_MAX_LEN+1 ]; - aGroup->InternalObjectIndentify( i, aDSName ); - // read data - aDataset = new HDFdataset( aDSName, aGroup ); - aDataset->OpenOnDisk(); - if ( aDataset->GetType() == HDF_FLOAT64 ) // Positions - { - double* pos = new double [ aDataset->GetSize() ]; - aDataset->ReadFromDisk( pos ); - // which one? - if ( strncmp( aDSName, aEu_DSName, strlen( aEu_DSName )) == 0 ) - aEpos = pos; - else if ( strncmp( aDSName, aFu_DSName, strlen( aFu_DSName )) == 0 ) - aFupos = pos; - else - aFvpos = pos; - } - else // NODE IDS - { - int aSize = aDataset->GetSize(); - - // for reading files, created from 18.07.2005 till 10.10.2005 - if (aDataset->GetType() == HDF_STRING) - aSize /= sizeof(int); - - int* ids = new int [aSize]; - aDataset->ReadFromDisk( ids ); - // on face or nodes? - if ( strncmp( aDSName, aEid_DSName, strlen( aEid_DSName )) == 0 ) { - aEids = ids; - nbEids = aSize; - } - else { - aFids = ids; - nbFids = aSize; - } - } - aDataset->CloseOnDisk(); - } // loop on 5 datasets - - // Set node positions on edges or faces - for ( int onFace = 0; onFace < 2; onFace++ ) - { - int nbNodes = ( onFace ? nbFids : nbEids ); - if ( nbNodes == 0 ) continue; - int* aNodeIDs = ( onFace ? aFids : aEids ); - double* aUPos = ( onFace ? aFupos : aEpos ); - double* aVPos = ( onFace ? aFvpos : 0 ); - // loop on node IDs - for ( int iNode = 0; iNode < nbNodes; iNode++ ) - { - const SMDS_MeshNode* node = mySMESHDSMesh->FindNode( aNodeIDs[ iNode ]); - ASSERT( node ); - SMDS_PositionPtr aPos = node->GetPosition(); - ASSERT( aPos ) - if ( onFace ) { - ASSERT( aPos->GetTypeOfPosition() == SMDS_TOP_FACE ); - SMDS_FacePosition* fPos = const_cast - ( static_cast( aPos.get() )); - fPos->SetUParameter( aUPos[ iNode ]); - fPos->SetVParameter( aVPos[ iNode ]); - } - else { - ASSERT( aPos->GetTypeOfPosition() == SMDS_TOP_EDGE ); - SMDS_EdgePosition* fPos = const_cast - ( static_cast( aPos.get() )); - fPos->SetUParameter( aUPos[ iNode ]); - } - } - } - if ( aEids ) delete [] aEids; - if ( aFids ) delete [] aFids; - if ( aEpos ) delete [] aEpos; - if ( aFupos ) delete [] aFupos; - if ( aFvpos ) delete [] aFvpos; - - aGroup->CloseOnDisk(); - - } // if ( aTopGroup->ExistInternalObject( "Node Positions" ) ) - } // if ( hasData ) - - // Recompute State (as computed sub-meshes are restored from MED) - if ( !aShapeObject->_is_nil() || !myNewMeshImpl->HasShapeToMesh()) { - MESSAGE("Compute State Engine ..."); - TopoDS_Shape myLocShape; - if(myNewMeshImpl->HasShapeToMesh()) - myLocShape = GeomObjectToShape( aShapeObject ); - else - myLocShape = SMESH_Mesh::PseudoShape(); - - myNewMeshImpl->GetImpl().GetSubMesh(myLocShape)->ComputeStateEngine - (SMESH_subMesh::SUBMESH_RESTORED); - MESSAGE("Compute State Engine finished"); - } - - // try to get groups - for ( int ii = GetNodeGroupsTag(); ii <= GetVolumeGroupsTag(); ii++ ) { + // try to get GROUPS + for ( int ii = GetNodeGroupsTag(); ii <= GetBallElementsGroupsTag(); ii++ ) { char name_group[ 30 ]; if ( ii == GetNodeGroupsTag() ) strcpy( name_group, "Groups of Nodes" ); @@ -3895,12 +4589,16 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, strcpy( name_group, "Groups of Faces" ); else if ( ii == GetVolumeGroupsTag() ) strcpy( name_group, "Groups of Volumes" ); + else if ( ii == Get0DElementsGroupsTag() ) + strcpy( name_group, "Groups of 0D Elements" ); + else if ( ii == GetBallElementsGroupsTag() ) + strcpy( name_group, "Groups of Balls" ); if ( aTopGroup->ExistInternalObject( name_group ) ) { aGroup = new HDFgroup( name_group, aTopGroup ); aGroup->OpenOnDisk(); // get number of groups - int aNbSubObjects = aGroup->nInternalObjects(); + int aNbSubObjects = aGroup->nInternalObjects(); for ( int j = 0; j < aNbSubObjects; j++ ) { char name_dataset[ HDF_NAME_MAX_LEN+1 ]; aGroup->InternalObjectIndentify( j, name_dataset ); @@ -3932,7 +4630,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, aDataset->ReadFromDisk( refFromFile ); aDataset->CloseOnDisk(); if ( strlen( refFromFile ) > 0 ) { - SALOMEDS::SObject_var shapeSO = myCurrentStudy->FindObjectID( refFromFile ); + SALOMEDS::SObject_wrap shapeSO = myCurrentStudy->FindObjectID( refFromFile ); CORBA::Object_var shapeObject = SObjectToObject( shapeSO ); if ( !CORBA::is_nil( shapeObject ) ) { aShapeObject = GEOM::GEOM_Object::_narrow( shapeObject ); @@ -3941,67 +4639,170 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, } } } + // Try to read a filter of SMESH_GroupOnFilter + SMESH::Filter_var filter; + SMESH_PredicatePtr predicate; + std::string hdfGrpName = "Filter " + SMESH_Comment(subid); + if ( aGroup->ExistInternalObject( hdfGrpName.c_str() )) + { + aDataset = new HDFdataset( hdfGrpName.c_str(), aGroup ); + aDataset->OpenOnDisk(); + size = aDataset->GetSize(); + char* persistStr = new char[ size ]; + aDataset->ReadFromDisk( persistStr ); + aDataset->CloseOnDisk(); + if ( strlen( persistStr ) > 0 ) { + filter = SMESH_GroupOnFilter_i::StringToFilter( persistStr ); + predicate = SMESH_GroupOnFilter_i::GetPredicate( filter ); + } + } + // Create group servant SMESH::ElementType type = (SMESH::ElementType)(ii - GetNodeGroupsTag() + 1); SMESH::SMESH_GroupBase_var aNewGroup = SMESH::SMESH_GroupBase::_duplicate - ( myNewMeshImpl->createGroup( type, nameFromFile, aShape ) ); - // Obtain a SMESHDS_Group object + ( myNewMeshImpl->createGroup( type, nameFromFile, aShape, predicate ) ); + // Obtain a SMESHDS_Group object if ( aNewGroup->_is_nil() ) continue; string iorSubString = GetORB()->object_to_string( aNewGroup ); - int newSubId = myStudyContext->findId( iorSubString ); + int newSubId = myStudyContext->findId( iorSubString ); myStudyContext->mapOldToNew( subid, newSubId ); - SMESH_GroupBase_i* aGroupImpl = - dynamic_cast( GetServant( aNewGroup ).in() ); + SMESH_GroupBase_i* aGroupImpl = SMESH::DownCast< SMESH_GroupBase_i*>( aNewGroup ); if ( !aGroupImpl ) continue; - SMESH_Group* aLocalGroup = myLocMesh.GetGroup( aGroupImpl->GetLocalID() ); - if ( !aLocalGroup ) + if ( SMESH_GroupOnFilter_i* aFilterGroup = + dynamic_cast< SMESH_GroupOnFilter_i*>( aGroupImpl )) + { + aFilterGroup->SetFilter( filter ); + filter->UnRegister(); + } + SMESHDS_GroupBase* aGroupBaseDS = aGroupImpl->GetGroupDS(); + if ( !aGroupBaseDS ) continue; - SMESHDS_GroupBase* aGroupBaseDS = aLocalGroup->GetGroupDS(); aGroupBaseDS->SetStoreName( name_dataset ); - // ouv : NPAL12872 - // Read color of the group + // ouv : NPAL12872 + // Read color of the group char aGroupColorName[ 30 ]; sprintf( aGroupColorName, "ColorGroup %d", subid); if ( aGroup->ExistInternalObject( aGroupColorName ) ) - { - aDataset = new HDFdataset( aGroupColorName, aGroup ); - aDataset->OpenOnDisk(); - size = aDataset->GetSize(); - double* anRGB = new double[ size ]; - aDataset->ReadFromDisk( anRGB ); - aDataset->CloseOnDisk(); - Quantity_Color aColor( anRGB[0], anRGB[1], anRGB[2], Quantity_TOC_RGB ); - aGroupBaseDS->SetColor( aColor ); - } + { + aDataset = new HDFdataset( aGroupColorName, aGroup ); + aDataset->OpenOnDisk(); + size = aDataset->GetSize(); + double* anRGB = new double[ size ]; + aDataset->ReadFromDisk( anRGB ); + aDataset->CloseOnDisk(); + Quantity_Color aColor( anRGB[0], anRGB[1], anRGB[2], Quantity_TOC_RGB ); + aGroupBaseDS->SetColor( aColor ); + } // Fill group with contents from MED file - SMESHDS_Group* aGrp = dynamic_cast( aGroupBaseDS ); - if ( aGrp ) - myReader.GetGroup( aGrp ); + // SMESHDS_Group* aGrp = dynamic_cast( aGroupBaseDS ); + // if ( aGrp ) + // myReader.GetGroup( aGrp ); } } aGroup->CloseOnDisk(); } + } // reading GROUPs + + // instead of reading mesh data, we read only brief information of all + // objects: mesh, groups, sub-meshes (issue 0021208 ) + if ( hasData ) + { + SMESH_PreMeshInfo::LoadFromFile( myNewMeshImpl, id, + meshfile.ToCString(), filename.ToCString(), + !isMultiFile ); } + + // read Sub-Mesh ORDER if any + if( aTopGroup->ExistInternalObject( "Mesh Order" ) ) { + aDataset = new HDFdataset( "Mesh Order", aTopGroup ); + aDataset->OpenOnDisk(); + size = aDataset->GetSize(); + int* smIDs = new int[ size ]; + aDataset->ReadFromDisk( smIDs ); + aDataset->CloseOnDisk(); + TListOfListOfInt anOrderIds; + anOrderIds.push_back( TListOfInt() ); + for ( int i = 0; i < size; i++ ) + if ( smIDs[ i ] < 0 ) // is separator + anOrderIds.push_back( TListOfInt() ); + else + anOrderIds.back().push_back(smIDs[ i ]); + + myNewMeshImpl->GetImpl().SetMeshOrder( anOrderIds ); + } + } // loop on meshes + + // update hyps needing full mesh data restored (issue 20918) + for ( hyp_data = hypDataList.begin(); hyp_data != hypDataList.end(); ++hyp_data ) + { + SMESH_Hypothesis_i* hyp = hyp_data->first; + hyp->UpdateAsMeshesRestored(); + } + + // notify algos on completed restoration to set sub-mesh event listeners + for ( meshi_group = meshGroupList.begin(); meshi_group != meshGroupList.end(); ++meshi_group ) + { + SMESH_Mesh_i* myNewMeshImpl = meshi_group->first; + ::SMESH_Mesh& myLocMesh = myNewMeshImpl->GetImpl(); + + TopoDS_Shape myLocShape; + if(myLocMesh.HasShapeToMesh()) + myLocShape = myLocMesh.GetShapeToMesh(); + else + myLocShape = SMESH_Mesh::PseudoShape(); + + myLocMesh.GetSubMesh(myLocShape)-> + ComputeStateEngine (SMESH_subMesh::SUBMESH_RESTORED); } + // close mesh group if(aTopGroup) - aTopGroup->CloseOnDisk(); + aTopGroup->CloseOnDisk(); } // close HDF file aFile->CloseOnDisk(); delete aFile; // Remove temporary files created from the stream - if ( !isMultiFile ) - SALOMEDS_Tool::RemoveTemporaryFiles( tmpDir.ToCString(), aFileSeq.in(), true ); + if ( !isMultiFile ) + { + SMESH_File meshFile( meshfile.ToCString() ); + if ( !meshFile ) // no meshfile exists + { + SALOMEDS_Tool::RemoveTemporaryFiles( tmpDir.ToCString(), aFileSeq.in(), true ); + } + else + { + Engines::Container_var container = GetContainerRef(); + if ( Engines_Container_i* container_i = SMESH::DownCast( container )) + { + container_i->registerTemporaryFile( filename.ToCString() ); + container_i->registerTemporaryFile( meshfile.ToCString() ); + container_i->registerTemporaryFile( tmpDir.ToCString() ); + } + } + } + pd << ""; // prevent optimizing pd out + + // creation of tree nodes for all data objects in the study + // to support tree representation customization and drag-n-drop: + SALOMEDS::UseCaseBuilder_wrap useCaseBuilder = theComponent->GetStudy()->GetUseCaseBuilder(); + if ( !useCaseBuilder->IsUseCaseNode( theComponent ) ) { + useCaseBuilder->SetRootCurrent(); + useCaseBuilder->Append( theComponent ); // component object is added as the top level item + SALOMEDS::ChildIterator_wrap it = theComponent->GetStudy()->NewChildIterator( theComponent ); + for (it->InitEx(true); it->More(); it->Next()) { + useCaseBuilder->AppendTo( it->Value()->GetFather(), it->Value() ); + } + } INFOS( "SMESH_Gen_i::Load completed" ); return true; @@ -4016,9 +4817,9 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, //============================================================================= bool SMESH_Gen_i::LoadASCII( SALOMEDS::SComponent_ptr theComponent, - const SALOMEDS::TMPFile& theStream, - const char* theURL, - bool isMultiFile ) { + const SALOMEDS::TMPFile& theStream, + const char* theURL, + bool isMultiFile ) { if(MYDEBUG) MESSAGE( "SMESH_Gen_i::LoadASCII" ); return Load( theComponent, theStream, theURL, isMultiFile ); @@ -4042,7 +4843,7 @@ bool SMESH_Gen_i::LoadASCII( SALOMEDS::SComponent_ptr theComponent, } SALOMEDS::TMPFile_var aRealStreamFile = new SALOMEDS::TMPFile(real_size, real_size, buffer, 1); - + return Load( theComponent, *(aRealStreamFile._retn()), theURL, isMultiFile ); } @@ -4059,8 +4860,9 @@ void SMESH_Gen_i::Close( SALOMEDS::SComponent_ptr theComponent ) if(MYDEBUG) MESSAGE( "SMESH_Gen_i::Close" ); // set correct current study - if (theComponent->GetStudy()->StudyId() != GetCurrentStudyID()) - SetCurrentStudy(theComponent->GetStudy()); + SALOMEDS::Study_var study = theComponent->GetStudy(); + if ( study->StudyId() != GetCurrentStudyID()) + setCurrentStudy( study, /*IsBeingClosed=*/true ); // Clear study contexts data int studyId = GetCurrentStudyID(); @@ -4069,31 +4871,17 @@ void SMESH_Gen_i::Close( SALOMEDS::SComponent_ptr theComponent ) myStudyContextMap.erase( studyId ); } - // delete SMESH_Mesh's -// See bug IPAL19437. -// -// StudyContextStruct* context = myGen.GetStudyContext( studyId ); -// map< int, SMESH_Mesh* >::iterator i_mesh = context->mapMesh.begin(); -// for ( ; i_mesh != context->mapMesh.end(); ++i_mesh ) { -// printf( "--------------------------- SMESH_Gen_i::Close, delete aGroup = %p \n", i_mesh->second ); -// delete i_mesh->second; -// } - + // remove the tmp files meshes are loaded from + SMESH_PreMeshInfo::RemoveStudyFiles_TMP_METHOD( theComponent ); - // delete SMESHDS_Mesh's - // it's too long on big meshes -// if ( context->myDocument ) { -// delete context->myDocument; -// context->myDocument = 0; -// } - + myCurrentStudy = SALOMEDS::Study::_nil(); return; } //============================================================================= /*! * SMESH_Gen_i::ComponentDataType - * + * * Get component data type */ //============================================================================= @@ -4104,23 +4892,23 @@ char* SMESH_Gen_i::ComponentDataType() return CORBA::string_dup( "SMESH" ); } - + //============================================================================= /*! * SMESH_Gen_i::IORToLocalPersistentID - * + * * Transform data from transient form to persistent */ //============================================================================= char* SMESH_Gen_i::IORToLocalPersistentID( SALOMEDS::SObject_ptr /*theSObject*/, - const char* IORString, - CORBA::Boolean /*isMultiFile*/, - CORBA::Boolean /*isASCII*/ ) + const char* IORString, + CORBA::Boolean /*isMultiFile*/, + CORBA::Boolean /*isASCII*/ ) { if(MYDEBUG) MESSAGE( "SMESH_Gen_i::IORToLocalPersistentID" ); StudyContext* myStudyContext = GetCurrentStudyContext(); - + if ( myStudyContext && strcmp( IORString, "" ) != 0 ) { int anId = myStudyContext->findId( IORString ); if ( anId ) { @@ -4142,9 +4930,9 @@ char* SMESH_Gen_i::IORToLocalPersistentID( SALOMEDS::SObject_ptr /*theSObject*/, //============================================================================= char* SMESH_Gen_i::LocalPersistentIDToIOR( SALOMEDS::SObject_ptr /*theSObject*/, - const char* aLocalPersistentID, - CORBA::Boolean /*isMultiFile*/, - CORBA::Boolean /*isASCII*/ ) + const char* aLocalPersistentID, + CORBA::Boolean /*isMultiFile*/, + CORBA::Boolean /*isASCII*/ ) { if(MYDEBUG) MESSAGE( "SMESH_Gen_i::LocalPersistentIDToIOR(): id = " << aLocalPersistentID ); StudyContext* myStudyContext = GetCurrentStudyContext(); @@ -4158,7 +4946,7 @@ char* SMESH_Gen_i::LocalPersistentIDToIOR( SALOMEDS::SObject_ptr /*theSObject*/, //======================================================================= //function : RegisterObject -//purpose : +//purpose : //======================================================================= int SMESH_Gen_i::RegisterObject(CORBA::Object_ptr theObject) @@ -4201,28 +4989,83 @@ void SMESH_Gen_i::SetName(const char* theIOR, { if ( theIOR && strcmp( theIOR, "" ) ) { CORBA::Object_var anObject = GetORB()->string_to_object( theIOR ); - SALOMEDS::SObject_var aSO = ObjectToSObject( myCurrentStudy, anObject ); + SALOMEDS::SObject_wrap aSO = ObjectToSObject( myCurrentStudy, anObject ); if ( !aSO->_is_nil() ) { SetName( aSO, theName ); } } } +int SMESH_Gen_i::GetCurrentStudyID() +{ + return myCurrentStudy->_is_nil() || myCurrentStudy->_non_existent() ? -1 : myCurrentStudy->StudyId(); +} + +// Version information +char* SMESH_Gen_i::getVersion() +{ +#if SMESH_DEVELOPMENT + return CORBA::string_dup(SMESH_VERSION_STR"dev"); +#else + return CORBA::string_dup(SMESH_VERSION_STR); +#endif +} + +//================================================================================= +// function : Move() +// purpose : Moves objects to the specified position. +// Is used in the drag-n-drop functionality. +//================================================================================= +void SMESH_Gen_i::Move( const SMESH::sobject_list& what, + SALOMEDS::SObject_ptr where, + CORBA::Long row ) +{ + if ( CORBA::is_nil( where ) ) return; + + SALOMEDS::Study_var study = where->GetStudy(); + SALOMEDS::StudyBuilder_var studyBuilder = study->NewBuilder(); + SALOMEDS::UseCaseBuilder_var useCaseBuilder = study->GetUseCaseBuilder(); + SALOMEDS::SComponent_var father = where->GetFatherComponent(); + std::string dataType = father->ComponentDataType(); + if ( dataType != "SMESH" ) return; // not a SMESH component + + SALOMEDS::SObject_var objAfter; + if ( row >= 0 && useCaseBuilder->HasChildren( where ) ) { + // insert at given row -> find insertion position + SALOMEDS::UseCaseIterator_var useCaseIt = useCaseBuilder->GetUseCaseIterator( where ); + int i; + for ( i = 0; i < row && useCaseIt->More(); i++, useCaseIt->Next() ); + if ( i == row && useCaseIt->More() ) { + objAfter = useCaseIt->Value(); + } + } + + for ( int i = 0; i < what.length(); i++ ) { + SALOMEDS::SObject_var sobj = what[i]; + if ( CORBA::is_nil( sobj ) ) continue; // skip bad object + // insert the object to the use case tree + if ( !CORBA::is_nil( objAfter ) ) + useCaseBuilder->InsertBefore( sobj, objAfter ); // insert at given row + else + useCaseBuilder->AppendTo( where, sobj ); // append to the end of list + } +} + //============================================================================= -/*! +/*! * SMESHEngine_factory * - * C factory, accessible with dlsym, after dlopen + * C factory, accessible with dlsym, after dlopen */ //============================================================================= extern "C" { SMESH_I_EXPORT PortableServer::ObjectId* SMESHEngine_factory( CORBA::ORB_ptr orb, - PortableServer::POA_ptr poa, - PortableServer::ObjectId* contId, - const char* instanceName, - const char* interfaceName ) + PortableServer::POA_ptr poa, + PortableServer::ObjectId* contId, + const char* instanceName, + const char* interfaceName ) { if(MYDEBUG) MESSAGE( "PortableServer::ObjectId* SMESHEngine_factory()" ); if(MYDEBUG) SCRUTE(interfaceName);