From: cs Date: Fri, 7 Sep 2007 12:28:27 +0000 (+0000) Subject: *** empty log message *** X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=refs%2Fheads%2FBR_MULTIPR_EVOLUTION;p=modules%2Fmultipr.git *** empty log message *** --- diff --git a/idl/MULTIPR.idl b/idl/MULTIPR.idl index 6c54f48..8a2a2eb 100644 --- a/idl/MULTIPR.idl +++ b/idl/MULTIPR.idl @@ -35,13 +35,18 @@ typedef sequence string_array; // Interface of the %MULTIPR component used to manage partition/decimation //************************************************************************* -interface MULTIPR_Obj +interface MULTIPR_Obj : SALOME::GenericObj { //--------------------------------------------------------------------- // Basic accessors/mutators //-------------------------------------------------------------------- + /*! + * Reset the object. + */ + void reset(); + /*! * Return true iff this obj represents a valid sequential MED file. */ @@ -86,15 +91,21 @@ interface MULTIPR_Obj /*! * Return the list of fields contained in the current mesh of the associated MED file. */ - string_array getFields() + string_array getFields(in string pPartList) raises (SALOME::SALOME_Exception); /*! * Return the number of iterations for a given field. */ - long getTimeStamps(in string fieldName) + long getTimeStamps(in string pPartList, in string fieldName) raises (SALOME::SALOME_Exception); + /*! + * Get the minimum and maximum value of a part's field. + */ + void getFieldMinMax(in string pPartName, in string pFieldName, inout float pMin, inout float pMax) + raises (SALOME::SALOME_Exception); + /*! * Return the name of all partitions. * Assume this object encapsulates a distributed MED file. @@ -114,7 +125,8 @@ interface MULTIPR_Obj //-------------------------------------------------------------------- /*! - * Create a distributed MED file (v2.3) by extracting all the groups from the current mesh of the current MED sequential MED file. + * Create a distributed MED file (v2.3) by extracting all the groups from the + * current mesh of the current MED sequential MED file. * Assume: * - the file is in MED format and can be read using MED file v2.3. * - the file is sequential (not a distributed MED). @@ -126,7 +138,8 @@ interface MULTIPR_Obj raises (SALOME::SALOME_Exception); /*! - * Create a distributed MED file (V2.3) by splitting a group of a MED file previously created by partitionneDomaine. + * Create a distributed MED file (V2.3) by splitting a group of a MED file + * previously created by partitionneDomaine. * Assume: * - the file is a distributed MED file, previously created by partitionneDomaine() * (=> each part only contain 1 mesh, TETRA10 elements only) @@ -134,7 +147,7 @@ interface MULTIPR_Obj * - partitionner METIS=0 or SCOTCH=1 * \return the name of each part. */ - string_array partitionneGrain( + string_array partitionneGroupe( in string partName, in long nbParts, in long partitionner) @@ -143,7 +156,8 @@ interface MULTIPR_Obj /*! * Create 3 resolutions of the given part of a distributed MED file (V2.3). * Assume: - * - the file is a distributed MED file, previously created by partitionneDomaine() or partitionneGrain() + * - the file is a distributed MED file, previously created by + * partitionneDomaine() or partitionneGrain() * (=> each part only contain 1 mesh, TETRA10 elements only) */ string_array decimePartition( @@ -151,9 +165,7 @@ interface MULTIPR_Obj in string fieldName, in long fieldIt, in string filterName, - in double tmed, - in double tlow, - in double radius) + in string filterParams) raises (SALOME::SALOME_Exception); /*! @@ -170,12 +182,20 @@ interface MULTIPR_Obj /*! * Remove all the parts starting with the given prefix from the distributed MED file. - * Example: if prefixPartName="PART_4" => remove "PART_4" and all sub-parts "PART_4_*", but not "PART41". + * Example: if prefixPartName="PART_4" => remove "PART_4" and all sub-parts "PART_4_*", + * but not "PART41". * Assume this object encapsulates a distributed MED file. */ void removeParts(in string prefixPartName) raises (SALOME::SALOME_Exception); + /*! + * Get mesh statistics. + */ + string getMEDInfo( + in string partName) + raises (SALOME::SALOME_Exception); + //--------------------------------------------------------------------- // i/o //-------------------------------------------------------------------- @@ -186,6 +206,17 @@ interface MULTIPR_Obj void save(in string path) raises (SALOME::SALOME_Exception); + /*! + * Check save progress. + * \return current save progress in percents. + */ + long getSaveProgress(); + + /*! + * Reset save progress to zero. + */ + void resetSaveProgress(); + }; // interface MULTIPR_Obj @@ -193,7 +224,7 @@ interface MULTIPR_Obj // Interface of the %MULTIPR component; used to create MULTIPR_Obj object // and to define high level API. //************************************************************************* -interface MULTIPR_Gen : Engines::Component +interface MULTIPR_Gen : Engines::Component, SALOMEDS::Driver { /*! * Return the version of the MULTIPR library. @@ -207,7 +238,8 @@ interface MULTIPR_Gen : Engines::Component //------------------------------------------------------------------------ /*! - * Create a distributed MED file (v2.3) by extracting all the groups from the mesh of a sequential MED file. + * Create a distributed MED file (v2.3) by extracting all the groups from the + * mesh of a sequential MED file. * High level function. */ void partitionneDomaine( @@ -216,10 +248,11 @@ interface MULTIPR_Gen : Engines::Component raises (SALOME::SALOME_Exception); /*! - * Create a distributed MED file (V2.3) by splitting a group of a MED file previously created by partitionneDomaine(). + * Create a distributed MED file (V2.3) by splitting a group of a MED file + * previously created by partitionneDomaine(). * High level function. */ - void partitionneGrain( + void partitionneGroupe( in string medFilename, in string partName, in long nbParts, @@ -236,10 +269,7 @@ interface MULTIPR_Gen : Engines::Component in string fieldName, in long fieldIt, in string filterName, - in double tmed, - in double tlow, - in double radius, - in long boxing) + in string filterParams) raises (SALOME::SALOME_Exception); //------------------------------------------------------------------------ @@ -253,6 +283,22 @@ interface MULTIPR_Gen : Engines::Component MULTIPR_Obj getObject(in string medFilename) raises (SALOME::SALOME_Exception); + //------------------------------------------------------------------------ + // Engine API + // Methods to correctly serve Persistence and Dump Python. + //------------------------------------------------------------------------ + + /*! + * Set the current study + */ + void SetCurrentStudy (in SALOMEDS::Study theStudy); + + /*! + * Get the current study + */ + SALOMEDS::Study GetCurrentStudy(); + + }; // interface MULTIPR_Gen diff --git a/src/MULTIPR/MULTIPR_i.cxx b/src/MULTIPR/MULTIPR_i.cxx index 126f14a..b31adb0 100644 --- a/src/MULTIPR/MULTIPR_i.cxx +++ b/src/MULTIPR/MULTIPR_i.cxx @@ -22,10 +22,161 @@ using namespace std; #include "utilities.h" #include +#include #include "MULTIPR_API.hxx" #include "MULTIPR_Exceptions.hxx" +#include "MULTIPR_Utils.hxx" +#include + +#include CORBA_CLIENT_HEADER(SALOMEDS) +#include CORBA_CLIENT_HEADER(SALOMEDS_Attributes) + +#ifdef _DEBUG_ +static int MYDEBUG = 1; +#else +static int MYDEBUG = 0; +#endif + +// Dump Python utilities +namespace MULTIPR +{ + class TPythonDump + { + std::ostringstream myStream; + static size_t myCounter; + //MULTIPR_ORB::MULTIPR_Gen_ptr myEngine; + MULTIPR_Gen_i* myEngine; + + public: + //TPythonDump (MULTIPR_ORB::MULTIPR_Gen_ptr theEngine); + TPythonDump (MULTIPR_Gen_i* theEngine); + virtual ~TPythonDump(); + + TPythonDump& operator<< (long int theArg); + TPythonDump& operator<< (int theArg); + TPythonDump& operator<< (double theArg); + TPythonDump& operator<< (float theArg); + TPythonDump& operator<< (const void* theArg); + TPythonDump& operator<< (const char* theArg); + + TPythonDump& operator<< (SALOMEDS::SObject_ptr theArg); + TPythonDump& operator<< (CORBA::Object_ptr theArg); + + TPythonDump& operator<< (MULTIPR_ORB::MULTIPR_Gen_ptr theArg); + TPythonDump& operator<< (MULTIPR_ORB::MULTIPR_Obj_ptr theArg); + + TPythonDump& operator<< (MULTIPR_Gen_i* theArg); + TPythonDump& operator<< (MULTIPR_Obj_i* theArg); + + static char* MULTIPRGenName() { return "mpr_gen"; } + static char* MULTIPRObjName() { return "mpr_obj"; } + }; + + size_t TPythonDump::myCounter = 0; + + //TPythonDump::TPythonDump (MULTIPR_ORB::MULTIPR_Gen_ptr theEngine) + TPythonDump::TPythonDump (MULTIPR_Gen_i* theEngine) + { + ++myCounter; + //myEngine = MULTIPR_ORB::MULTIPR_Gen::_duplicate(theEngine); + myEngine = theEngine; + } + + TPythonDump::~TPythonDump() + { + if (--myCounter == 0) + { + SALOMEDS::Study_ptr aStudy = myEngine->GetCurrentStudy(); + int aStudyID = -1; + if (!aStudy->_is_nil()) aStudyID = aStudy->StudyId(); + + std::string aString = myStream.str(); + myEngine->AddToPythonScript(aStudyID, aString); + //if(MYDEBUG) MESSAGE(" *DP* " << aString.c_str()); + } + } + + TPythonDump& TPythonDump::operator<< (long int theArg) + { + myStream << theArg; + return *this; + } + + TPythonDump& TPythonDump::operator<< (int theArg) + { + myStream << theArg; + return *this; + } + + TPythonDump& TPythonDump::operator<< (double theArg) + { + myStream << theArg; + return *this; + } + + TPythonDump& TPythonDump::operator<< (float theArg) + { + myStream << theArg; + return *this; + } + + TPythonDump& TPythonDump::operator<< (const void* theArg) + { + myStream << theArg; + return *this; + } + + TPythonDump& TPythonDump::operator<< (const char* theArg) + { + if (theArg) + myStream << theArg; + return *this; + } + + TPythonDump& TPythonDump::operator<< (SALOMEDS::SObject_ptr aSObject) + { + if (aSObject->_is_nil()) + myStream << "None"; + else + myStream << "theStudy.FindObjectID(\"" << aSObject->GetID() << "\")"; + return *this; + } + + TPythonDump& TPythonDump::operator<< (CORBA::Object_ptr theArg) + { + if (CORBA::is_nil(theArg)) + myStream << "None"; + else + myStream << theArg; + return *this; + } + + TPythonDump& TPythonDump::operator<< (MULTIPR_ORB::MULTIPR_Gen_ptr theArg) + { + myStream << MULTIPRGenName(); + return *this; + } + + TPythonDump& TPythonDump::operator<< (MULTIPR_ORB::MULTIPR_Obj_ptr theArg) + { + myStream << MULTIPRObjName(); + return *this; + } + + TPythonDump& TPythonDump::operator<< (MULTIPR_Gen_i* theArg) + { + myStream << MULTIPRGenName(); + return *this; + } + + TPythonDump& TPythonDump::operator<< (MULTIPR_Obj_i* theArg) + { + myStream << MULTIPRObjName(); + return *this; + } +} //***************************************************************************** // Class MULTIPR_Gen_i implementation @@ -78,7 +229,7 @@ void MULTIPR_Gen_i::partitionneDomaine( } -void MULTIPR_Gen_i::partitionneGrain( +void MULTIPR_Gen_i::partitionneGroupe( const char* medFilename, const char* partName, CORBA::Long nbParts, @@ -87,7 +238,7 @@ void MULTIPR_Gen_i::partitionneGrain( { try { - multipr::partitionneGrain( + multipr::partitionneGroupe( medFilename, partName, nbParts, @@ -96,7 +247,7 @@ void MULTIPR_Gen_i::partitionneGrain( catch (multipr::RuntimeException& e) { e.dump(cout); - THROW_SALOME_CORBA_EXCEPTION("partitionneGrain() failed", SALOME::INTERNAL_ERROR); + THROW_SALOME_CORBA_EXCEPTION("partitionneGroupe() failed", SALOME::INTERNAL_ERROR); } } @@ -107,12 +258,10 @@ void MULTIPR_Gen_i::decimePartition( const char* fieldName, CORBA::Long fieldIt, const char* filterName, - CORBA::Double tmed, - CORBA::Double tlow, - CORBA::Double radius, - CORBA::Long boxing) + const char* filterParams) throw (SALOME::SALOME_Exception) { + /* // debug cout << "File : " << medFilename << endl; @@ -135,10 +284,7 @@ void MULTIPR_Gen_i::decimePartition( fieldName, fieldIt, filterName, - tmed, - tlow, - radius, - boxing); + filterParams); } catch (multipr::RuntimeException& e) { @@ -154,22 +300,36 @@ void MULTIPR_Gen_i::decimePartition( MULTIPR_ORB::MULTIPR_Obj_ptr MULTIPR_Gen_i::getObject(const char* medFilename) throw (SALOME::SALOME_Exception) -{ - MULTIPR_Obj_i* obj = new MULTIPR_Obj_i(medFilename); +{ + MULTIPR_Obj_i* obj = new MULTIPR_Obj_i(_poa, medFilename); + obj->setEngine(this); + + // Dump Python + MULTIPR::TPythonDump(this) << obj << " = " << this << ".getObject(\"" << medFilename << "\")"; + return obj->POA_MULTIPR_ORB::MULTIPR_Obj::_this(); } -MULTIPR_Obj_i::MULTIPR_Obj_i(const char* medFilename) +MULTIPR_Obj_i::MULTIPR_Obj_i(PortableServer::POA_ptr thePOA, + const char* medFilename, + bool isPersistence, + bool isMultifile) throw (SALOME::SALOME_Exception) + : SALOME::GenericObj_i(thePOA), + mBoxing(100), + _engine(NULL), + mIsTmp(isPersistence && !isMultifile) { mObj = new multipr::Obj(); - mBoxing = 100; - + try { cout << "Load " << medFilename << endl; - mObj->create(medFilename); + if (isPersistence) + mObj->restorePersistent(medFilename); + else + mObj->create(medFilename); cout << endl; } catch (multipr::RuntimeException& e) @@ -186,12 +346,31 @@ MULTIPR_Obj_i::~MULTIPR_Obj_i() { if (mObj != NULL) { - cout << "MULTIPR: Destructor: remove mObj" << endl; + if (mIsTmp) + { + // Remove temporary files, created during study loading, together with directory + std::string strFile = mObj->getMEDFilename(); + std::string strPath = multipr::getPath(strFile.c_str()); +#ifdef WNT + //std::string cmd_rm ("del /F \""); +#else + std::string cmd_rm ("rm -rf \""); +#endif + cmd_rm += strPath + "\""; + system(cmd_rm.c_str()); + } + + if(MYDEBUG) MESSAGE("MULTIPR_Obj_i: Destructor: remove mObj"); delete mObj; mObj = NULL; } } +void MULTIPR_Obj_i::reset() + throw (SALOME::SALOME_Exception) +{ + mObj->reset(); +} CORBA::Boolean MULTIPR_Obj_i::isValidSequentialMEDFile() throw (SALOME::SALOME_Exception) @@ -238,7 +417,10 @@ void MULTIPR_Obj_i::setMesh(const char* meshName) { mObj->setMesh(meshName); - cout << "Set mesh OK" << endl << endl; + // Dump Python + MULTIPR::TPythonDump(_engine) << this << ".setMesh(\"" << meshName << "\")"; + + if(MYDEBUG) MESSAGE("MULTIPR_Gen_i::setMesh - OK"); } catch (multipr::RuntimeException& e) { @@ -247,6 +429,14 @@ void MULTIPR_Obj_i::setMesh(const char* meshName) } } +std::string MULTIPR_Obj_i::getMeshName() const + throw (SALOME::SALOME_Exception) +{ + if (mObj == NULL) THROW_SALOME_CORBA_EXCEPTION("No associated MED file", SALOME::INTERNAL_ERROR); + + return mObj->getMeshName(); +} + void MULTIPR_Obj_i::setBoxing(CORBA::Long pBoxing) throw (SALOME::SALOME_Exception) @@ -255,6 +445,9 @@ void MULTIPR_Obj_i::setBoxing(CORBA::Long pBoxing) if (mBoxing > 200) THROW_SALOME_CORBA_EXCEPTION("Invalid boxing parameter; should be <= 200", SALOME::INTERNAL_ERROR); mBoxing = pBoxing; + + // Dump Python + MULTIPR::TPythonDump(_engine) << this << ".setBoxing(" << pBoxing << ")"; } @@ -285,7 +478,7 @@ MULTIPR_ORB::string_array* MULTIPR_Obj_i::getMeshes() } -MULTIPR_ORB::string_array* MULTIPR_Obj_i::getFields() +MULTIPR_ORB::string_array* MULTIPR_Obj_i::getFields(const char* pPartList) throw (SALOME::SALOME_Exception) { if (mObj == NULL) THROW_SALOME_CORBA_EXCEPTION("No associated MED file", SALOME::INTERNAL_ERROR); @@ -294,7 +487,7 @@ MULTIPR_ORB::string_array* MULTIPR_Obj_i::getFields() try { - std::vector listFields = mObj->getFields(); + std::vector listFields = mObj->getFields(pPartList); mySeq->length(listFields.size()); for (size_t i = 0 ; i < listFields.size() ; i++) @@ -312,14 +505,14 @@ MULTIPR_ORB::string_array* MULTIPR_Obj_i::getFields() } -CORBA::Long MULTIPR_Obj_i::getTimeStamps(const char* fieldName) +CORBA::Long MULTIPR_Obj_i::getTimeStamps(const char* pPartList, const char* fieldName) throw (SALOME::SALOME_Exception) { if (mObj == NULL) THROW_SALOME_CORBA_EXCEPTION("No associated MED file", SALOME::INTERNAL_ERROR); try { - return mObj->getTimeStamps(fieldName); + return mObj->getTimeStamps(pPartList, fieldName); } catch (multipr::RuntimeException& e) { @@ -328,6 +521,21 @@ CORBA::Long MULTIPR_Obj_i::getTimeStamps(const char* fieldName) } } +void MULTIPR_Obj_i::getFieldMinMax(const char* pPartName, const char* pFieldName, + CORBA::Float& pMin, CORBA::Float& pMax) + throw (SALOME::SALOME_Exception) +{ + if (mObj == NULL) THROW_SALOME_CORBA_EXCEPTION("No associated MED file", SALOME::INTERNAL_ERROR); + try + { + mObj->getFieldMinMax(pPartName, pFieldName, pMin, pMax); + } + catch (multipr::RuntimeException& e) + { + e.dump(cout); + THROW_SALOME_CORBA_EXCEPTION("Unable to get parts", SALOME::INTERNAL_ERROR); + } +} MULTIPR_ORB::string_array* MULTIPR_Obj_i::getParts() throw (SALOME::SALOME_Exception) @@ -381,6 +589,9 @@ MULTIPR_ORB::string_array* MULTIPR_Obj_i::partitionneDomaine() { mySeq[i] = CORBA::string_dup(listParts[i].c_str()); } + + // Dump Python + MULTIPR::TPythonDump(_engine) << "parts = " << this << ".partitionneDomaine()"; } catch (multipr::RuntimeException& e) { @@ -392,7 +603,7 @@ MULTIPR_ORB::string_array* MULTIPR_Obj_i::partitionneDomaine() } -MULTIPR_ORB::string_array* MULTIPR_Obj_i::partitionneGrain( +MULTIPR_ORB::string_array* MULTIPR_Obj_i::partitionneGroupe( const char* pPartName, CORBA::Long pNbParts, CORBA::Long pPartitionner) @@ -404,7 +615,7 @@ MULTIPR_ORB::string_array* MULTIPR_Obj_i::partitionneGrain( try { - std::vector listParts = mObj->partitionneGrain( + std::vector listParts = mObj->partitionneGroupe( pPartName, pNbParts, pPartitionner); @@ -415,11 +626,21 @@ MULTIPR_ORB::string_array* MULTIPR_Obj_i::partitionneGrain( { mySeq[i] = CORBA::string_dup(listParts[i].c_str()); } + + // Dump Python + MULTIPR::TPythonDump(_engine) << "new_parts = " << this << ".partitionneGrain(\"" + << pPartName << "\", " << pNbParts << ", " << pPartitionner << ")"; } - catch (multipr::RuntimeException& e) + catch (std::exception& exc) { - e.dump(cout); - THROW_SALOME_CORBA_EXCEPTION("Unable to partition group", SALOME::INTERNAL_ERROR); + THROW_SALOME_CORBA_EXCEPTION(exc.what(), SALOME::INTERNAL_ERROR); + } + catch (multipr::RuntimeException& exc) + { + std::ostringstream aStream; + exc.dump(aStream); + aStream<length(listParts.size()); - for (size_t i = 0 ; i < listParts.size() ; i++) { mySeq[i] = CORBA::string_dup(listParts[i].c_str()); } + + // Dump Python + MULTIPR::TPythonDump(_engine) << "parts = " << this << ".decimePartition(\"" + << pPartName << "\", \"" << pFieldName << "\", " + << pFieldIt << ", \"" << pFilterName << "\", " << + pFilterParams << ")"; } catch (multipr::RuntimeException& e) { e.dump(cout); THROW_SALOME_CORBA_EXCEPTION("Unable to decimate", SALOME::INTERNAL_ERROR); } - return mySeq._retn(); } @@ -487,7 +708,12 @@ char* MULTIPR_Obj_i::evalDecimationParams( pFieldIt, pFilterName, pFilterParams); - + + // Dump Python + MULTIPR::TPythonDump(_engine) << "dec_params = " << this << ".evalDecimationParams(\"" + << pPartName << "\", \"" << pFieldName << "\", " << pFieldIt + << ", \"" << pFilterName << "\", \"" << pFilterParams + << "\") # " << res.c_str(); return CORBA::string_dup(res.c_str()); } @@ -505,27 +731,890 @@ void MULTIPR_Obj_i::removeParts(const char* pPrefixPartName) if (mObj == NULL) THROW_SALOME_CORBA_EXCEPTION("No associated MED file", SALOME::INTERNAL_ERROR); mObj->removeParts(pPrefixPartName); + + // Dump Python + MULTIPR::TPythonDump(_engine) << this << ".removeParts(\"" << pPrefixPartName << "\")"; } +char* MULTIPR_Obj_i::getMEDInfo(const char* pPartName) + throw (SALOME::SALOME_Exception) +{ + if (mObj == NULL) THROW_SALOME_CORBA_EXCEPTION("No associated MED file", SALOME::INTERNAL_ERROR); + char res[128]; + + mObj->getMEDInfo(res, const_cast(pPartName)); + return CORBA::string_dup(res); +} void MULTIPR_Obj_i::save(const char* pPath) throw (SALOME::SALOME_Exception) { - if (mObj == NULL) THROW_SALOME_CORBA_EXCEPTION("No associated MED file", SALOME::INTERNAL_ERROR); - - try + if (mObj == NULL) THROW_SALOME_CORBA_EXCEPTION("No associated MED file", SALOME::INTERNAL_ERROR); + + try + { + std::string strFile = mObj->getMEDFilename(); + + // Do Save + mObj->save(pPath); + + // Remove temporary files, if needed + if (mIsTmp) { - mObj->save(pPath); - + mIsTmp = false; + + // Remove temporary files, created during study loading, together with directory + std::string strPath = multipr::getPath(strFile.c_str()); +#ifdef WNT + //std::string cmd_rm ("del /F \""); +#else + std::string cmd_rm ("rm -rf \""); +#endif + cmd_rm += strPath + "\""; + system(cmd_rm.c_str()); } - catch (multipr::RuntimeException& e) + } + catch (multipr::RuntimeException& e) + { + e.dump(cout); + THROW_SALOME_CORBA_EXCEPTION("Unable to save MED file", SALOME::INTERNAL_ERROR); + } + + // Dump Python + MULTIPR::TPythonDump(_engine) << this << ".save(\"" << pPath << "\")"; +} + +CORBA::Long MULTIPR_Obj_i::getSaveProgress() +{ + return mObj->getProgress(); +} + +void MULTIPR_Obj_i::resetSaveProgress() +{ + mObj->resetProgress(); +} + +//----------------------------------------------------------------------------- +// savePersistent and setEngine (for Persistence & Dump Python) +//----------------------------------------------------------------------------- + +void MULTIPR_Obj_i::savePersistent (const char* pPath) + throw (SALOME::SALOME_Exception) +{ + if (mObj == NULL) THROW_SALOME_CORBA_EXCEPTION("No associated MED file", SALOME::INTERNAL_ERROR); + + try + { + mObj->savePersistent(pPath); + } + catch (multipr::RuntimeException& e) + { + e.dump(cout); + THROW_SALOME_CORBA_EXCEPTION("Unable to save MED file", SALOME::INTERNAL_ERROR); + } +} + +void MULTIPR_Obj_i::setEngine (MULTIPR_Gen_i* theEngine) +{ + _engine = theEngine; +} + + +//----------------------------------------------------------------------------- +// Set/Get current study (for Persistence & Dump Python) +//----------------------------------------------------------------------------- + +/*! Set current study + */ +void MULTIPR_Gen_i::SetCurrentStudy (SALOMEDS::Study_ptr theStudy) +{ + //if(MYDEBUG) MESSAGE("MULTIPR_Gen_i::SetCurrentStudy"); + + // theStudy or myCurrentStudy may be nil + if (!CORBA::is_nil(theStudy)) + { + if (CORBA::is_nil(myCurrentStudy)) { - e.dump(cout); - THROW_SALOME_CORBA_EXCEPTION("Unable to save MED file", SALOME::INTERNAL_ERROR); + // move python trace of unknown study to the real study + int studyId = theStudy->StudyId(); + if (myPythonScripts.find(-1) != myPythonScripts.end()) + { + myPythonScripts[studyId].insert(myPythonScripts[studyId].begin(), // at + myPythonScripts[-1].begin(), // from + myPythonScripts[-1].end()); // to + myPythonScripts[-1].clear(); + } + } + } + + myCurrentStudy = SALOMEDS::Study::_duplicate(theStudy); +} + +/*! Get current study + */ +SALOMEDS::Study_ptr MULTIPR_Gen_i::GetCurrentStudy() +{ + //if(MYDEBUG) MESSAGE("MULTIPR_Gen_i::GetCurrentStudy: study Id = " << GetCurrentStudyID()); + return SALOMEDS::Study::_duplicate(myCurrentStudy); +} + +//----------------------------------------------------------------------------- +// SALOMEDS::Driver methods (Persistence & Dump Python) +//----------------------------------------------------------------------------- + +/*! Get component data type + */ +char* MULTIPR_Gen_i::ComponentDataType() +{ + if(MYDEBUG) MESSAGE( "MULTIPR_Gen_i::ComponentDataType" ); + return CORBA::string_dup( "MULTIPR" ); +} + +/*! Clears study-connected data when it is closed + */ +void MULTIPR_Gen_i::Close (SALOMEDS::SComponent_ptr theComponent) +{ + if(MYDEBUG) MESSAGE("MULTIPR_Gen_i::Close"); +} + +/*! Save MULTIPR module's data + */ +SALOMEDS::TMPFile* MULTIPR_Gen_i::Save (SALOMEDS::SComponent_ptr theComponent, + const char* theURL, + bool isMultiFile) +{ + INFOS( "MULTIPR_Gen_i::Save" ); + + if (myCurrentStudy->_is_nil() || + theComponent->GetStudy()->StudyId() != myCurrentStudy->StudyId()) + SetCurrentStudy(theComponent->GetStudy()); + + // Store study contents as a set of python commands + SavePython(myCurrentStudy); + + // Study name (for tmp directory and tmp files naming) + std::string aStudyName; + if (isMultiFile) + aStudyName = SALOMEDS_Tool::GetNameFromPath(myCurrentStudy->URL()); + + // Declare a byte stream + SALOMEDS::TMPFile_var aStreamFile; + + SALOMEDS::ChildIterator_ptr obj_it (myCurrentStudy->NewChildIterator(theComponent)); + + // TODO: iterate on all objects under theComponent + if (!obj_it->More()) + return aStreamFile._retn(); + + SALOMEDS::SObject_ptr aSObj = obj_it->Value(); + CORBA::Object_var anObj = aSObj->GetObject(); + MULTIPR_ORB::MULTIPR_Obj_ptr obj = MULTIPR_ORB::MULTIPR_Obj::_narrow(anObj); + if (CORBA::is_nil(obj)) + return aStreamFile._retn(); + + // Obtain a temporary directory + std::string tmpDir = isMultiFile ? theURL : SALOMEDS_Tool::GetTmpDir(); + + // Directory for MED data to be stored in a distributed MED file + std::string subDir = aStudyName + "_MULTIPR_MED"; + std::string meshDir = tmpDir + subDir; + + // Create a new dir to save the sequential/distributed file in. + // Remove all the files in if they exist. +#ifdef WNT + std::string dirSeparator = "\\"; + //std::string cmd_mk ("mkdir /F \""); + //std::string cmd_rm ("del /F \""); +#else + std::string dirSeparator = "/"; + std::string cmd_mk ("mkdir \""); + std::string cmd_rm ("rm -rf \""); +#endif + cmd_mk += meshDir + "\""; + cmd_rm += meshDir + dirSeparator + "\"*"; + system(cmd_mk.c_str()); + system(cmd_rm.c_str()); + + // Create a sequence of files processed + SALOMEDS::ListOfFileNames_var aFileSeq = new SALOMEDS::ListOfFileNames; + + if (obj->isValidSequentialMEDFile()) + { + std::string aFile = obj->getFilename(); + std::string aFileName = multipr::getFilenameWithoutPath(aFile.c_str()); + + // Copy initial sequential MED file to +#ifdef WNT + std::string dirSeparator = "\\"; + //std::string cmd_cp ("copy \""); +#else + std::string dirSeparator = "/"; + std::string cmd_cp ("cp \""); +#endif + cmd_cp += aFile + "\" \"" + meshDir + dirSeparator + "\""; + system(cmd_cp.c_str()); + + // Set names of temporary files + std::string aFileNameRel = subDir + dirSeparator + aFileName; + aFileSeq->length(1); + aFileSeq[0] = CORBA::string_dup(aFileNameRel.c_str()); // sequential MED file + } + else if (obj->isValidDistributedMEDFile()) + { + // Save distributed MED file to the + PortableServer::Servant aServant = _poa->reference_to_servant(obj); + MULTIPR_Obj_i* objServant = dynamic_cast(aServant); + if (!objServant) + { + // TODO: exception + return aStreamFile._retn(); + } + objServant->savePersistent(meshDir.c_str()); + + // ASCII master file name + std::string aMaitreFile = obj->getFilename(); + std::string aMaitreFileName = multipr::getFilenameWithoutPath(aMaitreFile.c_str()); + // just after partitionneDomaine() the state is MULTIPR_OBJ_STATE_DIS_MEM, + // and getFilename() returns name of sequential file + // (because distributed file is not created on disk yet). So, build the name: + if (aMaitreFile == obj->getSeqFilename()) + { + std::string strExtension (".med"); + std::string strNamePrefix = + multipr::removeExtension(aMaitreFileName.c_str(), strExtension.c_str()); + aMaitreFileName = strNamePrefix + "_grains_maitre" + strExtension; + } + //std::string aMaitreFileName = SALOMEDS_Tool::GetNameFromPath(aMaitreFile); + std::string aMaitreFileNameRel = subDir + dirSeparator + aMaitreFileName; + + // Set names of temporary files + MULTIPR_ORB::string_array* listParts = obj->getParts(); + unsigned int nbParts = listParts->length(); + aFileSeq->length(nbParts + 1); + + char lMeshName[256]; + int lId; + char lPartName[256]; + char lPath[256]; + char lMEDFileName[256]; + + for (unsigned int i = 0; i < nbParts; i++) // each part MED files + { + const char* strPartName = (*listParts)[i]; + char* strPartInfo = obj->getPartInfo(strPartName); + + // parse infos + int ret = sscanf(strPartInfo, "%s %d %s %s %s", + lMeshName, &lId, lPartName, lPath, lMEDFileName); + + if (ret != 5) + { + // TODO: exception + return aStreamFile._retn(); + } + + std::string aPartFileName = multipr::getFilenameWithoutPath(lMEDFileName); + std::string aPartFileNameRel = subDir + dirSeparator + aPartFileName; + + aFileSeq[i] = CORBA::string_dup(aPartFileNameRel.c_str()); // part MED file + } + aFileSeq[nbParts] = CORBA::string_dup(aMaitreFileNameRel.c_str()); // ASCII master file + } + else + { + // TODO: exception + return aStreamFile._retn(); + } + + // Convert temporary files to stream + aStreamFile = SALOMEDS_Tool::PutFilesToStream(tmpDir, aFileSeq.in(), isMultiFile); + + // Remove temporary files and directory + if (!isMultiFile) + { + //SALOMEDS_Tool::RemoveTemporaryFiles(tmpDir, aFileSeq.in(), true); + // remove with shell command, because SALOMEDS_Tool::RemoveTemporaryFiles does not remove sub-folders +#ifdef WNT + //std::string cmd_rm ("del /F \""); +#else + std::string cmd_rm ("rm -rf \""); +#endif + cmd_rm += tmpDir + "\""; + system(cmd_rm.c_str()); + } + + INFOS("MULTIPR_Gen_i::Save() completed"); + return aStreamFile._retn(); +} + +/*! Save MULTIPR module's data in ASCII format + */ +SALOMEDS::TMPFile* MULTIPR_Gen_i::SaveASCII (SALOMEDS::SComponent_ptr theComponent, + const char* theURL, + bool isMultiFile) +{ + if(MYDEBUG) MESSAGE( "MULTIPR_Gen_i::SaveASCII" ); + SALOMEDS::TMPFile_var aStreamFile = Save(theComponent, theURL, isMultiFile); + return aStreamFile._retn(); +} + +/*! Load MULTIPR module's data + */ +bool MULTIPR_Gen_i::Load (SALOMEDS::SComponent_ptr theComponent, + const SALOMEDS::TMPFile& theStream, + const char* theURL, + bool isMultiFile) +{ + INFOS("MULTIPR_Gen_i::Load"); + + if (myCurrentStudy->_is_nil() || + theComponent->GetStudy()->StudyId() != myCurrentStudy->StudyId()) + SetCurrentStudy(theComponent->GetStudy()); + + // Get temporary files location + std::string tmpDir = isMultiFile ? theURL : SALOMEDS_Tool::GetTmpDir(); + + INFOS("THE URL++++++++++++++"); + INFOS(theURL); + INFOS("THE TMP PATH+++++++++"); + INFOS(tmpDir.c_str()); + + // For LocalPersistentIDToIOR(): + myTmpDir = tmpDir; + + // Create a new dir to restore the distributed/sequential + // MED file in. It is needed only if not multifile, because in + // multifile study all required files are already on disk. + if (!isMultiFile) + { + std::string subDir = "_MULTIPR_MED"; + std::string meshDir = tmpDir + subDir; +#ifdef WNT + //std::string cmd_mk ("mkdir /F \""); +#else + std::string cmd_mk ("mkdir \""); +#endif + cmd_mk += meshDir + "\""; + system(cmd_mk.c_str()); + } + + // Convert the stream into sequence of files to process + SALOMEDS::ListOfFileNames_var aFileSeq = + SALOMEDS_Tool::PutStreamToFiles(theStream, tmpDir.c_str(), isMultiFile); + + //TCollection_AsciiString aStudyName; + //if (isMultiFile) + // aStudyName = ((char*)SALOMEDS_Tool::GetNameFromPath(myCurrentStudy->URL()).c_str()); + + // Set names of "temporary" files + //TCollection_AsciiString filename = tmpDir + aStudyName + TCollection_AsciiString( "_MULTIPR.hdf" ); + //TCollection_AsciiString meshfile = tmpDir + aStudyName + TCollection_AsciiString( "_MULTIPR_Mesh.med" ); + + // Remove temporary files created from the stream + //if (!isMultiFile) + // SALOMEDS_Tool::RemoveTemporaryFiles( tmpDir.ToCString(), aFileSeq.in(), true ); + + INFOS("MULTIPR_Gen_i::Load completed"); + return true; +} + +/*! Load MULTIPR module's data in ASCII format + */ +bool MULTIPR_Gen_i::LoadASCII (SALOMEDS::SComponent_ptr theComponent, + const SALOMEDS::TMPFile& theStream, + const char* theURL, + bool isMultiFile) +{ + if(MYDEBUG) MESSAGE( "MULTIPR_Gen_i::LoadASCII" ); + return Load(theComponent, theStream, theURL, isMultiFile); +} + +/*! Transform data from transient form to persistent + */ +char* MULTIPR_Gen_i::IORToLocalPersistentID (SALOMEDS::SObject_ptr /*theSObject*/, + const char* IORString, + CORBA::Boolean isMultiFile, + CORBA::Boolean /*isASCII*/ ) +{ + if(MYDEBUG) MESSAGE("MULTIPR_Gen_i::IORToLocalPersistentID"); + + MULTIPR_ORB::MULTIPR_Obj_ptr obj = + MULTIPR_ORB::MULTIPR_Obj::_narrow(_orb->string_to_object(IORString)); + + if (!CORBA::is_nil(obj)) + { + std::string aStudyName; + if (isMultiFile) + aStudyName = SALOMEDS_Tool::GetNameFromPath(myCurrentStudy->URL()); + + std::string subDir = aStudyName + "_MULTIPR_MED"; + + std::string aFile = obj->getFilename(); + std::string aFileName = multipr::getFilenameWithoutPath(aFile.c_str()); + + // Get servant (to call methods, not present in IDL interface + PortableServer::Servant aServant = _poa->reference_to_servant(obj); + MULTIPR_Obj_i* objServant = dynamic_cast(aServant); + if (!objServant) + { + // TODO: exception + return CORBA::string_dup(""); + } + + std::string strSeparator ("|"); + if (obj->isValidSequentialMEDFile()) + { + // Save Boxing + char strBoxing[32]; + sprintf(strBoxing, "%d", objServant->getBoxing()); + aFileName += strSeparator + strBoxing; + + // Save Mesh Name + std::string aMeshName = objServant->getMeshName(); + if (!aMeshName.empty()) + { + aFileName += strSeparator + aMeshName; + } + } + else if (obj->isValidDistributedMEDFile()) + { + // just after partitionneDomaine() the state is MULTIPR_OBJ_STATE_DIS_MEM, + // and getFilename() returns name of sequential file + // (because distributed file is not created on disk yet). So, build the name: + if (aFile == obj->getSeqFilename()) + { + std::string strExtension (".med"); + std::string strNamePrefix = + multipr::removeExtension(aFileName.c_str(), strExtension.c_str()); + aFileName = strNamePrefix + "_grains_maitre" + strExtension; + } + + // Save Boxing + char strBoxing[32]; + sprintf(strBoxing, "%d", objServant->getBoxing()); + aFileName += strSeparator + strBoxing; + } + else + { + // TODO: exception + return CORBA::string_dup(""); + } + + // PersistentID will be a relative path to MED file (relatively tmp dir) + // plus additianal parameters, separated by '|' (see above) +#ifdef WNT + std::string dirSeparator = "\\"; +#else + std::string dirSeparator = "/"; +#endif + aFileName = subDir + dirSeparator + aFileName; + + if(MYDEBUG) MESSAGE("MULTIPR_Gen_i::IORToLocalPersistentID: id = " << aFileName.c_str()); + + return CORBA::string_dup(aFileName.c_str()); + } + return CORBA::string_dup(""); +} + +/*! Transform data from persistent form to transient + */ +char* MULTIPR_Gen_i::LocalPersistentIDToIOR (SALOMEDS::SObject_ptr /*theSObject*/, + const char* aLocalPersistentID, + CORBA::Boolean isMultiFile, + CORBA::Boolean /*isASCII*/) +{ + if(MYDEBUG) MESSAGE("MULTIPR_Gen_i::LocalPersistentIDToIOR(): id = " << aLocalPersistentID); + + if (strlen(aLocalPersistentID) > 0) + { + // Extract relative path + std::string strLocalPersistentID (aLocalPersistentID); + int nb = strLocalPersistentID.find("|"); + if (nb < 1) nb = strLocalPersistentID.size(); + if (nb < 1) + { + // TODO: exception + return CORBA::string_dup(""); + } + std::string strRelativePath = strLocalPersistentID.substr(0, nb); + strLocalPersistentID.erase(0, nb); // erase + if (strLocalPersistentID.size() > 0) strLocalPersistentID.erase(0, 1); // erase "|" + + // the only kind of available objects is a MULTIPR_ORB::MULTIPR_Obj, + // representing a sequential or a distributed MED file. + std::string medFilename = myTmpDir + strRelativePath; // myTmpDir already contains dir separator + + // create MULTIPR_Obj from file + //MULTIPR_ORB::MULTIPR_Obj_ptr obj = getObject(medFilename.c_str()); + MULTIPR_Obj_i* obj_i = new MULTIPR_Obj_i (_poa, + medFilename.c_str(), + /*isPersistence = */true, + isMultiFile); + obj_i->setEngine(this); + MULTIPR_ORB::MULTIPR_Obj_ptr obj = obj_i->POA_MULTIPR_ORB::MULTIPR_Obj::_this(); + + // Set boxing and mesh name, if provided + nb = strLocalPersistentID.find("|"); + if (nb < 1) nb = strLocalPersistentID.size(); + if (nb > 0) + { + std::string strBoxing = strLocalPersistentID.substr(0, nb); + strLocalPersistentID.erase(0, nb); // erase + if (strLocalPersistentID.size() > 0) strLocalPersistentID.erase(0, 1); // erase "|" + int aBoxing = atoi(strBoxing.c_str()); + obj->setBoxing(aBoxing); + } + + if (obj->isValidSequentialMEDFile()) + { + nb = strLocalPersistentID.size(); + if (nb > 0) + { + std::string strMeshName = strLocalPersistentID.substr(0, nb); + obj->setMesh(strMeshName.c_str()); + // we do not cut here, + // because we do not expect to find in it anything + } + } + + // get IOR string + CORBA::String_var anIORString = _orb->object_to_string(obj); + return CORBA::string_dup(anIORString); + } + return CORBA::string_dup(""); +} + +/*! Transform data from persistent form to transient + */ +Engines::TMPFile* MULTIPR_Gen_i::DumpPython (CORBA::Object_ptr theStudy, + CORBA::Boolean isPublished, + CORBA::Boolean& isValidScript) +{ + isValidScript = false; + + SALOMEDS::Study_var aStudy = SALOMEDS::Study::_narrow(theStudy); + if (CORBA::is_nil(aStudy)) + return new Engines::TMPFile(0); + + /* + SALOMEDS::SObject_var aSO = aStudy->FindComponent(ComponentDataType()); + if (CORBA::is_nil(aSO)) + return new Engines::TMPFile(0); + + // Map study entries to object names + Resource_DataMapOfAsciiStringAsciiString aMap; + Resource_DataMapOfAsciiStringAsciiString aMapNames; + + SALOMEDS::ChildIterator_var Itr = aStudy->NewChildIterator(aSO); + for (Itr->InitEx(true); Itr->More(); Itr->Next()) { + SALOMEDS::SObject_var aValue = Itr->Value(); + CORBA::String_var anID = aValue->GetID(); + CORBA::String_var aName = aValue->GetName(); + TCollection_AsciiString aGUIName ( (char*) aName.in() ); + TCollection_AsciiString anEnrty ( (char*) anID.in() ); + if (aGUIName.Length() > 0) { + aMapNames.Bind( anEnrty, aGUIName ); + aMap.Bind( anEnrty, aGUIName ); + } + } + //*/ + + // Get trace of restored study + SALOMEDS::SObject_var aSO = aStudy->FindComponent(ComponentDataType()); + SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder(); + SALOMEDS::GenericAttribute_var anAttr = + aStudyBuilder->FindOrCreateAttribute(aSO, "AttributePythonObject"); + + char* oldValue = SALOMEDS::AttributePythonObject::_narrow(anAttr)->GetObject(); + std::string aSavedTrace (oldValue); + + // Add trace of API methods calls and replace study entries by names + std::string aScript = + "### This file is generated by SALOME automatically " + "by dump python functionality of MULTIPR component\n\n"; + aScript += DumpPython_impl(aStudy->StudyId(), isPublished, isValidScript, aSavedTrace); + + int aLen = aScript.length(); + unsigned char* aBuffer = new unsigned char[aLen+1]; + strcpy((char*)aBuffer, aScript.c_str()); + + CORBA::Octet* anOctetBuf = (CORBA::Octet*)aBuffer; + Engines::TMPFile_var aStreamFile = new Engines::TMPFile (aLen+1, aLen+1, anOctetBuf, 1); + + //bool hasNotPublishedObjects = aScript.Location( NotPublishedObjectName(), 1, aLen); + //isValidScript = isValidScript && !hasNotPublishedObjects; + + return aStreamFile._retn(); +} + +/*! DumpPython_impl + */ +std::string MULTIPR_Gen_i::DumpPython_impl (int theStudyID, + bool isPublished, + bool& aValidScript, + std::string theSavedTrace) +{ + std::string helper; + std::string aGen = MULTIPR::TPythonDump::MULTIPRGenName(); + + // set initial part of a script + std::string aScript ("import salome\n"); + aScript += "import MULTIPR_ORB\n\n"; + aScript += "def RebuildData(theStudy):\n"; + + aScript += helper + "\tmpr_comp = salome.lcc.FindOrLoadComponent(\"FactoryServer\", \"" + + ComponentDataType() + "\")\n"; + aScript += helper + "\t" + aGen + " = mpr_comp._narrow(MULTIPR_ORB.MULTIPR_Gen)\n"; + + //if ( isPublished ) + // aScript += helper + "\t" + aGen + ".SetCurrentStudy(theStudy)"; + //else + // aScript += helper + "\t" + aGen + ".SetCurrentStudy(None)"; + aScript += helper + "\t" + aGen + ".SetCurrentStudy(theStudy)\n"; + + // Dump trace of restored study + if (theSavedTrace.length() > 0) + { + aScript += helper + "\n" + theSavedTrace; + } + + // Dump trace of API methods calls + std::string aNewLines = GetNewPythonLines(theStudyID); + if (aNewLines.length() > 0) + { + aScript += helper + "\n" + aNewLines; + } + + // add final part of a script + //aScript += helper + "\n\tisGUIMode = " + isPublished; + //aScript += "\n\tif isGUIMode and salome.sg.hasDesktop():"; + //aScript += "\n\t\tsalome.sg.updateObjBrowser(0)"; + aScript += "\n\n\tpass\n"; + + aValidScript = true; + + return aScript; +} + +/*! GetNewPythonLines + */ +std::string MULTIPR_Gen_i::GetNewPythonLines (int theStudyID) +{ + std::string aScript; + + // Dump trace of API methods calls + if (myPythonScripts.find(theStudyID) != myPythonScripts.end()) + { + std::vector aPythonScript = myPythonScripts[theStudyID]; + int istr, aLen = aPythonScript.size(); + for (istr = 0; istr < aLen; istr++) + { + aScript += "\n\t"; + aScript += aPythonScript[istr]; } + aScript += "\n"; + } + + return aScript; +} + +/*! CleanPythonTrace + */ +void MULTIPR_Gen_i::CleanPythonTrace (int theStudyID) +{ + // Clean trace of API methods calls + if (myPythonScripts.find(theStudyID) != myPythonScripts.end()) + { + myPythonScripts[theStudyID].clear(); + } +} + +/*! AddToPythonScript + */ +void MULTIPR_Gen_i::AddToPythonScript (int theStudyID, std::string theString) +{ + //if (myPythonScripts.find(theStudyID) == myPythonScripts.end()) + //{ + // myPythonScripts[theStudyID] = std::vector; + //} + myPythonScripts[theStudyID].push_back(theString); } +/*! SavePython + */ +void MULTIPR_Gen_i::SavePython (SALOMEDS::Study_ptr theStudy) +{ + // Dump trace of API methods calls + std::string aScript = GetNewPythonLines(theStudy->StudyId()); + + // Check contents of PythonObject attribute + SALOMEDS::SObject_var aSO = theStudy->FindComponent(ComponentDataType()); + SALOMEDS::StudyBuilder_var aStudyBuilder = theStudy->NewBuilder(); + SALOMEDS::GenericAttribute_var anAttr = + aStudyBuilder->FindOrCreateAttribute(aSO, "AttributePythonObject"); + + char* oldValue = SALOMEDS::AttributePythonObject::_narrow(anAttr)->GetObject(); + std::string oldScript (oldValue); + + if (oldScript.length() > 0) { + oldScript += "\n"; + oldScript += aScript; + } + else { + oldScript = aScript; + } + // Store in PythonObject attribute + SALOMEDS::AttributePythonObject::_narrow(anAttr)->SetObject(oldScript.c_str(), 1); + + // Clean trace of API methods calls + CleanPythonTrace(theStudy->StudyId()); +} + + +/*! Returns true if object can be published in the study + */ +bool MULTIPR_Gen_i::CanPublishInStudy (CORBA::Object_ptr theIOR) +{ + //if(MYDEBUG) MESSAGE("MULTIPR_Gen_i::CanPublishInStudy - " << !CORBA::is_nil(myCurrentStudy)); + if(MYDEBUG) MESSAGE("MULTIPR_Gen_i::CanPublishInStudy"); + + //if (CORBA::is_nil(myCurrentStudy)) + // return false; + + MULTIPR_ORB::MULTIPR_Obj_var anObj = MULTIPR_ORB::MULTIPR_Obj::_narrow(theIOR); + if (!anObj->_is_nil()) + return true; + + if(MYDEBUG) MESSAGE("MULTIPR_Gen_i::CanPublishInStudy - CANNOT"); + return false; +} + +/*! Publish object in the study + */ +SALOMEDS::SObject_ptr MULTIPR_Gen_i::PublishInStudy (SALOMEDS::Study_ptr theStudy, + SALOMEDS::SObject_ptr theSObject, + CORBA::Object_ptr theIOR, + const char* theName) + throw (SALOME::SALOME_Exception) +{ + //Unexpect aCatch(SALOME_SalomeException); + + if(MYDEBUG) MESSAGE("MULTIPR_Gen_i::PublishInStudy"); + + //if (myCurrentStudy->_is_nil() || theStudy->StudyId() != myCurrentStudy->StudyId()) + if (myCurrentStudy->_is_nil()) + SetCurrentStudy(theStudy); + + SALOMEDS::SObject_var aSO; + if (CORBA::is_nil(theStudy) || CORBA::is_nil(theIOR)) + return aSO._retn(); + + // Publishing a MULTIPR_Object + MULTIPR_ORB::MULTIPR_Obj_var anObj = MULTIPR_ORB::MULTIPR_Obj::_narrow(theIOR); + if (!anObj->_is_nil()) + { + //aSO = ObjectToSObject(theStudy, anObj); + if (aSO->_is_nil()) + { + SALOMEDS::GenericAttribute_var anAttr; + SALOMEDS::StudyBuilder_var aStudyBuilder = theStudy->NewBuilder(); + + SALOMEDS::SComponent_var aFather = theStudy->FindComponent(ComponentDataType()); + if (aFather->_is_nil()) + { + aFather = aStudyBuilder->NewComponent(ComponentDataType()); + anAttr = aStudyBuilder->FindOrCreateAttribute(aFather, "AttributeName"); + SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr); + aName->SetValue("MULTI-PR"); + //anAttr = aStudyBuilder->FindOrCreateAttribute(aFather, "AttributePixMap"); + //SALOMEDS::AttributePixMap::_narrow(anAttr)->SetPixMap("ICON_OBJBROWSER_MULTIPR"); + //aStudyBuilder->DefineComponentInstance(aFather, MULTIPR_ORB::MULTIPR_Gen::_this()); + aStudyBuilder->DefineComponentInstance(aFather, MULTIPR_Gen::_this()); + } + if (aFather->_is_nil()) return aSO._retn(); + + if (CORBA::is_nil(theSObject)) + { + aSO = aStudyBuilder->NewObject(aFather); + } + else + { + if (!theSObject->ReferencedObject(aSO)) + aSO = SALOMEDS::SObject::_duplicate(theSObject); + } + + anAttr = aStudyBuilder->FindOrCreateAttribute(aSO, "AttributeIOR"); + SALOMEDS::AttributeIOR_var anIORAttr = SALOMEDS::AttributeIOR::_narrow(anAttr); + CORBA::String_var anIOR = _orb->object_to_string(anObj); + anIORAttr->SetValue(anIOR); + + //anAttr = aStudyBuilder->FindOrCreateAttribute(aSO, "AttributePixMap"); + //SALOMEDS::AttributePixMap_var aPixmap = SALOMEDS::AttributePixMap::_narrow(anAttr); + //aPixmap->SetPixMap("ICON_OBJBROWSER_GROUP_PNT"); + + anAttr = aStudyBuilder->FindOrCreateAttribute(aSO, "AttributeName"); + SALOMEDS::AttributeName_var aNameAttrib = SALOMEDS::AttributeName::_narrow(anAttr); + if (strlen(theName) == 0) + aNameAttrib->SetValue(anObj->getFilename()); + else + aNameAttrib->SetValue(theName); + + // Dump Python + MULTIPR::TPythonDump(this) << "sobj = " << this << ".PublishInStudy(theStudy, " + << theSObject << ", " << anObj << ", \"" << theName + << "\") # " << aSO->GetID(); + } + } + + if(MYDEBUG) MESSAGE("MULTIPR_Gen_i::PublishInStudy - END"); + + return aSO._retn(); +} + +/* +SALOMEDS::SComponent_ptr _Gen_i::PublishComponent(SALOMEDS::Study_ptr theStudy) +{ + if ( CORBA::is_nil( theStudy )) + return SALOMEDS::SComponent::_nil(); + if(MYDEBUG) MESSAGE("PublishComponent"); + + SALOMEDS::SComponent_var father = + SALOMEDS::SComponent::_narrow( theStudy->FindComponent( ComponentDataType() ) ); + if ( !CORBA::is_nil( father ) ) + return father._retn(); + + SALOME_ModuleCatalog::ModuleCatalog_var aCat = + SALOME_ModuleCatalog::ModuleCatalog::_narrow( GetNS()->Resolve("/Kernel/ModulCatalog") ); + if ( CORBA::is_nil( aCat ) ) + return father._retn(); + + SALOME_ModuleCatalog::Acomponent_var aComp = aCat->GetComponent( ComponentDataType() ); + if ( CORBA::is_nil( aComp ) ) + return father._retn(); + + SALOMEDS::StudyBuilder_var aStudyBuilder = theStudy->NewBuilder(); + SALOMEDS::GenericAttribute_var anAttr; + SALOMEDS::AttributePixMap_var aPixmap; + + father = aStudyBuilder->NewComponent( ComponentDataType() ); + aStudyBuilder->DefineComponentInstance( father, SMESH_Gen::_this() ); + anAttr = aStudyBuilder->FindOrCreateAttribute( father, "AttributePixMap" ); + aPixmap = SALOMEDS::AttributePixMap::_narrow( anAttr ); + aPixmap ->SetPixMap( "ICON_OBJBROWSER_SMESH" ); + SetName( father, aComp->componentusername(), "MESH" ); + if(MYDEBUG) MESSAGE("PublishComponent--END"); + + return father._retn(); +} +//*/ + + +/*! + * MULTIPREngine_factory + * + * C factory, accessible with dlsym, after dlopen + */ extern "C" { PortableServer::ObjectId* MULTIPREngine_factory( diff --git a/src/MULTIPR/MULTIPR_i.hxx b/src/MULTIPR/MULTIPR_i.hxx index 23f567a..97f600d 100644 --- a/src/MULTIPR/MULTIPR_i.hxx +++ b/src/MULTIPR/MULTIPR_i.hxx @@ -24,8 +24,15 @@ #include "SALOME_Component_i.hxx" #include "Utils_CorbaException.hxx" +#include "SALOME_GenericObj_i.hh" + #include "MULTIPR_Obj.hxx" +#include +#include +#include + +class MULTIPR_Gen_i; //***************************************************************************** // Class MULTIPR_Obj_i @@ -34,7 +41,8 @@ //***************************************************************************** class MULTIPR_Obj_i : - public POA_MULTIPR_ORB::MULTIPR_Obj + public POA_MULTIPR_ORB::MULTIPR_Obj, + public virtual SALOME::GenericObj_i { public: @@ -44,9 +52,12 @@ public: * Associate a MED file (sequential or distributed) with this object. * \param pMEDFilename MED file to be associated with this object. */ - MULTIPR_Obj_i(const char* pMEDFilename) + MULTIPR_Obj_i (PortableServer::POA_ptr thePOA, + const char* pMEDFilename, + bool isPersistence = false, + bool isMultifile = false) throw (SALOME::SALOME_Exception); - + /** * Destructor. */ @@ -56,6 +67,12 @@ public: // Basic accessors/mutators //-------------------------------------------------------------------- + /** + * Reset the object. + */ + void reset() + throw (SALOME::SALOME_Exception); + /** * Returns true iff this obj represents a valid sequential MED file. * \return true iff this obj represents a valid sequential MED file. @@ -90,13 +107,27 @@ public: void setMesh(const char* pMeshName) throw (SALOME::SALOME_Exception); + /** + * Returns a name of the mesh to be processed. + * \return a name of the mesh to be processed. + */ + std::string getMeshName() const + throw (SALOME::SALOME_Exception); + /** * Sets boxing parameters for decimation (100 by default). - * \param pBoxing number of cells along each axis of the grid (= acceleration structure) ; should be in [1..200]. + * \param pBoxing number of cells along each axis of the grid + * (= acceleration structure) ; should be in [1..200]. */ void setBoxing(CORBA::Long pBoxing) throw (SALOME::SALOME_Exception); + /** + * Returns currently set boxing parameter for decimation. + * \return currently set boxing parameter for decimation. + */ + int getBoxing() const { return mBoxing; } + /** * Returns the list of meshes contained in the sequential MED file. * Assumes this object encapsulates a sequential MED file. @@ -108,20 +139,32 @@ public: /** * Returns the list of fields contained in the sequential MED file. * Assumes this object encapsulates a sequential MED file. + * \param pPartList The list of parts to get the fields from (separator is '|'). * \return the list of fields contained in the sequential MED file. */ - MULTIPR_ORB::string_array* getFields() + MULTIPR_ORB::string_array* getFields(const char* pPartList) throw (SALOME::SALOME_Exception); /** * Returns the number of timestamps for a given field. * Assumes this object encapsulates a sequential MED file. - * \param pFieldName name of any field. + * \param pPartList The list of parts to get the fields from (separator is '|'). + * \param pFieldName name of any field. * \return the number of timestamps for a given field; 0 if field not found. */ - CORBA::Long getTimeStamps(const char* pFieldName) + CORBA::Long getTimeStamps(const char* pPartList, const char* pFieldName) throw (SALOME::SALOME_Exception); - + + /** + * Get the minimum and maximum value of a part's field. + * \param pPartName The name of the part. + * \param pFieldName The name of the field. + * \param pMin The mininum value to fill. + * \param pMax The maxinum value to fill. + */ + void getFieldMinMax(const char* pPartName, const char* pFieldName, CORBA::Float& pMin, CORBA::Float& pMax) + throw (SALOME::SALOME_Exception); + /** * Returns the name of all partitions. * Assumes this object encapsulates a distributed MED file. @@ -166,7 +209,7 @@ public: * \param pPartitionner use value 0=MULTIPR_METIS for Metis or 1=MULTIPR_SCOTCH for Scotch. * \return the name of each part. */ - MULTIPR_ORB::string_array* partitionneGrain( + MULTIPR_ORB::string_array* partitionneGroupe( const char* pPartName, CORBA::Long pNbParts, CORBA::Long pPartitionner) @@ -191,9 +234,7 @@ public: const char* pFieldName, CORBA::Long pFieldIt, const char* pFilterName, - CORBA::Double pTmed, - CORBA::Double pTlow, - CORBA::Double pRadius) + const char* pFilterParams) throw (SALOME::SALOME_Exception); /** @@ -221,7 +262,14 @@ public: */ void removeParts(const char* pPrefixPartName) throw (SALOME::SALOME_Exception); - + + /** + * Get mesh statistics. + * \return Mesh statistics ! + */ + char* getMEDInfo(const char* pPartName) + throw (SALOME::SALOME_Exception); + //--------------------------------------------------------------------- // I/O //--------------------------------------------------------------------- @@ -232,7 +280,36 @@ public: */ void save(const char* pPath) throw (SALOME::SALOME_Exception); - + + /** + * Check save progress. + * \return current save progress in percents. + */ + CORBA::Long getSaveProgress(); + + /** + * Reset save progress to zero. + */ + void resetSaveProgress(); + + //--------------------------------------------------------------------- + // Persistence and Dump Python + //--------------------------------------------------------------------- + + /** + * Saves the associated MED file to the given location. + * \note To be used only for persistence. + * \param pPath path where to save the file. + */ + void savePersistent (const char* pPath) + throw (SALOME::SALOME_Exception); + + /** + * Set Engine. + */ + //void setEngine (MULTIPR_ORB::MULTIPR_Gen_ptr theEngine); + void setEngine (MULTIPR_Gen_i* theEngine); + private: /** @@ -246,7 +323,16 @@ private: * By default, mBoxing=100. */ int mBoxing; - + + /** + * Engine. + */ + MULTIPR_Gen_i* _engine; + + /** + * Is restored MED file (Used by Persistence to remove temporary files). + */ + bool mIsTmp; }; @@ -279,7 +365,7 @@ public: const char* meshName) throw (SALOME::SALOME_Exception); - void partitionneGrain( + void partitionneGroupe( const char* medFilename, const char* partName, CORBA::Long nbParts, @@ -292,14 +378,113 @@ public: const char* fieldName, CORBA::Long fieldIt, const char* filterName, - CORBA::Double tmed, - CORBA::Double tlow, - CORBA::Double radius, - CORBA::Long boxing) + const char* filterParams) throw (SALOME::SALOME_Exception); MULTIPR_ORB::MULTIPR_Obj_ptr getObject(const char* medFilename) throw (SALOME::SALOME_Exception); + + // **************************************************** + // Set/Get current study for Persistence and Dump Python + // **************************************************** + + // Set current study + void SetCurrentStudy (SALOMEDS::Study_ptr theStudy); + // Get current study + SALOMEDS::Study_ptr GetCurrentStudy(); + + // **************************************************** + // Interface inherited methods (from SALOMEDS::Driver) + // **************************************************** + + // Save SMESH data + SALOMEDS::TMPFile* Save (SALOMEDS::SComponent_ptr theComponent, + const char* theURL, + bool isMultiFile); + // Load SMESH data + bool Load (SALOMEDS::SComponent_ptr theComponent, + const SALOMEDS::TMPFile& theStream, + const char* theURL, + bool isMultiFile); + + // Save SMESH data in ASCII format + SALOMEDS::TMPFile* SaveASCII (SALOMEDS::SComponent_ptr theComponent, + const char* theURL, + bool isMultiFile); + // Load SMESH data in ASCII format + bool LoadASCII (SALOMEDS::SComponent_ptr theComponent, + const SALOMEDS::TMPFile& theStream, + const char* theURL, + bool isMultiFile); + + // Clears study-connected data when it is closed + void Close (SALOMEDS::SComponent_ptr theComponent); + + // Get component data type + char* ComponentDataType(); + + // Transform data from transient form to persistent + char* IORToLocalPersistentID (SALOMEDS::SObject_ptr theSObject, + const char* IORString, + CORBA::Boolean isMultiFile, + CORBA::Boolean isASCII); + // Transform data from persistent form to transient + char* LocalPersistentIDToIOR (SALOMEDS::SObject_ptr theSObject, + const char* aLocalPersistentID, + CORBA::Boolean isMultiFile, + CORBA::Boolean isASCII); + + // Returns true if object can be published in the study + bool CanPublishInStudy (CORBA::Object_ptr theIOR); + // Publish object in the study + SALOMEDS::SObject_ptr PublishInStudy (SALOMEDS::Study_ptr theStudy, + SALOMEDS::SObject_ptr theSObject, + CORBA::Object_ptr theObject, + const char* theName) + throw (SALOME::SALOME_Exception); + + // Copy-paste methods - returns true if object can be copied to the clipboard + CORBA::Boolean CanCopy (SALOMEDS::SObject_ptr theObject) { return false; } + // Copy-paste methods - copy object to the clipboard + SALOMEDS::TMPFile* CopyFrom (SALOMEDS::SObject_ptr theObject, CORBA::Long& theObjectID) { return false; } + // Copy-paste methods - returns true if object can be pasted from the clipboard + CORBA::Boolean CanPaste (const char* theComponentName, CORBA::Long theObjectID) { return false; } + // Copy-paste methods - paste object from the clipboard + SALOMEDS::SObject_ptr PasteInto (const SALOMEDS::TMPFile& theStream, + CORBA::Long theObjectID, + SALOMEDS::SObject_ptr theObject) + { + SALOMEDS::SObject_var aResultSO; + return aResultSO._retn(); + } + + // ============ + // Dump python + // ============ + + virtual Engines::TMPFile* DumpPython (CORBA::Object_ptr theStudy, + CORBA::Boolean isPublished, + CORBA::Boolean& isValidScript); + + void AddToPythonScript (int theStudyID, std::string theString); + +private: + std::string DumpPython_impl (int theStudyID, + bool isPublished, + bool& aValidScript, + std::string theSavedTrace); + + std::string GetNewPythonLines (int theStudyID); + void CleanPythonTrace (int theStudyID); + void SavePython (SALOMEDS::Study_ptr theStudy); + +private: + // Current study + SALOMEDS::Study_var myCurrentStudy; + // Dump Python: trace of API methods calls + std::map < int, std::vector > myPythonScripts; + // Tmp directory. Used by Persistence. + std::string myTmpDir; }; diff --git a/src/MULTIPRGUI/MULTIPR_GUI.cxx b/src/MULTIPRGUI/MULTIPR_GUI.cxx index d74519e..52aedb9 100644 --- a/src/MULTIPRGUI/MULTIPR_GUI.cxx +++ b/src/MULTIPRGUI/MULTIPR_GUI.cxx @@ -21,21 +21,27 @@ #include "MULTIPR_Utils.hxx" // Salome Includes -#include -#include -#include #include #include #include #include + #include #include #include #include + #include #include +#include +#include +#include + #include +#include + +#include #include @@ -58,7 +64,8 @@ #include #include #include - +#include +#include #include @@ -69,13 +76,70 @@ using namespace std; // Global variable //***************************************************************************** -namespace multipr +//namespace multipr +//{ +// // progress callback used by the MULTIPR library +// extern MULTIPR_ProgressCallback* gProgressCallback; +// extern MULTIPR_EmptyMeshCallback* gEmptyMeshCallback; +//} +class MULTIPR_GUI_FinishSaveEvent: public SALOME_Event { - // progress callback used by the MULTIPR library - extern MULTIPR_ProgressCallback* gProgressCallback; - extern MULTIPR_EmptyMeshCallback* gEmptyMeshCallback; -} + SalomeApp_Application* myApp; + bool myIsError; +public: + MULTIPR_GUI_FinishSaveEvent (SalomeApp_Application* theApp, + bool theIsError) + : myApp(theApp), + myIsError(theIsError) + {} + virtual void Execute() + { + if (myIsError) { + SUIT_MessageBox::error1(myApp->desktop(), + "Save distributed MED file error", + "Error while writing distributed MED file", + myApp->tr("MULTIPR_BUT_OK")); + } + else { + myApp->updateObjectBrowser(); + } + QApplication::restoreOverrideCursor(); + } +}; +class MULTIPR_GUI_SaveThread : public QThread +{ +public: + MULTIPR_GUI_SaveThread (MULTIPR_GUI* pModule, + MULTIPR_ORB::MULTIPR_Obj_ptr pObj, + QString pPath) + : mModule(pModule) + { + mObj = MULTIPR_ORB::MULTIPR_Obj::_duplicate(pObj); + mPath = pPath; + } + virtual void run(); + +private: + MULTIPR_GUI* mModule; + MULTIPR_ORB::MULTIPR_Obj_ptr mObj; + QString mPath; +}; + +void MULTIPR_GUI_SaveThread::run() +{ + try + { + mObj->save(mPath); + } + catch(...) + { + ProcessVoidEvent(new MULTIPR_GUI_FinishSaveEvent(mModule->getApp(), true)); + return; + } + + ProcessVoidEvent(new MULTIPR_GUI_FinishSaveEvent(mModule->getApp(), false)); +} //***************************************************************************** // Global function @@ -88,12 +152,19 @@ MULTIPR_ORB::MULTIPR_Gen_ptr GetMultiprGen(const CAM_Module* theModule) if (!aGen) { - SALOME_LifeCycleCORBA aLCC(SalomeApp_Application::namingService()); + SALOME_LifeCycleCORBA aLCC (SalomeApp_Application::namingService()); Engines::Component_var aComponent = aLCC.FindOrLoad_Component("FactoryServer", "MULTIPR"); aGen = MULTIPR_ORB::MULTIPR_Gen::_narrow(aComponent); if (!CORBA::is_nil(aGen)) { - //aGen->SetCurrentStudy(GetDSStudy(GetCStudy(GetAppStudy(theModule)))); + // Set current study + SalomeApp_Study* aSAStudy = + dynamic_cast(theModule->application()->activeStudy()); + _PTR(Study) aStudy = aSAStudy->studyDS(); + SALOMEDS::Study_ptr aStudyDS; + if (aStudy) + aStudyDS = _CAST(Study,aStudy)->GetStudy(); + aGen->SetCurrentStudy(aStudyDS); } } @@ -108,10 +179,14 @@ MULTIPR_ORB::MULTIPR_Gen_ptr GetMultiprGen(const CAM_Module* theModule) // Class MULTIPR_GUI implementation //***************************************************************************** -MULTIPR_GUI::MULTIPR_GUI() : SalomeApp_Module("MULTIPR") +MULTIPR_GUI::MULTIPR_GUI() + : SalomeApp_Module("MULTIPR"), + mMULTIPRObj(NULL), + mMEDFileName(""), + mProgress(NULL) { - mMEDFileName = ""; - mMULTIPRObj = NULL; + mTimer = new QTimer (this); + connect(mTimer, SIGNAL(timeout()), this, SLOT(timerDone())); } @@ -129,6 +204,10 @@ MULTIPR_ORB::MULTIPR_Obj_ptr MULTIPR_GUI::getMULTIPRObj() return mMULTIPRObj; } +void MULTIPR_GUI::setMULTIPRObj (MULTIPR_ORB::MULTIPR_Obj_ptr theObj) +{ + mMULTIPRObj = MULTIPR_ORB::MULTIPR_Obj::_duplicate(theObj); +} SalomeApp_Application* MULTIPR_GUI::getAppli() const { @@ -253,11 +332,13 @@ void MULTIPR_GUI::initialize(CAM_Application* app) //------------------------------------------------------------------------- // set progress dialog //------------------------------------------------------------------------- - MULTIPR_GUI_ProgressCallbackDlg* progressDlg = new MULTIPR_GUI_ProgressCallbackDlg(application()->desktop()); - multipr::gProgressCallback = progressDlg; + //MULTIPR_GUI_ProgressCallbackDlg* progressDlg = + // new MULTIPR_GUI_ProgressCallbackDlg(application()->desktop()); + //multipr::gProgressCallback = progressDlg; - MULTIPR_GUI_EmptyMeshCallbackDlg* emptyMeshDlg = new MULTIPR_GUI_EmptyMeshCallbackDlg(application()->desktop()); - multipr::gEmptyMeshCallback = emptyMeshDlg; + //MULTIPR_GUI_EmptyMeshCallbackDlg* emptyMeshDlg = + // new MULTIPR_GUI_EmptyMeshCallbackDlg(application()->desktop()); + //multipr::gEmptyMeshCallback = emptyMeshDlg; } @@ -273,7 +354,6 @@ QString MULTIPR_GUI::engineIOR() const return QString(anIOR.in()); } - bool MULTIPR_GUI::activateModule(SUIT_Study* theStudy) { bool bOk = SalomeApp_Module::activateModule(theStudy); @@ -361,10 +441,17 @@ void MULTIPR_GUI::OnImportFromMEDFile() mMEDFileName = aFileInfo.filePath(); QApplication::setOverrideCursor(Qt::waitCursor); + + // Delete previous MULTIPR object. + if (mMULTIPRObj != NULL) + { + mMULTIPRObj->reset(); + } + + MULTIPR_ORB::MULTIPR_Gen_ptr multiprgen = GetMultiprGen(this); try { - MULTIPR_ORB::MULTIPR_Gen_ptr multiprgen = GetMultiprGen(this); mMULTIPRObj = multiprgen->getObject(mMEDFileName.latin1()); } catch(...) @@ -379,18 +466,26 @@ void MULTIPR_GUI::OnImportFromMEDFile() if (mMULTIPRObj != NULL) { + SALOMEDS::SObject_ptr aSObject = SALOMEDS::SObject::_nil(); + SalomeApp_Study* aSAStudy = dynamic_cast(getApp()->activeStudy()); + _PTR(Study) aStudyDSClient = aSAStudy->studyDS(); + SALOMEDS::Study_ptr aStudyDS = _CAST(Study,aStudyDSClient)->GetStudy(); + multiprgen->PublishInStudy(aStudyDS, aSObject, mMULTIPRObj, "Mesh"); + try { if (mMULTIPRObj->isValidSequentialMEDFile()) { OnPartition1(); } + else + { + getApp()->updateObjectBrowser(); + } } catch (...) { } - - getApp()->updateObjectBrowser(); } } @@ -402,10 +497,51 @@ void MULTIPR_GUI::OnPartition1() { return; } - + + // do the partition. MULTIPR_GUI_Partition1Dlg* dialog = new MULTIPR_GUI_Partition1Dlg(this); dialog->exec(); delete dialog; + + // Now we need to save the file. + SalomeApp_CheckFileDlg* fd = new SalomeApp_CheckFileDlg( + this->application()->desktop(), + true, + tr("") ); + + fd->setCaption(tr("Save distributed MED file - Destination directory")); + fd->setMode(QFileDialog::DirectoryOnly); + + if (fd->exec() == QDialog::Rejected) + { + delete fd; + mMULTIPRObj->reset(); + getApp()->updateObjectBrowser(); + return; + } + + QFileInfo aFileInfo(fd->selectedFile()); + delete fd; + + QString path = aFileInfo.filePath(); + + QApplication::setOverrideCursor(Qt::waitCursor); + mMULTIPRObj->resetSaveProgress(); + + MULTIPR_GUI_SaveThread* a = new MULTIPR_GUI_SaveThread (this, mMULTIPRObj, path); + a->start(); + + // save progress + //mProgress = new MULTIPR_GUI_ProgressCallbackDlg (getApp()->desktop()); + //mProgress->start("Save mesh", 100); + if (mProgress == NULL) + mProgress = new QProgressDialog ("Save mesh", "Cancel", /*totalSteps*/100, getApp()->desktop()); + //mProgress->setProgress(0); + //mProgress->init(100); + //mTimer->start(500); // 0.5 seconds timer + //QApplication::restoreOverrideCursor(); + //getApp()->updateObjectBrowser(); + } @@ -460,12 +596,24 @@ void MULTIPR_GUI::OnDecimate() tr("MULTIPR_BUT_OK") ); return; } - + if (!removeLowerResolution()) { return; } - + const QStringList& partsList = this->getSelectedParts(); + QString allParts = partsList.join("|"); + MULTIPR_ORB::string_array* listFields = this->getMULTIPRObj()->getFields(allParts.latin1()); + if (listFields->length() == 0) + { + SUIT_MessageBox::error1( + this->getAppli()->desktop(), + "Decimation error", + "No field for this part.", + tr("OK") ); + return ; + } + MULTIPR_GUI_DecimateDlg* dialog = new MULTIPR_GUI_DecimateDlg(this); dialog->exec(); delete dialog; @@ -558,25 +706,32 @@ void MULTIPR_GUI::OnSave() QString path = aFileInfo.filePath(); QApplication::setOverrideCursor(Qt::waitCursor); + mMULTIPRObj->resetSaveProgress(); + MULTIPR_GUI_SaveThread* a = new MULTIPR_GUI_SaveThread (this, mMULTIPRObj, path); + a->start(); - try - { - mMULTIPRObj->save(path); - getApp()->updateObjectBrowser(); - } - catch(...) - { - SUIT_MessageBox::error1( - getApp()->desktop(), - "Save distributed MED file error", - "Error while writing distributed MED file", - tr("MULTIPR_BUT_OK") ); - } - + // save progress + //mProgress = new MULTIPR_GUI_ProgressCallbackDlg (getApp()->desktop()); + //mProgress->start("Save mesh", 100); + if (mProgress == NULL) + mProgress = new QProgressDialog ("Save mesh", "Cancel", /*totalSteps*/100, getApp()->desktop()); + //mProgress->setProgress(0); + //mProgress->init(100); + mTimer->start(500); // 0.5 seconds timer QApplication::restoreOverrideCursor(); } +void MULTIPR_GUI::timerDone() +{ + int progress = mMULTIPRObj->getSaveProgress(); + if (mProgress != NULL) { + mProgress->setProgress(progress); + if (progress >= 100) { + mTimer->stop(); + } + } +} void MULTIPR_GUI::retrieveSelectedParts() { @@ -911,98 +1066,175 @@ QString MULTIPR_GUI_DataObject_Resolution::toolTip() const // Data Model //***************************************************************************** -MULTIPR_GUI_DataModel::MULTIPR_GUI_DataModel(CAM_Module* module) : - LightApp_DataModel(module) +MULTIPR_GUI_DataModel::MULTIPR_GUI_DataModel(CAM_Module* module) + //: LightApp_DataModel(module) + : SalomeApp_DataModel(module) { mMULTIPR_GUI = dynamic_cast(module); } - MULTIPR_GUI_DataModel::~MULTIPR_GUI_DataModel() { // do nothing! } +void MULTIPR_GUI_DataModel::update (LightApp_DataObject*, LightApp_Study* theStudy) +{ + LightApp_ModuleObject* modelRoot = dynamic_cast( root() ); + DataObjectList ch; + QMap aMap; + if( modelRoot ) + { + ch = modelRoot->children(); + for ( DataObjectListIterator it( ch ); it.current(); ++it ) + it.current()->setParent( 0 ); + } + + buildAll(theStudy); + + modelRoot = dynamic_cast( root() ); + if( modelRoot ) + { + DataObjectList new_ch = modelRoot->children(); + for ( DataObjectListIterator it1( new_ch ); it1.current(); ++it1 ) + aMap.insert( it1.current(), 0 ); + } + + updateWidgets(); + + for( DataObjectListIterator it( ch ); it.current(); ++it ) + if( !aMap.contains( it.current() ) ) + delete it.current(); +} + void MULTIPR_GUI_DataModel::build() { - try +} + +void MULTIPR_GUI_DataModel::buildAll (LightApp_Study* theStudy) +{ + try + { + SalomeApp_Study* aSAStudy = dynamic_cast(theStudy); + if (!aSAStudy) + aSAStudy = dynamic_cast(getModule()->getApp()->activeStudy()); + + if (!aSAStudy) return; + + MULTIPR_GUI_DataObject_Module* modelRoot = dynamic_cast(root()); + if (!modelRoot) + { + // root is not set yet + modelRoot = new MULTIPR_GUI_DataObject_Module(this, NULL, "MULTIPR"); + setRoot(modelRoot); + } + + // find SObject in Study + _PTR(SComponent) aSComp = aSAStudy->studyDS()->FindComponent(module()->name()); + if (aSComp) { - MULTIPR_GUI_DataObject_Module* modelRoot = dynamic_cast(root()); - - if (!modelRoot) - { - // root is not set yet - modelRoot = new MULTIPR_GUI_DataObject_Module(this, NULL, "MULTIPR"); - setRoot(modelRoot); - } - - MULTIPR_ORB::MULTIPR_Obj_ptr obj = mMULTIPR_GUI->getMULTIPRObj(); - - if (obj != NULL) + // remove Data Objects, automatically built for not loaded MULTIPR module + // by SalomeApp_Application::updateObjectBrowser + if (aSAStudy->root()) + { + DataObjectList ch_comp; + aSAStudy->root()->children(ch_comp); + DataObjectList::const_iterator anIt_comp = ch_comp.begin(), aLast_comp = ch_comp.end(); + for (; anIt_comp != aLast_comp; anIt_comp++) { - MULTIPR_ORB::string_array* listParts = obj->getParts(); - - if (listParts->length() >= 1) - { - const char* strPartName0 = (*listParts)[0]; - char* strPartInfo0 = obj->getPartInfo(strPartName0); - - char lMeshName[256]; - int lId; - char lPartName[256]; - char lPath[256]; - char lMEDFileName[256]; - - // parse infos - int ret = sscanf(strPartInfo0, "%s %d %s %s %s", - lMeshName, - &lId, - lPartName, - lPath, - lMEDFileName); - - if (ret != 5) - { - cout << "MULTIPR: build() tree; error while parsing part info" << endl; - std::runtime_error("MULTIPR: build() tree; error while parsing part info"); - return; - } - - MULTIPR_GUI_DataObject_Mesh* dataObjectMesh = new MULTIPR_GUI_DataObject_Mesh(modelRoot, lMeshName); - - MULTIPR_GUI_DataObject_Part* dataObjectPart_prev = NULL; - - for (int i = 0 ; i < listParts->length() ; i++) - { - const char* strItem = (*listParts)[i]; - char* strPartInfo = obj->getPartInfo(strItem); - - // parse infos - int ret = sscanf(strPartInfo, "%s %d %s %s %s", - lMeshName, - &lId, - lPartName, - lPath, - lMEDFileName); - - if (ret != 5) return; - - if ((strstr(lPartName,"_MED") != NULL) || (strstr(lPartName,"_LOW") != NULL)) - { - new MULTIPR_GUI_DataObject_Resolution(dataObjectPart_prev, strItem, strPartInfo); - } - else - { - dataObjectPart_prev = new MULTIPR_GUI_DataObject_Part(dataObjectMesh, strItem, strPartInfo); - } - } - } + LightApp_DataObject* dobj = dynamic_cast(*anIt_comp); + if (dobj && dobj->name() == aSComp->GetName().c_str()) + { + //SalomeApp_DataModelSync sync (aSAStudy->studyDS(), aSAStudy->root()); + //sync.deleteItemWithChildren(dobj); + DataObjectList ch_obj; + dobj->children(ch_obj); + DataObjectList::const_iterator anIt_obj = ch_obj.begin(), aLast_obj = ch_obj.end(); + for (; anIt_obj != aLast_obj; anIt_obj++) + // delete data object of each SObject + delete (*anIt_obj); + + // delete data object of SComponent itself + delete dobj; + break; + } } + } } - catch (...) + + MULTIPR_ORB::MULTIPR_Obj_ptr obj = mMULTIPR_GUI->getMULTIPRObj(); + if (obj != NULL) { + // MED file object + std::string lMEDFile = obj->getFilename(); + std::string lMEDFileName = multipr::getFilenameWithoutPath(lMEDFile.c_str()); + MULTIPR_GUI_DataObject_Mesh* dataObjectMED = + new MULTIPR_GUI_DataObject_Mesh(modelRoot, lMEDFileName.c_str()); + + // MESH object + MULTIPR_ORB::string_array* listParts = obj->getParts(); + + if (listParts->length() >= 1) + { + const char* strPartName0 = (*listParts)[0]; + char* strPartInfo0 = obj->getPartInfo(strPartName0); + char lMeshName[256]; + int lId; + char lPartName[256]; + char lPath[256]; + char lMEDFileName[256]; + + // parse infos + int ret = sscanf(strPartInfo0, "%s %d %s %s %s", + lMeshName, + &lId, + lPartName, + lPath, + lMEDFileName); + + if (ret != 5) + { + cout << "MULTIPR: build() tree; error while parsing part info" << endl; + std::runtime_error("MULTIPR: build() tree; error while parsing part info"); + return; + } + + MULTIPR_GUI_DataObject_Mesh* dataObjectMesh = + new MULTIPR_GUI_DataObject_Mesh(dataObjectMED, lMeshName); + + // PART and RESOLUTION objects + MULTIPR_GUI_DataObject_Part* dataObjectPart_prev = NULL; + + for (int i = 0 ; i < listParts->length() ; i++) + { + const char* strItem = (*listParts)[i]; + char* strPartInfo = obj->getPartInfo(strItem); + // parse infos + int ret = sscanf(strPartInfo, "%s %d %s %s %s", + lMeshName, + &lId, + lPartName, + lPath, + lMEDFileName); + + if (ret != 5) return; + + if ((strstr(lPartName,"_MED") != NULL) || (strstr(lPartName,"_LOW") != NULL)) + { + new MULTIPR_GUI_DataObject_Resolution(dataObjectPart_prev, strItem, strPartInfo); + } + else + { + dataObjectPart_prev = new MULTIPR_GUI_DataObject_Part(dataObjectMesh, strItem, strPartInfo); + } + } + } } + } + catch (...) + { + } } diff --git a/src/MULTIPRGUI/MULTIPR_GUI.h b/src/MULTIPRGUI/MULTIPR_GUI.h index bab9f4a..fec3818 100644 --- a/src/MULTIPRGUI/MULTIPR_GUI.h +++ b/src/MULTIPRGUI/MULTIPR_GUI.h @@ -21,7 +21,8 @@ #include #include -#include +//#include +#include #include #include CORBA_CLIENT_HEADER(MULTIPR) @@ -47,6 +48,9 @@ class QLineEdit; class QSpinBox; class QPushButton; +class QTimer; +//class MULTIPR_GUI_ProgressCallbackDlg; +class QProgressDialog; //***************************************************************************** // Class MULTIPR_GUI @@ -70,6 +74,7 @@ public: void windows(QMap&) const; MULTIPR_ORB::MULTIPR_Obj_ptr getMULTIPRObj(); + void setMULTIPRObj (MULTIPR_ORB::MULTIPR_Obj_ptr theObj); SalomeApp_Application* getAppli() const; @@ -90,7 +95,9 @@ protected slots: void OnDecimate(); void OnRemove(); void OnSave(); - + + void timerDone(); // update saving progress dialog + protected: virtual CAM_DataModel* createDataModel(); @@ -116,6 +123,10 @@ private: QStringList mSelectedParts; MULTIPR_ORB::MULTIPR_Obj_ptr mMULTIPRObj; + QProgressDialog* mProgress; + //MULTIPR_GUI_ProgressCallbackDlg* mProgress; + QTimer* mTimer; + }; // class MULTIPR_GUI @@ -223,16 +234,20 @@ public: // Class MULTIPR_GUI_DataModel //***************************************************************************** -class MULTIPR_GUI_DataModel : public LightApp_DataModel +//class MULTIPR_GUI_DataModel : public LightApp_DataModel +class MULTIPR_GUI_DataModel : public SalomeApp_DataModel { public: MULTIPR_GUI_DataModel(CAM_Module*); virtual ~MULTIPR_GUI_DataModel(); + virtual void update (LightApp_DataObject* = 0, LightApp_Study* = 0); + protected: virtual void build(); + void buildAll (LightApp_Study* = 0); private: diff --git a/src/MULTIPRGUI/MULTIPR_GUI_Dlg.cxx b/src/MULTIPRGUI/MULTIPR_GUI_Dlg.cxx index 0e2667b..8e9ed50 100644 --- a/src/MULTIPRGUI/MULTIPR_GUI_Dlg.cxx +++ b/src/MULTIPRGUI/MULTIPR_GUI_Dlg.cxx @@ -46,6 +46,11 @@ #include #include +// MED include +extern "C" +{ + #include "med.h" +} using namespace std; @@ -227,7 +232,7 @@ void MULTIPR_GUI_Partition2Dlg::accept() { const QString& partName = (*it); //cout << "Split " << partName.latin1() << " #parts=" << nbParts << " splitter=" << strSplitter << endl; - mModule->getMULTIPRObj()->partitionneGrain(partName.latin1(), nbParts, partitionner); + mModule->getMULTIPRObj()->partitionneGroupe(partName.latin1(), nbParts, partitionner); } } @@ -259,9 +264,8 @@ MULTIPR_GUI_DecimateDlg::MULTIPR_GUI_DecimateDlg(MULTIPR_GUI* theModule) : WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu) { mModule = theModule; - buttonGroupSelectField = new QButtonGroup( this, "buttonGroupSelectField" ); - buttonGroupSelectField->setGeometry( QRect( 10, 10, 450, 140 ) ); + buttonGroupSelectField->setGeometry( QRect( 10, 10, 710, 140 ) ); textLabelSelectFieldName = new QLabel( buttonGroupSelectField, "textLabelSelectFieldName" ); textLabelSelectFieldName->setGeometry( QRect( 30, 30, 141, 31 ) ); @@ -269,27 +273,34 @@ MULTIPR_GUI_DecimateDlg::MULTIPR_GUI_DecimateDlg(MULTIPR_GUI* theModule) : textLabelSelectFieldIteration = new QLabel( buttonGroupSelectField, "textLabelSelectFieldIteration" ); textLabelSelectFieldIteration->setGeometry( QRect( 30, 80, 111, 31 ) ); - MULTIPR_ORB::string_array* listFields = theModule->getMULTIPRObj()->getFields(); + const QStringList& partsList = mModule->getSelectedParts(); + // Lets get the fields !. + QString allParts = partsList.join("|"); + MULTIPR_ORB::string_array* listFields = theModule->getMULTIPRObj()->getFields(allParts.latin1()); int maxIteration = 0; - for (int i=0 ; ilength() ; i++) + int i, j; + for (i = 0 ; i < listFields->length() ; ++i) { - const char* strItem = (*listFields)[i]; - CORBA::Long nbIteration = theModule->getMULTIPRObj()->getTimeStamps(strItem); + char* strItem = (*listFields)[i]; + for (j = 0; strItem[j] && strItem[j] != ' '; ++j); + strItem[j] = 0; + CORBA::Long nbIteration = theModule->getMULTIPRObj()->getTimeStamps(allParts.latin1(), strItem); + strItem[j] = ' '; if (nbIteration > maxIteration) { maxIteration = nbIteration; } } - + comboBoxSelectFieldIteration = new QComboBox( FALSE, buttonGroupSelectField, "comboBoxSelectFieldIteration" ); - comboBoxSelectFieldIteration->setGeometry( QRect( 150, 80, 280, 40 ) ); + comboBoxSelectFieldIteration->setGeometry( QRect( 150, 80, 540, 40 ) ); for (int i=1 ; i<=maxIteration ; i++) { comboBoxSelectFieldIteration->insertItem(QString::number(i)); } comboBoxSelectFieldName = new QComboBox( FALSE, buttonGroupSelectField, "comboBoxSelectFieldName" ); - comboBoxSelectFieldName->setGeometry( QRect( 150, 30, 280, 40 ) ); + comboBoxSelectFieldName->setGeometry( QRect( 150, 30, 540, 40 ) ); for (int i=0 ; ilength() ; i++) { const char* strItem = (*listFields)[i]; @@ -299,17 +310,18 @@ MULTIPR_GUI_DecimateDlg::MULTIPR_GUI_DecimateDlg(MULTIPR_GUI* theModule) : QToolTip::add( comboBoxSelectFieldName, tr( "only scalar fields are listed (multi-component fields are not displayed)" ) ); buttonGroupSelectFilter = new QButtonGroup( this, "buttonGroupSelectFilter" ); - buttonGroupSelectFilter->setGeometry( QRect( 10, 160, 450, 90 ) ); + buttonGroupSelectFilter->setGeometry( QRect( 10, 160, 710, 90 ) ); textLabelSelectFilter = new QLabel( buttonGroupSelectFilter, "textLabelSelectFilter" ); textLabelSelectFilter->setGeometry( QRect( 30, 30, 101, 31 ) ); comboBoxSelectFilter = new QComboBox( FALSE, buttonGroupSelectFilter, "comboBoxSelectFilter" ); - comboBoxSelectFilter->setGeometry( QRect( 150, 30, 280, 40 ) ); + comboBoxSelectFilter->setGeometry( QRect( 150, 30, 540, 40 ) ); comboBoxSelectFilter->insertItem("Filtre_GradientMoyen"); + comboBoxSelectFilter->insertItem("Filtre_Direct"); buttonGroupParameters = new QButtonGroup( this, "buttonGroupParameters" ); - buttonGroupParameters->setGeometry( QRect( 10, 260, 450, 210 ) ); + buttonGroupParameters->setGeometry( QRect( 10, 260, 710, 210 ) ); textLabelTMed = new QLabel( buttonGroupParameters, "textLabelTMed" ); textLabelTMed->setGeometry( QRect( 20, 40, 242, 30 ) ); @@ -324,29 +336,54 @@ MULTIPR_GUI_DecimateDlg::MULTIPR_GUI_DecimateDlg(MULTIPR_GUI* theModule) : textLabelBoxing->setGeometry( QRect( 20, 160, 241, 30 ) ); lineEditTMed = new QLineEdit( buttonGroupParameters, "lineEditTMed" ); - lineEditTMed->setGeometry( QRect( 320, 40, 111, 30 ) ); + lineEditTMed->setGeometry( QRect( 580, 40, 111, 30 ) ); lineEditTLow = new QLineEdit( buttonGroupParameters, "lineEditTLow" ); - lineEditTLow->setGeometry( QRect( 320, 80, 111, 30 ) ); + lineEditTLow->setGeometry( QRect( 580, 80, 111, 30 ) ); lineEditRadius = new QLineEdit( buttonGroupParameters, "lineEditRadius" ); - lineEditRadius->setGeometry( QRect( 320, 120, 111, 30 ) ); + lineEditRadius->setGeometry( QRect( 580, 120, 111, 30 ) ); spinBoxBoxing = new QSpinBox( buttonGroupParameters, "spinBoxBoxing" ); - spinBoxBoxing->setGeometry( QRect( 320, 160, 111, 30 ) ); + spinBoxBoxing->setGeometry( QRect( 580, 160, 111, 30 ) ); spinBoxBoxing->setMaxValue( 200 ); spinBoxBoxing->setMinValue( 2 ); spinBoxBoxing->setValue( 100 ); QToolTip::add( spinBoxBoxing, tr( "grid: number of cells along each axis" ) ); + infoGroup = new QButtonGroup(this, "infoGroup"); + infoGroup->setGeometry( QRect( 10, 480, 710, 60 ) ); + + char* stats; + int tmp; + // Accumulator used to display the number of meshes in the current selection. + int acum = 0; + for (QStringList::const_iterator it = partsList.begin(), last = partsList.end(); it != last; it++) + { + const QString& partName = (*it); + stats = theModule->getMULTIPRObj()->getMEDInfo(partName.latin1()); + sscanf(stats, "%d", &tmp); + acum += tmp; + } + + char buf[512]; + sprintf(buf, "%d", acum); + textLabelInfo = new QLabel( infoGroup, "textLabelInfo"); + textLabelInfo->setText("Number of cells:"); + textLabelInfo->setGeometry( QRect( 20, 10, 242, 30 ) ); + textLabelInfoValue = new QLabel( infoGroup, "textLabelInfoValue"); + textLabelInfoValue->setAlignment(AlignRight); + textLabelInfoValue->setText(buf); + textLabelInfoValue->setGeometry( QRect( 400, 10, 290, 30 ) ); + buttonGroupProcess = new QButtonGroup( this, "buttonGroupProcess" ); - buttonGroupProcess->setGeometry( QRect( 10, 480, 450, 60 ) ); + buttonGroupProcess->setGeometry( QRect( 10, 580, 710, 60 ) ); pushButtonOK = new QPushButton( buttonGroupProcess, "pushButtonOK" ); pushButtonOK->setGeometry( QRect( 10, 10, 110, 41 ) ); pushButtonCancel = new QPushButton( buttonGroupProcess, "pushButtonCancel" ); - pushButtonCancel->setGeometry( QRect( 321, 10, 110, 41 ) ); + pushButtonCancel->setGeometry( QRect( 581, 10, 110, 41 ) ); pushButtonCancel->setAccel( QKeySequence( tr( "Esc" ) ) ); setCaption( tr( "Decimation" ) ); @@ -370,7 +407,7 @@ MULTIPR_GUI_DecimateDlg::MULTIPR_GUI_DecimateDlg(MULTIPR_GUI* theModule) : pushButtonOK->setText( tr("OK") ); pushButtonThresholdAuto = new QPushButton( buttonGroupParameters, "pushButtonThresholdAuto" ); - pushButtonThresholdAuto->setGeometry( QRect( 260, 80, 50, 30 ) ); + pushButtonThresholdAuto->setGeometry( QRect( 520, 80, 50, 30 ) ); QFont pushButtonThresholdAuto_font( pushButtonThresholdAuto->font() ); pushButtonThresholdAuto_font.setPointSize( 11 ); pushButtonThresholdAuto->setFont( pushButtonThresholdAuto_font ); @@ -378,20 +415,21 @@ MULTIPR_GUI_DecimateDlg::MULTIPR_GUI_DecimateDlg(MULTIPR_GUI* theModule) : QToolTip::add( pushButtonThresholdAuto, tr( "compute extremum for gradient (set medium=MIN and low=MAX)" ) ); pushButtonRadiusAuto = new QPushButton( buttonGroupParameters, "pushButtonRadiusAuto" ); - pushButtonRadiusAuto->setGeometry( QRect( 260, 120, 50, 30 ) ); + pushButtonRadiusAuto->setGeometry( QRect( 520, 120, 50, 30 ) ); QFont pushButtonRadiusAuto_font( pushButtonRadiusAuto->font() ); pushButtonRadiusAuto_font.setPointSize( 11 ); pushButtonRadiusAuto->setFont( pushButtonRadiusAuto_font ); pushButtonRadiusAuto->setText( tr( "auto" ) ); QToolTip::add( pushButtonRadiusAuto, tr( "set radius automatically (average #neighbours equal to 8)" ) ); - resize( QSize(470, 554).expandedTo(minimumSizeHint()) ); + resize( QSize(730, 654).expandedTo(minimumSizeHint()) ); clearWState( WState_Polished ); connect(pushButtonOK, SIGNAL(clicked()), this, SLOT(accept())); connect(pushButtonCancel, SIGNAL(clicked()), this, SLOT(reject())); connect(pushButtonRadiusAuto, SIGNAL(clicked()), this, SLOT(OnRadiusAuto())); connect(pushButtonThresholdAuto, SIGNAL(clicked()), this, SLOT(OnThresholdAuto())); + connect(comboBoxSelectFilter, SIGNAL(activated (const QString &)), this, SLOT(selectField(const QString &))); } @@ -405,11 +443,87 @@ MULTIPR_GUI_DecimateDlg::~MULTIPR_GUI_DecimateDlg() void MULTIPR_GUI_DecimateDlg::accept() -{ - const char* strFieldName = comboBoxSelectFieldName->currentText().latin1(); - const char* strFieldIt = comboBoxSelectFieldIteration->currentText().latin1(); - int fieldIteration = atoi(strFieldIt); - +{ + const char* strFieldNameTmp = comboBoxSelectFieldName->currentText().latin1(); + const char* strFieldIt = comboBoxSelectFieldIteration->currentText().latin1(); + int fieldIteration = atoi(strFieldIt); + char strFieldName[MED_TAILLE_NOM + 1]; + const char* filterName = comboBoxSelectFilter->currentText().latin1(); + char params[MULTIPR_GUI_MAX_PARAMS_LENGTH]; + int i; + + // Get the field name. + strncpy(strFieldName, strFieldNameTmp, MED_TAILLE_NOM); + strFieldName[MED_TAILLE_NOM] = '\0'; + for (i = 0; strFieldName[i] && strFieldName[i] != ' '; ++i); + strFieldName[i] = 0; + + // Fill the corresponding filter parameters string. + if (strcmp(filterName, "Filtre_GradientMoyen") == 0) + { + if (this->setGradAvgFilterParams(params) == false) + { + return ; + } + } + else if (strcmp(filterName, "Filtre_Direct") == 0) + { + if (this->setDirectFilterParams(params) == false) + { + return ; + } + } + else + { + SUIT_MessageBox::error1( + mModule->getAppli()->desktop(), + "Decimation error", + "Unknown filter name.", + tr("OK") ); + } + + QApplication::setOverrideCursor(Qt::waitCursor); + MULTIPR_ORB::string_array* list = NULL; + try + { + const QStringList& partsList = mModule->getSelectedParts(); + for (QStringList::const_iterator it = partsList.begin(), last = partsList.end(); it != last; it++) + { + const QString& partName = (*it); + + list = mModule->getMULTIPRObj()->decimePartition( + partName.latin1(), + strFieldName, + fieldIteration, + filterName, + params); + } + } + catch(...) + { + SUIT_MessageBox::error1( + mModule->getAppli()->desktop(), + "Decimation error", + "Error while decimating selected part(s)", + tr("OK") ); + } + if (list != NULL && list->length() >= 4) + { + const char* rate = (*list)[list->length() - 1]; + SUIT_MessageBox::info1( + mModule->getAppli()->desktop(), + "Compression rate", + rate, + tr("OK") ); + } + QApplication::restoreOverrideCursor(); + QDialog::accept(); +} + +bool MULTIPR_GUI_DecimateDlg::setGradAvgFilterParams(char* pParams) +{ + int boxing = spinBoxBoxing->value(); + double thresholdMed; int ret = sscanf(lineEditTMed->text().latin1(), "%lf", &thresholdMed); if ((ret != 1) || (thresholdMed <= 0.0f)) @@ -420,7 +534,7 @@ void MULTIPR_GUI_DecimateDlg::accept() "Invalid medium threshold (should be > 0.0)", tr("OK") ); - return; + return false; } double thresholdLow; @@ -433,7 +547,7 @@ void MULTIPR_GUI_DecimateDlg::accept() "Invalid low threshold (should be > 0.0)", tr("OK") ); - return; + return false; } if (thresholdMed >= thresholdLow) @@ -444,7 +558,7 @@ void MULTIPR_GUI_DecimateDlg::accept() "Medium threshold must be < low threshold", tr("OK") ); - return; + return false; } double radius; @@ -457,43 +571,89 @@ void MULTIPR_GUI_DecimateDlg::accept() "Invalid radius (should be > 0.0)", tr("OK") ); - return; + return false; } - - QApplication::setOverrideCursor(Qt::waitCursor); - - try + + sprintf(pParams, "%lf %lf %lf %d", thresholdMed, thresholdLow, radius, boxing); + + return true; +} + +bool MULTIPR_GUI_DecimateDlg::setDirectFilterParams(char* pParams) +{ + int boxing = spinBoxBoxing->value(); + + double thresholdMed; + int ret = sscanf(lineEditTMed->text().latin1(), "%lf", &thresholdMed); + if (ret != 1) { - const QStringList& partsList = mModule->getSelectedParts(); - for (QStringList::const_iterator it = partsList.begin(), last = partsList.end(); it != last; it++) - { - const QString& partName = (*it); - - mModule->getMULTIPRObj()->setBoxing(spinBoxBoxing->value()); + SUIT_MessageBox::error1( + mModule->getAppli()->desktop(), + "Decimation parameters error", + "Invalid medium threshold.", + tr("OK") ); - mModule->getMULTIPRObj()->decimePartition( - partName.latin1(), - strFieldName, - fieldIteration, - comboBoxSelectFilter->currentText().latin1(), - thresholdMed, - thresholdLow, - radius); - } + return false; } - catch(...) + + double thresholdLow; + ret = sscanf(lineEditTLow->text().latin1(), "%lf", &thresholdLow); + if (ret != 1) { SUIT_MessageBox::error1( mModule->getAppli()->desktop(), - "Decimation error", - "Error while decimating selected part(s)", + "Decimation parameters error", + "Invalid low threshold.", tr("OK") ); + + return false; } - QApplication::restoreOverrideCursor(); - QDialog::accept(); + if (thresholdMed >= thresholdLow) + { + SUIT_MessageBox::error1( + mModule->getAppli()->desktop(), + "Decimation parameters error", + "Medium threshold must be < low threshold", + tr("OK") ); + + return false; + } + + sprintf(pParams, "%lf %lf", thresholdMed, thresholdLow); + + return true; } +void MULTIPR_GUI_DecimateDlg::selectField(const QString& valueText) +{ + if (valueText == "Filtre_GradientMoyen") + { + lineEditRadius->show(); + spinBoxBoxing->show(); + pushButtonRadiusAuto->show(); + textLabelRadius->show(); + textLabelBoxing->show(); + //pushButtonThresholdAuto->show(); + } + else if (valueText == "Filtre_Direct") + { + lineEditRadius->hide(); + spinBoxBoxing->hide(); + pushButtonRadiusAuto->hide(); + textLabelRadius->hide(); + textLabelBoxing->hide(); + //pushButtonThresholdAuto->hide(); + } + else + { + SUIT_MessageBox::error1( + mModule->getAppli()->desktop(), + "Decimation error", + "Unknown filter name.", + tr("OK") ); + } +} void MULTIPR_GUI_DecimateDlg::reject() { @@ -560,7 +720,7 @@ void MULTIPR_GUI_DecimateDlg::OnThresholdAuto() const char* strFieldIt = comboBoxSelectFieldIteration->currentText().latin1(); int fieldIteration = atoi(strFieldIt); char* strPartInfo0 = mModule->getMULTIPRObj()->getPartInfo(partsList[0].latin1()); - + QString filterName = comboBoxSelectFilter->currentText(); char lMeshName[256]; int lId; char lPartName[256]; @@ -576,46 +736,63 @@ void MULTIPR_GUI_DecimateDlg::OnThresholdAuto() lMEDFileName); QApplication::setOverrideCursor(Qt::waitCursor); - - try + if (filterName == "Filtre_GradientMoyen") { - float radius; - ret = sscanf(lineEditRadius->text().latin1(), "%f", &radius); - if ((ret != 1) || (radius <= 0.0f)) + try + { + float radius; + ret = sscanf(lineEditRadius->text().latin1(), "%f", &radius); + if ((ret != 1) || (radius <= 0.0f)) + { + SUIT_MessageBox::error1( + mModule->getAppli()->desktop(), + "Decimation parameters error", + "Invalid radius (should be > 0.0)", + tr("OK") ); + + return; + } + + char strParams[256]; + sprintf(strParams, "1 %f %d", radius, spinBoxBoxing->value()); + + char* res = mModule->getMULTIPRObj()->evalDecimationParams( + lPartName, + comboBoxSelectFieldName->currentText().latin1(), + fieldIteration, + comboBoxSelectFilter->currentText().latin1(), + strParams); + + float gradMin, gradAvg, gradMax; + sscanf(res, "%f %f %f", &gradMin, &gradAvg, &gradMax); + + lineEditTMed->setText( QString::number(gradMin) ); + lineEditTLow->setText( QString::number(gradMax) ); + } + catch (...) { - SUIT_MessageBox::error1( - mModule->getAppli()->desktop(), - "Decimation parameters error", - "Invalid radius (should be > 0.0)", - tr("OK") ); - - return; } - - char strParams[256]; - sprintf(strParams, "1 %f %d", radius, spinBoxBoxing->value()); - - char* res = mModule->getMULTIPRObj()->evalDecimationParams( - lPartName, - comboBoxSelectFieldName->currentText().latin1(), - fieldIteration, - comboBoxSelectFilter->currentText().latin1(), - strParams); - - float gradMin, gradAvg, gradMax; - sscanf(res, "%f %f %f", &gradMin, &gradAvg, &gradMax); - - lineEditTMed->setText( QString::number(gradMin) ); - lineEditTLow->setText( QString::number(gradMax) ); } - catch (...) + else if (filterName == "Filtre_Direct") { + float lMin = 1.0f; + float lMax = 2.0f; + + mModule->getMULTIPRObj()->getFieldMinMax(lPartName, comboBoxSelectFieldName->currentText().latin1(), lMin, lMax); + lineEditTMed->setText(QString::number(lMin)); + lineEditTLow->setText(QString::number(lMax)); } - + else + { + SUIT_MessageBox::error1( + mModule->getAppli()->desktop(), + "Decimation error", + "Unknown filter name.", + tr("OK") ); + } QApplication::restoreOverrideCursor(); } - //***************************************************************************** // MULTIPR_GUI_ProgressCallbackDlg // QT dialog box used to display progress in time consuming task (e.g. save) diff --git a/src/MULTIPRGUI/MULTIPR_GUI_Dlg.h b/src/MULTIPRGUI/MULTIPR_GUI_Dlg.h index 888cad7..6d69464 100644 --- a/src/MULTIPRGUI/MULTIPR_GUI_Dlg.h +++ b/src/MULTIPRGUI/MULTIPR_GUI_Dlg.h @@ -45,7 +45,10 @@ class QPushButton; class MULTIPR_GUI; - +/** + * Max length for filter parameters string. + */ +#define MULTIPR_GUI_MAX_PARAMS_LENGTH 1024 //***************************************************************************** // Class MULTIPR_GUI_Partition1Dlg @@ -143,7 +146,10 @@ public: QPushButton* pushButtonOK; QPushButton* pushButtonThresholdAuto; QPushButton* pushButtonRadiusAuto; - + QButtonGroup* infoGroup; + QLabel* textLabelInfo; + QLabel* textLabelInfoValue; + protected: protected slots: @@ -151,10 +157,25 @@ protected slots: void reject(); void OnRadiusAuto(); void OnThresholdAuto(); + void selectField(const QString & valueText); private: MULTIPR_GUI* mModule; - + + /** + * Create the parameter string for gradient average filter. + * \param pParams The parameter string to fill. + * \return True if the operation is successfull, false otherwise. + */ + bool setGradAvgFilterParams(char* pParams); + + /** + * Create the parameter string for direct filter. + * \param pParams The parameter string to fill. + * \return True if the operation is successfull, false otherwise. + */ + bool setDirectFilterParams(char* pParams); + };