Integration of the PADDER algorithm as a simple SALOME plugin.
The plugin contains: - a SALOME component (C++) - a graphical interface (python) - a plugin_manager.py file for integration The compilation of this package is NOT activated yet because some feature still not work correctly (next week I hope).
@ -39,6 +39,12 @@ salomescriptdir = $(bindir)
|
||||
salomepythondir = $(pythondir)/salome
|
||||
salomepyexecdir = $(pyexecdir)/salome
|
||||
|
||||
# Root directory of the python packages of SMESH
|
||||
smeshpypkgdir = $(salomepythondir)/salome/smesh
|
||||
|
||||
# Directory for installing SALOME plugins files
|
||||
salomepluginsdir = $(prefix)/plugins
|
||||
|
||||
# Directory for installing idl files
|
||||
salomeidldir = $(prefix)/idl/salome
|
||||
|
||||
|
29
configure.ac
@ -301,6 +301,10 @@ if test "${gui_ok}" = "yes"; then
|
||||
echo
|
||||
|
||||
CHECK_QT
|
||||
AC_PATH_PROG(PYUIC, pyuic4)
|
||||
AC_SUBST(PYUIC)
|
||||
AC_PATH_PROG(PYRCC, pyrcc4)
|
||||
AC_SUBST(PYRCC)
|
||||
|
||||
echo
|
||||
echo ---------------------------------------------
|
||||
@ -366,6 +370,14 @@ echo ---------------------------------------------
|
||||
echo
|
||||
CHECK_SPHINX
|
||||
|
||||
echo
|
||||
echo ---------------------------------------------
|
||||
echo testing libxm
|
||||
echo ---------------------------------------------
|
||||
echo
|
||||
dnl Check the libxml that will be required to use the SALOME launcher
|
||||
CHECK_LIBXML
|
||||
|
||||
echo
|
||||
echo ---------------------------------------------
|
||||
echo Testing Kernel
|
||||
@ -520,6 +532,23 @@ AC_OUTPUT([ \
|
||||
src/SMESH_PY/Makefile \
|
||||
src/Tools/Makefile \
|
||||
src/Tools/MeshCut/Makefile \
|
||||
src/Tools/padder/Makefile \
|
||||
src/Tools/padder/meshjob/Makefile \
|
||||
src/Tools/padder/meshjob/idl/Makefile \
|
||||
src/Tools/padder/meshjob/impl/Makefile \
|
||||
src/Tools/padder/spadderpy/Makefile \
|
||||
src/Tools/padder/spadderpy/padder.cfg \
|
||||
src/Tools/padder/spadderpy/gui/Makefile \
|
||||
src/Tools/padder/spadderpy/plugin/Makefile \
|
||||
src/Tools/padder/spadderpy/plugin/envPlugins.sh \
|
||||
src/Tools/padder/resources/Makefile \
|
||||
src/Tools/padder/resources/appligen/Makefile \
|
||||
src/Tools/padder/resources/appligen/appligen.sh \
|
||||
src/Tools/padder/resources/appligen/config_appli.xml \
|
||||
src/Tools/padder/resources/padderexe/Makefile \
|
||||
src/Tools/padder/resources/padderexe/envPadder.sh \
|
||||
src/Tools/padder/unittests/Makefile \
|
||||
src/Tools/padder/unittests/autotest.sh \
|
||||
resources/Makefile \
|
||||
resources/SMESHCatalog.xml \
|
||||
resources/SalomeApp.xml \
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
include $(top_srcdir)/adm_local/unix/make_common_starter.am
|
||||
|
||||
salomepypkgdir = $(salomepythondir)/salome/smesh
|
||||
salomepypkgdir = $(smeshpypkgdir)
|
||||
salomepypkg_PYTHON = \
|
||||
__init__.py \
|
||||
smeshstudytools.py
|
||||
|
@ -25,6 +25,7 @@
|
||||
#
|
||||
include $(top_srcdir)/adm_local/unix/make_common_starter.am
|
||||
|
||||
#SUBDIRS = MeshCut padder
|
||||
SUBDIRS = MeshCut
|
||||
|
||||
DIST_SUBDIRS = MeshCut
|
||||
|
1
src/Tools/padder/Makefile.am
Normal file
@ -0,0 +1 @@
|
||||
SUBDIRS = meshjob spadderpy unittests resources
|
38
src/Tools/padder/README.txt
Normal file
@ -0,0 +1,38 @@
|
||||
|
||||
|
||||
PADDER overview
|
||||
---------------
|
||||
|
||||
PADDER is an algorithm that creates a set of particules called a "discrete mesh".
|
||||
The particules are characterized by a location in space and a weight that can be considered
|
||||
as the radius of a sphere whose center is the location of the particule.
|
||||
|
||||
Discrete meshes are typically used to modelize civil components in rapid dynamic
|
||||
computation problems (seisms, chocs). These components consists in concrete parts
|
||||
embedding steal bares for reinforcement. These parts are input to the algorithm
|
||||
as standard finite elements meshes. The cells of theses meshes drive the location
|
||||
and sizing of particules.
|
||||
|
||||
In the med representation, a discrete mesh is described as MED_BALL elements.
|
||||
A MED_BALL element is defined by a location and a radius.
|
||||
|
||||
PADDER plugin
|
||||
-------------
|
||||
|
||||
This directory provides SMESH with a SALOME plugin that can be used to define
|
||||
and then run a PADDER execution. The inputs are the FE meshes that describe
|
||||
the concrete parts and steal bares parts. The output is a discrete mesh
|
||||
containing MED_BALL elements.
|
||||
|
||||
A graphical interface is used to drive the user for data input and computation
|
||||
supervision (the algorithm may last more than an hour long), and finally the publication
|
||||
of the resulting mesh (when succeed) in the SALOME study.
|
||||
|
||||
Technically speaking, the PADDER plugin consists in:
|
||||
|
||||
* a SALOME component MESHJOB that do the computation job (wrapper to the padder executable program)
|
||||
* a graphical interface composed of two dialog windows
|
||||
* a configuration mechanism (data file and read function), to define
|
||||
the computation resource (a SALOME resource + the software configuration of the padder executable
|
||||
program on this resource)
|
||||
* an integration file (salomeplugin.py)
|
1
src/Tools/padder/meshjob/Makefile.am
Normal file
@ -0,0 +1 @@
|
||||
SUBDIRS = idl impl
|
126
src/Tools/padder/meshjob/idl/MESHJOB.idl
Normal file
@ -0,0 +1,126 @@
|
||||
// Copyright (C) 2011 CEA/DEN, EDF R&D
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
|
||||
//
|
||||
// Authors : Guillaume Boulant (EDF) - 31/01/2011
|
||||
|
||||
#ifndef _MESHJOB_IDL_
|
||||
#define _MESHJOB_IDL_
|
||||
|
||||
#include "SALOME_Exception.idl"
|
||||
#include "SALOME_Component.idl"
|
||||
|
||||
//
|
||||
// This interface is used for mesh job submission from within the
|
||||
// SALOME plugin for PADDER.
|
||||
//
|
||||
module MESHJOB
|
||||
{
|
||||
|
||||
//
|
||||
// Structure to transmit the parameters requiered for the job to run
|
||||
// the executable program on the target resource. See configure
|
||||
// service.
|
||||
//
|
||||
struct ConfigParameter {
|
||||
string resname; // The name of the SALOME resource to be used
|
||||
string binpath; // The path of the executable program on this resource
|
||||
string envpath; // The path of the environment file on this resource
|
||||
};
|
||||
|
||||
//
|
||||
// This set of specification defines the data structure used to
|
||||
// initialize a job on a specific resource, then supervise the job
|
||||
// and finally retrieve the result data.
|
||||
//
|
||||
|
||||
// This defines the set of temporary folders used by the jobmanager
|
||||
// when executing a job (may depends on the job).
|
||||
struct MeshJobPaths
|
||||
{
|
||||
string local_inputdir;
|
||||
string local_resultdir;
|
||||
string remote_workdir;
|
||||
};
|
||||
|
||||
// This defines the possible types for a job parameter
|
||||
enum FileType {MED_CONCRETE, MED_STEELBAR};
|
||||
|
||||
// This defines a single parameter for the job initialization (a med file)
|
||||
struct MeshJobParameter
|
||||
{
|
||||
string file_name;
|
||||
FileType file_type;
|
||||
string group_name;
|
||||
};
|
||||
|
||||
// This defines a set of parameters for the job initialization
|
||||
typedef sequence<MESHJOB::MeshJobParameter> MeshJobParameterList;
|
||||
|
||||
// This defines the result data of a job
|
||||
struct MeshJobResults
|
||||
{
|
||||
string results_dirname;
|
||||
string outputmesh_filename;
|
||||
string status;
|
||||
};
|
||||
|
||||
// This defines the possible states of a job
|
||||
enum MeshJobState {CREATED, IN_PROCESS, QUEUED, RUNNING, PAUSED, FINISHED, ERROR};
|
||||
|
||||
//
|
||||
// This interface defines the computation services of the component
|
||||
//
|
||||
|
||||
interface MeshJobManager: Engines::EngineComponent
|
||||
{
|
||||
|
||||
/*! Add a resource configuration, identified by the string
|
||||
configId and characterized by the parameters in
|
||||
configParameter */
|
||||
boolean configure(in string configId, in MESHJOB::ConfigParameter configParameter)
|
||||
raises (SALOME::SALOME_Exception);
|
||||
|
||||
/*! Initialize a smesh computation job and return the job identifier */
|
||||
long initialize(in MESHJOB::MeshJobParameterList meshJobParameterList, in string configId)
|
||||
raises (SALOME::SALOME_Exception);
|
||||
|
||||
/*! Submit the job execution and return true if submission is OK */
|
||||
boolean start(in long jobId)
|
||||
raises (SALOME::SALOME_Exception);
|
||||
|
||||
/*! Request the launch manager for the state of the specified job */
|
||||
string getState(in long jobId)
|
||||
raises (SALOME::SALOME_Exception);
|
||||
|
||||
/*! Request the launch manager for downloading the results */
|
||||
MeshJobResults finalize(in long jobid)
|
||||
raises (SALOME::SALOME_Exception);
|
||||
|
||||
/*! Clean all data associated to this job and remove the job from the launch manager */
|
||||
boolean clean(in long jobId)
|
||||
raises (SALOME::SALOME_Exception);
|
||||
|
||||
/*! Returns the set of temporary folders used by the job instance */
|
||||
MeshJobPaths getPaths(in long jobId)
|
||||
raises (SALOME::SALOME_Exception);
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif // _MESHJOB_IDL_
|
85
src/Tools/padder/meshjob/idl/Makefile.am
Normal file
@ -0,0 +1,85 @@
|
||||
# Copyright (C) 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
|
||||
#
|
||||
|
||||
# This Makefile is responsible of generating the client and server
|
||||
# implementation of IDL interfaces for both C++ and python usage.
|
||||
# The building process of the C++ files is in charge of each source
|
||||
# package and then is not manage here.
|
||||
#
|
||||
include $(top_srcdir)/adm_local/unix/make_common_starter.am
|
||||
|
||||
BUILT_SOURCES = \
|
||||
MESHJOBSK.cc
|
||||
|
||||
IDL_FILES = \
|
||||
MESHJOB.idl
|
||||
|
||||
salomeidl_DATA = $(IDL_FILES)
|
||||
|
||||
lib_LTLIBRARIES = libSalomeIDLSPADDER.la
|
||||
libSalomeIDLSPADDER_la_SOURCES =
|
||||
nodist_libSalomeIDLSPADDER_la_SOURCES = $(BUILT_SOURCES)
|
||||
nodist_salomeinclude_HEADERS= $(IDL_FILES:%idl=%hh)
|
||||
|
||||
OMNIORB_CXXFLAGS=@OMNIORB_CXXFLAGS@ @OMNIORB_INCLUDES@
|
||||
OMNIORB_LIBS=@OMNIORB_LIBS@
|
||||
|
||||
libSalomeIDLSPADDER_la_CXXFLAGS = \
|
||||
$(KERNEL_CXXFLAGS) \
|
||||
$(OMNIORB_CXXFLAGS) \
|
||||
-I.
|
||||
|
||||
libSalomeIDLSPADDER_la_LIBADD = \
|
||||
$(KERNEL_LDFLAGS) -lSalomeIDLKernel \
|
||||
$(OMNIORB_LIBS)
|
||||
|
||||
|
||||
# These variables defines the building process of CORBA files
|
||||
IDLCXXFLAGS = \
|
||||
-bcxx -I. \
|
||||
@OMNIORB_IDLCXXFLAGS@ \
|
||||
-I$(KERNEL_ROOT_DIR)/idl/salome
|
||||
|
||||
IDLPYFLAGS = \
|
||||
-I. \
|
||||
@OMNIORB_IDLPYFLAGS@ \
|
||||
-I$(KERNEL_ROOT_DIR)/idl/salome
|
||||
|
||||
##########################################################
|
||||
SUFFIXES = .idl .hh SK.cc
|
||||
|
||||
%SK.cc %.hh : %.idl
|
||||
$(OMNIORB_IDL) $(IDLCXXFLAGS) $<
|
||||
|
||||
%_idl.py : %.idl
|
||||
$(OMNIORB_IDL) $(IDLPYFLAGS) $<
|
||||
|
||||
CLEANFILES = *.hh *SK.cc *.py *.hxx *.cxx
|
||||
|
||||
EXTRA_DIST += $(IDL_FILES)
|
||||
|
||||
install-data-local: $(IDL_FILES)
|
||||
$(INSTALL) -d $(DESTDIR)$(salomepythondir)
|
||||
ls $^ | while read file; do \
|
||||
$(OMNIORB_IDL) $(IDLPYFLAGS) -C$(DESTDIR)$(salomepythondir) $$file ; \
|
||||
done
|
||||
|
||||
uninstall-local:
|
||||
rm -rf $(DESTDIR)$(salomepythondir)/*
|
||||
|
40
src/Tools/padder/meshjob/impl/Makefile.am
Normal file
@ -0,0 +1,40 @@
|
||||
|
||||
include $(top_srcdir)/adm_local/unix/make_common_starter.am
|
||||
|
||||
AM_CFLAGS=$(SALOME_INCLUDES) -fexceptions
|
||||
|
||||
lib_LTLIBRARIES= libMeshJobManagerEngine.la
|
||||
|
||||
salomeinclude_HEADERS= \
|
||||
MeshJobManager_i.hxx
|
||||
|
||||
|
||||
# =============================================================
|
||||
# Definition of MeshJobManagerEngine construction
|
||||
# =============================================================
|
||||
libMeshJobManagerEngine_la_SOURCES = \
|
||||
MeshJobManager_i.cxx
|
||||
|
||||
|
||||
LIBXML_INCLUDES=@LIBXML_INCLUDES@
|
||||
LIBXML_LIBS=@LIBXML_LIBS@
|
||||
KERNEL_CXXFLAGS=@KERNEL_CXXFLAGS@
|
||||
#KERNEL_LIBS=@KERNEL_LDFLAGS@ -lSalomeContainer -lOpUtil -lSalomeDSCContainer -lSalomeDSCSuperv -lSalomeDatastream -lSalomeDSCSupervBasic -lCalciumC -lSalomeKernelHelpers
|
||||
KERNEL_LIBS = \
|
||||
@KERNEL_LDFLAGS@ \
|
||||
-lSalomeContainer
|
||||
|
||||
# -lSalomeLauncher -lSalomeKernelHelpers \
|
||||
# -lSalomeGenericObj -lSalomeIDLKernel
|
||||
|
||||
OMNIORB_CXXFLAGS=
|
||||
|
||||
libMeshJobManagerEngine_la_CXXFLAGS = \
|
||||
-I$(builddir)/../idl $(KERNEL_CXXFLAGS) \
|
||||
@CORBA_CXXFLAGS@ @CORBA_INCLUDES@ \
|
||||
$(LIBXML_INCLUDES)
|
||||
|
||||
libMeshJobManagerEngine_la_LDFLAGS = \
|
||||
$(builddir)/../idl/libSalomeIDLSPADDER.la \
|
||||
$(KERNEL_LIBS) \
|
||||
$(LIBXML_LIBS)
|
571
src/Tools/padder/meshjob/impl/MeshJobManager_i.cxx
Normal file
@ -0,0 +1,571 @@
|
||||
// Copyright (C) 2011 EDF R&D
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
|
||||
//
|
||||
// Authors : Guillaume Boulant (EDF) - 01/03/2011
|
||||
|
||||
#include "MeshJobManager_i.hxx"
|
||||
|
||||
#include <SALOMEconfig.h>
|
||||
#include CORBA_SERVER_HEADER(SALOME_Exception)
|
||||
|
||||
#include "Basics_Utils.hxx" // For standard logging
|
||||
#include "SALOME_KernelServices.hxx" // For CORBA logging
|
||||
#undef LOG
|
||||
#define LOG STDLOG
|
||||
|
||||
#include "testhelper.hxx"
|
||||
|
||||
//
|
||||
// ====================================================================
|
||||
// General purpose helper functions (to put elsewhere at least)
|
||||
// ====================================================================
|
||||
//
|
||||
#include <sys/time.h>
|
||||
/*!
|
||||
* This function must be used to associate a datetime tag to a job
|
||||
*/
|
||||
static long timetag() {
|
||||
timeval tv;
|
||||
gettimeofday(&tv,0);
|
||||
long tag = tv.tv_usec + tv.tv_sec*1000000;
|
||||
return tag;
|
||||
}
|
||||
|
||||
/*!
|
||||
* This function returns true if the string text starts with the string
|
||||
* token.
|
||||
*/
|
||||
static bool myStartsWith(const std::string& text,const std::string& token){
|
||||
if(text.length() < token.length())
|
||||
return false;
|
||||
return (text.compare(0, token.length(), token) == 0);
|
||||
}
|
||||
|
||||
//
|
||||
// ====================================================================
|
||||
// Constructor/Destructor
|
||||
// ====================================================================
|
||||
//
|
||||
MeshJobManager_i::MeshJobManager_i(CORBA::ORB_ptr orb,
|
||||
PortableServer::POA_ptr poa,
|
||||
PortableServer::ObjectId * contId,
|
||||
const char *instanceName,
|
||||
const char *interfaceName)
|
||||
: Engines_Component_i(orb, poa, contId, instanceName, interfaceName)
|
||||
{
|
||||
LOG("Activating MESHJOB::MeshJobManager object");
|
||||
_thisObj = this ;
|
||||
_id = _poa->activate_object(_thisObj);
|
||||
|
||||
_salomeLauncher = KERNEL::getSalomeLauncher();
|
||||
if(CORBA::is_nil(_salomeLauncher)){
|
||||
LOG("The SALOME launcher can't be reached ==> STOP");
|
||||
throw KERNEL::createSalomeException("SALOME launcher can't be reached");
|
||||
}
|
||||
|
||||
_resourcesManager = KERNEL::getResourcesManager();
|
||||
if(CORBA::is_nil(_resourcesManager)){
|
||||
LOG("The SALOME resource manager can't be reached ==> STOP");
|
||||
throw KERNEL::createSalomeException("The SALOME resource manager can't be reached");
|
||||
}
|
||||
}
|
||||
|
||||
MeshJobManager_i::~MeshJobManager_i() {
|
||||
LOG("MeshJobManager_i::~MeshJobManager_i()");
|
||||
}
|
||||
|
||||
//
|
||||
// ====================================================================
|
||||
// Helper functions to deals with the local and remote file systems
|
||||
// ====================================================================
|
||||
//
|
||||
#include <fstream> // to get the file streams
|
||||
#include <sys/stat.h> // to get mkdir
|
||||
#include <sys/types.h> // to get mkdir options
|
||||
#include <unistd.h> // to get basename
|
||||
#include <stdlib.h> // to get system and getenv
|
||||
|
||||
static std::string OUTPUTFILE("output.med");
|
||||
static std::string DATAFILE("data.txt");
|
||||
static std::string SCRIPTFILE("padder.sh");
|
||||
static std::string SEPARATOR(" ");
|
||||
|
||||
static std::string USER(getenv("USER"));
|
||||
static std::string LOCAL_INPUTDIR("/tmp/spadder.local.inputdir."+USER);
|
||||
static std::string LOCAL_RESULTDIR("/tmp/spadder.local.resultdir."+USER);
|
||||
static std::string REMOTE_WORKDIR("/tmp/spadder.remote.workdir."+USER);
|
||||
|
||||
/*!
|
||||
* This function creates the padder text input file containing the
|
||||
* input data (list of filenames and groupnames) and returns the path
|
||||
* of the created file. This function is the one that knows the format
|
||||
* of the padder input file. If the input file format changes, then
|
||||
* this function (and only this one) should be updated.
|
||||
*/
|
||||
const char * MeshJobManager_i::_writeDataFile(std::vector<MESHJOB::MeshJobParameter> listConcreteMesh,
|
||||
std::vector<MESHJOB::MeshJobParameter> listSteelBarMesh) {
|
||||
|
||||
mkdir(LOCAL_INPUTDIR.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
|
||||
|
||||
// Make it static so that it's allocated once (constant name)
|
||||
static std::string * dataFilename = new std::string(LOCAL_INPUTDIR+"/"+DATAFILE);
|
||||
std::ofstream dataFile(dataFilename->c_str());
|
||||
|
||||
// We first specify the concrete mesh data (filename and groupname)
|
||||
std::string line;
|
||||
line = std::string(basename(listConcreteMesh[0].file_name)) + " " + std::string(listConcreteMesh[0].group_name);
|
||||
dataFile << line.c_str() << std::endl;
|
||||
// Note that we use here the basename because the files are supposed
|
||||
// to be copied in the REMOTE_WORKDIR for execution.
|
||||
|
||||
// The, we can specify the steelbar mesh data, starting by the
|
||||
// number of meshes
|
||||
int nbSteelBarMesh=listSteelBarMesh.size();
|
||||
line = std::string("nbSteelbarMesh") + SEPARATOR + ToString(nbSteelBarMesh);
|
||||
dataFile << line.c_str() << std::endl;
|
||||
for (int i=0; i<nbSteelBarMesh; i++) {
|
||||
line = std::string(basename(listSteelBarMesh[i].file_name)) + " " + std::string(listSteelBarMesh[i].group_name);
|
||||
dataFile << line.c_str() << std::endl;
|
||||
}
|
||||
|
||||
// Finally, we conclude with the name of the output file
|
||||
line = OUTPUTFILE;
|
||||
dataFile << line.c_str() << std::endl;
|
||||
dataFile.close();
|
||||
return dataFilename->c_str();
|
||||
}
|
||||
|
||||
/*!
|
||||
* This function creates a shell script that runs padder whith the
|
||||
* specified data file, and returns the path of the created script
|
||||
* file. The config id is used to retrieve the path to the binary file
|
||||
* and other required files.
|
||||
*/
|
||||
const char* MeshJobManager_i::_writeScriptFile(const char * dataFileName, const char * configId) {
|
||||
mkdir(LOCAL_INPUTDIR.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
|
||||
|
||||
// Make it static so that it's allocated once (constant name)
|
||||
static std::string * scriptFilename = new std::string(LOCAL_INPUTDIR+"/"+SCRIPTFILE);
|
||||
|
||||
char * binpath = _configMap[configId].binpath;
|
||||
char * envpath = _configMap[configId].envpath;
|
||||
|
||||
std::ofstream script(scriptFilename->c_str());
|
||||
script << "#!/bin/sh" << std::endl;
|
||||
script << "here=$(dirname $0)" << std::endl;
|
||||
script << ". " << envpath << std::endl;
|
||||
script << binpath << " $here/" << basename(dataFileName) << std::endl;
|
||||
// Note that we use the basename of the datafile because all data
|
||||
// files are supposed to have been copied in the REMOTE_WORKDIR.
|
||||
script.close();
|
||||
return scriptFilename->c_str();
|
||||
}
|
||||
|
||||
//
|
||||
// ====================================================================
|
||||
// Functions to initialize and supervise the mesh computation job
|
||||
// ====================================================================
|
||||
//
|
||||
bool MeshJobManager_i::configure(const char *configId,
|
||||
const MESHJOB::ConfigParameter & configParameter)
|
||||
{
|
||||
beginService("MeshJobManager_i::configure");
|
||||
|
||||
_configMap[configId] = configParameter;
|
||||
|
||||
LOG("Adding configuration for " << configId);
|
||||
LOG("- binpath = " << _configMap[configId].binpath);
|
||||
LOG("- envpath = " << _configMap[configId].envpath);
|
||||
|
||||
endService("MeshJobManager_i::configure");
|
||||
return true;
|
||||
}
|
||||
|
||||
long MeshJobManager_i::JOBID_UNDEFINED = -1;
|
||||
|
||||
/*! Initialize a smesh computation job and return the job identifier */
|
||||
CORBA::Long MeshJobManager_i::initialize(const MESHJOB::MeshJobParameterList & meshJobParameterList,
|
||||
const char * configId)
|
||||
{
|
||||
beginService("MeshJobManager_i::initialize");
|
||||
|
||||
//
|
||||
// We first analyse the CORBA sequence to store data in C++ vectors
|
||||
//
|
||||
std::vector<MESHJOB::MeshJobParameter> listConcreteMesh;
|
||||
std::vector<MESHJOB::MeshJobParameter> listSteelBarMesh;
|
||||
for(CORBA::ULong i=0; i<meshJobParameterList.length(); i++) {
|
||||
MESHJOB::MeshJobParameter currentMesh = meshJobParameterList[i];
|
||||
switch ( currentMesh.file_type ) {
|
||||
case MESHJOB::MED_CONCRETE:
|
||||
listConcreteMesh.push_back(currentMesh);
|
||||
break;
|
||||
case MESHJOB::MED_STEELBAR:
|
||||
listSteelBarMesh.push_back(currentMesh);
|
||||
break;
|
||||
default:
|
||||
LOG("The type of the file is not recognized");
|
||||
return JOBID_UNDEFINED;
|
||||
}
|
||||
}
|
||||
|
||||
if ( listConcreteMesh.size() != 1 ) {
|
||||
// Not consistent with the specification
|
||||
LOG("You specify more than one concrete mesh");
|
||||
return JOBID_UNDEFINED;
|
||||
}
|
||||
|
||||
LOG("Nb. concrete mesh = " << listConcreteMesh.size());
|
||||
LOG("Nb. steelbar mesh = " << listSteelBarMesh.size());
|
||||
|
||||
// We initiate here a datetime to tag the files and folder
|
||||
// associated to this job.
|
||||
long jobDatetimeTag = timetag();
|
||||
// And a MESHJOB::MeshJobPaths structure to hold the directories
|
||||
// where to find data
|
||||
MESHJOB::MeshJobPaths * jobPaths = new MESHJOB::MeshJobPaths();
|
||||
jobPaths->local_inputdir = LOCAL_INPUTDIR.c_str();
|
||||
jobPaths->local_resultdir = (LOCAL_RESULTDIR + "." + ToString(jobDatetimeTag)).c_str();
|
||||
jobPaths->remote_workdir = (REMOTE_WORKDIR + "." + ToString(jobDatetimeTag)).c_str();
|
||||
|
||||
//
|
||||
// Then, we have to create the padder input data file. This input
|
||||
// data is a text file containing the list of file names and group
|
||||
// names.
|
||||
//
|
||||
const char * dataFilename = this->_writeDataFile(listConcreteMesh, listSteelBarMesh);
|
||||
LOG("dataFilename = " << dataFilename);
|
||||
const char * scriptFilename = this->_writeScriptFile(dataFilename, configId);
|
||||
LOG("scriptFilename = " << scriptFilename);
|
||||
|
||||
//
|
||||
// Then, the following instructions consists in preparing the job
|
||||
// parameters to request the SALOME launcher for creating a new
|
||||
// job.
|
||||
//
|
||||
Engines::JobParameters_var jobParameters = new Engines::JobParameters;
|
||||
jobParameters->job_type = CORBA::string_dup("command");
|
||||
// CAUTION: the job_file must be a single filename specifying a
|
||||
// self-consistent script to be executed without any argument on the
|
||||
// remote host.
|
||||
jobParameters->job_file = CORBA::string_dup(scriptFilename);
|
||||
|
||||
//
|
||||
// Specification of the working spaces:
|
||||
//
|
||||
// - local_directory: can be used to specify where to find the input
|
||||
// files on the local resource. It's optionnal if you specify the
|
||||
// absolute path name of input files.
|
||||
//
|
||||
// - result_directory: must be used to specify where to download the
|
||||
// output files on the local resources
|
||||
//
|
||||
// - work_directory: must be used to specify the remote directory
|
||||
// where to put all the stuff to run the job. Note that the job
|
||||
// will be executed from within this directory, i.e. a change
|
||||
// directory toward this working directory is done by the batch
|
||||
// system before running the specified job script.
|
||||
//
|
||||
jobParameters->local_directory = CORBA::string_dup("");
|
||||
jobParameters->result_directory = CORBA::string_dup(jobPaths->local_resultdir);
|
||||
jobParameters->work_directory = CORBA::string_dup(jobPaths->remote_workdir);
|
||||
|
||||
// We specify the input files that are required to execute the
|
||||
// job_file. If basenames are specified, then the files are supposed
|
||||
// to be located in local_directory.
|
||||
int nbFiles = listSteelBarMesh.size()+2;
|
||||
// The number of input file is:
|
||||
// (nb. of steelbar meshfile)
|
||||
// + (1 concrete meshfile)
|
||||
// + (1 padder input file)
|
||||
// = nb steelbar meshfile + 2
|
||||
jobParameters->in_files.length(nbFiles);
|
||||
jobParameters->in_files[0] = CORBA::string_dup(listConcreteMesh[0].file_name);
|
||||
for (int i=0; i<listSteelBarMesh.size(); i++) {
|
||||
jobParameters->in_files[1+i] = CORBA::string_dup(listSteelBarMesh[i].file_name);
|
||||
}
|
||||
jobParameters->in_files[1+listSteelBarMesh.size()] = CORBA::string_dup(dataFilename);
|
||||
// Note that all these input files will be copied in the
|
||||
// REMOTE_WORKDIR on the remote host
|
||||
|
||||
// Then, we have to specify the existance of an output
|
||||
// filenames. The path is supposed to be a path on the remote
|
||||
// resource, i.e. where the job is executed.
|
||||
jobParameters->out_files.length(1);
|
||||
std::string outputfile_name = std::string(jobPaths->remote_workdir)+"/"+OUTPUTFILE;
|
||||
jobParameters->out_files[0] = CORBA::string_dup(outputfile_name.c_str());
|
||||
|
||||
// CAUTION: the maximum duration has to be set with a format like "hh:mm"
|
||||
jobParameters->maximum_duration = CORBA::string_dup("01:00");
|
||||
jobParameters->queue = CORBA::string_dup("");
|
||||
|
||||
// Setting resource and additionnal properties (if needed)
|
||||
// The resource parameters can be initiated from scratch, for
|
||||
// example by specifying the values in hard coding:
|
||||
// >>>
|
||||
//jobParameters->resource_required.name = CORBA::string_dup("localhost");
|
||||
//jobParameters->resource_required.hostname = CORBA::string_dup("localhost");
|
||||
//jobParameters->resource_required.mem_mb = 1024 * 10;
|
||||
//jobParameters->resource_required.nb_proc = 1;
|
||||
// <<<
|
||||
// But it's better to initiate these parameters from a resource
|
||||
// definition known by the resource manager. This ensures that the
|
||||
// resource will be available:
|
||||
//const char * resourceName = "localhost";
|
||||
//const char * resourceName = "boulant@claui2p1";
|
||||
//const char * resourceName = "nepal@nepal";
|
||||
const char * resourceName = _configMap[configId].resname;
|
||||
Engines::ResourceDefinition * resourceDefinition = _resourcesManager->GetResourceDefinition(resourceName);
|
||||
// CAUTION: This resource should have been defined in the
|
||||
// CatalogResource.xml associated to the SALOME application.
|
||||
//
|
||||
// Then, the values can be used to initiate the resource parameters
|
||||
// of the job:
|
||||
jobParameters->resource_required.name = CORBA::string_dup(resourceDefinition->name.in());
|
||||
// CAUTION: the additionnal two following parameters MUST be
|
||||
// specified explicitly, because they are not provided by the
|
||||
// resource definition:
|
||||
jobParameters->resource_required.mem_mb = resourceDefinition->mem_mb;
|
||||
jobParameters->resource_required.nb_proc = resourceDefinition->nb_proc_per_node;
|
||||
// CAUTION: the parameter mem_mb specifies the maximum memory value
|
||||
// that could be allocated for executing the job. This takes into
|
||||
// account not only the data that could be loaded by the batch
|
||||
// process but also the linked dynamic library.
|
||||
//
|
||||
// A possible problem, for exemple in the case where you use the ssh
|
||||
// emulation of a batch system, is to get an error message as below
|
||||
// when libBatch try to run the ssh command:
|
||||
//
|
||||
// ## /usr/bin/ssh: error while loading shared libraries: libcrypto.so.0.9.8: failed
|
||||
// ## to map segment from shared object: Cannot allocate memory
|
||||
//
|
||||
// In this exemple, the mem_mb was set to 1MB, value that is not
|
||||
// sufficient to load the dynamic libraries linked to the ssh
|
||||
// executable (libcrypto.so in the error message).
|
||||
//
|
||||
// So, even in the case of a simple test shell script, you should
|
||||
// set this value at least to a standard threshold as 500MB
|
||||
|
||||
int jobId = JOBID_UNDEFINED;
|
||||
try {
|
||||
jobId = _salomeLauncher->createJob(jobParameters);
|
||||
// We register the datetime tag of this job
|
||||
_jobDateTimeMap[jobId]=jobDatetimeTag;
|
||||
_jobPathsMap[jobId] = jobPaths;
|
||||
}
|
||||
catch (const SALOME::SALOME_Exception & ex) {
|
||||
LOG("SALOME Exception in createJob !" <<ex.details.text.in());
|
||||
//LOG(ex.details.text.in());
|
||||
return JOBID_UNDEFINED;
|
||||
}
|
||||
catch (const CORBA::SystemException& ex) {
|
||||
LOG("Receive SALOME System Exception: "<<ex);
|
||||
LOG("Check SALOME servers...");
|
||||
return JOBID_UNDEFINED;
|
||||
}
|
||||
|
||||
endService("MeshJobManager_i::initialize");
|
||||
return jobId;
|
||||
}
|
||||
|
||||
/*! Submit the job execution and return true if submission is OK */
|
||||
bool MeshJobManager_i::start(CORBA::Long jobId) {
|
||||
beginService("MeshJobManager_i::start");
|
||||
|
||||
try {
|
||||
_salomeLauncher->launchJob(jobId);
|
||||
}
|
||||
catch (const SALOME::SALOME_Exception & ex) {
|
||||
LOG("SALOME Exception in createJob !" <<ex.details.text.in());
|
||||
//LOG(ex.details.text.in());
|
||||
return false;
|
||||
}
|
||||
catch (const CORBA::SystemException& ex) {
|
||||
LOG("Receive SALOME System Exception: "<<ex);
|
||||
LOG("Check SALOME servers...");
|
||||
return false;
|
||||
}
|
||||
|
||||
endService("MeshJobManager_i::initialize");
|
||||
return true;
|
||||
}
|
||||
|
||||
/*! Request the launch manager for the state of the specified job */
|
||||
char* MeshJobManager_i::getState(CORBA::Long jobId) {
|
||||
beginService("MeshJobManager_i::getState");
|
||||
|
||||
std::string state;
|
||||
try
|
||||
{
|
||||
state = _salomeLauncher->getJobState(jobId);
|
||||
}
|
||||
catch (const SALOME::SALOME_Exception & ex)
|
||||
{
|
||||
LOG("SALOME Exception in getJobState !");
|
||||
state = ex.details.text;
|
||||
}
|
||||
catch (const CORBA::SystemException& ex)
|
||||
{
|
||||
LOG("Receive SALOME System Exception: " << ex);
|
||||
state="SALOME System Exception - see logs";
|
||||
}
|
||||
LOG("jobId="<<ToString(jobId)<<" state="<<state);
|
||||
endService("MeshJobManager_i::getState");
|
||||
return CORBA::string_dup(state.c_str());
|
||||
}
|
||||
|
||||
MESHJOB::MeshJobPaths * MeshJobManager_i::getPaths(CORBA::Long jobId) {
|
||||
|
||||
MESHJOB::MeshJobPaths * jobPaths = _jobPathsMap[jobId];
|
||||
if ( jobPaths == NULL ) {
|
||||
LOG("You request the working paths for an undefined job (jobId="<<ToString(jobId)<<")");
|
||||
return NULL; // Maybe raise an exception?
|
||||
}
|
||||
return jobPaths;
|
||||
}
|
||||
|
||||
|
||||
MESHJOB::MeshJobResults * MeshJobManager_i::finalize(CORBA::Long jobId) {
|
||||
beginService("MeshJobManager_i::getResults");
|
||||
MESHJOB::MeshJobResults * result = new MESHJOB::MeshJobResults();
|
||||
|
||||
MESHJOB::MeshJobPaths * jobPaths = this->getPaths(jobId);
|
||||
std::string local_resultdir(jobPaths->local_resultdir);
|
||||
result->results_dirname = local_resultdir.c_str();
|
||||
try
|
||||
{
|
||||
_salomeLauncher->getJobResults(jobId, local_resultdir.c_str());
|
||||
|
||||
// __BUG__: to prevent from a bug of the MED driver (SALOME
|
||||
// 5.1.5), we change the basename of the output file to force the
|
||||
// complete reloading of data by the med driver.
|
||||
long jobDatetimeTag = _jobDateTimeMap[jobId];
|
||||
std::string outputFileName = "output"+ToString(jobDatetimeTag)+".med";
|
||||
rename((local_resultdir+"/"+OUTPUTFILE).c_str(), (local_resultdir+"/"+outputFileName).c_str());
|
||||
|
||||
result->outputmesh_filename = outputFileName.c_str();
|
||||
result->status = "OK";
|
||||
}
|
||||
catch (const SALOME::SALOME_Exception & ex)
|
||||
{
|
||||
LOG("SALOME Exception in getResults !");
|
||||
result->status = "SALOME Exception in getResults !";
|
||||
}
|
||||
catch (const CORBA::SystemException& ex)
|
||||
{
|
||||
LOG("Receive CORBA System Exception: " << ex);
|
||||
result->status = "Receive CORBA System Exception: see log";
|
||||
}
|
||||
endService("MeshJobManager_i::getResults");
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*! Clean all data associated to this job and remove the job from the launch manager */
|
||||
bool MeshJobManager_i::clean(CORBA::Long jobId) {
|
||||
beginService("MeshJobManager_i::clean");
|
||||
|
||||
// __GBO__ WORK IN PROGRESS: we just clean the temporary local
|
||||
// directories. The remote working directories are tag with the
|
||||
// execution datetime and the we prevent the task from conflict
|
||||
// with files of another task.
|
||||
MESHJOB::MeshJobPaths * jobPaths = this->getPaths(jobId);
|
||||
if ( jobPaths == NULL ) return false;
|
||||
|
||||
// WARN: !!!!!
|
||||
// For safety reason (and prevent from bug that could erase the
|
||||
// filesystem), we cancel the operation in the case where the
|
||||
// directories to delete are not in the /tmp folder.
|
||||
std::string shell_command("rm -rf ");
|
||||
std::string inputdir(jobPaths->local_inputdir);
|
||||
std::string resultdir(jobPaths->local_resultdir);
|
||||
if ( !myStartsWith(inputdir,"/tmp/") ) {
|
||||
LOG("WRN: The directory "<<inputdir<<" is not in /tmp. NO DELETE is done");
|
||||
} else {
|
||||
shell_command+=inputdir+" ";
|
||||
}
|
||||
if ( !myStartsWith(resultdir,"/tmp/")) {
|
||||
LOG("WRN: The directory "<<resultdir<<" is not in /tmp. NO DELETE is done");
|
||||
} else {
|
||||
shell_command+=resultdir;
|
||||
}
|
||||
|
||||
LOG("DBG: clean shell command = "<<shell_command);
|
||||
|
||||
bool cleanOk = false;
|
||||
int error = system(shell_command.c_str());
|
||||
if (error == 0) cleanOk = true;
|
||||
|
||||
endService("MeshJobManager_i::clean");
|
||||
return cleanOk;
|
||||
}
|
||||
|
||||
|
||||
std::vector<std::string> * MeshJobManager_i::_getResourceNames() {
|
||||
|
||||
//
|
||||
// These part is just to control the available resources
|
||||
//
|
||||
Engines::ResourceParameters params;
|
||||
KERNEL::getLifeCycleCORBA()->preSet(params);
|
||||
|
||||
Engines::ResourceList * resourceList = _resourcesManager->GetFittingResources(params);
|
||||
Engines::ResourceDefinition * resourceDefinition = NULL;
|
||||
LOG("### resource list:");
|
||||
std::vector<std::string>* resourceNames = new std::vector<std::string>();
|
||||
if (resourceList) {
|
||||
for (int i = 0; i < resourceList->length(); i++) {
|
||||
const char* aResourceName = (*resourceList)[i];
|
||||
resourceNames->push_back(std::string(aResourceName));
|
||||
LOG("resource["<<i<<"] = "<<aResourceName);
|
||||
resourceDefinition = _resourcesManager->GetResourceDefinition(aResourceName);
|
||||
LOG("protocol["<<i<<"] = "<<resourceDefinition->protocol);
|
||||
}
|
||||
}
|
||||
|
||||
// Note: a ResourceDefinition is used to create a batch configuration
|
||||
// in the Launcher. This operation is done at Launcher startup from
|
||||
// the configuration file CatalogResources.xml provided by the
|
||||
// SALOME application.
|
||||
// In the code instructions, you just have to choose a resource
|
||||
// configuration by its name and then define the ResourceParameters
|
||||
// that specify additionnal properties for a specific job submission
|
||||
// (use the attribute resource_required of the JobParameters).
|
||||
|
||||
return resourceNames;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ==========================================================================
|
||||
// Factory services
|
||||
// ==========================================================================
|
||||
//
|
||||
extern "C"
|
||||
{
|
||||
PortableServer::ObjectId * MeshJobManagerEngine_factory( CORBA::ORB_ptr orb,
|
||||
PortableServer::POA_ptr poa,
|
||||
PortableServer::ObjectId * contId,
|
||||
const char *instanceName,
|
||||
const char *interfaceName)
|
||||
{
|
||||
MESSAGE("PortableServer::ObjectId * MeshJobManagerEngine_factory()");
|
||||
MeshJobManager_i * myEngine = new MeshJobManager_i(orb, poa, contId, instanceName, interfaceName);
|
||||
return myEngine->getId() ;
|
||||
}
|
||||
}
|
81
src/Tools/padder/meshjob/impl/MeshJobManager_i.hxx
Normal file
@ -0,0 +1,81 @@
|
||||
// Copyright (C) 2011 EDF R&D
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
|
||||
//
|
||||
// Authors : Guillaume Boulant (EDF) - 01/03/2011
|
||||
|
||||
#ifndef _MESHJOBMANAGER_HXX_
|
||||
#define _MESHJOBMANAGER_HXX_
|
||||
|
||||
// include the stubs generating from MESHJOB.idl
|
||||
#include <SALOMEconfig.h>
|
||||
#include CORBA_SERVER_HEADER(MESHJOB)
|
||||
#include CORBA_SERVER_HEADER(SALOME_Component)
|
||||
#include "SALOME_Component_i.hxx"
|
||||
|
||||
#include "SALOME_Launcher.hxx"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
class MeshJobManager_i: public virtual POA_MESHJOB::MeshJobManager,
|
||||
public Engines_Component_i
|
||||
{
|
||||
public:
|
||||
MeshJobManager_i(CORBA::ORB_ptr orb, PortableServer::POA_ptr poa,
|
||||
PortableServer::ObjectId * contId,
|
||||
const char *instanceName, const char *interfaceName);
|
||||
~MeshJobManager_i();
|
||||
|
||||
bool configure (const char *configId,
|
||||
const MESHJOB::ConfigParameter & configParameter);
|
||||
CORBA::Long initialize (const MESHJOB::MeshJobParameterList & meshJobParameterList,
|
||||
const char *configId);
|
||||
bool start (CORBA::Long jobId);
|
||||
char* getState (CORBA::Long jobId);
|
||||
MESHJOB::MeshJobResults * finalize(CORBA::Long jobId);
|
||||
MESHJOB::MeshJobPaths * getPaths(CORBA::Long jobId);
|
||||
bool clean (CORBA::Long jobId);
|
||||
|
||||
static long JOBID_UNDEFINED;
|
||||
|
||||
private:
|
||||
Engines::SalomeLauncher_var _salomeLauncher;
|
||||
Engines::ResourcesManager_var _resourcesManager;
|
||||
|
||||
// This maps the config identifier to the config parameters. A
|
||||
// config is a resource with additionnal data specifying the
|
||||
// location of the binary program to be executed by the task
|
||||
std::map<std::string, MESHJOB::ConfigParameter> _configMap;
|
||||
|
||||
// This maps a job identifier to its associated datetime tag. When
|
||||
// a job is created during the initialize function, a datetime tag
|
||||
// is associated to this job and can be used to characterized files
|
||||
// and directories associated to this job.
|
||||
std::map<long, long> _jobDateTimeMap;
|
||||
std::map<long, MESHJOB::MeshJobPaths*> _jobPathsMap;
|
||||
|
||||
const char* _writeDataFile (std::vector<MESHJOB::MeshJobParameter> listConcreteMesh,
|
||||
std::vector<MESHJOB::MeshJobParameter> listSteelBarMesh);
|
||||
const char* _writeScriptFile (const char * dataFileName, const char * configId);
|
||||
|
||||
std::vector<std::string> * _getResourceNames();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
35
src/Tools/padder/meshjob/impl/testhelper.hxx
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef __TESTHELPER_HXX__
|
||||
#define __TESTHELPER_HXX__
|
||||
|
||||
#include <stdlib.h> // Standard C include (for getenv)
|
||||
#include <unistd.h>
|
||||
#include <string>
|
||||
|
||||
/*!
|
||||
* This function returns the module SPADDER installation root
|
||||
* directory as a string.
|
||||
*/
|
||||
static std::string SPADDER_ROOT_DIR() {
|
||||
static std::string * spadder_root_dir;
|
||||
if ( spadder_root_dir == NULL ) {
|
||||
char * SPADDER_ROOT_DIR = getenv("SPADDER_ROOT_DIR");
|
||||
spadder_root_dir = new std::string(SPADDER_ROOT_DIR);
|
||||
}
|
||||
return *spadder_root_dir;
|
||||
}
|
||||
|
||||
/*! Relative path of the directory containing data and exe for tests */
|
||||
static std::string PADDEREXE_RPATH("/share/salome/resources/spadder/padderexe");
|
||||
/*! Absolute path of the directory containing data and exe for tests */
|
||||
static std::string PADDEREXE_APATH(SPADDER_ROOT_DIR()+PADDEREXE_RPATH);
|
||||
/*! Absolute path of the exe shell script for tests */
|
||||
static std::string PADDEREXE_SCRIPT_FILENAME(PADDEREXE_APATH+"/padder.sh");
|
||||
|
||||
|
||||
static int testssh_using_system() {
|
||||
const char * cmd = "/usr/bin/ssh claui2p1 -l boulant 'cd /tmp && ./runCommand_padder_Mon_Feb_28_14_28_36_2011.sh'";
|
||||
int result = system(cmd);
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // __TESTHELPER_HXX__
|
7
src/Tools/padder/resources/Makefile.am
Normal file
@ -0,0 +1,7 @@
|
||||
|
||||
SUBDIRS = appligen padderexe
|
||||
|
||||
include $(top_srcdir)/adm_local/unix/make_common_starter.am
|
||||
|
||||
mysalomeresdir=$(salomeresdir)
|
||||
mysalomeres_DATA = SPADDERCatalog.xml
|
13
src/Tools/padder/resources/SPADDERCatalog.xml
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version='1.0' encoding='us-ascii' ?>
|
||||
|
||||
<!-- XML component catalog -->
|
||||
|
||||
<begin-catalog>
|
||||
<path-prefix-list></path-prefix-list>
|
||||
<type-list></type-list>
|
||||
<component-list>
|
||||
<component>
|
||||
<component-name>MeshJobManager</component-name>
|
||||
</component>
|
||||
</component-list>
|
||||
</begin-catalog>
|
21
src/Tools/padder/resources/appligen/CatalogResources.xml
Normal file
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE ResourcesCatalog>
|
||||
<resources>
|
||||
|
||||
<!-- Generic configuration that should works on every workstation -->
|
||||
<machine name="localhost" hostname="localhost"
|
||||
protocol="ssh" batch="ssh_batch"
|
||||
memInMB="500" CPUFreqMHz="0" nbOfNodes="1" nbOfProcPerNode="1"/>
|
||||
|
||||
<!-- Specific configuration that only works on my workstation (needs ssh authentification) -->
|
||||
<machine name="boulant@claui2p1"
|
||||
hostname="claui2p1" userName="boulant"
|
||||
protocol="ssh" batch="ssh_batch"
|
||||
memInMB="500" CPUFreqMHz="0" nbOfNodes="1" nbOfProcPerNode="1"/>
|
||||
|
||||
<!-- Specific configuration that only works for nepal team (needs ssh authentification) -->
|
||||
<machine name="nepal@nepal"
|
||||
hostname="nepal" userName="nepal"
|
||||
protocol="ssh" batch="ssh_batch"
|
||||
memInMB="500" CPUFreqMHz="0" nbOfNodes="1" nbOfProcPerNode="1"/>
|
||||
|
||||
</resources>
|
37
src/Tools/padder/resources/appligen/Makefile.am
Normal file
@ -0,0 +1,37 @@
|
||||
# Copyright (C) 2011 CEA/DEN, EDF R&D
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
|
||||
|
||||
include $(top_srcdir)/adm_local/unix/make_common_starter.am
|
||||
|
||||
appligendir = $(salomeresdir)/appligen
|
||||
|
||||
appligen_DATA= \
|
||||
envappli.sh \
|
||||
config_appli.xml \
|
||||
appli-splashscreen.jpg \
|
||||
SalomeApp.xml \
|
||||
CatalogResources.xml
|
||||
|
||||
appligen_SCRIPTS= \
|
||||
appligen.sh
|
||||
|
||||
EXTRA_DIST += $(appligen_DATA) $(appligen_SCRIPTS)
|
||||
|
||||
|
||||
envappli.sh:
|
||||
$(srcdir)/genenv.sh envappli.sh
|
24
src/Tools/padder/resources/appligen/README.txt
Normal file
@ -0,0 +1,24 @@
|
||||
This package defines a build procedure that creates a
|
||||
set of files ready to use to generate a SALOME application
|
||||
embedding this module.
|
||||
|
||||
The files are created in the directory:
|
||||
|
||||
<installdir>/share/salome/resources/<module_name>/appligen
|
||||
|
||||
Where <installdir> is the installation directory of the module.
|
||||
|
||||
To generate a SALOME application, just change directory to go
|
||||
where you want to install the SALOME application and type the
|
||||
following command in a standard shell (the SALOME environment
|
||||
is not required, all paths are "hard" coded in the script):
|
||||
|
||||
$ <installdir>/share/salome/resources/<module_name>/appligen/appligen.sh
|
||||
|
||||
This script generates an application in a directory ./appli.
|
||||
Then type the following command to run a SALOME application
|
||||
embedding your module:
|
||||
|
||||
$ ./appli/runAppli -k
|
||||
|
||||
|
40
src/Tools/padder/resources/appligen/SalomeApp.xml
Normal file
@ -0,0 +1,40 @@
|
||||
<document>
|
||||
<section name="launch">
|
||||
<!-- SALOME launching parameters -->
|
||||
<parameter name="gui" value="yes"/>
|
||||
<parameter name="splash" value="yes"/>
|
||||
<parameter name="file" value="no"/>
|
||||
<parameter name="key" value="no"/>
|
||||
<parameter name="interp" value="no"/>
|
||||
<parameter name="logger" value="no"/>
|
||||
<parameter name="xterm" value="no"/>
|
||||
<parameter name="portkill" value="no"/>
|
||||
<parameter name="killall" value="no"/>
|
||||
<parameter name="noexcepthandler" value="no"/>
|
||||
<parameter name="modules" value="KERNEL,MED,GUI,GEOM,SMESH,JOBMANAGER,VISU,YACS"/>
|
||||
<parameter name="pyModules" value=""/>
|
||||
<parameter name="embedded" value="SalomeAppEngine,study,cppContainer,registry,moduleCatalog"/>
|
||||
<parameter name="standalone" value="pyContainer"/>
|
||||
</section>
|
||||
<section name="SMESH">
|
||||
<parameter name="plugins" value="NETGENPlugin,GHS3DPlugin,BLSURFPlugin"/>
|
||||
</section>
|
||||
<section name="splash" >
|
||||
<!-- Splash screen settings. This only works when using a SALOME application, -->
|
||||
<!-- where the file appli-splashscreen.jpg has been copy into. -->
|
||||
<parameter name="image" value="${SMESH_ROOT_DIR}/share/salome/resources/smesh/appligen/appli-splashscreen.jpg" />
|
||||
<parameter name="constant_info" value="%A [ %V ]" />
|
||||
<parameter name="text_colors" value="#eeeeff|#555555" />
|
||||
<parameter name="hide_on_click" value="no" />
|
||||
<parameter name="show_progress" value="yes" />
|
||||
<parameter name="show_message" value="yes" />
|
||||
<parameter name="show_percents" value="yes" />
|
||||
<parameter name="margin" value="40" />
|
||||
<parameter name="progress_width" value="20" />
|
||||
<parameter name="progress_flags" value="bottom,left_to_right" />
|
||||
<parameter name="opacity" value="0.70" />
|
||||
<parameter name="font" value="Tahoma,12,normal" />
|
||||
<parameter name="alignment" value="top,left" />
|
||||
<parameter name="progress_colors" value="#3b3e5d|#d14949|v" />
|
||||
</section>
|
||||
</document>
|
BIN
src/Tools/padder/resources/appligen/appli-splashscreen.jpg
Normal file
After Width: | Height: | Size: 109 KiB |
31
src/Tools/padder/resources/appligen/appligen.sh.in
Executable file
@ -0,0 +1,31 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# This script installs or updates a SALOME application for testing the
|
||||
# PADDER plugin for SMESH. The application is installed in the
|
||||
# directory ./appli. The configuration file is supposed to be adapted
|
||||
# to your own environment (see config_appli.xml).
|
||||
#
|
||||
# To run this script, you should have first configure your
|
||||
# shell with the SALOME environment, i.e. source the files
|
||||
# prerequis.sh and envSalome.sh (or equivalent) that fit
|
||||
# your configuration. You can alternatively customize the env.sh file
|
||||
# to fit your SALOME environment and let the script do the job (see
|
||||
# source below).
|
||||
#
|
||||
# (gboulant - 3/2/2011)
|
||||
#
|
||||
|
||||
here=$(dirname $0)
|
||||
|
||||
#
|
||||
# Run the appli_gen.py
|
||||
#
|
||||
APPLIDIR="./appli"
|
||||
@KERNEL_ROOT_DIR@/bin/salome/appli_gen.py --prefix=$APPLIDIR --config=$here/config_appli.xml
|
||||
|
||||
#
|
||||
# Copy customized configuration files in the application
|
||||
#
|
||||
cp $here/SalomeApp.xml $APPLIDIR/.
|
||||
cp $here/CatalogResources.xml $APPLIDIR/.
|
||||
cp @prefix@/plugins/envPlugins.sh $APPLIDIR/env.d/.
|
15
src/Tools/padder/resources/appligen/config_appli.xml.in
Normal file
@ -0,0 +1,15 @@
|
||||
<application>
|
||||
<!-- The path should be the absolute path of installation of the file envappli.sh -->
|
||||
<prerequisites path="@prefix@/share/salome/resources/@MODULE_NAME@/appligen/envappli.sh"/>
|
||||
|
||||
<modules>
|
||||
<module name="KERNEL" path="@KERNEL_ROOT_DIR@"/>
|
||||
<module name="MED" path="@MED_ROOT_DIR@"/>
|
||||
<module name="GUI" path="@GUI_ROOT_DIR@"/>
|
||||
<module name="GEOM" path="@GEOM_ROOT_DIR@"/>
|
||||
<module name="SMESH" path="@prefix@"/>
|
||||
<module name="BLSURFPLUGIN" gui="no" path="@BLSURFPLUGIN_ROOT_DIR@"/>
|
||||
<module name="GHS3DPLUGIN" gui="no" path="@GHS3DPLUGIN_ROOT_DIR@"/>
|
||||
<module name="NETGENPLUGIN" gui="no" path="@NETGENPLUGIN_ROOT_DIR@"/>
|
||||
</modules>
|
||||
</application>
|
41
src/Tools/padder/resources/appligen/genenv.sh
Executable file
@ -0,0 +1,41 @@
|
||||
#!/bin/bash
|
||||
|
||||
# This script creates a source file that defines a SALOME shell
|
||||
# environment. We assume here that the SALOME environment has been
|
||||
# previously set, so that the env command get all environment
|
||||
# variables required for building and executing SALOME. We talk
|
||||
# about third party software programs and libraries. The environment
|
||||
# variables defining SALOME module are exluded (i.e. *_ROOT_DIR)
|
||||
# because they are automatically set when generating a SALOME application..
|
||||
#
|
||||
# The argument is the filepath to be created.
|
||||
#
|
||||
|
||||
if [ $# == 1 ]; then
|
||||
ENVAPPLI_SH=$1
|
||||
else
|
||||
ENVAPPLI_SH=envappli.sh
|
||||
fi
|
||||
|
||||
function header {
|
||||
echo "#"
|
||||
echo "# >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
|
||||
echo "# THIS FILE IS GENERATED from the shell environment used to build the SALOME module."
|
||||
echo "# IT SHOULD NOT BE EDITED, it is generated for the need of the SALOME application "
|
||||
echo "# that embeds the module (for test purposes). "
|
||||
echo "# >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
|
||||
echo "#"
|
||||
}
|
||||
header > $ENVAPPLI_SH
|
||||
env | grep -v -e PWD -e SalomeAppConfig -e _ROOT_DIR | while read f; do
|
||||
key=$(echo $f | cut -d"=" -f1)
|
||||
value=$(echo $f | cut -d"=" -f2-)
|
||||
|
||||
# if the key is a path (LD_LIBRARY_PATH, PATH and PYTHONPATH) then
|
||||
# we must extends the variable.
|
||||
if [ $key == "LD_LIBRARY_PATH" -o $key == "PATH" -o $key == "PYTHONPATH" ]; then
|
||||
echo export $key=\"$value:\$$key\"
|
||||
else
|
||||
echo export $key=\"$value\"
|
||||
fi
|
||||
done >> $ENVAPPLI_SH
|
38
src/Tools/padder/resources/padderexe/Makefile.am
Normal file
@ -0,0 +1,38 @@
|
||||
# Copyright (C) 2011 EDF R&D
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
|
||||
#
|
||||
# Author(s): Guillaume Boulant (23/03/2011)
|
||||
#
|
||||
|
||||
include $(top_srcdir)/adm_local/unix/make_common_starter.am
|
||||
|
||||
mysalomeresdir=$(salomeresdir)/padderexe
|
||||
|
||||
version=med3
|
||||
|
||||
# We install the padder.exe program and the files required for testing
|
||||
# the execution from within the installation directory
|
||||
mysalomeres_SCRIPTS = \
|
||||
$(version)/padder.exe \
|
||||
envPadder.sh \
|
||||
padder.sh
|
||||
|
||||
mysalomeres_DATA = \
|
||||
$(version)/data.txt \
|
||||
$(version)/concrete.med \
|
||||
$(version)/ferraill.med
|
24
src/Tools/padder/resources/padderexe/buildparticules.py
Executable file
@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import geompy
|
||||
import salome
|
||||
salome.salome_init()
|
||||
theStudy = salome.myStudy
|
||||
geompy.init_geom(theStudy)
|
||||
|
||||
filename="/home/gboulant/development/projets/salome/SPADDER/spadder/resources/padderexe/REF_spheres.dat.xyz"
|
||||
file=open(filename,'rb')
|
||||
|
||||
import csv
|
||||
datalines = csv.reader(file, delimiter=' ')
|
||||
i=0
|
||||
for row in datalines:
|
||||
x=float(row[0])
|
||||
y=float(row[1])
|
||||
z=float(row[2])
|
||||
rayon=float(row[3])/2.
|
||||
|
||||
centre = geompy.MakeVertex(x, y, z)
|
||||
particule = geompy.MakeSpherePntR(centre, rayon)
|
||||
geompy.addToStudy( particule, 'p'+str(i) )
|
||||
i+=1
|
8
src/Tools/padder/resources/padderexe/envPadder.sh.in
Normal file
@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
# This script defines the shell extension required for executing the
|
||||
# padder executable program on the localhost (for test purposes)
|
||||
|
||||
MED_ROOT="@MED2HOME@"
|
||||
HDF_ROOT="@HDF5HOME@"
|
||||
CGAL_ROOT="/usr"
|
||||
export LD_LIBRARY_PATH="$MED_ROOT/lib:$HDF_ROOT/lib:$CGAL_ROOT/lib:$LD_LIBRARY_PATH"
|
BIN
src/Tools/padder/resources/padderexe/med2/REF_FinalEDMesh.med
Normal file
4097
src/Tools/padder/resources/padderexe/med2/REF_spheres.dat.xyz
Normal file
BIN
src/Tools/padder/resources/padderexe/med2/concrete.med
Normal file
5
src/Tools/padder/resources/padderexe/med2/data.txt
Normal file
@ -0,0 +1,5 @@
|
||||
concrete.med concrete
|
||||
nbSteelFiles 2
|
||||
ferrtran.med ferrtran
|
||||
ferraill.med ferraill
|
||||
output.med
|
BIN
src/Tools/padder/resources/padderexe/med2/ferraill.med
Normal file
BIN
src/Tools/padder/resources/padderexe/med2/ferrtran.med
Normal file
BIN
src/Tools/padder/resources/padderexe/med2/padder.exe
Executable file
BIN
src/Tools/padder/resources/padderexe/med3/concrete.med
Normal file
4
src/Tools/padder/resources/padderexe/med3/data.txt
Normal file
@ -0,0 +1,4 @@
|
||||
concrete.med concrete
|
||||
nbSteelbarMesh= 1
|
||||
ferraill.med ferraill
|
||||
FinalEDMesh.med
|
BIN
src/Tools/padder/resources/padderexe/med3/ferraill.med
Normal file
BIN
src/Tools/padder/resources/padderexe/med3/padder.exe
Executable file
15
src/Tools/padder/resources/padderexe/padder.sh
Executable file
@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
# This script emulates the launcher script that will be generated by
|
||||
# the padder SALOME component and give as the "job file" to the SALOME
|
||||
# launcher to execute the padder job.
|
||||
# The script is supposed to be executed where the data are located.
|
||||
|
||||
here=$(dirname $0)
|
||||
|
||||
# >>> This part should be written by the component
|
||||
binpath=$here/padder.exe
|
||||
envpath=$here/envPadder.sh
|
||||
# <<<
|
||||
|
||||
. $envpath
|
||||
$binpath $here/data.txt
|
BIN
src/Tools/padder/resources/padderexe/particules.png
Normal file
After Width: | Height: | Size: 328 KiB |
11
src/Tools/padder/spadderpy/Makefile.am
Normal file
@ -0,0 +1,11 @@
|
||||
include $(top_srcdir)/adm_local/unix/make_common_starter.am
|
||||
|
||||
SUBDIRS = gui plugin
|
||||
|
||||
spadderpydir=$(smeshpypkgdir)/spadder
|
||||
spadderpy_PYTHON = \
|
||||
__init__.py \
|
||||
configreader.py
|
||||
|
||||
salomeplugins_DATA = \
|
||||
padder.cfg
|
89
src/Tools/padder/spadderpy/__init__.py
Normal file
@ -0,0 +1,89 @@
|
||||
# Copyright (C) 2011 EDF R&D
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
|
||||
#
|
||||
# Author(s): Guillaume Boulant (23/03/2011)
|
||||
#
|
||||
|
||||
# TODO: put all this stuff in the unitests package
|
||||
|
||||
import os
|
||||
def getRootDir():
|
||||
'''
|
||||
This returns the root directory where the module SPADDER is
|
||||
installed. All test files are looked up from this location.
|
||||
'''
|
||||
return os.environ['SMESH_ROOT_DIR']
|
||||
|
||||
def getTestDataDir():
|
||||
'''
|
||||
This function gives the absolute path to the directory containing
|
||||
the data files for test (realistic med files).
|
||||
'''
|
||||
datadir=os.path.join(getRootDir(),"share/salome/resources/smesh/padderexe")
|
||||
return datadir
|
||||
|
||||
import MESHJOB # to get the enum constant values
|
||||
from MESHJOB import MeshJobParameter, MeshJobParameterList
|
||||
|
||||
DEFAULT_CONCRETE_FILENAME=os.path.join(getTestDataDir(),'concrete.med')
|
||||
DEFAULT_STEELBAR_LISTFILENAME=[
|
||||
os.path.join(getTestDataDir(),'ferraill.med')
|
||||
]
|
||||
|
||||
def getMeshJobParameterList(concrete_filename=DEFAULT_CONCRETE_FILENAME,
|
||||
steelbar_listfilename=DEFAULT_STEELBAR_LISTFILENAME):
|
||||
'''
|
||||
This helper function creates a complete set of parameters (a
|
||||
MeshJobParameterList) for a simple test case, i.e. a case with a
|
||||
concrete filename and a single steelbar filename.
|
||||
'''
|
||||
# Note that a CORBA sequence (MeshJobParameterList) is mapped on a
|
||||
# simple list in python
|
||||
meshJobParameterList = []
|
||||
# We can add some parameters
|
||||
param = MeshJobParameter(
|
||||
file_name = concrete_filename,
|
||||
file_type = MESHJOB.MED_CONCRETE,
|
||||
group_name = "concrete")
|
||||
meshJobParameterList.append(param)
|
||||
|
||||
for steelbar_filename in steelbar_listfilename:
|
||||
param = MeshJobParameter(
|
||||
file_name = steelbar_filename,
|
||||
file_type = MESHJOB.MED_STEELBAR,
|
||||
group_name = "steelbar")
|
||||
meshJobParameterList.append(param)
|
||||
|
||||
return meshJobParameterList
|
||||
|
||||
|
||||
def getSpadderCatalogFilename():
|
||||
filename=os.path.join(getRootDir(),"share/salome/resources/smesh/SPADDERCatalog.xml")
|
||||
return filename
|
||||
|
||||
def loadSpadderCatalog():
|
||||
import salome
|
||||
salome.salome_init()
|
||||
obj = salome.naming_service.Resolve('Kernel/ModulCatalog')
|
||||
import SALOME_ModuleCatalog
|
||||
catalog = obj._narrow(SALOME_ModuleCatalog.ModuleCatalog)
|
||||
if not catalog:
|
||||
raise RuntimeError, "Can't accesss module catalog"
|
||||
|
||||
filename = getSpadderCatalogFilename()
|
||||
catalog.ImportXmlCatalogFile(filename)
|
124
src/Tools/padder/spadderpy/configreader.py
Normal file
@ -0,0 +1,124 @@
|
||||
# -*- coding: iso-8859-1 -*-
|
||||
# Copyright (C) 2011 EDF R&D
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
|
||||
#
|
||||
# Author(s): Guillaume Boulant (23/03/2011)
|
||||
#
|
||||
|
||||
import sys, os
|
||||
import ConfigParser
|
||||
from MESHJOB import ConfigParameter
|
||||
from salome.kernel.uiexception import AdminException, UiException
|
||||
|
||||
CONFIG_FILENAME = "padder.cfg"
|
||||
TYPE_LOCAL = 'local'
|
||||
TYPE_REMOTE = 'remote'
|
||||
TYPES=[TYPE_LOCAL, TYPE_REMOTE]
|
||||
|
||||
class ConfigReader:
|
||||
def __init__(self):
|
||||
# The first step is to look for the config file. This file
|
||||
# is supposed to be located in the same directory than the
|
||||
# padder plugin. Then, we have to scan the directories
|
||||
# specified in the SALOME plugins path.
|
||||
self.__configFilename = None
|
||||
pluginspath=os.environ["SALOME_PLUGINS_PATH"]
|
||||
for path in pluginspath.split(":"):
|
||||
filename = os.path.join(path,CONFIG_FILENAME)
|
||||
if os.path.exists(filename):
|
||||
self.__configFilename = filename
|
||||
break
|
||||
if self.__configFilename is None:
|
||||
msg = "The configuration file %s can't be found in SALOME_PLUGINS_PATH"
|
||||
raise AdminException(msg%CONFIG_FILENAME)
|
||||
|
||||
print "The configuration file is : %s"%self.__configFilename
|
||||
self.__configparser = ConfigParser.RawConfigParser()
|
||||
self.__configparser.read(self.__configFilename)
|
||||
|
||||
def getLocalConfig(self):
|
||||
return self.__getConfig(TYPE_LOCAL)
|
||||
|
||||
def getRemoteConfig(self):
|
||||
return self.__getConfig(TYPE_REMOTE)
|
||||
|
||||
def getDefaultConfig(self):
|
||||
defaultType = self.__getDefaultType()
|
||||
return self.__getConfig(defaultType)
|
||||
|
||||
def __getConfig(self, type=TYPE_LOCAL):
|
||||
configName = self.__configparser.get('resources', type)
|
||||
resname = self.__configparser.get(configName, 'resname')
|
||||
binpath = self.__configparser.get(configName, 'binpath')
|
||||
envpath = self.__configparser.get(configName, 'envpath')
|
||||
config = ConfigParameter(resname, binpath, envpath)
|
||||
config.resname = resname
|
||||
return config
|
||||
|
||||
def __getDefaultType(self):
|
||||
'''This returns the default type read in the config file ([resources], default)'''
|
||||
defaultType = self.__configparser.get('preferences', 'defaultres')
|
||||
if defaultType not in TYPES:
|
||||
return TYPE_LOCAL
|
||||
return defaultType
|
||||
|
||||
#
|
||||
# =========================================================================
|
||||
# Test runner
|
||||
# =========================================================================
|
||||
#
|
||||
def TEST_getDefaultConfig():
|
||||
try:
|
||||
configReader = ConfigReader()
|
||||
defaultConfig = configReader.getDefaultConfig()
|
||||
print defaultConfig.resname
|
||||
print defaultConfig.binpath
|
||||
print defaultConfig.envpath
|
||||
except Exception, ex:
|
||||
sys.stderr.write('ERROR: %s\n' % str(ex))
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def TEST_getDefaultConfig_withError():
|
||||
global CONFIG_FILENAME
|
||||
CONFIG_FILENAME = "toto.cfg"
|
||||
try:
|
||||
configReader = ConfigReader()
|
||||
defaultConfig = configReader.getDefaultConfig()
|
||||
except UiException, err:
|
||||
print 'ERROR: %s' % str(err)
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
from salome.kernel import unittester
|
||||
moduleName = "configreader"
|
||||
|
||||
def testsuite():
|
||||
unittester.run(moduleName, "TEST_getDefaultConfig")
|
||||
unittester.run(moduleName, "TEST_getDefaultConfig_withError")
|
||||
|
||||
if __name__ == "__main__":
|
||||
import os, sys
|
||||
pluginspath=os.environ["SALOME_PLUGINS_PATH"]
|
||||
for path in pluginspath.split(":"):
|
||||
sys.path.insert(0,path)
|
||||
|
||||
testsuite()
|
36
src/Tools/padder/spadderpy/gui/Makefile.am
Normal file
@ -0,0 +1,36 @@
|
||||
include $(top_srcdir)/adm_local/unix/make_common_starter.am
|
||||
|
||||
#
|
||||
# Files that compose the spadder graphical interface used by the
|
||||
# plugin. They are installed in the spadder python package, under the
|
||||
# sub-package plugins.
|
||||
#
|
||||
spadderpydir=$(smeshpypkgdir)/spadder/gui
|
||||
spadderpy_PYTHON = \
|
||||
__init__.py \
|
||||
plugindialog_ui.py \
|
||||
plugindialog.py \
|
||||
inputframe_ui.py \
|
||||
inputdialog.py \
|
||||
inputdata.py
|
||||
|
||||
spadderpy_DATA= \
|
||||
parameters.png \
|
||||
input.png \
|
||||
select.png \
|
||||
compute.png \
|
||||
refresh.png \
|
||||
publish.png \
|
||||
clear.png \
|
||||
addinput.png \
|
||||
deleteinput.png \
|
||||
concrete.png \
|
||||
steelbar.png
|
||||
|
||||
PYUIC = @PYUIC@
|
||||
%_ui.py:%.ui
|
||||
$(PYUIC) -x $< -o $@
|
||||
|
||||
PYRCC = @PYRCC@
|
||||
%_rc.py:%.qrc
|
||||
$(PYRCC) $< -o $@
|
20
src/Tools/padder/spadderpy/gui/__init__.py
Normal file
@ -0,0 +1,20 @@
|
||||
# Copyright (C) 2011 EDF R&D
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
|
||||
#
|
||||
# Author(s): Guillaume Boulant (23/03/2011)
|
||||
#
|
BIN
src/Tools/padder/spadderpy/gui/addinput.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
src/Tools/padder/spadderpy/gui/clear.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
src/Tools/padder/spadderpy/gui/compute.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
src/Tools/padder/spadderpy/gui/concrete.png
Normal file
After Width: | Height: | Size: 353 B |
BIN
src/Tools/padder/spadderpy/gui/deleteinput.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
src/Tools/padder/spadderpy/gui/input.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
79
src/Tools/padder/spadderpy/gui/inputdata.py
Normal file
@ -0,0 +1,79 @@
|
||||
# -*- coding: iso-8859-1 -*-
|
||||
# Copyright (C) 2011 EDF R&D
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
|
||||
#
|
||||
# -* Makefile *-
|
||||
#
|
||||
# Author : Guillaume Boulant (EDF)
|
||||
#
|
||||
|
||||
from salome.kernel.enumerate import Enumerate
|
||||
from salome.kernel.datamodeler import DataModeler, TypeString, TypeInteger
|
||||
|
||||
# __MEM__: Note that this module does not depend on the SPADDER
|
||||
# component on purpose (we could have use a derived structure of
|
||||
# SPADDER_ORB.MeshJobParameter). This choice is made to ease the test
|
||||
# and development of the gui part of the plugin. If this data
|
||||
# structure becomes too important, we could make another arrangement
|
||||
# and use directly a SPADDER_ORB.MeshJobParameter.
|
||||
|
||||
class InputData(DataModeler):
|
||||
MESHTYPES=Enumerate([
|
||||
'CONCRETE',
|
||||
'STEELBAR'
|
||||
])
|
||||
|
||||
def __init__(self):
|
||||
DataModeler.__init__(self)
|
||||
self.addAttribute(
|
||||
name = "meshObject",
|
||||
void = True
|
||||
)
|
||||
self.addAttribute(
|
||||
name = "meshName",
|
||||
type = TypeString,
|
||||
range = None
|
||||
)
|
||||
self.addAttribute(
|
||||
name = "meshType",
|
||||
type = TypeInteger,
|
||||
range = self.MESHTYPES.listvalues()
|
||||
)
|
||||
self.addAttribute(
|
||||
name = "groupName",
|
||||
type = TypeString,
|
||||
range = None
|
||||
)
|
||||
|
||||
#
|
||||
# ==============================================================================
|
||||
# Basic use cases and unit tests
|
||||
# ==============================================================================
|
||||
#
|
||||
def TEST_getName():
|
||||
testdata = InputData()
|
||||
testdata.meshName = "myMesh"
|
||||
testdata.meshObject = None
|
||||
testdata.meshType = InputData.MESHTYPES.CONCRETE
|
||||
if testdata.meshName != "myMesh" :
|
||||
return False
|
||||
return True
|
||||
|
||||
if __name__ == "__main__":
|
||||
from salome.kernel.unittester import run
|
||||
run("inputdata","TEST_getName")
|
378
src/Tools/padder/spadderpy/gui/inputdialog.py
Normal file
@ -0,0 +1,378 @@
|
||||
# -*- coding: iso-8859-1 -*-
|
||||
# Copyright (C) 2011 EDF R&D
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
|
||||
#
|
||||
# -* Makefile *-
|
||||
#
|
||||
# Author : Guillaume Boulant (EDF)
|
||||
#
|
||||
|
||||
import os
|
||||
|
||||
import salome
|
||||
from salome.kernel import studyedit
|
||||
from salome.gui.genericdialog import GenericDialog
|
||||
from salome.gui import helper as guihelper
|
||||
from salome.smesh.smeshstudytools import SMeshStudyTools
|
||||
|
||||
from omniORB import CORBA
|
||||
|
||||
from PyQt4.QtCore import QObject, SIGNAL, SLOT
|
||||
from PyQt4.QtGui import QIcon, QStandardItemModel, QStandardItem, QMessageBox
|
||||
|
||||
from inputframe_ui import Ui_InputFrame
|
||||
from inputdata import InputData
|
||||
|
||||
DEBUG_MODE=True
|
||||
GROUPNAME_MAXLENGTH=8
|
||||
|
||||
class InputDialog(GenericDialog):
|
||||
|
||||
TBL_HEADER_LABEL=["Input Mesh", "Output group name"]
|
||||
|
||||
def __init__(self, parent=None, name="InputDialog", modal=0):
|
||||
"""
|
||||
This initializes a dialog windows to define the input data of
|
||||
the plugin function. The input data consist in a list of
|
||||
meshes characterizes each by a name, a pointer to the smesh
|
||||
servant object, a type and a group name (see data model in the
|
||||
inputdata.py).
|
||||
"""
|
||||
GenericDialog.__init__(self, parent, name, modal)
|
||||
# Set up the user interface from Designer.
|
||||
self.__ui = Ui_InputFrame()
|
||||
# BE CAREFULL HERE, the ui form is NOT drawn in the global
|
||||
# dialog (already containing some generic widgets) but in the
|
||||
# center panel created in the GenericDialog as a void
|
||||
# container for the form. The InputFrame form is supposed
|
||||
# here to create only the widgets to be placed in the center
|
||||
# panel. Then, the setupUi function of this form draws itself
|
||||
# in the specified panel, i.e. the panel returned by
|
||||
# self.getPanel().
|
||||
self.__ui.setupUi(self.getPanel())
|
||||
|
||||
self.setWindowTitle("Specification of input files")
|
||||
|
||||
# The icon are supposed to be located in the plugin folder,
|
||||
# i.e. in the same folder than this python module file
|
||||
iconfolder=os.path.dirname(os.path.abspath(__file__))
|
||||
icon = QIcon()
|
||||
icon.addFile(os.path.join(iconfolder,"select.png"))
|
||||
self.__ui.btnSmeshObject.setIcon(icon)
|
||||
icon = QIcon()
|
||||
icon.addFile(os.path.join(iconfolder,"addinput.png"))
|
||||
self.__ui.btnAddInput.setIcon(icon)
|
||||
icon = QIcon()
|
||||
icon.addFile(os.path.join(iconfolder,"deleteinput.png"))
|
||||
self.__ui.btnDeleteInput.setIcon(icon)
|
||||
|
||||
# We specify here the items in the combo box (even if already
|
||||
# defined in the designer) so that we can be sure of the item
|
||||
# indexation.
|
||||
self.MESHTYPE_ICONS = {}
|
||||
meshTypeIndex = InputData.MESHTYPES.CONCRETE
|
||||
self.__ui.cmbMeshType.setItemText(meshTypeIndex, "Béton")
|
||||
icon = QIcon()
|
||||
icon.addFile(os.path.join(iconfolder,"concrete.png"))
|
||||
self.__ui.cmbMeshType.setItemIcon(meshTypeIndex, icon)
|
||||
self.MESHTYPE_ICONS[meshTypeIndex] = icon
|
||||
|
||||
meshTypeIndex = InputData.MESHTYPES.STEELBAR
|
||||
self.__ui.cmbMeshType.setItemText(meshTypeIndex, "Acier")
|
||||
icon = QIcon()
|
||||
icon.addFile(os.path.join(iconfolder,"steelbar.png"))
|
||||
self.__ui.cmbMeshType.setItemIcon(meshTypeIndex, icon)
|
||||
self.MESHTYPE_ICONS[meshTypeIndex] = icon
|
||||
|
||||
# The click on btnSmeshObject (signal clicked() emitted by the
|
||||
# button btnSmeshObject) is connected to the slot
|
||||
# onSelectSmeshObject, etc ...
|
||||
self.connect(self.__ui.btnSmeshObject, SIGNAL('clicked()'), self.onSelectSmeshObject )
|
||||
self.connect(self.__ui.btnAddInput, SIGNAL('clicked()'), self.onAddInput )
|
||||
self.connect(self.__ui.btnDeleteInput, SIGNAL('clicked()'), self.onDeleteInput )
|
||||
|
||||
# Set up the model of the Qt table list
|
||||
self.__inputModel = QStandardItemModel(0,2)
|
||||
self.__inputModel.setHorizontalHeaderLabels(InputDialog.TBL_HEADER_LABEL)
|
||||
self.__ui.tblListInput.setModel(self.__inputModel)
|
||||
self.__ui.tblListInput.verticalHeader().hide()
|
||||
self.__ui.tblListInput.horizontalHeader().setStretchLastSection(True)
|
||||
# Note that the type is not display explicitly in the Qt table
|
||||
# because it is specified using an icon on the text of the
|
||||
# name item.
|
||||
|
||||
# Note that PADDER does not support group name longer than 8
|
||||
# characters. We apply then this limit in the gui field.
|
||||
self.__ui.txtGroupName.setMaxLength(GROUPNAME_MAXLENGTH)
|
||||
|
||||
self.clear()
|
||||
|
||||
self.smeshStudyTool = SMeshStudyTools()
|
||||
|
||||
def clear(self):
|
||||
"""
|
||||
This function clears the data gui area and associated values.
|
||||
"""
|
||||
self.__ui.txtSmeshObject.setText("")
|
||||
self.__ui.txtGroupName.setText("")
|
||||
self.__inputModel.clear()
|
||||
self.__inputModel.setHorizontalHeaderLabels(InputDialog.TBL_HEADER_LABEL)
|
||||
if not DEBUG_MODE:
|
||||
self.__ui.txtSmeshObject.setEnabled(False)
|
||||
self.__ui.btnAddInput.setEnabled(False)
|
||||
self.__selectedMesh = None
|
||||
self.__dictInputData = {}
|
||||
self.__nbConcreteMesh = 0
|
||||
self.__nbSteelbarMesh = 0
|
||||
|
||||
def accept(self):
|
||||
"""
|
||||
This function is the slot connected to the button OK
|
||||
"""
|
||||
# The dialog is raised in a non modal mode to get
|
||||
# interactivity with the parents windows. Then we have to emit
|
||||
# a signal to warn the parent observer that the dialog has
|
||||
# been validated so that it can process the event
|
||||
GenericDialog.accept(self)
|
||||
if self.wasOk():
|
||||
self.emit(SIGNAL('inputValidated()'))
|
||||
|
||||
def onSelectSmeshObject(self):
|
||||
'''
|
||||
This function is the slot connected on the mesh selection
|
||||
button. It memorizes the selected mesh and put its name in the
|
||||
text field of the dialog box.
|
||||
'''
|
||||
mySObject, myEntry = guihelper.getSObjectSelected()
|
||||
if CORBA.is_nil(mySObject):
|
||||
self.__ui.txtSmeshObject.setText("You must choose a mesh")
|
||||
self.__ui.txtGroupName.setText("")
|
||||
self.__ui.txtSmeshObject.setEnabled(False)
|
||||
self.__ui.btnAddInput.setEnabled(False)
|
||||
self.__selectedMesh = None
|
||||
return
|
||||
|
||||
self.smeshStudyTool.updateStudy(studyedit.getActiveStudyId())
|
||||
self.__selectedMesh = self.smeshStudyTool.getMeshObjectFromSObject(mySObject)
|
||||
if CORBA.is_nil(self.__selectedMesh):
|
||||
self.__ui.txtSmeshObject.setText("The selected object is not a mesh")
|
||||
self.__ui.txtGroupName.setText("")
|
||||
self.__ui.txtSmeshObject.setEnabled(False)
|
||||
self.__ui.btnAddInput.setEnabled(False)
|
||||
self.__selectedMesh = None
|
||||
return
|
||||
myName = mySObject.GetName()
|
||||
self.__ui.txtSmeshObject.setText(myName)
|
||||
self.__ui.txtSmeshObject.setEnabled(True)
|
||||
self.__ui.btnAddInput.setEnabled(True)
|
||||
|
||||
# We can suggest a default group name from the mesh name
|
||||
self.__ui.txtGroupName.setText(myName)
|
||||
|
||||
def onAddInput(self):
|
||||
"""
|
||||
This function is the slot connected to the Add button. It
|
||||
creates a new entry in the list of input data, or updates this
|
||||
entry if it already exists.
|
||||
"""
|
||||
meshName = str(self.__ui.txtSmeshObject.text().trimmed())
|
||||
meshObject = self.__selectedMesh
|
||||
meshType = self.__ui.cmbMeshType.currentIndex()
|
||||
groupName = str(self.__ui.txtGroupName.text().trimmed())
|
||||
|
||||
self.__addInputInGui(meshName, meshObject, meshType, groupName)
|
||||
self.__addInputInMap(meshName, meshObject, meshType, groupName)
|
||||
|
||||
def __addInputInGui(self, meshName, meshObject, meshType, groupName):
|
||||
"""
|
||||
This function adds an entry with the specified data int the
|
||||
GUI table (for data visualization purpose).
|
||||
"""
|
||||
# The mesh name is used as the key index in the model. We have
|
||||
# to check first if this item already exists in the list.
|
||||
tblItems = self.__inputModel.findItems(meshName)
|
||||
row = self.__inputModel.rowCount()
|
||||
if not tblItems:
|
||||
tblItems = []
|
||||
tblItems.append(QStandardItem()) # input mesh name
|
||||
tblItems.append(QStandardItem()) # output group name
|
||||
else:
|
||||
row = tblItems[0].index().row()
|
||||
tblItems.append(self.__inputModel.item(row,1))
|
||||
|
||||
tblItems[0].setText(meshName)
|
||||
tblItems[0].setIcon(self.MESHTYPE_ICONS[meshType])
|
||||
tblItems[1].setText(groupName)
|
||||
self.__inputModel.setItem(row,0,tblItems[0])
|
||||
self.__inputModel.setItem(row,1,tblItems[1])
|
||||
self.__ui.tblListInput.setCurrentIndex(tblItems[0].index())
|
||||
|
||||
def __addInputInMap(self, meshName, meshObject, meshType, groupName):
|
||||
"""
|
||||
This function adds an entry with the specified data in the
|
||||
internal map (for data management purpose).
|
||||
"""
|
||||
# if the entry already exists, we remove it to replace by a
|
||||
# new one
|
||||
if self.__dictInputData.has_key(meshName):
|
||||
self.__delInputFromMap(meshName)
|
||||
|
||||
inputData = InputData()
|
||||
inputData.meshName = meshName
|
||||
inputData.meshObject = meshObject
|
||||
inputData.meshType = meshType
|
||||
inputData.groupName = groupName
|
||||
# The key of the map is the mesh name
|
||||
self.__dictInputData[meshName] = inputData
|
||||
if inputData.meshType == InputData.MESHTYPES.CONCRETE:
|
||||
self.__nbConcreteMesh += 1
|
||||
else:
|
||||
self.__nbSteelbarMesh += 1
|
||||
|
||||
print inputData
|
||||
print "meshType = ",inputData.meshType
|
||||
print "nb concrete mesh ",self.__nbConcreteMesh
|
||||
print "nb steelbar mesh ",self.__nbSteelbarMesh
|
||||
|
||||
|
||||
def onDeleteInput(self):
|
||||
"""
|
||||
This function is the slot connected to the Delete button. It
|
||||
remove from the data list the entry selected in the Qt table.
|
||||
"""
|
||||
selectedIdx = self.__ui.tblListInput.selectedIndexes()
|
||||
if selectedIdx:
|
||||
row = selectedIdx[0].row()
|
||||
tblItem = self.__inputModel.item(row,0)
|
||||
meshName = str(tblItem.text())
|
||||
self.__inputModel.takeRow(row)
|
||||
# Don't forget to remove this entry from the mesh object
|
||||
# internal dictionnary
|
||||
self.__delInputFromMap(meshName)
|
||||
|
||||
def __delInputFromMap(self, meshName):
|
||||
"""
|
||||
This function removes the specified entry from the internal
|
||||
map (for data management purpose)
|
||||
"""
|
||||
inputData = self.__dictInputData.pop(meshName)
|
||||
if inputData.meshType == InputData.MESHTYPES.CONCRETE:
|
||||
self.__nbConcreteMesh -= 1
|
||||
else:
|
||||
self.__nbSteelbarMesh -= 1
|
||||
|
||||
print inputData
|
||||
print "nb concrete mesh ",self.__nbConcreteMesh
|
||||
print "nb steelbar mesh ",self.__nbSteelbarMesh
|
||||
|
||||
|
||||
def setData(self, listInputData=[]):
|
||||
"""
|
||||
This function fills the dialog widgets with values provided by
|
||||
the specified data list.
|
||||
"""
|
||||
self.clear()
|
||||
for inputData in listInputData:
|
||||
|
||||
meshName = inputData.meshName
|
||||
meshObject = inputData.meshObject
|
||||
meshType = inputData.meshType
|
||||
groupName = inputData.groupName
|
||||
|
||||
self.__addInputInGui(meshName, meshObject, meshType, groupName)
|
||||
self.__addInputInMap(meshName, meshObject, meshType, groupName)
|
||||
|
||||
if not DEBUG_MODE:
|
||||
self.onSelectSmeshObject()
|
||||
|
||||
def getData(self):
|
||||
"""
|
||||
This function returns a list of InputData that corresponds to
|
||||
the data in the dialog widgets of the current dialog.
|
||||
"""
|
||||
# Note that the values() function returns a copy of the list
|
||||
# of values.
|
||||
return self.__dictInputData.values()
|
||||
|
||||
def checkData(self):
|
||||
"""
|
||||
This function checks if the data are valid, from the dialog
|
||||
window point of view.
|
||||
"""
|
||||
if self.__nbConcreteMesh < 1:
|
||||
self.checkDataMessage = "You must define at least one CONCRETE mesh"
|
||||
return False
|
||||
if self.__nbConcreteMesh > 1:
|
||||
self.checkDataMessage = "You define multiple CONCRETE meshes."
|
||||
self.checkDataMessage += "You should verify first that your version of PADDER support this configuration."
|
||||
# just warn the user, but don't block
|
||||
QMessageBox.information(self, "Info", self.checkDataMessage)
|
||||
return True
|
||||
if self.__nbSteelbarMesh < 1:
|
||||
self.checkDataMessage = "You must define at least one STEELBAR mesh"
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
# ==============================================================================
|
||||
# Basic use case
|
||||
# ==============================================================================
|
||||
#
|
||||
def TEST_InputDialog():
|
||||
import sys
|
||||
from PyQt4.QtCore import QObject, SIGNAL, SLOT
|
||||
from PyQt4.QtGui import QApplication
|
||||
app = QApplication(sys.argv)
|
||||
QObject.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()"))
|
||||
|
||||
dlg=InputDialog()
|
||||
dlg.displayAndWait()
|
||||
if dlg.wasOk():
|
||||
print "OK has been pressed"
|
||||
|
||||
def TEST_InputDialog_setData():
|
||||
import sys
|
||||
from PyQt4.QtCore import QObject, SIGNAL, SLOT
|
||||
from PyQt4.QtGui import QApplication
|
||||
app = QApplication(sys.argv)
|
||||
QObject.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()"))
|
||||
|
||||
dlg=InputDialog()
|
||||
|
||||
from inputdata import InputData
|
||||
inputData = InputData()
|
||||
inputData.meshName = "myMesh"
|
||||
inputData.meshObject = None
|
||||
inputData.meshType = InputData.MESHTYPES.CONCRETE
|
||||
inputData.groupName = "myGroup"
|
||||
listInputData = []
|
||||
listInputData.append(inputData)
|
||||
|
||||
dlg.setData2(listInputData)
|
||||
|
||||
dlg.displayAndWait()
|
||||
if dlg.wasOk():
|
||||
print "OK has been pressed"
|
||||
outputListInputData = dlg.getData2()
|
||||
print outputListInputData
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
#TEST_InputDialog()
|
||||
TEST_InputDialog_setData()
|
||||
|
204
src/Tools/padder/spadderpy/gui/inputframe.ui
Normal file
@ -0,0 +1,204 @@
|
||||
<ui version="4.0" >
|
||||
<class>InputFrame</class>
|
||||
<widget class="QDialog" name="InputFrame" >
|
||||
<property name="geometry" >
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>509</width>
|
||||
<height>307</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle" >
|
||||
<string>Input parameters</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" >
|
||||
<property name="margin" >
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" >
|
||||
<property name="margin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblSmeshObject" >
|
||||
<property name="text" >
|
||||
<string>Input MESH / Output group name / Type :</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" >
|
||||
<property name="margin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" >
|
||||
<property name="margin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" >
|
||||
<property name="margin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" >
|
||||
<property name="margin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnSmeshObject" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy>
|
||||
<hsizetype>0</hsizetype>
|
||||
<vsizetype>0</vsizetype>
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize" >
|
||||
<size>
|
||||
<width>31</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon" >
|
||||
<iconset>select.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="txtSmeshObject" >
|
||||
<property name="toolTip" >
|
||||
<string comment="Select the input mesh in the object browser" />
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line" >
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="txtGroupName" >
|
||||
<property name="toolTip" >
|
||||
<string comment="Specify the name of the associated group in the output mesh" />
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line_2" >
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="cmbMeshType" >
|
||||
<property name="toolTip" >
|
||||
<string comment="Select the type of the mesh" />
|
||||
</property>
|
||||
<item>
|
||||
<property name="text" >
|
||||
<string>Béton</string>
|
||||
</property>
|
||||
<property name="icon" >
|
||||
<iconset>concrete.png</iconset>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text" >
|
||||
<string>Acier</string>
|
||||
</property>
|
||||
<property name="icon" >
|
||||
<iconset>steelbar.png</iconset>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTableView" name="tblListInput" />
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" >
|
||||
<property name="margin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnAddInput" >
|
||||
<property name="text" >
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon" >
|
||||
<iconset>addinput.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnDeleteInput" >
|
||||
<property name="text" >
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon" >
|
||||
<iconset>deleteinput.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
BIN
src/Tools/padder/spadderpy/gui/parameters.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
386
src/Tools/padder/spadderpy/gui/plugindialog.py
Normal file
@ -0,0 +1,386 @@
|
||||
# -*- coding: iso-8859-1 -*-
|
||||
# Copyright (C) 2011 EDF R&D
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
|
||||
#
|
||||
# -* Makefile *-
|
||||
#
|
||||
# Author : Guillaume Boulant (EDF)
|
||||
#
|
||||
|
||||
from PyQt4.QtGui import QDialog, QMessageBox, QIcon
|
||||
from PyQt4.QtCore import QObject, SIGNAL, SLOT, Qt
|
||||
|
||||
from plugindialog_ui import Ui_PluginDialog
|
||||
from inputdialog import InputDialog
|
||||
from inputdata import InputData
|
||||
# __GBO__: uncomment this line and comment the previous one to use the
|
||||
# demo input dialog instead of the real one.
|
||||
#from demoinputdialog import InputDialog
|
||||
|
||||
import os
|
||||
import salome
|
||||
from salome.kernel import studyedit
|
||||
|
||||
from omniORB import CORBA
|
||||
import SMESH
|
||||
import smesh
|
||||
import MESHJOB
|
||||
|
||||
gui_states = ["CAN_SELECT", "CAN_COMPUTE", "CAN_REFRESH", "CAN_PUBLISH"]
|
||||
|
||||
run_states = ["CREATED", "IN_PROCESS", "QUEUED", "RUNNING", "PAUSED"];
|
||||
end_states = ["FINISHED", "ERROR"]
|
||||
all_states = run_states+end_states;
|
||||
|
||||
# The SALOME launcher resource is specified by its name as defined in
|
||||
# the file CatalogResources.xml (see root directory of the
|
||||
# application). We could have a check box in the dialog to specify
|
||||
# wether we want a local execution or a remote one.
|
||||
resource_name = "localhost"
|
||||
from salome.smesh.spadder.configreader import ConfigReader
|
||||
|
||||
|
||||
class PluginDialog(QDialog):
|
||||
|
||||
def __init__(self,parent = None,name = None,modal = 0,fl = 0):
|
||||
QDialog.__init__(self,parent)
|
||||
# Set up the user interface from Designer.
|
||||
self.__ui = Ui_PluginDialog()
|
||||
self.__ui.setupUi(self)
|
||||
|
||||
# The default display strategy is to use a separate dialog box
|
||||
# to select the input data.
|
||||
self.viewInputFrame(False)
|
||||
|
||||
# The icon are supposed to be located in the plugin folder,
|
||||
# i.e. in the same folder than this python module file
|
||||
iconfolder=os.path.dirname(os.path.abspath(__file__))
|
||||
icon = QIcon()
|
||||
icon.addFile(os.path.join(iconfolder,"input.png"))
|
||||
self.__ui.btnInput.setIcon(icon)
|
||||
icon = QIcon()
|
||||
icon.addFile(os.path.join(iconfolder,"compute.png"))
|
||||
self.__ui.btnCompute.setIcon(icon)
|
||||
icon = QIcon()
|
||||
icon.addFile(os.path.join(iconfolder,"refresh.png"))
|
||||
self.__ui.btnRefresh.setIcon(icon)
|
||||
icon = QIcon()
|
||||
icon.addFile(os.path.join(iconfolder,"publish.png"))
|
||||
self.__ui.btnPublish.setIcon(icon)
|
||||
icon = QIcon()
|
||||
icon.addFile(os.path.join(iconfolder,"clear.png"))
|
||||
self.__ui.btnClear.setIcon(icon)
|
||||
|
||||
# Then, we can connect the slot to there associated button event
|
||||
self.connect(self.__ui.btnInput, SIGNAL('clicked()'), self.onInput )
|
||||
self.connect(self.__ui.btnCompute, SIGNAL('clicked()'), self.onCompute )
|
||||
self.connect(self.__ui.btnRefresh, SIGNAL('clicked()'), self.onRefresh )
|
||||
self.connect(self.__ui.btnPublish, SIGNAL('clicked()'), self.onPublish )
|
||||
self.connect(self.__ui.btnClear, SIGNAL('clicked()'), self.onClear )
|
||||
|
||||
self.clear()
|
||||
|
||||
self.setupJobManager()
|
||||
|
||||
|
||||
def setupJobManager(self):
|
||||
'''
|
||||
This function configures the jobmanager by transmiting the
|
||||
parameters required for a local execution and a remote
|
||||
execution. The choice between "local" and "remote" is done at
|
||||
the initialize step, by specifing the name of the resource to
|
||||
be used.
|
||||
'''
|
||||
configReader = ConfigReader()
|
||||
config = configReader.getLocalConfig()
|
||||
configId = config.resname
|
||||
self.__getJobManager().configure(configId, config)
|
||||
# Note that the resname parameter is used as the key identifier of
|
||||
# the configuration in the job manager. As is, there can be then
|
||||
# only one configuration for each machine defined in the resources
|
||||
# catalog (no need to have further, I thing)
|
||||
config = configReader.getRemoteConfig()
|
||||
configId = config.resname
|
||||
self.__getJobManager().configure(configId, config)
|
||||
|
||||
# We specify the default configuration identifier as the
|
||||
# resource name of the default configuration
|
||||
self.__configId = configReader.getDefaultConfig().resname
|
||||
|
||||
|
||||
def viewInputFrame(self, view=True):
|
||||
# By default, the top input frame is visible and the input
|
||||
# button is not visible.
|
||||
if view is False:
|
||||
self.__ui.frameInput.setVisible(False)
|
||||
self.__ui.btnInput.setVisible(True)
|
||||
# We create the input dialog that will be displayed when
|
||||
# button input is pressed:
|
||||
self.__inputDialog = InputDialog(self)
|
||||
# The window is kept on the top to ease the selection of
|
||||
# items in the object browser:
|
||||
self.__inputDialog.setWindowFlags(
|
||||
self.__inputDialog.windowFlags() | Qt.WindowStaysOnTopHint)
|
||||
# The signal inputValidated emited from inputDialog is
|
||||
# connected to the slot function onProcessInput:
|
||||
self.connect(self.__inputDialog, SIGNAL('inputValidated()'), self.onProcessInput)
|
||||
|
||||
else:
|
||||
self.__ui.frameInput.setVisible(True)
|
||||
self.__ui.btnInput.setVisible(False)
|
||||
# This case is NOT IMPLEMENTED YET (not really). It could
|
||||
# be used to draw the input frame directly in the frame
|
||||
# frameInput of this dialog box.
|
||||
|
||||
def getInputFrame(self):
|
||||
return self.__ui.frameInput
|
||||
|
||||
def __setGuiState(self,states=["CAN_SELECT"]):
|
||||
if "CAN_SELECT" in states:
|
||||
self.__ui.btnInput.setEnabled(True)
|
||||
else:
|
||||
self.__ui.btnInput.setEnabled(False)
|
||||
|
||||
if "CAN_COMPUTE" in states:
|
||||
self.__ui.btnCompute.setEnabled(True)
|
||||
else:
|
||||
self.__ui.btnCompute.setEnabled(False)
|
||||
|
||||
if "CAN_REFRESH" in states:
|
||||
self.__ui.btnRefresh.setEnabled(True)
|
||||
else:
|
||||
self.__ui.btnRefresh.setEnabled(False)
|
||||
|
||||
if "CAN_PUBLISH" in states:
|
||||
self.__ui.btnPublish.setEnabled(True)
|
||||
else:
|
||||
self.__ui.btnPublish.setEnabled(False)
|
||||
|
||||
def __getJobManager(self):
|
||||
"""
|
||||
This function requests a pointer to the MeshJobManager servant.
|
||||
"""
|
||||
component=salome.lcc.FindOrLoadComponent("FactoryServer","MeshJobManager")
|
||||
if component is None:
|
||||
self.__log("ERR: the SALOME component MeshJobManager can't be reached")
|
||||
return component
|
||||
|
||||
def __log(self, message):
|
||||
"""
|
||||
This function prints the specified message in the log area
|
||||
"""
|
||||
self.__ui.txtLog.append(message)
|
||||
|
||||
def __exportMesh(self, meshName, meshObject):
|
||||
'''
|
||||
This function exports the specified mesh object to a med
|
||||
file whose name (basepath) is built from the specified mesh
|
||||
name. This returns the filename.
|
||||
'''
|
||||
filename=str("/tmp/padder_inputfile_"+meshName+".med")
|
||||
meshObject.ExportToMEDX( filename, 0, SMESH.MED_V2_2, 1 )
|
||||
return filename
|
||||
|
||||
def clear(self):
|
||||
"""
|
||||
This function clears the log area and the states of the buttons
|
||||
"""
|
||||
self.__listInputData = []
|
||||
self.__ui.txtLog.clear()
|
||||
self.__setGuiState(["CAN_SELECT"])
|
||||
self.__isRunning = False
|
||||
self.__ui.lblStatusBar.setText("Ready")
|
||||
|
||||
def update(self):
|
||||
'''
|
||||
This function can be used to programmatically force the
|
||||
refresh of the dialog box, the job state in particular.
|
||||
'''
|
||||
if self.__isRunning:
|
||||
self.onRefresh()
|
||||
|
||||
def onInput(self):
|
||||
'''
|
||||
This function is the slot connected to the Input button
|
||||
(signal clicked()). It opens the dialog window to input
|
||||
data. The dialog is opened in a window modal mode so that the
|
||||
SALOME study objects can be selected. In conterpart, this
|
||||
class must listen to signals emitted by the child dialog
|
||||
windows to process the validation event (see the slot
|
||||
onProcessInput which is connected to this event).
|
||||
'''
|
||||
self.__inputDialog.setData(self.__listInputData)
|
||||
self.__inputDialog.open()
|
||||
|
||||
def onProcessInput(self):
|
||||
"""
|
||||
This function is the slot connected to the signal
|
||||
inputValidated(), emit by the input dialog window when it's
|
||||
validated, i.e. OK is pressed and data are valid.
|
||||
"""
|
||||
# The processing simply consists in requesting the input data
|
||||
# from the dialog window.
|
||||
self.__listInputData = self.__inputDialog.getData()
|
||||
self.__ui.lblStatusBar.setText("Input data OK")
|
||||
self.__setGuiState(["CAN_SELECT", "CAN_COMPUTE"])
|
||||
|
||||
|
||||
def onCompute(self):
|
||||
'''
|
||||
This function is the slot connected to the Compute button. It
|
||||
initializes a mesh computation job and start it using the
|
||||
SALOME launcher.
|
||||
'''
|
||||
# We first have to create the list of parameters for the
|
||||
# initialize function. For that, we have to create the files
|
||||
# from the mesh objects:
|
||||
meshJobParameterList=[]
|
||||
concreteIndex=0
|
||||
for inputData in self.__listInputData:
|
||||
# For each input data, we have to create a
|
||||
# MeshJobParameter and add it to the list.
|
||||
filename = self.__exportMesh(inputData.meshName, inputData.meshObject)
|
||||
if inputData.meshType == InputData.MESHTYPES.CONCRETE:
|
||||
filetype = MESHJOB.MED_CONCRETE
|
||||
else:
|
||||
filetype = MESHJOB.MED_STEELBAR
|
||||
|
||||
parameter = MESHJOB.MeshJobParameter(
|
||||
file_name = filename,
|
||||
file_type = filetype,
|
||||
group_name = inputData.groupName)
|
||||
meshJobParameterList.append(parameter)
|
||||
|
||||
jobManager = self.__getJobManager()
|
||||
self.__jobid = jobManager.initialize(meshJobParameterList, self.__configId)
|
||||
if self.__jobid < 0:
|
||||
self.__log("ERR: the job can't be initialized")
|
||||
return
|
||||
self.__log("INF: the job has been initialized with jobid = "+str(self.__jobid))
|
||||
|
||||
startOk = jobManager.start(self.__jobid)
|
||||
if not startOk:
|
||||
self.__log("ERR: the job with jobid = "+str(self.__jobid)+" can't be started")
|
||||
return
|
||||
self.__log("INF: the job "+str(self.__jobid)+" has been started")
|
||||
self.__ui.lblStatusBar.setText("Submission OK")
|
||||
self.__setGuiState(["CAN_REFRESH"])
|
||||
self.__isRunning = True
|
||||
|
||||
def onRefresh(self):
|
||||
"""
|
||||
This function is the slot connected on the Refresh button. It
|
||||
requests the mesh job manager to get the state of the job and
|
||||
display it in the log area.
|
||||
"""
|
||||
jobManager = self.__getJobManager()
|
||||
state = jobManager.getState(self.__jobid)
|
||||
self.__log("INF: job state = "+str(state))
|
||||
self.__ui.lblStatusBar.setText("")
|
||||
if state in run_states:
|
||||
return
|
||||
|
||||
self.__isRunning = False
|
||||
if state == "FINISHED":
|
||||
self.__setGuiState(["CAN_PUBLISH"])
|
||||
else:
|
||||
self.__setGuiState(["CAN_SELECT"])
|
||||
|
||||
|
||||
def onPublish(self):
|
||||
"""
|
||||
This function is the slot connected on the Publish button. It
|
||||
requests the mesh job manager to download the results data
|
||||
from the computation resource host and load the med file in
|
||||
the SALOME study.
|
||||
"""
|
||||
jobManager = self.__getJobManager()
|
||||
state = jobManager.getState(self.__jobid)
|
||||
if state in run_states:
|
||||
self.__log("WRN: jobid = "+str(self.__jobid)+" is not finished (state="+str(state)+")")
|
||||
return
|
||||
|
||||
if state not in end_states:
|
||||
self.__log("ERR: jobid = "+str(self.__jobid)+" ended abnormally with state="+str(state))
|
||||
return
|
||||
|
||||
meshJobResults = jobManager.finalize(self.__jobid)
|
||||
if state == "ERROR":
|
||||
self.__log("ERR: jobid = "+str(self.__jobid)+" ended with error: "+meshJobResults.status)
|
||||
return
|
||||
|
||||
logsdirname = os.path.join(meshJobResults.results_dirname, "logs")
|
||||
self.__log("INF: jobid="+str(self.__jobid)+" ended normally : "+meshJobResults.status)
|
||||
self.__log("INF: jobid="+str(self.__jobid)+" see log files in : "+logsdirname)
|
||||
|
||||
medfilename = os.path.join(meshJobResults.results_dirname,
|
||||
meshJobResults.outputmesh_filename)
|
||||
|
||||
smesh.SetCurrentStudy(studyedit.getActiveStudy())
|
||||
([outputMesh], status) = smesh.CreateMeshesFromMED(medfilename)
|
||||
|
||||
# By convention, the name of the output mesh in the study is
|
||||
# build from a constant string 'padder' and the session jobid
|
||||
meshname = 'padder_'+str(self.__jobid)
|
||||
smesh.SetName(outputMesh.GetMesh(), meshname)
|
||||
if salome.sg.hasDesktop():
|
||||
salome.sg.updateObjBrowser(0)
|
||||
|
||||
self.__ui.lblStatusBar.setText("Publication OK")
|
||||
self.__setGuiState(["CAN_SELECT"])
|
||||
|
||||
def onClear(self):
|
||||
"""
|
||||
This function is the slot connected on the Clear button. It
|
||||
erases data in the dialog box and cancel the current job if
|
||||
one is running.
|
||||
"""
|
||||
self.clear()
|
||||
|
||||
|
||||
|
||||
__dialog=None
|
||||
def getDialog():
|
||||
"""
|
||||
This function returns a singleton instance of the plugin dialog.
|
||||
"""
|
||||
global __dialog
|
||||
if __dialog is None:
|
||||
__dialog = PluginDialog()
|
||||
return __dialog
|
||||
|
||||
#
|
||||
# ==============================================================================
|
||||
# Basic use cases and unit test functions
|
||||
# ==============================================================================
|
||||
#
|
||||
def TEST_PluginDialog():
|
||||
import sys
|
||||
from PyQt4.QtGui import QApplication
|
||||
from PyQt4.QtCore import QObject, SIGNAL, SLOT
|
||||
app = QApplication(sys.argv)
|
||||
QObject.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()"))
|
||||
|
||||
dlg=PluginDialog()
|
||||
dlg.exec_()
|
||||
|
||||
if __name__ == "__main__":
|
||||
TEST_PluginDialog()
|
||||
|
||||
|
||||
|
159
src/Tools/padder/spadderpy/gui/plugindialog.ui
Normal file
@ -0,0 +1,159 @@
|
||||
<ui version="4.0" >
|
||||
<class>PluginDialog</class>
|
||||
<widget class="QDialog" name="PluginDialog" >
|
||||
<property name="geometry" >
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>417</width>
|
||||
<height>367</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle" >
|
||||
<string>Create a mesh with PADDER</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" >
|
||||
<property name="margin" >
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" >
|
||||
<property name="margin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QFrame" name="frameInput" >
|
||||
<property name="frameShadow" >
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<property name="lineWidth" >
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="midLineWidth" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" >
|
||||
<property name="margin" >
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" >
|
||||
<property name="margin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QTextEdit" name="txtLog" />
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" >
|
||||
<property name="margin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnInput" >
|
||||
<property name="text" >
|
||||
<string>Input</string>
|
||||
</property>
|
||||
<property name="icon" >
|
||||
<iconset>parameters.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnCompute" >
|
||||
<property name="text" >
|
||||
<string>Compute</string>
|
||||
</property>
|
||||
<property name="icon" >
|
||||
<iconset>compute.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnRefresh" >
|
||||
<property name="text" >
|
||||
<string>Refresh</string>
|
||||
</property>
|
||||
<property name="icon" >
|
||||
<iconset>refresh.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnPublish" >
|
||||
<property name="text" >
|
||||
<string>Publish</string>
|
||||
</property>
|
||||
<property name="icon" >
|
||||
<iconset>publish.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>75</width>
|
||||
<height>101</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnClear" >
|
||||
<property name="text" >
|
||||
<string>Clear</string>
|
||||
</property>
|
||||
<property name="icon" >
|
||||
<iconset>clear.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblStatusBar" >
|
||||
<property name="enabled" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="frameShape" >
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow" >
|
||||
<enum>QFrame::Sunken</enum>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
BIN
src/Tools/padder/spadderpy/gui/publish.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
src/Tools/padder/spadderpy/gui/refresh.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
src/Tools/padder/spadderpy/gui/select.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
src/Tools/padder/spadderpy/gui/steelbar.png
Normal file
After Width: | Height: | Size: 538 B |
35
src/Tools/padder/spadderpy/padder.cfg.in
Normal file
@ -0,0 +1,35 @@
|
||||
# This section specify the configurations to be used respectively for
|
||||
# the local execution and the remote execution. The value for 'local'
|
||||
# and 'remote' keys must be the name of a configuration section in
|
||||
# this file. The default key must specify a value between "local" or
|
||||
# "remote" to indicate the user preference.
|
||||
[resources]
|
||||
local = localhost
|
||||
remote = nepal
|
||||
|
||||
[preferences]
|
||||
defaultres = local
|
||||
|
||||
# The following sections defines the available configurations.
|
||||
# The name of the section can be choosen arbitrary. But the value of
|
||||
# the resname key MUST be the name of a SALOME resource defined in the
|
||||
# catalog of resources (CatalogResources.xml).
|
||||
|
||||
# For each section:
|
||||
# - resname : the name of the SALOME resource to be used in this configuration
|
||||
# - binpath : the path to the padder executable program on this resource
|
||||
# - envpath : the path to the environment file on this resource
|
||||
[localhost]
|
||||
resname = localhost
|
||||
binpath = @prefix@/share/salome/resources/spadder/padderexe/padder.exe
|
||||
envpath = @prefix@/share/salome/resources/spadder/padderexe/envPadder.sh
|
||||
|
||||
[venus]
|
||||
resname = gboulant@venus
|
||||
binpath = /usr/local/bin/padder.exe
|
||||
envpath = /usr/local/share/envPadder.sh
|
||||
|
||||
[nepal]
|
||||
resname = nepal@nepal
|
||||
binpath = /usr/local/bin/padder.exe
|
||||
envpath = /usr/local/share/envPadder.sh
|
12
src/Tools/padder/spadderpy/plugin/Makefile.am
Normal file
@ -0,0 +1,12 @@
|
||||
include $(top_srcdir)/adm_local/unix/make_common_starter.am
|
||||
|
||||
#
|
||||
# Files that strictly concern the SALOME plugins registration and
|
||||
# configuration. They are installed in a dedicated folder named
|
||||
# plugins and created in the root installation directory.
|
||||
#
|
||||
salomeplugins_PYTHON = \
|
||||
salome_plugins.py
|
||||
|
||||
salomeplugins_DATA = \
|
||||
envPlugins.sh
|
3
src/Tools/padder/spadderpy/plugin/envPlugins.sh.in
Normal file
@ -0,0 +1,3 @@
|
||||
SPADDER_PLUGINS_PATH=@prefix@/plugins
|
||||
export SALOME_PLUGINS_PATH=$SALOME_PLUGINS_PATH:$SPADDER_PLUGINS_PATH
|
||||
|
36
src/Tools/padder/spadderpy/plugin/salome_plugins.py
Executable file
@ -0,0 +1,36 @@
|
||||
# -*- coding: iso-8859-1 -*-
|
||||
# Copyright (C) 2011 EDF R&D
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
|
||||
#
|
||||
# -* Makefile *-
|
||||
#
|
||||
# Author : Guillaume Boulant (EDF)
|
||||
#
|
||||
import salome_pluginsmanager
|
||||
|
||||
|
||||
def runSpadderPlugin(context):
|
||||
from salome.smesh.spadder.gui import plugindialog
|
||||
dialog=plugindialog.getDialog()
|
||||
dialog.update()
|
||||
dialog.show()
|
||||
|
||||
salome_pluginsmanager.AddFunction('PADDER mesher',
|
||||
'Create a mesh with PADDER',
|
||||
runSpadderPlugin)
|
||||
|
11
src/Tools/padder/unittests/Makefile.am
Normal file
@ -0,0 +1,11 @@
|
||||
include $(top_srcdir)/adm_local/unix/make_common_starter.am
|
||||
|
||||
spadderpydir=$(smeshpypkgdir)/spadder/unittests
|
||||
|
||||
spadderpy_PYTHON = \
|
||||
__init__.py \
|
||||
usecase_meshJobManager.py
|
||||
|
||||
spadderbindir=$(bindir)/spadder
|
||||
spadderbin_SCRIPTS = \
|
||||
autotest.sh
|
0
src/Tools/padder/unittests/__init__.py
Normal file
63
src/Tools/padder/unittests/autotest.sh.in
Normal file
@ -0,0 +1,63 @@
|
||||
#!/bin/bash
|
||||
# Copyright (C) 2010 CEA/DEN, EDF R&D, OPEN CASCADE
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
|
||||
#
|
||||
# -* Makefile *-
|
||||
#
|
||||
# Author : Guillaume Boulant (EDF)
|
||||
#
|
||||
|
||||
|
||||
# This script should be executed in a SALOME shell session,
|
||||
# for example the shell obtained from the command runSession
|
||||
# provided by the SALOME application.
|
||||
|
||||
# This list contains the filenames where test suites are to be
|
||||
# executed. The path are defined relative to the PYTHON installation
|
||||
# directory of the SALOME module.
|
||||
listfiles="\
|
||||
configreader.py \
|
||||
unittests/test_meshJobManager.py \
|
||||
gui/inputdata.py"
|
||||
|
||||
INSTALL_DIR=@prefix@
|
||||
PYTHON_DIR=$INSTALL_DIR/lib/python@PYTHON_VERSION@/site-packages/salome
|
||||
PYTHONPATH=$PYTHON_DIR:$PYTHONPATH
|
||||
export PYTHONPATH
|
||||
|
||||
stderr=2
|
||||
while getopts 'ql' OPTION
|
||||
do
|
||||
case $OPTION in
|
||||
q) stderr=1 ;;
|
||||
l) for f in $listfiles; do echo $f; done; exit 0;;
|
||||
?) printf "Usage: %s: [-q] [-l]\n" $(basename $0) >&2; exit 2;;
|
||||
esac
|
||||
done
|
||||
shift $(($OPTIND - 1))
|
||||
|
||||
here=$(pwd)
|
||||
package_path="salome/smesh/spadder"
|
||||
cd $PYTHON_DIR
|
||||
for file in $listfiles; do
|
||||
# Uncomment this line (and comment the next one) to display
|
||||
# the start line of a test and not only the result:
|
||||
python $package_path/$file 2>&$stderr | grep '^\[TEST'
|
||||
#python $package_path/$file $filter | grep '^\[TEST' | grep -v 'test in progress'
|
||||
done
|
||||
cd $here
|
98
src/Tools/padder/unittests/usecase_meshJobManager.py
Normal file
@ -0,0 +1,98 @@
|
||||
# -*- coding: iso-8859-1 -*-
|
||||
# Copyright (C) 2011 EDF R&D
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
|
||||
#
|
||||
# Author(s): Guillaume Boulant (23/03/2011)
|
||||
#
|
||||
|
||||
# This script illustrates the standard use case of the component
|
||||
# MeshJobManager from within a SALOME script.
|
||||
|
||||
|
||||
#
|
||||
# Preparing the configuration parameters
|
||||
#
|
||||
import os
|
||||
from salome.smesh import spadder
|
||||
pathpadderexe=os.path.join(spadder.getTestDataDir(),"padder.exe")
|
||||
pathpadderenv=os.path.join(spadder.getTestDataDir(),"envPadder.sh")
|
||||
file_concrete=os.path.join(spadder.getTestDataDir(),"concrete.med")
|
||||
file_steelbar=os.path.join(spadder.getTestDataDir(),"ferraill.med")
|
||||
|
||||
import salome
|
||||
import MESHJOB
|
||||
|
||||
#
|
||||
# Setup the configuration in the component. When first have to load
|
||||
# the catalog of SPADDER components, then load the component
|
||||
# MeshJobManager, and finally configure this component.
|
||||
#
|
||||
from salome.smesh import spadder
|
||||
spadder.loadSpadderCatalog()
|
||||
component = salome.lcc.FindOrLoadComponent("FactoryServer","MeshJobManager")
|
||||
config = MESHJOB.ConfigParameter(resname="localhost",
|
||||
binpath=pathpadderexe,
|
||||
envpath=pathpadderenv)
|
||||
component.configure("localhost",config)
|
||||
|
||||
#
|
||||
# Prepare the job parameters and initialize the job
|
||||
#
|
||||
meshJobParameterList = []
|
||||
param = MESHJOB.MeshJobParameter(file_name=file_concrete,
|
||||
file_type=MESHJOB.MED_CONCRETE,
|
||||
group_name="concrete")
|
||||
meshJobParameterList.append(param)
|
||||
|
||||
param = MESHJOB.MeshJobParameter(file_name=file_steelbar,
|
||||
file_type=MESHJOB.MED_STEELBAR,
|
||||
group_name="steelbar")
|
||||
meshJobParameterList.append(param)
|
||||
jobid = component.initialize(meshJobParameterList, "localhost")
|
||||
|
||||
#
|
||||
# Start the execution of the job identified by its job id.
|
||||
#
|
||||
component.start(jobid)
|
||||
|
||||
|
||||
#
|
||||
# This part illustrates how you can follow the execution of the job.
|
||||
#
|
||||
run_states = ["CREATED", "IN_PROCESS", "QUEUED", "RUNNING", "PAUSED"];
|
||||
end_states = ["FINISHED", "ERROR"]
|
||||
all_states = run_states+end_states;
|
||||
|
||||
ended = False
|
||||
nbiter = 0
|
||||
import time
|
||||
while not ended:
|
||||
state = component.getState(jobid)
|
||||
print "MeshJobManager ["+str(nbiter)+"] : state = "+str(state)
|
||||
if state not in run_states:
|
||||
ended=True
|
||||
time.sleep(0.5)
|
||||
nbiter+=1
|
||||
|
||||
if state not in end_states:
|
||||
print "ERR: jobid = "+str(jobid)+" ended abnormally with state="+str(state)
|
||||
else:
|
||||
print "OK: jobid = "+str(jobid)+" ended with state="+str(state)
|
||||
meshJobResults = component.finalize(jobid)
|
||||
print meshJobResults
|
||||
print "You will find the results files in the directory:\n%s"%meshJobResults.results_dirname
|