Salome HOME
Merge from V5_1_main 14/05/2010
[modules/visu.git] / src / VISU_I / VISU_MultiResult_i.cc
1 //  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
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.
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 //  VISU OBJECT : interactive object for VISU entities implementation
21 //  File   : VISU_MultiResult_i.cc
22 //  Author : Alexey PETROV
23 //  Module : VISU
24 //
25 #ifdef ENABLE_MULTIPR
26
27 #include "VISU_MultiResult_i.hh"
28 #include "VISU_ResultUtils.hh"
29
30 #include "VISU_Convertor.hxx"
31 #include "VISU_ConvertorUtils.hxx"
32
33 #include "MULTIPR_Obj.hxx"
34 #include "MULTIPR_API.hxx"
35 #include "MULTIPR_Exceptions.hxx"
36
37 #include "SALOMEDS_Tool.hxx"
38 #include "HDFascii.hxx"
39
40 #include <boost/thread/thread.hpp>
41 #include <boost/bind.hpp>
42
43 #include <QStringList>
44
45 #include <strstream>
46
47 #ifdef _DEBUG_
48 static int MYDEBUG = 0;
49 static int MYTIMEDEBUG = 0;
50 #else
51 static int MYDEBUG = 0;
52 static int MYTIMEDEBUG = 0;
53 #endif
54
55
56 namespace VISU
57 {
58   //---------------------------------------------------------------
59   class TSubString: public std::string
60   {
61   public:
62     typedef std::string::size_type size_type;
63
64     TSubString(std::string& theSource, 
65                const std::string& theTarget):
66       mySource(theSource),
67       myPosition(theSource.find(theTarget)),
68       mySize(theTarget.length())
69     {}
70
71     TSubString&
72     operator = (const std::string& theTarget)
73     {
74       if(myPosition != std::string::npos)
75         mySource.replace(myPosition, mySize, theTarget);
76       return *this;
77     }
78
79   private:
80     std::string& mySource;
81     size_type myPosition;
82     size_type mySize;
83   };
84
85
86   //---------------------------------------------------------------
87   inline
88   std::ostream& 
89   operator<<(std::ostream& theStream,
90              const MultiResult_i::TPartInfo& thePartInfo)
91   {
92     theStream<<(thePartInfo.myMeshName)<<" ";
93     theStream<<(thePartInfo.myPartID)<<" ";
94     theStream<<(thePartInfo.myName)<<" ";
95     theStream<<(thePartInfo.myPath)<<" ";
96     theStream<<(thePartInfo.myFileName);
97     return theStream;
98   }
99
100
101   //---------------------------------------------------------------
102   inline
103   std::istream& 
104   operator>>(std::istream& theStream,
105              MultiResult_i::TPartInfo& thePartInfo)
106   {
107     theStream>>(thePartInfo.myMeshName);
108     theStream>>(thePartInfo.myPartID);
109     theStream>>(thePartInfo.myName);
110     theStream>>(thePartInfo.myPath);
111     theStream>>(thePartInfo.myFileName);
112     return theStream;
113   }
114
115
116   //---------------------------------------------------------------
117   inline
118   MultiResult_i::TPartInfo
119   GetPartInfo(const std::string theInfoString)
120   {
121     MultiResult_i::TPartInfo aPartInfo;
122     std::istrstream anOutputStream(theInfoString.c_str());
123     anOutputStream>>aPartInfo;
124     return aPartInfo;
125   }
126
127
128   //---------------------------------------------------------------
129   inline
130   MultiResult_i::TPartInfo
131   GetPartInfo(multipr::Obj& theMultiprObj,
132               const MultiResult_i::TPartName& thePartName)
133   {
134     return GetPartInfo(theMultiprObj.getPartInfo(thePartName.c_str()));
135   }
136
137
138   //---------------------------------------------------------------
139   inline
140   std::string
141   ExtractMainPart(const std::string& thePartName)
142   {
143     size_t aPos = thePartName.rfind('_');
144     if(aPos == std::string::npos)
145       return thePartName;
146
147     std::string aSuffix = thePartName.substr(aPos);
148     if(aSuffix == "_MED" || aSuffix == "_LOW")
149       return thePartName.substr(0, aPos);
150
151     return thePartName;
152   }
153
154
155   //---------------------------------------------------------------
156   inline
157   bool
158   IsSubString(const std::string& theSource,
159               const std::string& theSubString)
160   {
161     return theSource.rfind(theSubString) != std::string::npos;
162   }
163
164
165   //---------------------------------------------------------------
166   inline
167   bool
168   IsMediumResolution(const std::string& thePartName)
169   {
170     return IsSubString(thePartName, "_MED");
171   }
172
173
174   //---------------------------------------------------------------
175   inline
176   bool
177   IsLowResolution(const std::string& thePartName)
178   {
179     return IsSubString(thePartName, "_LOW");
180   }
181
182
183   //---------------------------------------------------------------
184   inline
185   bool
186   IsFullResolution(const std::string& thePartName)
187   {
188     return !IsMediumResolution(thePartName)  && !IsLowResolution(thePartName);
189   }
190
191
192   //---------------------------------------------------------------
193   inline
194   MultiResult_i::TResolutions
195   GetResolutions(const MultiResult_i::TMainPart2SubPartNames& theMainPart2SubPartNames,
196                  const std::string& thePartName)
197   {
198     MultiResult_i::TResolutions aResolutions;
199     aResolutions.insert(VISU::Result::FULL);
200
201     MultiResult_i::TPartName aMainPart = ExtractMainPart(thePartName);
202     MultiResult_i::TMainPart2SubPartNames::const_iterator anIter = theMainPart2SubPartNames.find(aMainPart);
203     if(anIter != theMainPart2SubPartNames.end()){
204       const MultiResult_i::TSubPartNames& aSubPartNames = anIter->second;
205
206       if(aSubPartNames.find(aMainPart + "_LOW") != aSubPartNames.end())
207         aResolutions.insert(VISU::Result::LOW);
208
209       if(aSubPartNames.find(aMainPart + "_MED") != aSubPartNames.end())
210         aResolutions.insert(VISU::Result::MEDIUM);
211     }
212     return aResolutions;
213   }
214
215
216   std::string
217   Resolutions2String(const MultiResult_i::TResolutions& theResolutions)
218   {
219     std::string aResult;
220     MultiResult_i::TResolutions::const_iterator anIter = theResolutions.begin();
221     for(; anIter != theResolutions.end(); anIter++){
222       VISU::Result::Resolution aResolution = *anIter;
223       if(aResolution == VISU::Result::FULL)
224         aResult += "F";
225       if(aResolution == VISU::Result::LOW)
226         aResult += "L";
227       if(aResolution == VISU::Result::MEDIUM)
228         aResult += "M";
229     }
230     return aResult;
231   }
232
233
234   //---------------------------------------------------------------
235   inline
236   VISU::Result::Resolution
237   GetResolution(const MultiResult_i::TMainPart2SubPartNames& theMainPart2SubPartNames,
238                   const std::string& thePartName)
239   {
240     MultiResult_i::TResolutions aResolutions = GetResolutions(theMainPart2SubPartNames, thePartName);
241
242     if(aResolutions.find(VISU::Result::LOW) != aResolutions.end())
243       return VISU::Result::LOW;
244
245     if(aResolutions.find(VISU::Result::MEDIUM) != aResolutions.end())
246       return VISU::Result::MEDIUM;
247
248     return VISU::Result::FULL;
249   }
250
251
252   //---------------------------------------------------------------
253   inline
254   std::string
255   GetIconName(const MultiResult_i::TMainPart2SubPartNames& theMainPart2SubPartNames,
256               const std::string& thePartName)
257   {
258     VISU::Result::Resolution aResolution = GetResolution(theMainPart2SubPartNames,
259                                                          thePartName);
260     if(aResolution == VISU::Result::LOW)
261       return "ICON_MULTIPR_VIEW_LOW";
262
263     if(aResolution == VISU::Result::MEDIUM)
264       return "ICON_MULTIPR_VIEW_MEDIUM";
265
266     return "ICON_MULTIPR_VIEW_FULL";
267   }
268
269
270   //----------------------------------------------------------------------------
271   void 
272   BuildParts(Result_i* theResult,
273              Result_i::PInput theInput,
274              multipr::Obj* theMultiprObj,
275              MultiResult_i::TPartInfos* thePartInfos,
276              MultiResult_i::TPartName2FileName* thePartName2FileName,
277              MultiResult_i::TPartName2Resolution* thePartName2Resolution,
278              MultiResult_i::TMainPart2SubPartNames* theMainPart2SubPartNames,
279              CORBA::Boolean* theIsDone,
280              CORBA::Boolean theIsBuild,
281              _PTR(Study) theStudy,
282              bool thePublishInStudy)
283   {
284     if(!theIsBuild || *theIsDone)
285       return;
286     
287     INITMSG(MYDEBUG, "BuildParts\n");
288     TTimerLog aTimerLog(MYTIMEDEBUG, "BuildParts");
289     TResultManager aResultManager(theResult);
290     TTransactionManager aTransactionManager(theStudy);
291     
292     try {
293       multipr::Obj& aMultiprObj = *theMultiprObj;
294       const VISU::TMeshMap& aMeshMap = theInput->GetMeshMap();
295       VISU::TMeshMap::const_iterator aMeshMapIter = aMeshMap.begin();
296       const VISU::PMesh& aMesh = aMeshMapIter->second;
297       
298       MultiResult_i::TPartNames aPartNames = aMultiprObj.getParts();
299       BEGMSG(MYDEBUG, "aPartNames.size() = "<<aPartNames.size()<<"\n");
300       
301       if(thePublishInStudy){
302         QString aComment = "Sub-parts: #";
303         aComment += QString::number(aPartNames.size());
304         
305         CreateAttributes(theStudy,
306                          aMesh->myPartsEntry,
307                          NO_ICON,
308                          NO_IOR,
309                          "Parts",
310                          NO_PERFSITENT_REF,
311                          aComment.toLatin1().data(),
312                          false);
313       }
314       
315       MultiResult_i::TPartInfos& aPartInfos = *thePartInfos;
316       MultiResult_i::TPartName2FileName& aPartName2FileName = *thePartName2FileName;
317       MultiResult_i::TPartName2Resolution& aPartName2Resolution = *thePartName2Resolution;
318       
319       MultiResult_i::TMainPart2SubPartNames& aMainPart2SubPartNames = *theMainPart2SubPartNames;
320       
321       for (size_t aPartID = 0 ; aPartID < aPartNames.size() ; aPartID++) {
322         const MultiResult_i::TPartName& aPartName = aPartNames[aPartID];
323         MultiResult_i::TPartName aMainPart = ExtractMainPart(aPartName);
324         aMainPart2SubPartNames[aMainPart].insert(aPartName);
325         BEGMSG(MYDEBUG, "aMainPart2SubPartNames['"<<aMainPart<<"'].insert('"<<aPartName<<"')\n");
326       }
327       
328       for (size_t aPartID = 0 ; aPartID < aPartNames.size() ; aPartID++) {
329         const MultiResult_i::TPartName& aPartName = aPartNames[aPartID];
330         MultiResult_i::TPartInfo aPartInfo = GetPartInfo(aMultiprObj, aPartName);
331
332         QFileInfo aFileInfo(aPartInfo.myFileName.c_str());
333         aPartInfos[aFileInfo.fileName().toLatin1().data()] = aPartInfo;
334         
335         aPartName2FileName[aPartInfo.myName] = aPartInfo.myFileName;
336         BEGMSG(MYDEBUG, "aPartName2FileName['"<<aPartInfo.myName<<"'] = '"<<aPartInfo.myFileName<<"'\n");
337         
338         if(!thePublishInStudy)
339           continue;
340         
341         QString aComment = "";
342         MultiResult_i::TResolutions aResoltutions = GetResolutions(aMainPart2SubPartNames, aPartInfo.myName);
343         std::string aResoltutionsString = Resolutions2String(aResoltutions);
344         if ( IsFullResolution(aPartInfo.myName) ) {
345           std::string anIconName = GetIconName(aMainPart2SubPartNames, aPartInfo.myName);
346           VISU::Result::Resolution aResolution = GetResolution(aMainPart2SubPartNames, aPartInfo.myName);
347           aComment.sprintf("myComment=PART;myMeshName=%s;myName=%s;myResolutions=%s;myState=%d", 
348                            aPartInfo.myMeshName.c_str(), aPartInfo.myName.c_str(), aResoltutionsString.c_str(), aResolution); 
349           CreateAttributes(theStudy,
350                            aMesh->myPartsEntry,
351                            anIconName,
352                            NO_IOR,
353                            aPartInfo.myName,
354                            NO_PERFSITENT_REF,
355                            aComment.toLatin1().data(),
356                            true);
357           aPartName2Resolution[aPartInfo.myName] = aResolution;
358           BEGMSG(MYDEBUG, "aPartName2Resolution['"<<aPartInfo.myName<<"'] = '"<<aResoltutionsString<<"'\n");
359         }
360       }
361       
362       *theIsDone = true;
363     }catch(std::exception& exc){
364       INFOS("Follow exception was occured :\n"<<exc.what());
365     }catch(...){
366       INFOS("Unknown exception was occured!");
367     }
368     
369     ProcessVoidEvent(new TUpdateObjBrowser(theStudy->StudyId(), theIsDone));
370   }
371
372
373   //---------------------------------------------------------------
374   struct TBuildPartsArgs
375   {
376     Result_i* myResult;
377     Result_i::PInput myInput;
378     multipr::Obj* myMultiprObj;
379     MultiResult_i::TPartInfos* myPartInfos;
380     MultiResult_i::TPartName2FileName* myPartName2FileName;
381     MultiResult_i::TPartName2Resolution* myPartName2Resolution;
382     MultiResult_i::TMainPart2SubPartNames* myMainPart2SubPartNames;
383     CORBA::Boolean* myIsDone;
384     CORBA::Boolean myIsBuild;
385     _PTR(Study) myStudy;
386     bool myPublishInStudy;
387
388     TBuildPartsArgs(Result_i* theResult,
389                     Result_i::PInput theInput,
390                     multipr::Obj* theMultiprObj,
391                     MultiResult_i::TPartInfos* thePartInfos,
392                     MultiResult_i::TPartName2FileName* thePartName2FileName,
393                     MultiResult_i::TPartName2Resolution* thePartName2Resolution,
394                     MultiResult_i::TMainPart2SubPartNames* theMainPart2SubPartNames,
395                     CORBA::Boolean* theIsDone,
396                     CORBA::Boolean theIsBuild,
397                     _PTR(Study) theStudy,
398                     bool thePublishInStudy):
399       myResult(theResult),
400       myInput(theInput),
401       myMultiprObj(theMultiprObj),
402       myPartInfos(thePartInfos),
403       myPartName2FileName(thePartName2FileName),
404       myPartName2Resolution(thePartName2Resolution),
405       myMainPart2SubPartNames(theMainPart2SubPartNames),
406       myIsDone(theIsDone),
407       myIsBuild(theIsBuild),
408       myStudy(theStudy),
409       myPublishInStudy(thePublishInStudy)
410     {}
411   };
412
413
414   //----------------------------------------------------------------------------
415   void 
416   BuildParts(const TBuildPartsArgs& theArgs)
417   {
418     BuildParts(theArgs.myResult,
419                theArgs.myInput,
420                theArgs.myMultiprObj,
421                theArgs.myPartInfos,
422                theArgs.myPartName2FileName,
423                theArgs.myPartName2Resolution,
424                theArgs.myMainPart2SubPartNames,
425                theArgs.myIsDone,
426                theArgs.myIsBuild,
427                theArgs.myStudy,
428                theArgs.myPublishInStudy);
429   }
430
431
432   //---------------------------------------------------------------
433 }
434
435
436 //---------------------------------------------------------------
437 VISU::MultiResult_i
438 ::MultiResult_i(SALOMEDS::Study_ptr theStudy,
439                 const ESourceId& theSourceId,
440                 const ECreationId& theCreationId,
441                 CORBA::Boolean theIsBuildImmediately,
442                 CORBA::Boolean theIsBuildFields,
443                 CORBA::Boolean theIsBuildMinMax,
444                 CORBA::Boolean theIsBuildGroups):
445   Result_i(theStudy,
446            theSourceId,
447            theCreationId,
448            theIsBuildImmediately,
449            theIsBuildFields,
450            theIsBuildMinMax,
451            theIsBuildGroups)
452 {}
453
454
455 //---------------------------------------------------------------
456 VISU::MultiResult_i
457 ::MultiResult_i()
458 {}
459
460
461 //---------------------------------------------------------------
462 size_t
463 VISU::MultiResult_i
464 ::IsPossible()
465 {
466   return TSuperClass::IsPossible();
467 }
468
469
470 //---------------------------------------------------------------
471 VISU::Storable*
472 VISU::MultiResult_i
473 ::Build(SALOMEDS::SObject_ptr theSObject,
474         CORBA::Boolean theIsAtOnce)
475 {
476   if(!TSuperClass::Build(theSObject, theIsAtOnce))
477     return NULL;
478
479   if(IsDone())
480     return this;
481
482   if(theIsAtOnce){
483     BuildParts(this,
484                GetInput(),
485                &myMultiprObj,
486                &myPartInfos,
487                &myPartName2FileName,
488                &myPartName2Resolution,
489                &myMainPart2SubPartNames,
490                &myIsPartsDone,
491                myIsBuildParts,
492                myStudy,
493                true);
494   }
495
496   return this;
497 }
498
499
500 //---------------------------------------------------------------
501 void
502 VISU::MultiResult_i
503 ::BuildDataTree(const std::string& theResultEntry)
504 {
505   BuildEntities(this,
506                 GetInput(),
507                 &myIsEntitiesDone,
508                 theResultEntry,
509                 false,
510                 myIsBuildGroups,
511                 myIsBuildFields,
512                 myIsBuildParts,
513                 myStudy);
514   {
515     TBuildPartsArgs anArgs(this,
516                            GetInput(),
517                            &myMultiprObj,
518                            &myPartInfos,
519                            &myPartName2FileName,
520                            &myPartName2Resolution,
521                            &myMainPart2SubPartNames,
522                            &myIsPartsDone,
523                            myIsBuildParts,
524                            myStudy,
525                            true);
526
527     boost::thread aThread(boost::bind(&BuildParts, anArgs));
528   }
529   {
530     boost::thread aThread(boost::bind(&BuildGroups,
531                                       this,
532                                       GetInput(),
533                                       &myIsGroupsDone,
534                                       myIsBuildGroups,
535                                       false,
536                                       myStudy));
537   }
538   {
539     boost::thread aThread(boost::bind(&BuildFieldDataTree,
540                                       this,
541                                       GetInput(),
542                                       &myIsFieldsDone,
543                                       myIsBuildFields,
544                                       &myIsMinMaxDone,
545                                       myIsBuildMinMax,
546                                       myStudy));
547   }
548 }
549
550
551 //---------------------------------------------------------------
552 VISU::Storable*
553 VISU::MultiResult_i
554 ::Create(const char* theFileName)
555 {
556   QFileInfo aFileInfo(theFileName);
557   QString aTargetFileName = aFileInfo.filePath();
558   if(aTargetFileName.endsWith("_maitre.med")){
559     try {
560       myMultiprObj.create(theFileName);
561       if ( myMultiprObj.isValidDistributedMEDFile() ) {
562         aTargetFileName = myMultiprObj.getSequentialMEDFilename().c_str();
563         SetInitFileName(aFileInfo.filePath().toLatin1().data());
564         SetName(VISU::GenerateName(aFileInfo.fileName().toLatin1().data()).toLatin1().data(), false);
565         myIsBuildParts = true;
566       }
567     }catch(std::exception& exc){
568       MSG(MYDEBUG,"Follow exception was occured in:\n"<<exc.what());
569     }catch(multipr::RuntimeException& exc){
570       std::ostringstream aStream;
571       exc.dump(aStream);
572       aStream<<ends;
573       MSG(MYDEBUG,"Follow exception was occured in:\n"<<aStream.str());
574     }catch(...){
575       MSG(MYDEBUG,"Unknown exception !!!");
576     }
577   }
578
579   return TSuperClass::Create(aTargetFileName.toLatin1().data());
580 }
581
582
583 //---------------------------------------------------------------
584 bool
585 VISU::MultiResult_i
586 ::Save(SALOMEDS::SComponent_ptr theComponent,
587        const std::string& theURL,
588        bool theIsMultiFile,
589        bool theIsASCII,
590        TFileNames& theFileNames,
591        TFileNames& theFiles)
592 {
593   bool anIsDone = Result_i::Save(theComponent, 
594                                  theURL, 
595                                  theIsMultiFile,
596                                  theIsASCII, 
597                                  theFileNames, 
598                                  theFiles);
599   if(!anIsDone)
600     return false;
601
602   if(!myMultiprObj.isValidDistributedMEDFile())
603     return true;
604
605   INITMSG(MYDEBUG, "MultiResult_i::Save - this = "<<this<<"\n");
606   INITMSGA(MYDEBUG, 0, "theIsMultiFile = "<<theIsMultiFile<<"; theIsASCII = "<<theIsASCII<<"\n");
607
608   // To generate an unique prefix for the set of multi sub files
609   std::string aPrefix;
610   if (theIsMultiFile) {
611     CORBA::String_var anURL = GetStudyDocument()->URL();
612     aPrefix = SALOMEDS_Tool::GetNameFromPath(anURL.in());
613   }
614
615   std::string aBase, aSuffix;
616   SplitName(GetFileName(), aBase, aSuffix);
617   BEGMSG(MYDEBUG, "aBase = '"<<aBase<<"'; aSuffix = '"<<aSuffix<<"'\n");
618
619   aPrefix = aPrefix + "_" + aBase;
620   VISU::TSubString(aPrefix, ".med") = "";
621
622   BEGMSG(MYDEBUG, "aPrefix = '"<<aPrefix<<"'\n");
623
624   // To get a common prefix used in the multi file
625   QFileInfo aFileInfo(myMultiprObj.getSequentialMEDFilename().c_str());
626   std::string aFilePrefix = aFileInfo.completeBaseName().toLatin1().data();
627
628   MultiResult_i::TPartNames aPartNames = myMultiprObj.getParts();
629   for (size_t aPartID = 0 ; aPartID < aPartNames.size() ; aPartID++) {
630     const MultiResult_i::TPartName& aPartName = aPartNames[aPartID];
631     MultiResult_i::TPartInfo aPartInfo = GetPartInfo(myMultiprObj, aPartName);
632
633     QFileInfo aFileInfo(aPartInfo.myFileName.c_str());
634     std::string aFile = aFileInfo.absoluteFilePath().toLatin1().data();
635
636     std::string aFileName = aFileInfo.fileName().toLatin1().data();
637     VISU::TSubString(aFileName, aFilePrefix) = aPrefix;
638     VISU::TSubString(aFileName, aSuffix) = "";
639     aFileName = aFileName + aSuffix;
640     INITMSG(MYDEBUG, "aFileName = '"<<aFileName<<"'\n");
641
642     if(theIsMultiFile || theIsASCII){
643       std::string aPathToCopy(theURL + aFileName);
644       BEGMSG(MYDEBUG, "aPathToCopy = '"<<aPathToCopy<<"'\n");
645       
646       if(!VISU::CopyFile(aFile, aPathToCopy))
647         return false;
648
649       if(theIsASCII)
650         HDFascii::ConvertFromHDFToASCII(const_cast<char*>(aPathToCopy.c_str()), true);
651     }
652
653     theFileNames.push_back(aFileName);
654     theFiles.push_back(aFile);
655   }
656   
657   return true;
658 }
659
660
661 //---------------------------------------------------------------
662 CORBA::Boolean 
663 VISU::MultiResult_i
664 ::CanCopy(SALOMEDS::SObject_ptr theObject) 
665 {
666   if(!myIsPartsDone)
667     return Result_i::CanCopy(theObject);
668
669   return false;
670 }
671
672
673 //---------------------------------------------------------------
674 void 
675 VISU::MultiResult_i
676 ::ToStream(std::ostringstream& theStr)
677 {
678   INITMSG(MYDEBUG, "MultiResult_i::ToStream - this = "<<this<<"\n");
679
680   TSuperClass::ToStream(theStr);
681
682   Storable::DataToStream(theStr,"myIsBuildParts", myIsPartsDone);
683   if(!myIsPartsDone)
684     return;
685
686   {
687     std::ostringstream aPartNames, aResolutions;
688     TPartName2Resolution::const_iterator anIter = myPartName2Resolution.begin();
689     for ( ; anIter != myPartName2Resolution.end() ; anIter++) {
690       const TPartName& aPartName = anIter->first;
691       aPartNames<<aPartName<<"|";
692       const VISU::Result::Resolution& aResolution = anIter->second;
693       aResolutions<<aResolution<<"|";
694     }
695     
696     Storable::DataToStream(theStr, "myPartNames",  aPartNames.str().c_str());   
697     Storable::DataToStream(theStr, "myResolutions", aResolutions.str().c_str());
698   }
699
700   {
701     std::string aBase, aSuffix;
702     VISU::SplitName(GetFileName(), aBase, aSuffix);
703     INITMSG(MYDEBUG, "aBase = '"<<aBase<<"'; aSuffix = '"<<aSuffix<<"'\n");
704
705     QFileInfo aFileInfo(myMultiprObj.getSequentialMEDFilename().c_str());
706     std::string aFilePrefix = aFileInfo.completeBaseName().toLatin1().data();
707     BEGMSG(MYDEBUG, "aFilePrefix = '"<<aFilePrefix<<"'\n");
708
709     std::ostringstream aPartInfos;
710     MultiResult_i::TPartNames aPartNames = myMultiprObj.getParts();
711     for (size_t aPartID = 0 ; aPartID < aPartNames.size() ; aPartID++) {
712       const MultiResult_i::TPartName& aPartName = aPartNames[aPartID];
713       MultiResult_i::TPartInfo aPartInfo = GetPartInfo(myMultiprObj, aPartName);
714
715       QFileInfo aFileInfo(aPartInfo.myFileName.c_str());
716       std::string aFileName = aFileInfo.fileName().toLatin1().data();
717       VISU::TSubString(aFileName, aFilePrefix + "_") = "";      
718       VISU::TSubString(aFileName, aSuffix) = "";
719       aPartInfo.myFileName = aFileName + aSuffix;
720       aPartInfos<<aPartInfo<<"|";
721
722       INITMSG(MYDEBUG, "aFileName = '"<<aPartInfo.myFileName<<"'\n");
723     }
724
725     Storable::DataToStream(theStr, "myPartInfos", aPartInfos.str().c_str());
726   }
727 }
728
729
730 //---------------------------------------------------------------
731 VISU::Storable*
732 VISU::MultiResult_i
733 ::Restore(SALOMEDS::SObject_ptr theSObject,
734           const Storable::TRestoringMap& theMap,
735           const std::string& thePrefix,
736           CORBA::Boolean theIsMultiFile)
737 {
738   INITMSG(MYDEBUG, "MultiResult_i::Restore - this = "<<this<<"\n");
739
740   if(!TSuperClass::Restore(theSObject, theMap, thePrefix, theIsMultiFile))
741     return NULL;
742
743   myIsBuildParts = Storable::FindValue(theMap, "myIsBuildParts", "0").toInt();
744   if(!myIsBuildParts)
745     return this;
746   
747   QStringList aResolutions = VISU::Storable::FindValue(theMap, "myResolutions").split("|", QString::SkipEmptyParts);
748   QStringList aPartNames = VISU::Storable::FindValue(theMap, "myPartNames").split("|", QString::SkipEmptyParts);
749   for(size_t anId = 0, anEnd = aPartNames.size(); anId < anEnd; anId++){
750     const QString& aPartName = aPartNames[anId];
751     VISU::Result::Resolution aResolution = VISU::Result::Resolution(aResolutions[anId].toInt());
752     myPartName2Resolution[aPartName.toLatin1().data()] = aResolution;
753     INITMSG(MYDEBUG, "aPartName = '"<<aPartName.toLatin1().data()<<"' = "<<aResolution<<"\n");
754   }
755   
756   std::string aBase, aSuffix;
757   SplitName(GetFileName(), aBase, aSuffix);
758   INITMSGA(MYDEBUG, 0, "aBase = '"<<aBase<<"'; aSuffix = '"<<aSuffix<<"'\n");
759
760   std::string aSourceFileName = GetFileInfo().absoluteFilePath().toLatin1().data();
761   BEGMSG(MYDEBUG, "aSourceFileName = '"<<aSourceFileName<<"'\n");    
762   
763   std::string aPrefix = aSourceFileName;
764   VISU::TSubString(aPrefix, ".med") = "";
765   VISU::TSubString(aPrefix, aSuffix) = "";
766   BEGMSG(MYDEBUG, "aPrefix = '"<<aPrefix<<"'\n");    
767   
768   std::string aMultiFileName(aPrefix + "_maitre.med" + aSuffix);
769   BEGMSG(MYDEBUG, "aMultiFileName = '"<<aMultiFileName<<"'\n");    
770
771   {
772     std::ofstream aMultiFileStream(aMultiFileName.c_str());
773     aMultiFileStream<<"# MED file v2.3 - Master file created by VISU\n";
774     aMultiFileStream<<"#\n";
775     aMultiFileStream<<"# [SOURCE]="<<aSourceFileName<<"\n";
776     aMultiFileStream<<"#\n";
777
778     QStringList aPartInfos = VISU::Storable::FindValue(theMap, "myPartInfos").split("|", QString::SkipEmptyParts);
779     aMultiFileStream<<aPartInfos.size()<<"\n";
780
781     for(size_t anId = 0, anEnd = aPartInfos.size(); anId < anEnd; anId++){
782       MultiResult_i::TPartInfo aPartInfo = GetPartInfo(aPartInfos[anId].toLatin1().data());
783       aPartInfo.myFileName = aPrefix + "_" + aPartInfo.myFileName;
784       INITMSG(MYDEBUG, "aPartInfo.myFileName = '"<<aPartInfo.myFileName<<"'\n");    
785       aMultiFileStream<<aPartInfo<<"\n";
786     }
787   }
788
789   {
790     myMultiprObj.create(aMultiFileName.c_str());
791     BuildParts(this,
792                GetInput(),
793                &myMultiprObj,
794                &myPartInfos,
795                &myPartName2FileName,
796                &myPartName2Resolution,
797                &myMainPart2SubPartNames,
798                &myIsPartsDone,
799                myIsBuildParts,
800                myStudy,
801                false);
802   }
803
804   return this;
805 }
806
807
808 //---------------------------------------------------------------
809 CORBA::Boolean 
810 VISU::MultiResult_i
811 ::IsDone() 
812 {
813   return TSuperClass::IsDone() && 
814     (myIsBuildParts? myIsPartsDone: true);
815 }
816
817
818 //---------------------------------------------------------------
819 VISU::Result::EntityNames* 
820 VISU::MultiResult_i
821 ::GetPartNames(const char* theMeshName)
822 {
823   VISU::Result::EntityNames_var aResult = new VISU::Result::EntityNames();
824   if(!myIsBuildParts)
825     return aResult._retn();
826     
827   MultiResult_i::TPartNames aMeshParts;
828   MultiResult_i::TPartNames aPartNames = myMultiprObj.getParts();
829   for (size_t aPartID = 0 ; aPartID < aPartNames.size() ; aPartID++) {
830     const MultiResult_i::TPartName& aPartName = aPartNames[aPartID];
831     if(!IsFullResolution(aPartName))
832       continue;
833
834     MultiResult_i::TPartInfo aPartInfo = GetPartInfo(myMultiprObj, aPartName);
835     if(true || aPartInfo.myMeshName == theMeshName) // To ignore theMeshName input parameter
836       aMeshParts.push_back(aPartName);
837   }
838
839   if(aMeshParts.empty())
840     return aResult._retn();
841
842   aResult->length(aMeshParts.size());
843   for (size_t aPartID = 0 ; aPartID < aMeshParts.size() ; aPartID++) {
844     const MultiResult_i::TPartName& aPartName = aMeshParts[aPartID];
845     aResult[aPartID] = aPartName.c_str();
846   }
847
848   return aResult._retn();
849 }
850
851 VISU::Result::Resolutions* 
852 VISU::MultiResult_i
853 ::GetResolutions(const char* theMeshName, 
854                  const char* thePartName)
855 {
856   VISU::Result::Resolutions_var aResult = new VISU::Result::Resolutions();
857   if(!myIsBuildParts)
858     return aResult._retn();
859
860   MultiResult_i::TPartNames aPartNames = myMultiprObj.getParts();
861   for (size_t aPartID = 0 ; aPartID < aPartNames.size() ; aPartID++) {
862     const MultiResult_i::TPartName& aPartName = aPartNames[aPartID];
863     MultiResult_i::TPartName aMainPart = ExtractMainPart(thePartName);
864     if(aMainPart != thePartName)
865       continue;
866
867     MultiResult_i::TPartInfo aPartInfo = GetPartInfo(myMultiprObj, aPartName);
868     if(false || aPartInfo.myMeshName != theMeshName) // To ignore theMeshName input parameter
869       continue;
870
871     MultiResult_i::TResolutions aResolutions = VISU::GetResolutions(myMainPart2SubPartNames, thePartName);
872     if(aResolutions.empty())
873       return aResult._retn();
874
875     aResult->length(aResolutions.size());
876     MultiResult_i::TResolutions::const_iterator anIter = aResolutions.end();
877     for(size_t anId = 0; anIter != aResolutions.end(); anIter++, anId++){
878       const VISU::Result::Resolution& aResolution = *anIter;
879       aResult[anId] = aResolution;
880     }
881
882     break;
883   }
884
885   return aResult._retn();
886 }
887
888 VISU::Result::Resolution
889 VISU::MultiResult_i
890 ::GetResolution(const char* theMeshName, 
891                 const char* thePartName)
892 {
893   TPartName2Resolution::iterator anIter = myPartName2Resolution.find(thePartName);
894   if(anIter == myPartName2Resolution.end())
895     return VISU::Result::HIDDEN;
896
897   const VISU::Result::Resolution& aResolution = anIter->second;
898   return aResolution;
899 }
900
901 void 
902 VISU::MultiResult_i
903 ::SetResolution(const char* theMeshName, 
904                 const char* thePartName, 
905                 VISU::Result::Resolution theResolution)
906 {
907   if(!IsFullResolution(thePartName))
908     return;
909
910   TPartName2Resolution::iterator anIter = myPartName2Resolution.find(thePartName);
911   if(anIter == myPartName2Resolution.end())
912     return;
913
914   VISU::Result::Resolution& aResolution = anIter->second;
915   if(aResolution == theResolution)
916     return;
917
918   if(theResolution != VISU::Result::HIDDEN){
919     MultiResult_i::TResolutions aResolutions = VISU::GetResolutions(myMainPart2SubPartNames, thePartName);
920     MultiResult_i::TResolutions::iterator anIter = aResolutions.find(theResolution);
921     if(anIter == aResolutions.end())
922       return;
923   }
924
925   VISU::Storable::TRestoringMap aRestoringMap;
926   aRestoringMap["myComment"] = "PART";
927   //aRestoringMap["myMeshName"] = theMeshName; // To ignore theMeshName input parameter
928   aRestoringMap["myName"] = thePartName;
929
930   const VISU::TMeshMap& aMeshMap = Result_i::GetInput()->GetMeshMap();
931   //VISU::TMeshMap::const_iterator aMeshIter = aMeshMap.find(theMeshName); // To ignore theMeshName input parameter
932   VISU::TMeshMap::const_iterator aMeshIter = aMeshMap.begin();
933   if(aMeshIter == aMeshMap.end())
934     return;
935
936   std::string aFatherEntry;
937   const VISU::PMesh& aMesh = aMeshIter->second;
938   if(aMesh->myPartsEntry != "")
939     aFatherEntry = Storable::FindEntry(GetStudyDocument(),
940                                        aMesh->myPartsEntry,
941                                        aRestoringMap);
942   else
943     aFatherEntry = Result_i::GetEntry(aRestoringMap);
944   
945   if ( aFatherEntry == "" )
946     return;
947
948   std::string anIconName = "ICON_MULTIPR_VIEW_HIDE";
949   if(theResolution == VISU::Result::FULL)
950     anIconName = "ICON_MULTIPR_VIEW_FULL";
951   else if(theResolution == VISU::Result::MEDIUM)
952     anIconName = "ICON_MULTIPR_VIEW_MEDIUM";
953   else if(theResolution == VISU::Result::LOW)
954     anIconName = "ICON_MULTIPR_VIEW_LOW";
955
956   _PTR(Study) aStudy = GetStudy();
957   _PTR(SObject) aSObject = aStudy->FindObjectID(aFatherEntry);
958   aRestoringMap = Storable::GetStorableMap(aSObject);
959
960   std::ostrstream anOutputStream;
961   anOutputStream<<"myComment=PART;";
962   anOutputStream<<"myName="<<thePartName<<";";
963   anOutputStream<<"myMeshName="<<theMeshName<<";";
964   anOutputStream<<"myResolutions="<<aRestoringMap["myResolutions"].toLatin1().data()<<";";
965   anOutputStream<<"myState="<<theResolution;
966   anOutputStream<<ends;
967
968   CreateAttributes(aStudy,
969                    aFatherEntry,
970                    anIconName,
971                    NO_IOR,
972                    NO_NAME,
973                    NO_PERFSITENT_REF,
974                    anOutputStream.str(),
975                    false);
976
977   aResolution = theResolution;
978 }
979
980
981 //---------------------------------------------------------------
982 VISU::MultiResult_i
983 ::~MultiResult_i()
984 {
985   INITMSG(MYDEBUG, "MultiResult_i::~MultiResult_i - this = "<<this<<"\n");
986   if(myIsBuildParts){
987     TRepresentation2Input::iterator anIter = myRepresentation2Input.begin();
988     for ( ; anIter != myRepresentation2Input.end() ; anIter++) {
989       const PInput& anInput = anIter->second;
990       std::string aFileName = anInput->GetName();
991       INITMSG(MYDEBUG, "RemoveFile - aFileName = '"<<aFileName<<"'\n");
992       VISU::RemoveFile(aFileName);
993     }
994     if (GetSourceId() == eRestoredFile) {
995       INITMSG(MYDEBUG, "RemoveFile - myMultiprObj.getMEDFilename = '"<<myMultiprObj.getMEDFilename()<<"'\n");
996       VISU::RemoveFile(myMultiprObj.getMEDFilename());
997       MultiResult_i::TPartNames aPartNames = myMultiprObj.getParts();
998       for (size_t aPartID = 0 ; aPartID < aPartNames.size() ; aPartID++) {
999         const MultiResult_i::TPartName& aPartName = aPartNames[aPartID];
1000         MultiResult_i::TPartInfo aPartInfo = GetPartInfo(myMultiprObj, aPartName);
1001         INITMSG(MYDEBUG, "RemoveFile - aPartInfo.myFileName = '"<<aPartInfo.myFileName<<"'\n");
1002         VISU::RemoveFile(aPartInfo.myFileName);
1003       }
1004     }
1005   }
1006 }
1007
1008
1009 namespace VISU
1010 {
1011   //---------------------------------------------------------------
1012   inline
1013   void
1014   UpdateRepresentationKey(const MultiResult_i::TPartName2FileName& thePartName2FileName,
1015                           MultiResult_i::TRepresentationKey& theRepresentationKey,
1016                           const std::string& thePartName)
1017   {
1018     MultiResult_i::TPartName2FileName::const_iterator anIterator = thePartName2FileName.find(thePartName);
1019     if (anIterator != thePartName2FileName.end()){
1020       const MultiResult_i::TFileName& aFileName = anIterator->second;
1021       theRepresentationKey.insert(aFileName);
1022     }
1023   }
1024
1025
1026   //---------------------------------------------------------------
1027   MultiResult_i::TRepresentationKey
1028   GetRepresentation(const MultiResult_i::TPartName2FileName& thePartName2FileName,
1029                     const MultiResult_i::TPartName2Resolution& thePartName2Resolution)
1030   {
1031     // name of selected parts
1032     MultiResult_i::TRepresentationKey aRepresentationKey;
1033
1034     // for each part of the mesh
1035     MultiResult_i::TPartName2Resolution::const_iterator anIter = thePartName2Resolution.begin();
1036     for ( ; anIter != thePartName2Resolution.end() ; anIter++) {
1037       const MultiResult_i::TPartName& aPartName = anIter->first;
1038       if(IsFullResolution(aPartName)){
1039         const VISU::Result::Resolution& aResolution = anIter->second;
1040         if(aResolution == VISU::Result::FULL) 
1041           UpdateRepresentationKey(thePartName2FileName, aRepresentationKey, aPartName);
1042         if(aResolution == VISU::Result::MEDIUM) 
1043           UpdateRepresentationKey(thePartName2FileName, aRepresentationKey, aPartName + "_MED");
1044         else if(aResolution == VISU::Result::LOW) 
1045           UpdateRepresentationKey(thePartName2FileName, aRepresentationKey, aPartName + "_LOW");
1046       }
1047     }
1048     return aRepresentationKey;
1049   }
1050
1051
1052   //---------------------------------------------------------------
1053   bool 
1054   UseInitialInput(const MultiResult_i::TPartName2FileName& thePartName2FileName,
1055                   const MultiResult_i::TPartName2Resolution& thePartName2Resolution)
1056   {
1057     bool aResult = true;
1058     MultiResult_i::TPartName2FileName::const_iterator anIter = thePartName2FileName.begin();
1059     for ( ; anIter != thePartName2FileName.end() ; anIter++) {
1060       const MultiResult_i::TPartName& aPartName = anIter->first;
1061       if(IsFullResolution(aPartName)){
1062         MultiResult_i::TPartName2Resolution::const_iterator anIter2 = thePartName2Resolution.find(aPartName);
1063         if(anIter2 != thePartName2Resolution.end()){
1064           const VISU::Result::Resolution& aResolution = anIter2->second;
1065           if(aResolution == VISU::Result::FULL)
1066             continue;
1067         }
1068         aResult = false;
1069         break;
1070       }
1071     }
1072     return aResult;
1073   }
1074 }
1075
1076
1077 //---------------------------------------------------------------
1078 VISU::Result_i::PInput
1079 VISU::MultiResult_i
1080 ::GetInput(const std::string& theMeshName, 
1081            VISU::Entity theEntity,
1082            const std::string& theFieldName, 
1083            CORBA::Long theTimeStampNumber) 
1084 {
1085   if(theEntity == NONE) // If client wants use initial behaviour
1086     return TSuperClass::GetInput();
1087
1088   if(!myIsPartsDone) // If corresponding data is not ready yet
1089     return TSuperClass::GetInput();
1090
1091   //if(UseInitialInput(myPartName2FileName, myPartName2Resolution)) 
1092   //  return TSuperClass::GetInput();
1093
1094   MultiResult_i::TRepresentationKey aRepresentationKey = 
1095     GetRepresentation(myPartName2FileName, myPartName2Resolution);
1096
1097   typedef std::vector<TFileName> TFileNames;
1098   TFileNames aFileNames(aRepresentationKey.begin(), aRepresentationKey.end());
1099
1100   aRepresentationKey.insert( theMeshName );
1101   aRepresentationKey.insert( theFieldName );
1102
1103   TRepresentation2Input::iterator anIter = myRepresentation2Input.find(aRepresentationKey);
1104   if(anIter == myRepresentation2Input.end()){
1105     INITMSG(MYDEBUG, "MultiResult_i::GetInput - this = "<<this<<"\n");
1106     std::string aFileName = SALOMEDS_Tool::GetTmpDir() + "multipr_merge.med";
1107     if(MYDEBUG){
1108       INITMSG(MYDEBUG, "aFileName = '"<<aFileName<<"':\n");
1109       TFileNames::const_iterator anIter = aFileNames.begin();
1110       for ( ; anIter != aFileNames.end() ; anIter++) {
1111         const MultiResult_i::TFileName& aFileName = *anIter;
1112         INITMSG(MYDEBUG, "'"<<aFileName<<"'\n");
1113       }
1114     }
1115     int aRes = false;
1116     std::string anErrorMessage("empty mesh");
1117     try {
1118       INITMSG(MYDEBUG, "theMeshName = '"<<theMeshName<<"'; theFieldName = '"<<theFieldName<<"'\n");
1119       aRes = multipr::merge(aFileNames, theMeshName.c_str(), theFieldName.c_str(), aFileName.c_str());
1120     }catch(std::exception& exc){
1121       MSG(MYDEBUG,"Follow exception was occured in:\n"<<exc.what());
1122       anErrorMessage = exc.what();
1123     }catch(multipr::RuntimeException& exc){
1124       std::ostringstream aStream;
1125       exc.dump(aStream);
1126       aStream<<ends;
1127       MSG(MYDEBUG,"Follow exception was occured in:\n"<<aStream.str());
1128       anErrorMessage = aStream.str();
1129     }catch(...){
1130       MSG(MYDEBUG,"Unknown exception !!!");
1131     }
1132     INITMSGA(MYDEBUG, 0, "aRes = "<<aRes<<"\n");
1133     if (aRes == 0) {
1134       VISU::RemoveFile(aFileName);
1135       throw std::runtime_error(anErrorMessage); 
1136     }
1137     PInput anInput(CreateConvertor(aFileName));
1138     anInput->BuildFields();
1139     if(myIsBuildMinMax)
1140       anInput->BuildMinMax();
1141     myRepresentation2Input[aRepresentationKey] = anInput;
1142     return anInput;
1143   }
1144   
1145   return anIter->second;
1146 }
1147
1148
1149 #endif // ENABLE_MULTIPR