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