From: Cédric Aguerre Date: Tue, 21 Oct 2014 10:04:06 +0000 (+0200) Subject: Add field interpolation to GUI X-Git-Tag: V7_5_0b1~1 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=6f83c26127510dc0f245f97177b363361a4b5a59;p=modules%2Fmed.git Add field interpolation to GUI --- diff --git a/idl/MEDDataManager.idl b/idl/MEDDataManager.idl index ce1202018..51be0e61f 100644 --- a/idl/MEDDataManager.idl +++ b/idl/MEDDataManager.idl @@ -50,7 +50,7 @@ module MEDOP * point that aggregate a list of fields that relie on the same mesh * with the same type (the fields in a timeseries differ by their * time step). - * + * * Then you could have a field with no fieldseries associated but * directly associated to a mesh. That is typically the case of * fields created by MED operations: if you operate tow fields @@ -101,9 +101,18 @@ module MEDOP typedef sequence FieldHandlerList; typedef sequence FieldIdList; + struct InterpolationParameters { + double precision; + double defaultValue; + boolean reverse; + string method; + string nature; + string intersectionType; + }; + interface MEDDataManager: SALOME::GenericObj { - + //========================================================== // Datasource management //========================================================== @@ -112,7 +121,7 @@ module MEDOP //========================================================== // Mesh data management //========================================================== - + MeshHandler getMesh(in long meshId) raises (SALOME::SALOME_Exception); MeshHandlerList getMeshList(in long datasourceId); @@ -136,16 +145,19 @@ module MEDOP void updateFieldMetadata(in long fieldHandlerId, - in string fieldname, - in long iteration, - in long order, - in string source); + in string fieldname, + in long iteration, + in long order, + in string source); //void saveFields(in FieldHandlerList fieldHandlerList, in string filepath); void changeUnderlyingMesh(in long fieldHandlerId, in long meshHandlerId) raises (SALOME::SALOME_Exception); - + + FieldHandler interpolateField(in long fieldHandlerId, in long meshHandlerId, in InterpolationParameters params) + raises (SALOME::SALOME_Exception); + //========================================================== // General purpose data management //========================================================== diff --git a/src/MEDOP/cmp/CMakeLists.txt b/src/MEDOP/cmp/CMakeLists.txt index 2849b66eb..f55ccecbd 100644 --- a/src/MEDOP/cmp/CMakeLists.txt +++ b/src/MEDOP/cmp/CMakeLists.txt @@ -47,9 +47,10 @@ SET(COMMON_LIBS ${KERNEL_SalomeKernelHelpers} ${KERNEL_SalomeLifeCycleCORBA} ${KERNEL_SALOMELocalTrace} - ${KERNEL_SALOMEBasics} + ${KERNEL_SALOMEBasics} ${KERNEL_SalomeGenericObj} medcoupling + medcouplingremapper interpkernel ${MEDFILE_C_LIBRARIES} ${HDF5_LIBRARIES} @@ -57,7 +58,7 @@ SET(COMMON_LIBS ${PLATFORM_LIBRARIES} ) -# This undefines the macros MIN and MAX which are specified in the windows headers +# This undefines the macros MIN and MAX which are specified in the windows headers IF(WIN32) SET(COMMON_FLAGS "${COMMON_FLAGS} -DNOMINMAX") ENDIF(WIN32) diff --git a/src/MEDOP/cmp/MEDDataManager_i.cxx b/src/MEDOP/cmp/MEDDataManager_i.cxx index efd9b7af6..66115b422 100644 --- a/src/MEDOP/cmp/MEDDataManager_i.cxx +++ b/src/MEDOP/cmp/MEDDataManager_i.cxx @@ -79,7 +79,7 @@ std::string MEDDataManager_i::source_to_file(const char * source) */ MEDOP::DatasourceHandler * MEDDataManager_i::addDatasource(const char *filepath) { - // We first check that this datasource is not already registered + // We first check that this datasource is not already registered long sourceid = getDatasourceId(filepath); if ( sourceid != LONG_UNDEFINED ) { // The file is already registered under the identifier sourceid @@ -121,7 +121,7 @@ MEDOP::DatasourceHandler * MEDDataManager_i::addDatasource(const char *filepath) for (int iField = 0; iField < nbOfFields; iField++) { const char * fieldName = fieldNames[iField].c_str(); LOG("-- name of field " << iField << " = " << fieldName); - + // A field name could identify several MEDCoupling fields, that // differ by their spatial discretization on the mesh (values on // cells, values on nodes, ...). This spatial discretization is @@ -186,13 +186,13 @@ MEDOP::DatasourceHandler * MEDDataManager_i::addDatasource(const char *filepath) } } } - + return new MEDOP::DatasourceHandler(*datasourceHandler); } long MEDDataManager_i::getDatasourceId(const char *filepath) { std::string uri(file_to_source(filepath)); - DatasourceHandlerMapIterator it = _datasourceHandlerMap.begin(); + DatasourceHandlerMapIterator it = _datasourceHandlerMap.begin(); while ( it != _datasourceHandlerMap.end() ) { if ( strcmp(it->second->uri,uri.c_str()) == 0 ) { return it->first; @@ -268,7 +268,7 @@ MEDOP::FieldseriesHandlerList * MEDDataManager_i::getFieldseriesListOnMesh(CORBA /*! * A fieldseries is a timeseries of fields. Then the list of fields is - * the different time iterations defined for the specified field id. + * the different time iterations defined for the specified field id. */ MEDOP::FieldHandlerList * MEDDataManager_i::getFieldListInFieldseries(CORBA::Long fieldseriesId) { @@ -359,32 +359,32 @@ void MEDDataManager_i::saveFields(const char * filepath, if ( fieldIdList.length() == 0 ) { throw KERNEL::createSalomeException("No fields to save"); } - + // Consider the first field to initiate the med file CORBA::Long fieldHandlerId = fieldIdList[0]; MEDOP::FieldHandler * fieldHandler = getFieldHandler(fieldHandlerId); - MEDCouplingFieldDouble* fieldDouble = getFieldDouble(fieldHandler); + MEDCouplingFieldDouble* fieldDouble = getFieldDouble(fieldHandler); try { bool writeFromScratch = true; MEDLoader::WriteField(filepath, fieldDouble, writeFromScratch); - + writeFromScratch = false; for(CORBA::ULong i=1; ifirst); } } - + MEDOP::FieldIdList fieldIdList; fieldIdList.length(listId.size()); for (int i=0; isaveFields(filepath, fieldIdList); - } + } catch (const SALOME::SALOME_Exception & ex) { throw ex; } catch (const std::exception& ex) { - std::string message = + std::string message = std::string("Error when saving file ") + std::string(filepath) + std::string(" : ") + ex.what(); throw KERNEL::createSalomeException(message.c_str()); @@ -501,16 +501,16 @@ MEDCouplingUMesh * MEDDataManager_i::getUMesh(long meshHandlerId) { myMesh = _meshMap[meshHandlerId]; } else { // The mesh is not loaded yet ==> load it and register it in the map - LOG("getUMesh: the mesh must be loaded. meshid="<sourceid; - std::string filepath(source_to_file((_datasourceHandlerMap[sourceid])->uri)); + std::string filepath(source_to_file((_datasourceHandlerMap[sourceid])->uri)); const char * meshName = _meshHandlerMap[meshHandlerId]->name; int meshDimRelToMax = 0; myMesh = MEDLoader::ReadUMeshFromFile(filepath,meshName,meshDimRelToMax); @@ -525,7 +525,7 @@ MEDCouplingUMesh * MEDDataManager_i::getUMesh(long meshHandlerId) { */ long MEDDataManager_i::getUMeshId(const MEDCouplingMesh * mesh) { bool found = false; - MeshMapIterator it = _meshMap.begin(); + MeshMapIterator it = _meshMap.begin(); while ( it != _meshMap.end() ) { found = (it->second == mesh); if (found) { @@ -625,7 +625,7 @@ MEDOP::FieldHandler * MEDDataManager_i::addField(MEDCouplingFieldDouble * fieldD // variables are updated by this function call. This is the mean to // retrieve the iteration and order of the field. double timestamp = fieldDouble->getTime(iteration, order); - + // For the fields that are created in memory (by operations for // example), the convention for the source attribute is to specify // the fielddouble name, because this name describes the operation @@ -659,13 +659,13 @@ MEDOP::FieldHandler * MEDDataManager_i::addField(MEDCouplingFieldDouble * fieldD else { fieldHandler->meshid = meshHandlerId; } - + _fieldHandlerMap[fieldHandler->id] = fieldHandler; _fieldDoubleMap[fieldHandler->id] = fieldDouble; // >>> WARNING: CORBA structure assignement specification ==> return // >>> a deep copy to avoid the destruction of the fieldHandler // >>> registered in the map (assignement acts as a destructor for - // >>> CORBA struct). + // >>> CORBA struct). return new MEDOP::FieldHandler(*fieldHandler); } @@ -700,7 +700,7 @@ void MEDDataManager_i::updateFieldMetadata(CORBA::Long fieldHandlerId, * new mesh is not identical to the old one. */ void MEDDataManager_i::changeUnderlyingMesh(CORBA::Long fieldHandlerId, CORBA::Long meshHandlerId) { - + MEDOP::FieldHandler * fieldHandler = getFieldHandler(fieldHandlerId); MEDCouplingFieldDouble* fieldDouble = getFieldDouble(fieldHandler); MEDCouplingMesh * newMesh = getUMesh(meshHandlerId); @@ -724,6 +724,92 @@ void MEDDataManager_i::changeUnderlyingMesh(CORBA::Long fieldHandlerId, CORBA::L // synchronized } +INTERP_KERNEL::IntersectionType MEDDataManager_i::_getIntersectionType(const char* intersType) { + std::string type(intersType); + if (type == "Triangulation") { + return INTERP_KERNEL::Triangulation; + } + else if (type == "Convex") { + return INTERP_KERNEL::Convex; + } + else if (type == "Geometric2D") { + return INTERP_KERNEL::Geometric2D; + } + else if (type == "PointLocator") { + return INTERP_KERNEL::PointLocator; + } + else if (type == "Barycentric") { + return INTERP_KERNEL::Barycentric; + } + else if (type == "BarycentricGeo2D") { + return INTERP_KERNEL::BarycentricGeo2D; + } + + std::string message("Error when trying to interpolate field: "); + message.append("Unrecognized intersection type: "); + message.append(type); + throw KERNEL::createSalomeException(message.c_str()); +} + +ParaMEDMEM::NatureOfField MEDDataManager_i::_getNatureOfField(const char* fieldNature) { + std::string nature(fieldNature); + if (nature == "NoNature") { + return NoNature; + } + else if (nature == "ConservativeVolumic") { + return ConservativeVolumic; + } + else if (nature == "Integral") { + return Integral; + } + else if (nature == "IntegralGlobConstraint") { + return IntegralGlobConstraint; + } + else if (nature == "RevIntegral") { + return RevIntegral; + } + + std::string message("Error when trying to interpolate field: "); + message.append("Unrecognized field nature: "); + message.append(nature); + throw KERNEL::createSalomeException(message.c_str()); +} + +MEDOP::FieldHandler* MEDDataManager_i::interpolateField(CORBA::Long fieldHandlerId, CORBA::Long meshHandlerId, const MEDOP::InterpolationParameters& params) { + MEDOP::FieldHandler* fieldHandler = getFieldHandler(fieldHandlerId); + MEDCouplingFieldDouble* sourceField = getFieldDouble(fieldHandler); + MEDCouplingMesh* sourceMesh = getUMesh(fieldHandler->meshid); + MEDCouplingMesh* targetMesh = getUMesh(meshHandlerId); + + double precision = params.precision; + INTERP_KERNEL::IntersectionType interpType = this->_getIntersectionType(params.intersectionType); + std::string method(params.method); + double defaultValue = params.defaultValue; + bool reverse = params.reverse; + ParaMEDMEM::NatureOfField nature = this->_getNatureOfField(params.nature); + + // 1. Build remapper between sourceMesh and targetMesh (compute interpolation matrix) + MEDCouplingRemapper remapper; + remapper.setPrecision(precision); + remapper.setIntersectionType(interpType); + remapper.prepare(sourceMesh, targetMesh, method.c_str()); + + // 2. Apply interpolation to the field + sourceField->setNature(nature); + MEDCouplingFieldDouble* targetField = NULL; + if (reverse) { + targetField = remapper.reverseTransferField(sourceField, defaultValue); + } else { + targetField = remapper.transferField(sourceField, defaultValue); + } + targetField->setMesh(targetMesh); + targetField->setName(targetMesh->getName() + "_field"); + + // 3. Create and register field handler + MEDOP::FieldHandler* fieldResultHandler = this->addField(targetField, this->getUMeshId(targetField->getMesh())); + return fieldResultHandler; +} + /*! @@ -731,7 +817,7 @@ void MEDDataManager_i::changeUnderlyingMesh(CORBA::Long fieldHandlerId, CORBA::L * the server side (data in the SALOME container). */ void MEDDataManager_i::serverlog() { - + LOG("==== Field Handler Map ===================================================="); LOG("Size = "<<_fieldHandlerMap.size()); FieldHandlerMapIterator fhmIt; diff --git a/src/MEDOP/cmp/MEDDataManager_i.hxx b/src/MEDOP/cmp/MEDDataManager_i.hxx index 8a04315ad..96820420c 100644 --- a/src/MEDOP/cmp/MEDDataManager_i.hxx +++ b/src/MEDOP/cmp/MEDDataManager_i.hxx @@ -26,6 +26,7 @@ #include CORBA_SERVER_HEADER(MEDDataManager) #include "SALOME_GenericObj_i.hh" +#include "MEDCouplingRemapper.hxx" #include "MEDCouplingUMesh.hxx" #include "MEDCouplingFieldDouble.hxx" using namespace ParaMEDMEM; @@ -61,7 +62,7 @@ class MEDOP_EXPORT MEDDataManager_i: public POA_MEDOP::MEDDataManager, { public: - // + // // =========================================================== // Functions specified in the IDL interface // =========================================================== @@ -73,7 +74,7 @@ public: // ----------------------------------------------------------- // Mesh management MEDOP::MeshHandlerList * getMeshList(CORBA::Long datasourceId); - MEDOP::MeshHandler * getMesh(CORBA::Long meshId); + MEDOP::MeshHandler * getMesh(CORBA::Long meshId); // ----------------------------------------------------------- // Field management @@ -97,13 +98,14 @@ public: const char * source); void changeUnderlyingMesh(CORBA::Long fieldHandlerId, CORBA::Long meshHandlerId); + MEDOP::FieldHandler* interpolateField(CORBA::Long fieldHandlerId, CORBA::Long meshHandlerId, const MEDOP::InterpolationParameters& params); void setEventListenerIOR(const char * ior); char * getEventListenerIOR(); void serverlog(); - // + // // =========================================================== // Other public functions (non available via CORBA) // =========================================================== @@ -155,6 +157,10 @@ private: MEDCouplingUMesh * getUMesh(long meshHandlerId); long getUMeshId(const MEDCouplingMesh * mesh); + + INTERP_KERNEL::IntersectionType _getIntersectionType(const char* intersType); + ParaMEDMEM::NatureOfField _getNatureOfField(const char* fieldNature); + }; #endif // _MED_DATAMANAGER_I_HXX_ diff --git a/src/MEDOP/gui/DatasourceController.cxx b/src/MEDOP/gui/DatasourceController.cxx index 414431bf4..ca0d90b6d 100644 --- a/src/MEDOP/gui/DatasourceController.cxx +++ b/src/MEDOP/gui/DatasourceController.cxx @@ -44,11 +44,15 @@ DatasourceController::DatasourceController(StandardApp_Module * salomeModule) { STDLOG("Creating a DatasourceController"); _salomeModule = salomeModule; _studyEditor = new SALOME_AppStudyEditor(_salomeModule->getApp()); - _dlgChangeUnderlyingMesh = new DlgChangeUnderlyingMesh(_studyEditor); + _dlgChangeUnderlyingMesh = new DlgChangeUnderlyingMesh(_studyEditor); connect(_dlgChangeUnderlyingMesh,SIGNAL(inputValidated()), this, SLOT(OnChangeUnderlyingMeshInputValidated())); + _dlgInterpolateField = new DlgInterpolateField(_studyEditor); + connect(_dlgInterpolateField,SIGNAL(inputValidated()), + this, SLOT(OnInterpolateFieldInputValidated())); + } DatasourceController::~DatasourceController() { @@ -106,6 +110,11 @@ void DatasourceController::createActions() { actionId = _salomeModule->createStandardAction(label,this,SLOT(OnChangeUnderlyingMesh()),icon); _salomeModule->addActionInPopupMenu(actionId); + label = tr("LAB_INTERPOLATE_FIELD"); + icon = tr("ICO_DATASOURCE_INTERPOLATE_FIELD"); + actionId = _salomeModule->createStandardAction(label,this,SLOT(OnInterpolateField()),icon); + _salomeModule->addActionInPopupMenu(actionId); + } /** @@ -348,6 +357,13 @@ void DatasourceController::OnUseInWorkspace() { MEDOP::FieldHandler * fieldHandler = MEDOPFactoryClient::getDataManager()->getFieldHandler(fieldId); + if (! fieldHandler) { + QMessageBox::warning(_salomeModule->getApp()->desktop(), + tr("Operation not allowed"), + tr("No field is defined")); + return; + } + QString alias(fieldHandler->fieldname); DlgAlias dialog; dialog.setAlias(alias); @@ -406,7 +422,6 @@ void DatasourceController::OnUseInWorkspace() { } } - void DatasourceController::OnChangeUnderlyingMesh() { // We need a studyEditor updated on the active study _studyEditor->updateActiveStudy(); @@ -456,6 +471,79 @@ void DatasourceController::OnChangeUnderlyingMeshInputValidated() { // Tag the item to prevent double import //_studyEditor->setParameterBool(soField,OBJECT_IS_IN_WORKSPACE,true); +} + +void DatasourceController::OnInterpolateField() { + // We need a studyEditor updated on the active study + _studyEditor->updateActiveStudy(); + + // Get the selected objects in the study (SObject). In case of a + // multiple selection, we consider only the first item. At least one + // item must be selected. + SALOME_StudyEditor::SObjectList * listOfSObject = _studyEditor->getSelectedObjects(); + if ( listOfSObject->size() > 0 ) { + SALOMEDS::SObject_var soField = listOfSObject->at(0); + int fieldId = _studyEditor->getParameterInt(soField,OBJECT_ID); + // _GBO_ : the dialog should not be modal, so that we can choose a + // mesh in the browser. Then we have to emit a signal from the + // dialog.accept, connected to a slot of the DatasourceControler + _dlgInterpolateField->setFieldId(fieldId); + Qt::WindowFlags flags = _dlgInterpolateField->windowFlags(); + _dlgInterpolateField->setWindowFlags(flags | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint); + _dlgInterpolateField->open(); + } +} + +void DatasourceController::OnInterpolateFieldInputValidated() { + MEDOP::InterpolationParameters params; + params.precision = _dlgInterpolateField->getPrecision(); + STDLOG("precision = " << params.precision); + params.defaultValue = _dlgInterpolateField->getDefaultValue(); + STDLOG("defaultValue = " << params.defaultValue); + params.reverse = _dlgInterpolateField->getReverse(); + STDLOG("reverse = " << params.reverse); + params.intersectionType = _dlgInterpolateField->getIntersectionType().c_str(); + STDLOG("intersectionType = " << params.intersectionType); + params.method = _dlgInterpolateField->getMethod().c_str(); + STDLOG("method = " << params.method); + params.nature = _dlgInterpolateField->getFieldNature().c_str(); + STDLOG("nature = " << params.nature); + + int meshId = _dlgInterpolateField->getMeshId(); + STDLOG("meshId = " << ToString(meshId)); + int fieldId = _dlgInterpolateField->getFieldId(); + MEDOP::FieldHandler* fieldHandler = MEDOPFactoryClient::getDataManager()->getFieldHandler(fieldId); + + // We don't modify the original field but create first a duplicate + // MEDOP::FieldHandler* duplicate = MEDOPFactoryClient::getCalculator()->dup(*fieldHandler); + //MEDOPFactoryClient::getDataManager()->changeUnderlyingMesh(duplicate->id, meshId); + MEDOP::FieldHandler* result = NULL; + try { + result = MEDOPFactoryClient::getDataManager()->interpolateField(fieldId, meshId, params); + } + catch(...) { + STDLOG("Unable to process field interpolation; please check interpolation parameters"); + QMessageBox::critical(_salomeModule->getApp()->desktop(), + tr("Operation failed"), + tr("Unable to process field interpolation; please check interpolation parameters")); + return; + } + // Request once more the duplicate to update the meta-data on this + // client side + // duplicate = MEDOPFactoryClient::getDataManager()->getFieldHandler(duplicate->id); + + // >>> + // WARN: the following is a temporary code for test purpose + // Automatically add in ws + DatasourceEvent * event = new DatasourceEvent(); + event->eventtype = DatasourceEvent::EVENT_IMPORT_OBJECT; + XmedDataObject * dataObject = new XmedDataObject(); + dataObject->setFieldHandler(*result); + event->objectdata = dataObject; + emit datasourceSignal(event); + // Note that this signal is processed by the WorkspaceController + // // Tag the item to prevent double import + // //_studyEditor->setParameterBool(soField,OBJECT_IS_IN_WORKSPACE,true); } diff --git a/src/MEDOP/gui/DatasourceController.hxx b/src/MEDOP/gui/DatasourceController.hxx index 42c5b4eea..f64ee4fcf 100644 --- a/src/MEDOP/gui/DatasourceController.hxx +++ b/src/MEDOP/gui/DatasourceController.hxx @@ -17,7 +17,7 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// Author : Guillaume Boulant (EDF) +// Author : Guillaume Boulant (EDF) #ifndef DATASOURCE_CONTROLLER_H #define DATASOURCE_CONTROLLER_H @@ -31,6 +31,7 @@ #include "XmedDataModel.hxx" #include "DlgChangeUnderlyingMesh.hxx" +#include "DlgInterpolateField.hxx" #include "MEDOPGUI.hxx" // // The DatasourceController defines data structures and classes to @@ -48,7 +49,7 @@ // transmit an object AND an alias. typedef struct { enum EventType { - // + // EVENT_IMPORT_OBJECT, // Simply import the object in the workspace EVENT_USE_OBJECT, // Import in the workspace AND define a proxy // variable in the tui console to use it @@ -77,6 +78,7 @@ public: public slots: // Callback connected to dialog box validation signals void OnChangeUnderlyingMeshInputValidated(); + void OnInterpolateFieldInputValidated(); signals: void datasourceSignal(const DatasourceEvent * event); @@ -88,6 +90,7 @@ protected slots: void OnVisualize(); void OnUseInWorkspace(); void OnChangeUnderlyingMesh(); + void OnInterpolateField(); private: @@ -95,6 +98,7 @@ private: SALOME_AppStudyEditor * _studyEditor; DlgChangeUnderlyingMesh * _dlgChangeUnderlyingMesh; + DlgInterpolateField * _dlgInterpolateField; }; diff --git a/src/MEDOP/gui/MED_images.ts b/src/MEDOP/gui/MED_images.ts index 3b312eda6..62a6afbc5 100644 --- a/src/MEDOP/gui/MED_images.ts +++ b/src/MEDOP/gui/MED_images.ts @@ -19,6 +19,10 @@ ICO_DATASOURCE_CHANGE_MESH datasource_changeUnderlyingMesh.png + + ICO_DATASOURCE_INTERPOLATE_FIELD + datasource_interpolateField.png + ICO_DATASOURCE_EXPAND_FIELD datasource_expandfield.png diff --git a/src/MEDOP/gui/MED_msg_en.ts b/src/MEDOP/gui/MED_msg_en.ts index 40c9b6961..4008c8a7b 100644 --- a/src/MEDOP/gui/MED_msg_en.ts +++ b/src/MEDOP/gui/MED_msg_en.ts @@ -43,6 +43,11 @@ LAB_CHANGE_MESH Change underlying mesh + + + LAB_INTERPOLATE_FIELD + Interpolate field + IMPORT_MED_FIELDS @@ -121,6 +126,54 @@ You must select a mesh in the explorer and clic the button Mesh + + DlgInterpolateField + + + SELECT_MESH + You must select a mesh in the explorer and clic the button Mesh + + + + TARGET_MESH_GT + Target mesh -> + + + + MSG_EXPLORER + (Explorer provides a view on MED data sources (mesh and fields) referenced in data space) + + + + LABEL_PRECISION + Interpolator precision + + + + LABEL_INTERSECTION_TYPE + Intersection type + + + + LABEL_METHOD + Interpolation method + + + + LABEL_DEFAULT_VALUE + Default value of resulting field + + + + LABEL_REVERSE + Reverse interpolation ? + + + + LABEL_NATURE + Field nature + + DlgImageToMed diff --git a/src/MEDOP/gui/MED_msg_fr.ts b/src/MEDOP/gui/MED_msg_fr.ts index 9ba8ffcb7..2254d0549 100644 --- a/src/MEDOP/gui/MED_msg_fr.ts +++ b/src/MEDOP/gui/MED_msg_fr.ts @@ -43,6 +43,11 @@ LAB_CHANGE_MESH Changer le maillage sous-jacent + + + LAB_INTERPOLATE_FIELD + Interpoler le champ + IMPORT_MED_FIELDS @@ -121,6 +126,54 @@ Vous devez sélectionner un maillage dans l'explorateur et cliquer sur le bouton Maillage + + DlgInterpolateField + + + SELECT_MESH + Vous devez sélectionner un maillage dans l'explorateur et cliquer sur le bouton Maillage + + + + TARGET_MESH_GT + Maillage cible -> + + + + MSG_EXPLORER + (L'explorateur fournit une vue des données MED (maillage et champs) référencées dans l'espace des données) + + + + LABEL_PRECISION + Précision de l'interpolateur + + + + LABEL_INTERSECTION_TYPE + Type d'intersection + + + + LABEL_METHOD + Méthode d'interpolation + + + + LABEL_DEFAULT_VALUE + Valeur par défaut du champ résultant + + + + LABEL_REVERSE + Interpolation inverse ? + + + + LABEL_NATURE + Nature du champ + + DlgImageToMed diff --git a/src/MEDOP/gui/XmedConsoleDriver.cxx b/src/MEDOP/gui/XmedConsoleDriver.cxx index 99c0d7f30..ab3217b3f 100644 --- a/src/MEDOP/gui/XmedConsoleDriver.cxx +++ b/src/MEDOP/gui/XmedConsoleDriver.cxx @@ -16,7 +16,7 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// Author : Guillaume Boulant (EDF) +// Author : Guillaume Boulant (EDF) #include "XmedConsoleDriver.hxx" #include "Utils_SALOME_Exception.hxx" @@ -39,7 +39,7 @@ XmedConsoleDriver::XmedConsoleDriver(SalomeApp_Application * application) { * instructions are sent once. */ void XmedConsoleDriver::setup() { - + if ( !_importXmedDone ) { QStringList commands; // First import xmed to initialize the main objects, in particular @@ -52,6 +52,11 @@ void XmedConsoleDriver::setup() { // A last one to clear the console screen //commands+="wipe"; + // start PVServer and show render view + commands+="import pvsimple as pvs"; + commands+=""; + //commands+="pvs.ShowParaviewView()"; + this->exec(commands); _importXmedDone = true; } diff --git a/src/MEDOP/gui/dialogs/CMakeLists.txt b/src/MEDOP/gui/dialogs/CMakeLists.txt index 7b550727b..cad22cc20 100644 --- a/src/MEDOP/gui/dialogs/CMakeLists.txt +++ b/src/MEDOP/gui/dialogs/CMakeLists.txt @@ -26,6 +26,7 @@ SET(MEDOPGUI_dialogs_FORMS DlgAlias.ui DlgUseInWorkspace.ui DlgChangeUnderlyingMesh.ui + DlgInterpolateField.ui DlgImageToMed.ui ) QT4_WRAP_UI(MEDOPGUI_dialogs_FORMS_HEADERS ${MEDOPGUI_dialogs_FORMS}) @@ -35,6 +36,7 @@ SET(MEDOPGUI_dialogs_FILES DlgAlias.hxx DlgUseInWorkspace.hxx DlgChangeUnderlyingMesh.hxx + DlgInterpolateField.hxx DlgImageToMed.hxx ) QT4_WRAP_CPP(MEDOPGUI_dialogs_HEADERS_MOC ${MEDOPGUI_dialogs_FILES}) @@ -55,12 +57,13 @@ SET(MEDOPGUI_dialogs_SOURCES DlgAlias.cxx DlgUseInWorkspace.cxx DlgChangeUnderlyingMesh.cxx + DlgInterpolateField.cxx DlgImageToMed.cxx ) ADD_LIBRARY(MEDOPGUI_dialogs SHARED ${MEDOPGUI_dialogs_SOURCES} ${MEDOPGUI_dialogs_HEADERS_MOC} ${MEDOPGUI_dialogs_FORMS_HEADERS}) -TARGET_LINK_LIBRARIES(MEDOPGUI_dialogs ${CAS_KERNEL} ${QT_LIBRARIES} ${KERNEL_SalomeIDLKernel} - ${GUI_SalomeGuiHelpers} ${OMNIORB_LIBRARIES} ${GUI_qtx} ${GUI_suit} ${PLATFORM_LIBRARIES} +TARGET_LINK_LIBRARIES(MEDOPGUI_dialogs ${CAS_KERNEL} ${QT_LIBRARIES} ${KERNEL_SalomeIDLKernel} + ${GUI_SalomeGuiHelpers} ${OMNIORB_LIBRARIES} ${GUI_qtx} ${GUI_suit} ${PLATFORM_LIBRARIES} ${KERNEL_SalomeLifeCycleCORBA} ${KERNEL_SalomeKernelHelpers} ${GUI_SalomeGuiHelpers}) INSTALL(TARGETS MEDOPGUI_dialogs DESTINATION ${SALOME_INSTALL_LIBS}) @@ -76,4 +79,3 @@ INSTALL(TARGETS dlgTester DESTINATION ${SALOME_INSTALL_BINS}) FILE(GLOB COMMON_HEADERS_HXX "${CMAKE_CURRENT_SOURCE_DIR}/*.hxx") INSTALL(FILES ${COMMON_HEADERS_HXX} DESTINATION ${SALOME_INSTALL_HEADERS}) - diff --git a/src/MEDOP/gui/dialogs/DlgChangeUnderlyingMesh.ui b/src/MEDOP/gui/dialogs/DlgChangeUnderlyingMesh.ui index cad5ce3cb..f4bf310c5 100644 --- a/src/MEDOP/gui/dialogs/DlgChangeUnderlyingMesh.ui +++ b/src/MEDOP/gui/dialogs/DlgChangeUnderlyingMesh.ui @@ -6,10 +6,16 @@ 0 0 - 479 - 429 + 420 + 350 + + + 420 + 350 + + FORM diff --git a/src/MEDOP/gui/dialogs/DlgInterpolateField.cxx b/src/MEDOP/gui/dialogs/DlgInterpolateField.cxx new file mode 100644 index 000000000..1d49c9072 --- /dev/null +++ b/src/MEDOP/gui/dialogs/DlgInterpolateField.cxx @@ -0,0 +1,104 @@ +#include "DlgInterpolateField.hxx" +#include "DatasourceConstants.hxx" + +#include +#include +#include + +DlgInterpolateField::DlgInterpolateField(SALOME_AppStudyEditor * studyEditor, + QDialog * parent) + : GenericDialog(parent) +{ + ui.setupUi(this->getPanel()); + _meshId=-1; + _studyEditor = studyEditor; + + QDoubleValidator* precisionValidator = new QDoubleValidator(1e-15, 1e-1, 1, this); + precisionValidator->setNotation(QDoubleValidator::ScientificNotation); + this->ui.lineEditPrecision->setValidator(precisionValidator); + this->ui.lineEditPrecision->setText("1e-12"); + + QDoubleValidator* defaultValueValidator = new QDoubleValidator(this); + this->ui.lineEditDefaultValue->setValidator(defaultValueValidator); + this->ui.lineEditDefaultValue->setText("0"); + + QStringList intersectionTypes; + intersectionTypes << "Triangulation" << "Convex" << "Geometric2D" << "PointLocator" << "Barycentric" << "BarycentricGeo2D"; + this->ui.comboBoxIntersType->addItems(intersectionTypes); + + QStringList methods; + methods << "P0P0" << "P0P1" << "P1P0" << "P1P1" << "P2P0"; + this->ui.comboBoxMethod->addItems(methods); + + QStringList natures; + natures << "NoNature" << "ConservativeVolumic" << "Integral" << "IntegralGlobConstraint" << "RevIntegral"; + this->ui.comboBoxNature->addItems(natures); + + connect(this->ui.btnSelectMesh, SIGNAL(clicked()), this, SLOT(OnSelectMesh())); + this->setWindowTitle("Field interpolation"); + this->getPanel()->adjustSize(); + this->adjustSize(); +} + +/** This reset the dialog for a new selection */ +void DlgInterpolateField::setFieldId(int fieldId) { + _fieldId = fieldId; + _meshId=-1; + this->ui.txtMesh->setText(QString("")); +} +int DlgInterpolateField::getFieldId() { + return _fieldId; +} + +int DlgInterpolateField::getMeshId() { + return _meshId; +} + +double DlgInterpolateField::getPrecision() { + return this->ui.lineEditPrecision->text().toDouble(); +} + +double DlgInterpolateField::getDefaultValue() { + return this->ui.lineEditDefaultValue->text().toDouble(); +} + +bool DlgInterpolateField::getReverse() { + return this->ui.checkBoxReverse->isChecked(); +} + +std::string DlgInterpolateField::getIntersectionType() { + return this->ui.comboBoxIntersType->currentText().toStdString(); +} + +std::string DlgInterpolateField::getMethod() { + return this->ui.comboBoxMethod->currentText().toStdString(); +} + +std::string DlgInterpolateField::getFieldNature() { + return this->ui.comboBoxNature->currentText().toStdString(); +} + +void DlgInterpolateField::accept() { + if ( _meshId == -1 ) { + QMessageBox::warning(this, + tr("Data verification"), + tr("You must select a mesh in the explorer and clic the button Mesh")); + } + else { + GenericDialog::accept(); + emit inputValidated(); + } +} + +void DlgInterpolateField::OnSelectMesh() { + SALOME_StudyEditor::SObjectList * listOfSObject = _studyEditor->getSelectedObjects(); + if ( listOfSObject->size() > 0 ) { + SALOMEDS::SObject_var soMesh = listOfSObject->at(0); + // _GBO_ TODO: we should test here if it is a mesh (attribute in + // the sobject) + _meshId = _studyEditor->getParameterInt(soMesh,OBJECT_ID); + const char * meshname = _studyEditor->getName(soMesh); + this->ui.txtMesh->setText(QString(meshname)); + } + +} diff --git a/src/MEDOP/gui/dialogs/DlgInterpolateField.hxx b/src/MEDOP/gui/dialogs/DlgInterpolateField.hxx new file mode 100644 index 000000000..b4220997c --- /dev/null +++ b/src/MEDOP/gui/dialogs/DlgInterpolateField.hxx @@ -0,0 +1,46 @@ +#ifndef _DlgInterpolateField_HXX +#define _DlgInterpolateField_HXX + +#include +#include "ui_DlgInterpolateField.h" +#include "GenericDialog.hxx" + +#include +#include "MEDOPGUIdialogs.hxx" + +class MEDOPGUI_DIALOGS_EXPORT DlgInterpolateField : public GenericDialog +{ + Q_OBJECT + +public: + DlgInterpolateField(SALOME_AppStudyEditor * studyEditor, QDialog *parent = 0); + + void setFieldId(int fieldId); + int getFieldId(); + int getMeshId(); + + double getPrecision(); + double getDefaultValue(); + bool getReverse(); + std::string getIntersectionType(); + std::string getMethod(); + std::string getFieldNature(); + +signals: + void inputValidated(); + +protected slots: + void OnSelectMesh(); + + private: + void accept(); + int _meshId; + + SALOME_AppStudyEditor * _studyEditor; + int _fieldId; + + Ui_DlgInterpolateField ui; // instance of the class defined in ui_dlgInterpolateField.hxx +}; + + +#endif // _DlgInterpolateField_HXX diff --git a/src/MEDOP/gui/dialogs/DlgInterpolateField.ui b/src/MEDOP/gui/dialogs/DlgInterpolateField.ui new file mode 100644 index 000000000..ea069b53d --- /dev/null +++ b/src/MEDOP/gui/dialogs/DlgInterpolateField.ui @@ -0,0 +1,655 @@ + + + DlgInterpolateField + + + + 0 + 0 + 550 + 450 + + + + + 0 + 0 + + + + + 550 + 450 + + + + FORM + + + + + + + + + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 127 + 127 + 127 + + + + + + + 170 + 170 + 170 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 127 + 127 + 127 + + + + + + + 170 + 170 + 170 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + + + 127 + 127 + 127 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 127 + 127 + 127 + + + + + + + 170 + 170 + 170 + + + + + + + 127 + 127 + 127 + + + + + + + 255 + 255 + 255 + + + + + + + 127 + 127 + 127 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + + + Sans Serif + true + + + + SELECT_MESH + + + true + + + + + + + 7 + + + + + TARGET_MESH_GT + + + + + + + + + + + + + true + + + + MSG_EXPLORER + + + true + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + LABEL_PRECISION + + + + + + + true + + + + 0 + 0 + + + + + 225 + 16777215 + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + LABEL_INTERSECTION_TYPE + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + LABEL_METHOD + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + LABEL_DEFAULT_VALUE + + + + + + + + 0 + 0 + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + LABEL_REVERSE + + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + LABEL_NATURE + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + diff --git a/src/MEDOP/gui/dialogs/GenericDialog.ui b/src/MEDOP/gui/dialogs/GenericDialog.ui index c18fc4a69..058f5bed7 100644 --- a/src/MEDOP/gui/dialogs/GenericDialog.ui +++ b/src/MEDOP/gui/dialogs/GenericDialog.ui @@ -1,49 +1,62 @@ - + + GenericDialog - - + + 0 0 - 400 - 300 + 260 + 164 - + + + 0 + 0 + + + DIALOG - - - 9 - - + + 6 + + 9 + - - - 0 - - + + 6 + + 0 + - - + + + + 0 + 0 + + + QFrame::StyledPanel - + QFrame::Raised - - + + Qt::Horizontal - - QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok @@ -59,11 +72,11 @@ GenericDialog accept() - + 248 254 - + 157 274 @@ -75,11 +88,11 @@ GenericDialog reject() - + 316 260 - + 286 274 diff --git a/src/MEDOP/res/CMakeLists.txt b/src/MEDOP/res/CMakeLists.txt index 2ce2792ea..60a339ea8 100644 --- a/src/MEDOP/res/CMakeLists.txt +++ b/src/MEDOP/res/CMakeLists.txt @@ -22,6 +22,7 @@ ADD_SUBDIRECTORY(testfiles) SET(MED_RESOURCES_FILES datasource_add.png datasource_changeUnderlyingMesh.png + datasource_interpolateField.png datasource_expandfield.png datasource_field.png datasource_mesh.png @@ -37,4 +38,3 @@ SET(MED_RESOURCES_FILES workspace_save.png ) INSTALL(FILES ${MED_RESOURCES_FILES} DESTINATION ${SALOME_MED_INSTALL_RES_DATA}) - diff --git a/src/MEDOP/res/datasource_interpolateField.png b/src/MEDOP/res/datasource_interpolateField.png new file mode 100644 index 000000000..97b7c97d3 Binary files /dev/null and b/src/MEDOP/res/datasource_interpolateField.png differ diff --git a/src/MEDOP/res/testfiles/smooth_surface.med b/src/MEDOP/res/testfiles/smooth_surface.med new file mode 100644 index 000000000..56d7e4d6d Binary files /dev/null and b/src/MEDOP/res/testfiles/smooth_surface.med differ diff --git a/src/MEDOP/res/testfiles/smooth_surface_and_field.med b/src/MEDOP/res/testfiles/smooth_surface_and_field.med new file mode 100644 index 000000000..226ce3b21 Binary files /dev/null and b/src/MEDOP/res/testfiles/smooth_surface_and_field.med differ diff --git a/src/MEDOP/tui/xmedpy/driver_pvis.py b/src/MEDOP/tui/xmedpy/driver_pvis.py index 51f40e9b6..e7ed30e0e 100644 --- a/src/MEDOP/tui/xmedpy/driver_pvis.py +++ b/src/MEDOP/tui/xmedpy/driver_pvis.py @@ -17,7 +17,7 @@ # # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # -# Author : Guillaume Boulant (EDF) +# Author : Guillaume Boulant (EDF) import MEDCoupling __mapTypeOfField2ParavisLabel={ @@ -39,7 +39,7 @@ def pvis_typeOfFieldLabel(typeOfField): try: return __mapTypeOfField2ParavisLabel[typeOfField] except IndexError, e: - return "UNCKNOWN" + return "UNKNOWN" def pvis_scalarmap(filename,meshname,fieldname,typeOfField,iteration=-1): """ @@ -47,22 +47,44 @@ def pvis_scalarmap(filename,meshname,fieldname,typeOfField,iteration=-1): load from a med file using the PARAVIS module. """ import pvsimple - + reader = pvsimple.MEDReader( FileName=filename ) - # For fiels defined on cells, it seems to be required to specify - # the type of fields + + representation = pvsimple.Show() if typeOfField == MEDCoupling.ON_CELLS: - reader.Groups = ["GROUP/%s/%s/No_Group"%(meshname,pvis_typeOfFieldLabel(typeOfField))] + representation.ColorArrayName = ("CELLS", fieldname) + data = reader.CellData + else: + representation.ColorArrayName = ("POINTS", fieldname) + data = reader.PointData + + # :TODO: Determine nb components + nb_cmp = 1 + mode = "Magnitude" # "Component" if nb_cmp > 1 - representation = pvsimple.GetDisplayProperties(reader) - representation.ColorArrayName = fieldname + # Get data range (mini/maxi) + for n in range(data.GetNumberOfArrays()): + if data.GetArray(n).GetName() == fieldname: + mini,maxi = data.GetArray(n).GetRange() - lookupTable = pvsimple.GetLookupTableForArray( - fieldname, 1, NanColor=[0.25, 0.0, 0.0], - RGBPoints=[25.0, 0.23, 0.30, 0.754, 245.0, 0.71, 0.016, 0.15], - VectorMode='Magnitude', ColorSpace='Diverging', ScalarRangeInitialized=1.0 ) - representation.LookupTable = lookupTable + stepvalue = (maxi-mini)/100. # 100 steps + # Build Lookup table + RGBPoints = [mini, 0.0, 0.0, 1.0, maxi, 1.0, 0.0, 0.0] + nb = int((maxi-mini)/stepvalue)-1 + Table = pvsimple.GetLookupTableForArray("", nb_cmp, VectorMode=mode, ColorSpace='HSV') + Table.Discretize = 1 + Table.NumberOfTableValues = nb + Table.RGBPoints = RGBPoints + + representation.Representation = 'Surface' + representation.LookupTable = Table + + # Build scalar bar + scalarbar = pvsimple.CreateScalarBar(LabelFormat = '%.1f',Title= "",LabelFontSize=12,Enabled=1,LookupTable=Table,TitleFontSize=12,LabelColor=[0.0, 0.0, 0.0],TitleColor=[0.0, 0.0, 0.0],) + pvsimple.SetActiveSource(reader) + pvsimple.GetRenderView().Representations.append(scalarbar) + pvsimple.SetActiveSource(reader) pvsimple.Render() return True @@ -78,7 +100,7 @@ def TEST_scalarmap(): properties.testFieldName, properties.testTypeOfField, properties.testFieldIt) - + if __name__ == "__main__": TEST_scalarmap() diff --git a/src/MEDOP/tui/xmedpy/fieldtools.py b/src/MEDOP/tui/xmedpy/fieldtools.py index 532e22a2e..6fa6c32d8 100644 --- a/src/MEDOP/tui/xmedpy/fieldtools.py +++ b/src/MEDOP/tui/xmedpy/fieldtools.py @@ -17,7 +17,7 @@ # # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # -# Author : Guillaume Boulant (EDF) +# Author : Guillaume Boulant (EDF) # # =================================================================== @@ -29,7 +29,7 @@ import xmed from xmed.fieldproxy import FieldProxy, newFieldProxy - + # =================================================================== # Operations on fields @@ -87,7 +87,7 @@ def status(local=True,remote=False): if len(fieldHandlerList) > 0: status+="(use 'f=get(id)' to get a field in the current context)" - + return status # For simpler typing, one can create a python command for status @@ -104,7 +104,7 @@ class ListFields(object): # remote metadata on the engine (MEDCouplingFieldDouble) are # displayed by the stat command. Otherwise, only the local # metadata are displayed. - + def __repr__(self): return status(self.__local, self.__remote) @@ -121,13 +121,13 @@ def load(medFileName=filepath): """ This function indicates that we want to use the fields from the specified med file. The fields meta-data are loaded in the engine - part of the module. To get a fieldproxy on a field, call the get + part of the module. To get a fieldproxy on a field, call the get function with the id of the required field. To display the whole list of fields loaded in the engine, type 'ls' (la verbose). """ xmed.dataManager.addDatasource(filepath) print status(local=False,remote=True) - + def get(fieldHandlerId): """ This return a field proxy on the field identified by the specified @@ -163,22 +163,31 @@ VIEWER_VISU = "VISU" VIEWER_PARAVIS = "PARAVIS" VIEWER_DEFAULT = VIEWER_PARAVIS -VIEWER_TMP_FILE = "/tmp/medop_viewer.med" +import tempfile def view_using_paravis(aFieldProxy): + temp = tempfile.NamedTemporaryFile(prefix="medop_viewer", suffix='.med', delete=False) + # __GBO__ TO BE IMPROVED: we used a tmp file in this first step of # development, but we should used at last a MEDCoupling corba # object (see how to use the stuff in PARAVIS/src/Plugins) - xmed.dataManager.saveFields(VIEWER_TMP_FILE, [aFieldProxy.id]) - + xmed.dataManager.saveFields(temp.name, [aFieldProxy.id]) + from xmed.driver_pvis import pvis_scalarmap - pvis_scalarmap(VIEWER_TMP_FILE, + pvis_scalarmap(temp.name, aFieldProxy.meshname, aFieldProxy.fieldname, aFieldProxy.type, aFieldProxy.iteration) + temp.close() +# def view_using_visu(aFieldProxy): + # No more used + raise Exception("view_using_visu: No more used") + + VIEWER_TMP_FILE = "/tmp/medop_viewer.med" + # __GBO__ TO BE IMPROVED: we used a tmp file in this first step of # development, but we should used at last a MEDCoupling corba # object (see how to use the stuff in PARAVIS/src/Plugins) @@ -200,7 +209,7 @@ def view_using_visu(aFieldProxy): iteration) if result is False: xmed.err("the field can't be displayed") - + def view(aFieldProxy, using=VIEWER_DEFAULT): """ This displays a 3D view of the field using VISU or PARAVIS, @@ -213,4 +222,4 @@ def view(aFieldProxy, using=VIEWER_DEFAULT): view_using_paravis(aFieldProxy) else: view_using_visu(aFieldProxy) - +