Salome HOME
d6b4d0903454f9eff152b4ecbfb136cd73bb0ce8
[modules/med.git] / src / MEDCalc / cmp / MED.cxx
1 // Copyright (C) 2015-2021  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 #include <SALOMEDSImpl_AttributeParameter.hxx>
33
34 #include <string>
35 #include <sstream>
36
37 /*!
38   \brief Constructor
39
40   Creates an instance of the MED component engine
41
42   \param orb reference to the ORB
43   \param poa reference to the POA
44   \param contId CORBA object ID, pointing to the owner SALOME container
45   \param instanceName SALOME component instance name
46   \param interfaceName SALOME component interface name
47 */
48 MED::MED(CORBA::ORB_ptr orb,
49          PortableServer::POA_ptr poa,
50          PortableServer::ObjectId* contId,
51          const char* instanceName,
52          const char* interfaceName)
53   : Engines_Component_i(orb, poa, contId, instanceName, interfaceName),
54     _fieldSeriesEntries(),
55     _meshEntries()
56 {
57   _thisObj = this;
58   _id = _poa->activate_object(_thisObj); // register and activate this servant object
59 }
60
61 MED::~MED()
62 {
63   // nothing to do
64 }
65
66 MED_ORB::status
67 MED::addDatasourceToStudy(const MEDCALC::DatasourceHandler& datasourceHandler)
68 {
69   // set exception handler to catch unexpected CORBA exceptions
70   Unexpect aCatch(SALOME_SalomeException);
71
72   SALOMEDS::Study_var aStudy = KERNEL::getStudyServant();
73   // check if reference to study is valid
74   if (!CORBA::is_nil(aStudy)) {
75     // get full object path
76     std::string fullName = CORBA::string_dup(datasourceHandler.name);
77     // check if the object with the same name is already registered in the study
78     SALOMEDS::SObject_var sobj = aStudy->FindObjectByPath(fullName.c_str());
79     if (CORBA::is_nil(sobj)) {
80       // object is not registered yet -> register
81       SALOMEDS::GenericAttribute_var anAttr;
82       SALOMEDS::AttributeParameter_var aParam;
83       SALOMEDS::StudyBuilder_var studyBuilder = aStudy->NewBuilder();
84       SALOMEDS::UseCaseBuilder_var useCaseBuilder = aStudy->GetUseCaseBuilder();
85
86       // find MED component; create it if not found
87       SALOMEDS::SComponent_var father = aStudy->FindComponent("FIELDS");
88       if (CORBA::is_nil(father)) {
89         // create component
90         father = studyBuilder->NewComponent("FIELDS");
91         // set name attribute
92         father->SetAttrString("AttributeName", "FIELDS");
93         // set icon attribute
94         father->SetAttrString("AttributePixMap", "ICO_MED");
95         // register component in the study
96         studyBuilder->DefineComponentInstance(father, MED_Gen::_this());
97         // add component to the use case tree
98         // (to support tree representation customization and drag-n-drop)
99         useCaseBuilder->SetRootCurrent();
100         useCaseBuilder->Append(father); // component object is added as the top level item
101       }
102
103       // create new sub-object, as a child of the component object
104       SALOMEDS::SObject_var soDatasource = studyBuilder->NewObject(father);
105       soDatasource->SetAttrString("AttributeName", fullName.c_str());
106       soDatasource->SetAttrString("AttributePixMap", "ICO_DATASOURCE");
107       anAttr = studyBuilder->FindOrCreateAttribute(soDatasource, "AttributeParameter");
108       aParam = SALOMEDS::AttributeParameter::_narrow(anAttr);
109       aParam->SetInt(SOURCE_ID, datasourceHandler.id);
110       useCaseBuilder->AppendTo(soDatasource->GetFather(), soDatasource);
111
112       // We can add the meshes as children of the datasource
113       MEDCALC::MeshHandlerList* meshHandlerList =
114         MEDFactoryClient::getDataManager()->getMeshHandlerList(datasourceHandler.id);
115
116       for(CORBA::ULong iMesh=0; iMesh<meshHandlerList->length(); iMesh++) {
117         MEDCALC::MeshHandler meshHandler = (*meshHandlerList)[iMesh];
118         SALOMEDS::SObject_var soMesh = studyBuilder->NewObject(soDatasource);
119         _meshEntries[meshHandler.id] = soMesh->GetID();
120         soMesh->SetAttrString("AttributeName", meshHandler.name);
121         soMesh->SetAttrString("AttributePixMap", "ICO_DATASOURCE_MESH");
122         anAttr = studyBuilder->FindOrCreateAttribute(soMesh, "AttributeParameter");
123         aParam = SALOMEDS::AttributeParameter::_narrow(anAttr);
124         aParam->SetInt(MESH_ID, meshHandler.id);
125         aParam->SetBool(IS_IN_WORKSPACE, false);
126         useCaseBuilder->AppendTo(soMesh->GetFather(), soMesh);
127
128         // We add the field timeseries defined on this mesh, as children of the mesh SObject
129         MEDCALC::FieldseriesHandlerList * fieldseriesHandlerList =
130           MEDFactoryClient::getDataManager()->getFieldseriesListOnMesh(meshHandler.id);
131
132         for(CORBA::ULong iFieldseries=0; iFieldseries<fieldseriesHandlerList->length(); iFieldseries++) {
133           MEDCALC::FieldseriesHandler fieldseriesHandler = (*fieldseriesHandlerList)[iFieldseries];
134           SALOMEDS::SObject_var soFieldseries = studyBuilder->NewObject(soMesh);
135           _fieldSeriesEntries[fieldseriesHandler.id] = soFieldseries->GetID();
136
137           std::string label(fieldseriesHandler.name);
138           label +=" ("+std::string(mapTypeOfFieldLabel[fieldseriesHandler.type])+")";
139           soFieldseries->SetAttrString("AttributeName", label.c_str());
140           soFieldseries->SetAttrString("AttributePixMap", "ICO_DATASOURCE_FIELD");
141           anAttr = studyBuilder->FindOrCreateAttribute(soFieldseries, "AttributeParameter");
142           aParam = SALOMEDS::AttributeParameter::_narrow(anAttr);
143           aParam->SetInt(FIELD_SERIES_ID, fieldseriesHandler.id);
144           //aParam->SetInt(FIELD_ID, fieldseriesHandler.id);
145           aParam->SetBool(IS_IN_WORKSPACE, false);
146
147           useCaseBuilder->AppendTo(soFieldseries->GetFather(), soFieldseries);
148           soFieldseries->UnRegister();
149         }
150         soMesh->UnRegister();
151       }
152
153       // cleanup
154       father->UnRegister();
155       soDatasource->UnRegister();
156     }
157   }
158
159   return MED_ORB::OP_OK;
160 }
161
162 MED_ORB::status
163 MED::registerPresentationField(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::Study_var aStudy = KERNEL::getStudyServant();
185   SALOMEDS::SObject_var sobject = aStudy->FindObjectID(entry.c_str());
186   SALOMEDS::SObject_ptr soFieldseries = sobject._retn();
187
188   if (soFieldseries->IsNull()) {
189     std::cerr << "MED::registerPresentationField(): Entry not found\n";
190     return MED_ORB::OP_ERROR;
191   }
192
193   SALOMEDS::StudyBuilder_var studyBuilder = aStudy->NewBuilder();
194   SALOMEDS::UseCaseBuilder_var useCaseBuilder = aStudy->GetUseCaseBuilder();
195   SALOMEDS::SObject_var soPresentation = studyBuilder->NewObject(soFieldseries);
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   useCaseBuilder->AppendTo(soPresentation->GetFather(), soPresentation);
210
211   return MED_ORB::OP_OK;
212 }
213
214 MED_ORB::status
215 MED::registerPresentationMesh(CORBA::Long meshId,
216                               const char* name,
217                               const char* type,
218                               const char* ico,
219                               CORBA::Long presentationId)
220 {
221   // set exception handler to catch unexpected CORBA exceptions
222   Unexpect aCatch(SALOME_SalomeException);
223
224   MEDCALC::MeshHandler_var meshHandler = MEDFactoryClient::getDataManager()->getMeshHandler(meshId);
225   if (meshHandler->id < 0){
226       std::cerr << "MED::registerPresentationMesh(): Error getting mesh handler\n";
227       return MED_ORB::OP_ERROR ;
228     }
229
230   if (_meshEntries.find(meshHandler->id) == _meshEntries.end()) {
231     std::cerr << "MED::registerPresentationMesh(): mesh not found\n";
232     return MED_ORB::OP_ERROR ;
233   }
234   std::string entry = _meshEntries[meshHandler->id];
235   SALOMEDS::Study_var aStudy = KERNEL::getStudyServant();
236   SALOMEDS::SObject_var sobject = aStudy->FindObjectID(entry.c_str());
237   SALOMEDS::SObject_ptr soMesh = sobject._retn();
238
239   if (soMesh->IsNull()) {
240     std::cerr << "MED::registerPresentationMesh(): Entry not found\n";
241     return MED_ORB::OP_ERROR;
242   }
243
244   SALOMEDS::StudyBuilder_var studyBuilder = aStudy->NewBuilder();
245   SALOMEDS::UseCaseBuilder_var useCaseBuilder = aStudy->GetUseCaseBuilder();
246   SALOMEDS::SObject_var soPresentation = studyBuilder->NewObject(soMesh);
247   useCaseBuilder->AppendTo(soPresentation->GetFather(), soPresentation);
248
249   soPresentation->SetAttrString("AttributeName", name);
250   soPresentation->SetAttrString("AttributePixMap", ico);
251
252   SALOMEDS::GenericAttribute_var anAttr;
253   SALOMEDS::AttributeParameter_var aParam;
254   anAttr = studyBuilder->FindOrCreateAttribute(soPresentation, "AttributeParameter");
255   aParam = SALOMEDS::AttributeParameter::_narrow(anAttr);
256   aParam->SetInt(MESH_ID, meshId);
257   aParam->SetBool(IS_PRESENTATION, true);
258   aParam->SetInt(PRESENTATION_ID, presentationId);
259   aParam->SetString(PRESENTATION_TYPE, type);
260
261   return MED_ORB::OP_OK;
262 }
263
264
265 MED_ORB::status
266 MED::unregisterPresentation(CORBA::Long presentationId)
267 {
268   // set exception handler to catch unexpected CORBA exceptions
269   Unexpect aCatch(SALOME_SalomeException);
270
271   SALOMEDS::Study_var aStudy = KERNEL::getStudyServant();
272   SALOMEDS::StudyBuilder_var studyBuilder = aStudy->NewBuilder();
273   SALOMEDS::UseCaseBuilder_var useCaseBuilder = aStudy->GetUseCaseBuilder();
274
275   SALOMEDS::GenericAttribute_var anAttribute;
276   SALOMEDS::SComponent_var father = aStudy->FindComponent("FIELDS");
277   SALOMEDS::ChildIterator_var it = aStudy->NewChildIterator(father);
278   for (it->InitEx(true); it->More(); it->Next()) {
279     SALOMEDS::SObject_var child(it->Value());
280
281     if (child->FindAttribute(anAttribute, "AttributeParameter")) {
282       SALOMEDS::AttributeParameter_var attrParam = SALOMEDS::AttributeParameter::_narrow(anAttribute);
283       if (!attrParam->IsSet(IS_PRESENTATION, PT_BOOLEAN) || !attrParam->GetBool(IS_PRESENTATION) || !attrParam->IsSet(PRESENTATION_ID, PT_INTEGER))
284         continue;
285
286       if (presentationId == attrParam->GetInt(PRESENTATION_ID)) {
287         // remove object from study
288         studyBuilder->RemoveObjectWithChildren(child);
289         // remove object from use case tree
290         useCaseBuilder->Remove(child);
291       }
292     }
293   }
294
295   return MED_ORB::OP_OK;
296 }
297
298 MED_ORB::PresentationsList*
299 MED::getStudyPresentations()
300 {
301   // set exception handler to catch unexpected CORBA exceptions
302   Unexpect aCatch(SALOME_SalomeException);
303
304   MED_ORB::PresentationsList* presList = new MED_ORB::PresentationsList;
305
306   SALOMEDS::Study_var aStudy = KERNEL::getStudyServant();
307   SALOMEDS::StudyBuilder_var studyBuilder = aStudy->NewBuilder();
308   SALOMEDS::UseCaseBuilder_var useCaseBuilder = aStudy->GetUseCaseBuilder();
309
310   SALOMEDS::GenericAttribute_var anAttribute;
311   SALOMEDS::SComponent_var father = aStudy->FindComponent("FIELDS");
312   SALOMEDS::ChildIterator_var it = aStudy->NewChildIterator(father);
313   for (it->InitEx(true); it->More(); it->Next())
314     {
315       SALOMEDS::SObject_var child(it->Value());
316       if (child->FindAttribute(anAttribute, "AttributeParameter"))
317         {
318           SALOMEDS::AttributeParameter_var attrParam = SALOMEDS::AttributeParameter::_narrow(anAttribute);
319           if (!attrParam->IsSet(IS_PRESENTATION, PT_BOOLEAN) || !attrParam->GetBool(IS_PRESENTATION) || !attrParam->IsSet(PRESENTATION_ID, PT_INTEGER))
320             continue;
321
322           CORBA::ULong size = presList->length();
323           presList->length(size+1);
324           (*presList)[size] = attrParam->GetInt(PRESENTATION_ID);
325         }
326     }
327   return presList;
328 }
329
330 char*
331 MED::getStudyPresentationEntry(CORBA::Long presentationId)
332 {
333   // set exception handler to catch unexpected CORBA exceptions
334   Unexpect aCatch(SALOME_SalomeException);
335
336   //MED_ORB::PresentationsList* presList = new MED_ORB::PresentationsList; // todo: unused
337
338   SALOMEDS::Study_var aStudy = KERNEL::getStudyServant();
339   SALOMEDS::StudyBuilder_var studyBuilder = aStudy->NewBuilder();
340   SALOMEDS::UseCaseBuilder_var useCaseBuilder = aStudy->GetUseCaseBuilder();
341
342   SALOMEDS::GenericAttribute_var anAttribute;
343   SALOMEDS::SComponent_var father = aStudy->FindComponent("FIELDS");
344   SALOMEDS::ChildIterator_var it = aStudy->NewChildIterator(father);
345   for (it->InitEx(true); it->More(); it->Next())
346     {
347       SALOMEDS::SObject_var child(it->Value());
348       if (child->FindAttribute(anAttribute, "AttributeParameter"))
349         {
350           SALOMEDS::AttributeParameter_var attrParam = SALOMEDS::AttributeParameter::_narrow(anAttribute);
351           if (!attrParam->IsSet(IS_PRESENTATION, PT_BOOLEAN) || !attrParam->GetBool(IS_PRESENTATION) || !attrParam->IsSet(PRESENTATION_ID, PT_INTEGER))
352             continue;
353
354           if (attrParam->GetInt(PRESENTATION_ID) == presentationId)
355             return CORBA::string_dup(child->GetID());
356         }
357     }
358   return CORBA::string_dup("");
359 }
360
361
362 Engines::TMPFile*
363 MED::DumpPython(CORBA::Boolean /*isPublished*/,
364                 CORBA::Boolean /*isMultiFile*/,
365                 CORBA::Boolean& isValidScript)
366 {
367   SALOMEDS::SObject_var aSO = KERNEL::getStudyServant()->FindComponent("FIELDS");
368   if(CORBA::is_nil(aSO)) {
369     std::cerr << "Error: Cannot find component MED\n";
370     return new Engines::TMPFile(0);
371   }
372
373   std::string aScript;
374
375   MEDCALC::CommandsList* history = MEDFactoryClient::getCommandsHistoryManager()->getCommandsHistory();
376   for (CORBA::ULong i = 0; i < history->length(); ++i) {
377     aScript += (*history)[i];
378     aScript += "\n";
379   }
380
381   int aLen = aScript.size();
382   unsigned char* aBuffer = new unsigned char[aLen+1];
383   strcpy((char*)aBuffer, aScript.c_str());
384
385   CORBA::Octet* anOctetBuf =  (CORBA::Octet*)aBuffer;
386   Engines::TMPFile_var aStreamFile = new Engines::TMPFile(aLen+1, aLen+1, anOctetBuf, 1);
387
388   isValidScript = true;
389   return aStreamFile._retn();
390 }
391
392 CORBA::Boolean
393 MED::hasObjectInfo()
394 {
395   return true;
396 }
397
398 char*
399 MED::getObjectInfo(const char* entry)
400 {
401   SALOMEDS::SObject_var aSObj = KERNEL::getStudyServant()->FindObjectID( entry );
402   SALOMEDS::SObject_var aResultSObj;
403   if (aSObj->ReferencedObject(aResultSObj))
404     aSObj = aResultSObj;
405
406   if (aSObj->_is_nil())
407     return CORBA::string_dup("unknown");
408
409   SALOMEDS::GenericAttribute_var anAttribute;
410
411   std::string name("unknown");
412   if (aSObj->FindAttribute(anAttribute, "AttributeName")) {
413     SALOMEDS::AttributeName_var attrName = SALOMEDS::AttributeName::_narrow(anAttribute);
414     name = std::string(attrName->Value());
415   }
416
417   bool isInWorkspace = false;
418   //bool isPresentation = false;
419   int sourceId = -1;
420   int meshId = -1;
421   int fieldSeriesId = -1;
422   int fieldId = -1;
423   int presentationId = -1;
424   if (aSObj->FindAttribute(anAttribute, "AttributeParameter")) {
425     SALOMEDS::AttributeParameter_var attrParam = SALOMEDS::AttributeParameter::_narrow(anAttribute);
426     if (attrParam->IsSet(IS_IN_WORKSPACE, PT_BOOLEAN))
427       isInWorkspace = attrParam->GetBool(IS_IN_WORKSPACE);
428     //if (attrParam->IsSet(IS_PRESENTATION, PT_BOOLEAN))
429     //  isPresentation = attrParam->GetBool(IS_PRESENTATION);
430     if (attrParam->IsSet(SOURCE_ID, PT_INTEGER))
431       sourceId = attrParam->GetInt(SOURCE_ID);
432     if (attrParam->IsSet(MESH_ID, PT_INTEGER))
433       meshId = attrParam->GetInt(MESH_ID);
434     if (attrParam->IsSet(FIELD_SERIES_ID, PT_INTEGER))
435       fieldSeriesId = attrParam->GetInt(FIELD_SERIES_ID);
436     if (attrParam->IsSet(FIELD_ID, PT_INTEGER))
437       fieldId = attrParam->GetInt(FIELD_ID);
438     if (attrParam->IsSet(PRESENTATION_ID, PT_INTEGER))
439       presentationId = attrParam->GetInt(PRESENTATION_ID);
440   }
441
442   if (!aSObj->_is_nil() )
443     aSObj->UnRegister();
444
445   std::ostringstream oss;
446   if (sourceId > -1)
447     oss << "Source id: " << sourceId << std::endl;
448   if (meshId > -1)
449     oss << "Mesh id: " << meshId << std::endl;
450   if (fieldSeriesId > -1)
451     oss << "Field series id: " << fieldSeriesId << std::endl;
452   if (fieldId > -1)
453     oss << "Field id: " << fieldId << std::endl;
454   //oss << "Is presentation: " << isPresentation << std::endl;
455   if (presentationId > -1)
456     oss << "Presentation id: " << presentationId << std::endl;
457   oss << "Is in workspace: " << isInWorkspace << std::endl;
458
459   return CORBA::string_dup(oss.str().c_str());
460 }
461
462 void MED::cleanUp()
463 {
464   _fieldSeriesEntries.clear();
465   _meshEntries.clear();
466 }
467
468 extern "C"
469 {
470   /*!
471     \brief Exportable factory function: create an instance of the MED component engine
472     \param orb reference to the ORB
473     \param poa reference to the POA
474     \param contId CORBA object ID, pointing to the owner SALOME container
475     \param instanceName SALOME component instance name
476     \param interfaceName SALOME component interface name
477     \return CORBA object identifier of the registered servant
478   */
479   PortableServer::ObjectId* FIELDSEngine_factory(CORBA::ORB_ptr orb,
480                                               PortableServer::POA_ptr poa,
481                                               PortableServer::ObjectId* contId,
482                                               const char* instanceName,
483                                               const char* interfaceName)
484   {
485     MED* component = new MED(orb, poa, contId, instanceName, interfaceName);
486     return component->getId();
487   }
488 }