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