Salome HOME
Merge 'abn/V8_1_fix' branch into V8_1_BR.
[modules/med.git] / src / MEDCalc / cmp / MED.cxx
1 // Copyright (C) 2015-2016  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include "MED.hxx"
21 #include "MEDFactoryClient.hxx"
22 #include <MEDCalcConstants.hxx>
23
24 #include <SALOMEconfig.h>
25 #include CORBA_CLIENT_HEADER(SALOMEDS_Attributes)
26
27 #include <SALOMEDS_SObject.hxx>
28 #include <Utils_ExceptHandlers.hxx>
29 #include <SALOME_LifeCycleCORBA.hxx>
30 #include <SALOME_NamingService.hxx>
31 #include <SALOME_KernelServices.hxx>
32
33 #include <string>
34 #include <sstream>
35
36 /*!
37   \brief Constructor
38
39   Creates an instance of the MED component engine
40
41   \param orb reference to the ORB
42   \param poa reference to the POA
43   \param contId CORBA object ID, pointing to the owner SALOME container
44   \param instanceName SALOME component instance name
45   \param interfaceName SALOME component interface name
46 */
47 MED::MED(CORBA::ORB_ptr orb,
48          PortableServer::POA_ptr poa,
49          PortableServer::ObjectId* contId,
50          const char* instanceName,
51          const char* interfaceName)
52   : Engines_Component_i(orb, poa, contId, instanceName, interfaceName),
53     _fieldSeriesEntries(),
54     _meshEntries()
55 {
56   _thisObj = this;
57   _id = _poa->activate_object(_thisObj); // register and activate this servant object
58 }
59
60 MED::~MED()
61 {
62   // nothing to do
63 }
64
65 MED_ORB::status
66 MED::addDatasourceToStudy(SALOMEDS::Study_ptr study,
67                           const MEDCALC::DatasourceHandler& datasourceHandler)
68 {
69   // set exception handler to catch unexpected CORBA exceptions
70   Unexpect aCatch(SALOME_SalomeException);
71
72   // check if reference to study is valid
73   if (!CORBA::is_nil(study)) {
74     // get full object path
75     std::string fullName = CORBA::string_dup(datasourceHandler.name);
76     // check if the object with the same name is already registered in the study
77     SALOMEDS::SObject_var sobj = study->FindObjectByPath(fullName.c_str());
78     if (CORBA::is_nil(sobj)) {
79       // object is not registered yet -> register
80       SALOMEDS::GenericAttribute_var anAttr;
81       SALOMEDS::AttributeParameter_var aParam;
82       SALOMEDS::StudyBuilder_var studyBuilder = study->NewBuilder();
83       SALOMEDS::UseCaseBuilder_var useCaseBuilder = study->GetUseCaseBuilder();
84
85       // find MED component; create it if not found
86       SALOMEDS::SComponent_var father = study->FindComponent("MED");
87       if (CORBA::is_nil(father)) {
88         // create component
89         father = studyBuilder->NewComponent("MED");
90         // set name attribute
91         father->SetAttrString("AttributeName", "MEDCalc");
92         // set icon attribute
93         father->SetAttrString("AttributePixMap", "ICO_MED");
94         // register component in the study
95         studyBuilder->DefineComponentInstance(father, MED_Gen::_this());
96         // add component to the use case tree
97         // (to support tree representation customization and drag-n-drop)
98         useCaseBuilder->SetRootCurrent();
99         useCaseBuilder->Append(father); // component object is added as the top level item
100       }
101
102       // create new sub-object, as a child of the component object
103       SALOMEDS::SObject_var soDatasource = studyBuilder->NewObject(father);
104       soDatasource->SetAttrString("AttributeName", fullName.c_str());
105       soDatasource->SetAttrString("AttributePixMap", "ICO_DATASOURCE");
106       anAttr = studyBuilder->FindOrCreateAttribute(soDatasource, "AttributeParameter");
107       aParam = SALOMEDS::AttributeParameter::_narrow(anAttr);
108       aParam->SetInt(SOURCE_ID, datasourceHandler.id);
109       useCaseBuilder->AppendTo(soDatasource->GetFather(), soDatasource);
110
111       // We can add the meshes as children of the datasource
112       MEDCALC::MeshHandlerList* meshHandlerList =
113         MEDFactoryClient::getDataManager()->getMeshHandlerList(datasourceHandler.id);
114
115       for(CORBA::ULong iMesh=0; iMesh<meshHandlerList->length(); iMesh++) {
116         MEDCALC::MeshHandler meshHandler = (*meshHandlerList)[iMesh];
117         SALOMEDS::SObject_var soMesh = studyBuilder->NewObject(soDatasource);
118         _meshEntries[meshHandler.id] = soMesh->GetID();
119         soMesh->SetAttrString("AttributeName", meshHandler.name);
120         soMesh->SetAttrString("AttributePixMap", "ICO_DATASOURCE_MESH");
121         anAttr = studyBuilder->FindOrCreateAttribute(soMesh, "AttributeParameter");
122         aParam = SALOMEDS::AttributeParameter::_narrow(anAttr);
123         aParam->SetInt(MESH_ID, meshHandler.id);
124         aParam->SetBool(IS_IN_WORKSPACE, false);
125         useCaseBuilder->AppendTo(soMesh->GetFather(), soMesh);
126
127         // We add the field timeseries defined on this mesh, as children of the mesh SObject
128         MEDCALC::FieldseriesHandlerList * fieldseriesHandlerList =
129           MEDFactoryClient::getDataManager()->getFieldseriesListOnMesh(meshHandler.id);
130
131         for(CORBA::ULong iFieldseries=0; iFieldseries<fieldseriesHandlerList->length(); iFieldseries++) {
132           MEDCALC::FieldseriesHandler fieldseriesHandler = (*fieldseriesHandlerList)[iFieldseries];
133           SALOMEDS::SObject_var soFieldseries = studyBuilder->NewObject(soMesh);
134           _fieldSeriesEntries[fieldseriesHandler.id] = soFieldseries->GetID();
135
136           std::string label(fieldseriesHandler.name);
137           label +=" ("+std::string(mapTypeOfFieldLabel[fieldseriesHandler.type])+")";
138           soFieldseries->SetAttrString("AttributeName", label.c_str());
139           soFieldseries->SetAttrString("AttributePixMap", "ICO_DATASOURCE_FIELD");
140           anAttr = studyBuilder->FindOrCreateAttribute(soFieldseries, "AttributeParameter");
141           aParam = SALOMEDS::AttributeParameter::_narrow(anAttr);
142           aParam->SetInt(FIELD_SERIES_ID, fieldseriesHandler.id);
143           //aParam->SetInt(FIELD_ID, fieldseriesHandler.id);
144           aParam->SetBool(IS_IN_WORKSPACE, false);
145
146           useCaseBuilder->AppendTo(soFieldseries->GetFather(), soFieldseries);
147           soFieldseries->UnRegister();
148         }
149         soMesh->UnRegister();
150       }
151
152       // cleanup
153       father->UnRegister();
154       soDatasource->UnRegister();
155     }
156   }
157
158   return MED_ORB::OP_OK;
159 }
160
161 MED_ORB::status
162 MED::registerPresentationField(SALOMEDS::Study_ptr study,
163                           CORBA::Long fieldId,
164                           const char* name,
165                           const char* type,
166                           const char* ico,
167                           CORBA::Long presentationId)
168 {
169   // set exception handler to catch unexpected CORBA exceptions
170   Unexpect aCatch(SALOME_SalomeException);
171
172   MEDCALC::FieldHandler_var fldHandler = MEDFactoryClient::getDataManager()->getFieldHandler(fieldId);
173   int fieldSeriesId = fldHandler->fieldseriesId;
174   if (fieldSeriesId < 0){
175       std::cerr << "MED::registerPresentationField(): Error getting field handler\n";
176       return MED_ORB::OP_ERROR ;
177     }
178
179   if (_fieldSeriesEntries.find(fieldSeriesId) == _fieldSeriesEntries.end()) {
180     std::cerr << "MED::registerPresentationField(): Field series not found\n";
181     return MED_ORB::OP_ERROR ;
182   }
183   std::string entry = _fieldSeriesEntries[fieldSeriesId];
184   SALOMEDS::SObject_var sobject = study->FindObjectID(entry.c_str());
185   SALOMEDS::SObject_ptr soFieldseries = sobject._retn();
186
187   if (soFieldseries->IsNull()) {
188     std::cerr << "MED::registerPresentationField(): Entry not found\n";
189     return MED_ORB::OP_ERROR;
190   }
191
192   SALOMEDS::StudyBuilder_var studyBuilder = study->NewBuilder();
193   SALOMEDS::UseCaseBuilder_var useCaseBuilder = study->GetUseCaseBuilder();
194   SALOMEDS::SObject_var soPresentation = studyBuilder->NewObject(soFieldseries);
195   useCaseBuilder->AppendTo(soPresentation->GetFather(), soPresentation);
196
197   soPresentation->SetAttrString("AttributeName", name);
198   soPresentation->SetAttrString("AttributePixMap", ico);
199
200   SALOMEDS::GenericAttribute_var anAttr;
201   SALOMEDS::AttributeParameter_var aParam;
202   anAttr = studyBuilder->FindOrCreateAttribute(soPresentation, "AttributeParameter");
203   aParam = SALOMEDS::AttributeParameter::_narrow(anAttr);
204   aParam->SetInt(FIELD_ID, fieldId);
205   aParam->SetBool(IS_PRESENTATION, true);
206   aParam->SetInt(PRESENTATION_ID, presentationId);
207   aParam->SetString(PRESENTATION_TYPE, type);
208
209   return MED_ORB::OP_OK;
210 }
211
212 MED_ORB::status
213 MED::registerPresentationMesh(SALOMEDS::Study_ptr study,
214                           CORBA::Long meshId,
215                           const char* name,
216                           const char* type,
217                           const char* ico,
218                           CORBA::Long presentationId)
219 {
220   // set exception handler to catch unexpected CORBA exceptions
221   Unexpect aCatch(SALOME_SalomeException);
222
223   MEDCALC::MeshHandler_var meshHandler = MEDFactoryClient::getDataManager()->getMeshHandler(meshId);
224   if (meshHandler->id < 0){
225       std::cerr << "MED::registerPresentationMesh(): Error getting mesh handler\n";
226       return MED_ORB::OP_ERROR ;
227     }
228
229   if (_meshEntries.find(meshHandler->id) == _meshEntries.end()) {
230     std::cerr << "MED::registerPresentationMesh(): mesh not found\n";
231     return MED_ORB::OP_ERROR ;
232   }
233   std::string entry = _meshEntries[meshHandler->id];
234   SALOMEDS::SObject_var sobject = study->FindObjectID(entry.c_str());
235   SALOMEDS::SObject_ptr soMesh = sobject._retn();
236
237   if (soMesh->IsNull()) {
238     std::cerr << "MED::registerPresentationMesh(): Entry not found\n";
239     return MED_ORB::OP_ERROR;
240   }
241
242   SALOMEDS::StudyBuilder_var studyBuilder = study->NewBuilder();
243   SALOMEDS::UseCaseBuilder_var useCaseBuilder = study->GetUseCaseBuilder();
244   SALOMEDS::SObject_var soPresentation = studyBuilder->NewObject(soMesh);
245   useCaseBuilder->AppendTo(soPresentation->GetFather(), soPresentation);
246
247   soPresentation->SetAttrString("AttributeName", name);
248   soPresentation->SetAttrString("AttributePixMap", ico);
249
250   SALOMEDS::GenericAttribute_var anAttr;
251   SALOMEDS::AttributeParameter_var aParam;
252   anAttr = studyBuilder->FindOrCreateAttribute(soPresentation, "AttributeParameter");
253   aParam = SALOMEDS::AttributeParameter::_narrow(anAttr);
254   aParam->SetInt(MESH_ID, meshId);
255   aParam->SetBool(IS_PRESENTATION, true);
256   aParam->SetInt(PRESENTATION_ID, presentationId);
257   aParam->SetString(PRESENTATION_TYPE, type);
258
259   return MED_ORB::OP_OK;
260 }
261
262
263 MED_ORB::status
264 MED::unregisterPresentation(SALOMEDS::Study_ptr study,
265                             CORBA::Long presentationId)
266 {
267   // set exception handler to catch unexpected CORBA exceptions
268   Unexpect aCatch(SALOME_SalomeException);
269
270   SALOMEDS::StudyBuilder_var studyBuilder = study->NewBuilder();
271   SALOMEDS::UseCaseBuilder_var useCaseBuilder = study->GetUseCaseBuilder();
272
273   SALOMEDS::GenericAttribute_var anAttribute;
274   SALOMEDS::SComponent_var father = study->FindComponent("MED");
275   SALOMEDS::ChildIterator_var it = study->NewChildIterator(father);
276   for (it->InitEx(true); it->More(); it->Next()) {
277     SALOMEDS::SObject_var child(it->Value());
278
279     if (child->FindAttribute(anAttribute, "AttributeParameter")) {
280       SALOMEDS::AttributeParameter_var attrParam = SALOMEDS::AttributeParameter::_narrow(anAttribute);
281       if (!attrParam->IsSet(IS_PRESENTATION, PT_BOOLEAN) || !attrParam->GetBool(IS_PRESENTATION) || !attrParam->IsSet(PRESENTATION_ID, PT_INTEGER))
282         continue;
283
284       if (presentationId == attrParam->GetInt(PRESENTATION_ID)) {
285         // remove object from study
286         studyBuilder->RemoveObjectWithChildren(child);
287         // remove object from use case tree
288         useCaseBuilder->Remove(child);
289       }
290     }
291   }
292
293   return MED_ORB::OP_OK;
294 }
295
296 MED_ORB::PresentationsList*
297 MED::getStudyPresentations(SALOMEDS::Study_ptr study)
298 {
299   // set exception handler to catch unexpected CORBA exceptions
300   Unexpect aCatch(SALOME_SalomeException);
301
302   MED_ORB::PresentationsList* presList = new MED_ORB::PresentationsList;
303
304   SALOMEDS::StudyBuilder_var studyBuilder = study->NewBuilder();
305   SALOMEDS::UseCaseBuilder_var useCaseBuilder = study->GetUseCaseBuilder();
306
307   SALOMEDS::GenericAttribute_var anAttribute;
308   SALOMEDS::SComponent_var father = study->FindComponent("MED");
309   SALOMEDS::ChildIterator_var it = study->NewChildIterator(father);
310   for (it->InitEx(true); it->More(); it->Next())
311     {
312       SALOMEDS::SObject_var child(it->Value());
313       if (child->FindAttribute(anAttribute, "AttributeParameter"))
314         {
315           SALOMEDS::AttributeParameter_var attrParam = SALOMEDS::AttributeParameter::_narrow(anAttribute);
316           if (!attrParam->IsSet(IS_PRESENTATION, PT_BOOLEAN) || !attrParam->GetBool(IS_PRESENTATION) || !attrParam->IsSet(PRESENTATION_ID, PT_INTEGER))
317             continue;
318
319           CORBA::ULong size = presList->length();
320           presList->length(size+1);
321           (*presList)[size] = attrParam->GetInt(PRESENTATION_ID);
322         }
323     }
324   return presList;
325 }
326
327 char*
328 MED::getStudyPresentationEntry(SALOMEDS::Study_ptr study, int presentationId)
329 {
330   // set exception handler to catch unexpected CORBA exceptions
331   Unexpect aCatch(SALOME_SalomeException);
332
333   MED_ORB::PresentationsList* presList = new MED_ORB::PresentationsList;
334
335   SALOMEDS::StudyBuilder_var studyBuilder = study->NewBuilder();
336   SALOMEDS::UseCaseBuilder_var useCaseBuilder = study->GetUseCaseBuilder();
337
338   SALOMEDS::GenericAttribute_var anAttribute;
339   SALOMEDS::SComponent_var father = study->FindComponent("MED");
340   SALOMEDS::ChildIterator_var it = study->NewChildIterator(father);
341   for (it->InitEx(true); it->More(); it->Next())
342     {
343       SALOMEDS::SObject_var child(it->Value());
344       if (child->FindAttribute(anAttribute, "AttributeParameter"))
345         {
346           SALOMEDS::AttributeParameter_var attrParam = SALOMEDS::AttributeParameter::_narrow(anAttribute);
347           if (!attrParam->IsSet(IS_PRESENTATION, PT_BOOLEAN) || !attrParam->GetBool(IS_PRESENTATION) || !attrParam->IsSet(PRESENTATION_ID, PT_INTEGER))
348             continue;
349
350           if (attrParam->GetInt(PRESENTATION_ID) == presentationId)
351             return CORBA::string_dup(child->GetID());
352         }
353     }
354   return CORBA::string_dup("");
355 }
356
357
358 Engines::TMPFile*
359 MED::DumpPython(CORBA::Object_ptr theStudy,
360                 CORBA::Boolean isPublished,
361                 CORBA::Boolean isMultiFile,
362                 CORBA::Boolean& isValidScript)
363 {
364   SALOMEDS::Study_var aStudy = SALOMEDS::Study::_narrow(theStudy);
365   if(CORBA::is_nil(aStudy)) {
366     std::cerr << "Error: Cannot find the study\n";
367     return new Engines::TMPFile(0);
368   }
369
370   SALOMEDS::SObject_var aSO = aStudy->FindComponent("MED");
371   if(CORBA::is_nil(aSO)) {
372     std::cerr << "Error: Cannot find component MED\n";
373     return new Engines::TMPFile(0);
374   }
375
376   std::string aScript;
377
378   MEDCALC::CommandsList* history = MEDFactoryClient::getCommandsHistoryManager()->getCommandsHistory();
379   for (CORBA::ULong i = 0; i < history->length(); ++i) {
380     aScript += (*history)[i];
381     aScript += "\n";
382   }
383
384   int aLen = aScript.size();
385   unsigned char* aBuffer = new unsigned char[aLen+1];
386   strcpy((char*)aBuffer, aScript.c_str());
387
388   CORBA::Octet* anOctetBuf =  (CORBA::Octet*)aBuffer;
389   Engines::TMPFile_var aStreamFile = new Engines::TMPFile(aLen+1, aLen+1, anOctetBuf, 1);
390
391   isValidScript = true;
392   return aStreamFile._retn();
393 }
394
395 CORBA::Boolean
396 MED::hasObjectInfo()
397 {
398   return true;
399 }
400
401 char*
402 MED::getObjectInfo(CORBA::Long studyId, const char* entry)
403 {
404   SALOME_LifeCycleCORBA lcc;
405   CORBA::Object_var aSMObject = lcc.namingService()->Resolve( "/myStudyManager" );
406   SALOMEDS::StudyManager_var aStudyManager = SALOMEDS::StudyManager::_narrow( aSMObject );
407   SALOMEDS::Study_var aStudy = aStudyManager->GetStudyByID( studyId );
408   SALOMEDS::SObject_var aSObj = aStudy->FindObjectID( entry );
409   SALOMEDS::SObject_var aResultSObj;
410   if (aSObj->ReferencedObject(aResultSObj))
411     aSObj = aResultSObj;
412
413   if (aSObj->_is_nil())
414     return CORBA::string_dup("unknown");
415
416   SALOMEDS::GenericAttribute_var anAttribute;
417
418   std::string name("unknown");
419   if (aSObj->FindAttribute(anAttribute, "AttributeName")) {
420     SALOMEDS::AttributeName_var attrName = SALOMEDS::AttributeName::_narrow(anAttribute);
421     name = std::string(attrName->Value());
422   }
423
424   bool isInWorkspace = false;
425   //bool isPresentation = false;
426   int sourceId = -1;
427   int meshId = -1;
428   int fieldSeriesId = -1;
429   int fieldId = -1;
430   int presentationId = -1;
431   if (aSObj->FindAttribute(anAttribute, "AttributeParameter")) {
432     SALOMEDS::AttributeParameter_var attrParam = SALOMEDS::AttributeParameter::_narrow(anAttribute);
433     if (attrParam->IsSet(IS_IN_WORKSPACE, PT_BOOLEAN))
434       isInWorkspace = attrParam->GetBool(IS_IN_WORKSPACE);
435     //if (attrParam->IsSet(IS_PRESENTATION, PT_BOOLEAN))
436     //  isPresentation = attrParam->GetBool(IS_PRESENTATION);
437     if (attrParam->IsSet(SOURCE_ID, PT_INTEGER))
438       sourceId = attrParam->GetInt(SOURCE_ID);
439     if (attrParam->IsSet(MESH_ID, PT_INTEGER))
440       meshId = attrParam->GetInt(MESH_ID);
441     if (attrParam->IsSet(FIELD_SERIES_ID, PT_INTEGER))
442       fieldSeriesId = attrParam->GetInt(FIELD_SERIES_ID);
443     if (attrParam->IsSet(FIELD_ID, PT_INTEGER))
444       fieldId = attrParam->GetInt(FIELD_ID);
445     if (attrParam->IsSet(PRESENTATION_ID, PT_INTEGER))
446       presentationId = attrParam->GetInt(PRESENTATION_ID);
447   }
448
449   if (!aSObj->_is_nil() )
450     aSObj->UnRegister();
451
452   std::ostringstream oss;
453   if (sourceId > -1)
454     oss << "Source id: " << sourceId << std::endl;
455   if (meshId > -1)
456     oss << "Mesh id: " << meshId << std::endl;
457   if (fieldSeriesId > -1)
458     oss << "Field series id: " << fieldSeriesId << std::endl;
459   if (fieldId > -1)
460     oss << "Field id: " << fieldId << std::endl;
461   //oss << "Is presentation: " << isPresentation << std::endl;
462   if (presentationId > -1)
463     oss << "Presentation id: " << presentationId << std::endl;
464   oss << "Is in workspace: " << isInWorkspace << std::endl;
465
466   return CORBA::string_dup(oss.str().c_str());
467 }
468
469 void MED::cleanUp()
470 {
471   _fieldSeriesEntries.clear();
472   _meshEntries.clear();
473 }
474
475 extern "C"
476 {
477   /*!
478     \brief Exportable factory function: create an instance of the MED component engine
479     \param orb reference to the ORB
480     \param poa reference to the POA
481     \param contId CORBA object ID, pointing to the owner SALOME container
482     \param instanceName SALOME component instance name
483     \param interfaceName SALOME component interface name
484     \return CORBA object identifier of the registered servant
485   */
486   PortableServer::ObjectId* MEDEngine_factory(CORBA::ORB_ptr orb,
487                                               PortableServer::POA_ptr poa,
488                                               PortableServer::ObjectId* contId,
489                                               const char* instanceName,
490                                               const char* interfaceName)
491   {
492     MED* component = new MED(orb, poa, contId, instanceName, interfaceName);
493     return component->getId();
494   }
495 }