1 // Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 // VISU OBJECT : interactive object for VISU entities implementation
21 // File : VISU_ResultUtils.cc
22 // Author : Alexey PETROV
25 #include "VISU_ResultUtils.hh"
27 #include "SUIT_Session.h"
28 #include "SALOME_Event.h"
29 #include "SalomeApp_Study.h"
30 #include "SalomeApp_Application.h"
32 #include "VISU_Convertor.hxx"
33 #include "VISU_ConvertorUtils.hxx"
39 #include <boost/thread/recursive_mutex.hpp>
40 #include <boost/thread/thread.hpp>
41 #include <boost/bind.hpp>
44 static int MYTIMEDEBUG = 0;
46 static int MYTIMEDEBUG = 0;
53 //----------------------------------------------------------------------------
54 typedef boost::recursive_mutex TMutex;
55 typedef TMutex::scoped_lock TLock;
57 static TMutex myMutex;
59 //----------------------------------------------------------------------------
61 ::TResultManager(Result_i* theResult):
68 //----------------------------------------------------------------------------
72 myResult->UnRegister();
76 //----------------------------------------------------------------------------
78 ::TTransactionManager(_PTR(Study) theStudyDocument):
79 myStudyBuilder(theStudyDocument->NewBuilder())
82 myStudyBuilder->NewCommand();
86 //----------------------------------------------------------------------------
88 ::~TTransactionManager()
91 myStudyBuilder->CommitCommand();
95 //----------------------------------------------------------------------------
97 ::TUpdateObjBrowser(const int theStudyId, CORBA::Boolean* theIsDone):
98 myStudyId(theStudyId),
103 //----------------------------------------------------------------------------
108 TLock aLock(myMutex);
109 SUIT_Session* aSession = SUIT_Session::session();
110 QList<SUIT_Application*> anApplications = aSession->applications();
111 QListIterator<SUIT_Application*> anIter (anApplications);
112 while (anIter.hasNext()) {
113 SUIT_Application* aSApp = anIter.next();
114 if(SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>(aSApp)){
115 if (SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>(anApp->activeStudy())) {
116 if (_PTR(Study) aCStudy = aStudy->studyDS()) {
117 if (myStudyId == aCStudy->StudyId()) {
118 TTimerLog aTimerLog(MYTIMEDEBUG,"Result_i::updateObjectBrowser");
119 anApp->updateObjectBrowser();
130 //----------------------------------------------------------------------------
132 GenerateName(const std::string& theName)
134 TLock aLock(myMutex);
136 typedef std::map<std::string, int> TNameMap;
137 static TNameMap aMap;
139 TNameMap::const_iterator anIter = aMap.find(theName);
141 if (anIter == aMap.end()) {
143 aResult = theName.c_str();
145 aResult = GenerateName(theName,++aMap[theName]);
151 //----------------------------------------------------------------------------
153 SplitName(const std::string& theName,
154 std::string& theBase,
155 std::string& theSuffix,
158 size_t aPosition = theName.rfind(theDelimeter);
159 if(aPosition == std::string::npos){
165 theBase = theName.substr(0, aPosition);
166 theSuffix = theName.substr(aPosition);
171 //----------------------------------------------------------------------------
173 MakeFileName(const std::string& theName,
174 const void* thePointer)
176 std::ostringstream aStream;
177 aStream<<theName<<"_"<<thePointer;
178 return aStream.str();
182 //----------------------------------------------------------------------------
184 GenerateFieldName(const std::string& theName,
185 const std::string& theUnits)
188 const string tmp (theUnits.size(),' ');
189 if (theUnits == "" || theUnits == tmp)
190 aName = QString("%1, -").arg(theName.c_str());
192 aName = QString("%1, %2").arg(theName.c_str()).arg(theUnits.c_str());
193 aName = aName.simplified();
198 //----------------------------------------------------------------------------
200 CreateReference(_PTR(Study) theStudyDocument,
201 const std::string& theFatherEntry,
202 const std::string& theRefEntry)
204 _PTR(StudyBuilder) aStudyBuilder = theStudyDocument->NewBuilder();
205 _PTR(SObject) aFather = theStudyDocument->FindObjectID(theFatherEntry);
206 _PTR(SObject) aNewObj = aStudyBuilder->NewObject(aFather);
207 _PTR(SObject) aRefSObj = theStudyDocument->FindObjectID(theRefEntry);
208 aStudyBuilder->Addreference(aNewObj,aRefSObj);
212 //----------------------------------------------------------------------------
214 RemoveSObject(_PTR(Study) theStudyDocument,
215 const string& theEntry)
217 _PTR(StudyBuilder) aStudyBuilder = theStudyDocument->NewBuilder();
218 _PTR(SObject) aSObject = theStudyDocument->FindObjectID(theEntry);
219 aStudyBuilder->RemoveObject(aSObject);
223 //----------------------------------------------------------------------------
225 BuildEntities(Result_i* theResult,
226 Result_i::PInput theInput,
227 CORBA::Boolean* theIsDone,
228 const std::string& theResultEntry,
229 CORBA::Boolean theIsAtOnce,
230 CORBA::Boolean theIsBuildGroups,
231 CORBA::Boolean theIsBuildFields,
232 CORBA::Boolean theIsBuildParts,
233 _PTR(Study) theStudy)
238 TTimerLog aTimerLog(MYTIMEDEBUG,"Result_i::BuildEntities");
239 TResultManager aResultManager(theResult);
240 TTransactionManager aTransactionManager(theStudy);
243 TTimerLog aTimerLog(MYTIMEDEBUG,"theInput->BuildEntities");
244 theInput->BuildEntities();
247 QString aComment,aTmp;
248 const TMeshMap& aMeshMap = theInput->GetMeshMap();
249 TMeshMap::const_iterator aMeshMapIter = aMeshMap.begin();
250 for(; aMeshMapIter != aMeshMap.end(); aMeshMapIter++){
251 const string& aMeshName = aMeshMapIter->first;
252 const PMesh& aMesh = aMeshMapIter->second;
253 const TMeshOnEntityMap& aMeshOnEntityMap = aMesh->myMeshOnEntityMap;
254 if(aMeshOnEntityMap.empty())
256 aComment = QString("myComment=MESH;myName=%1;myDim=%2");
257 aComment = aComment.arg(aMeshName.c_str());
258 aComment = aComment.arg(aMesh->myDim);
260 CreateAttributes(theStudy,
266 aComment.toLatin1().data(),
269 aComment = QString("myComment=FAMILIES;myMeshName=%1").arg(aMeshName.c_str());
270 std::string aSubMeshesEntry =
271 CreateAttributes(theStudy,
277 aComment.toLatin1().data(),
280 if(theIsBuildGroups){
281 aMesh->myGroupsEntry =
282 CreateAttributes(theStudy,
292 if(theIsBuildFields){
293 aMesh->myFieldsEntry =
294 CreateAttributes(theStudy,
305 aMesh->myPartsEntry =
306 CreateAttributes(theStudy,
317 TMeshOnEntityMap::const_iterator aMeshOnEntityMapIter = aMeshOnEntityMap.begin();
318 for(; aMeshOnEntityMapIter != aMeshOnEntityMap.end(); aMeshOnEntityMapIter++){
319 const TEntity& anEntity = aMeshOnEntityMapIter->first;
320 const PMeshOnEntity& aMeshOnEntity = aMeshOnEntityMapIter->second;
325 anEntityName = "onNodes";
328 anEntityName = "onEdges";
331 anEntityName = "onFaces";
334 anEntityName = "onCells";
340 aComment = QString("myComment=ENTITY;myMeshName=%1;myId=%2");
341 aComment = aComment.arg(aMeshName.c_str());
342 aComment = aComment.arg(anEntity);
344 aMeshOnEntity->myEntry =
345 CreateAttributes(theStudy,
349 anEntityName.c_str(),
351 aComment.toLatin1().data(),
356 ProcessVoidEvent(new TUpdateObjBrowser(theStudy->StudyId(),theIsDone));
360 //----------------------------------------------------------------------------
362 BuildGroups(Result_i* theResult,
363 Result_i::PInput theInput,
364 CORBA::Boolean* theIsDone,
365 CORBA::Boolean theIsBuild,
366 CORBA::Boolean theIsAtOnce,
367 _PTR(Study) theStudy)
369 if(!theIsBuild || *theIsDone)
372 TTimerLog aTimerLog(MYTIMEDEBUG,"Result_i::BuildGroups");
373 TResultManager aResultManager(theResult);
374 TTransactionManager aTransactionManager(theStudy);
377 TTimerLog aTimerLog(MYTIMEDEBUG,"theInput->BuildGroups");
378 theInput->BuildGroups();
381 QString aComment,aTmp;
382 const TMeshMap& aMeshMap = theInput->GetMeshMap();
383 TMeshMap::const_iterator aMeshMapIter = aMeshMap.begin();
384 for(; aMeshMapIter != aMeshMap.end(); aMeshMapIter++){
385 const string& aMeshName = aMeshMapIter->first;
386 const PMesh& aMesh = aMeshMapIter->second;
388 const TMeshOnEntityMap& aMeshOnEntityMap = aMesh->myMeshOnEntityMap;
389 if(aMeshOnEntityMap.empty())
392 TMeshOnEntityMap::const_iterator aMeshOnEntityMapIter = aMeshOnEntityMap.begin();
393 for(; aMeshOnEntityMapIter != aMeshOnEntityMap.end(); aMeshOnEntityMapIter++){
394 const TEntity& anEntity = aMeshOnEntityMapIter->first;
395 const PMeshOnEntity& aMeshOnEntity = aMeshOnEntityMapIter->second;
396 const TFamilyMap& aFamilyMap = aMeshOnEntity->myFamilyMap;
397 TFamilyMap::const_iterator aFamilyMapIter = aFamilyMap.begin();
398 for(; aFamilyMapIter != aFamilyMap.end(); aFamilyMapIter++){
399 const string& aFamilyName = aFamilyMapIter->first;
400 const PFamily& aFamily = aFamilyMapIter->second;
401 aComment=QString("myComment=FAMILY;myMeshName=%1;myEntityId=%2;myName=%3");
402 aComment=aComment.arg(aMeshName.c_str());
403 aComment=aComment.arg(anEntity);
404 aComment=aComment.arg(aFamilyName.c_str());
405 aFamily->myEntry = CreateAttributes(theStudy,
406 aMeshOnEntity->myEntry,
411 aComment.toLatin1().data(),
416 const TGroupMap& aGroupMap = aMesh->myGroupMap;
417 if(!aGroupMap.empty()){
418 aComment = QString("myComment=GROUPS;myMeshName=%1").arg(aMeshName.c_str());
420 CreateAttributes(theStudy,
421 aMesh->myGroupsEntry,
426 aComment.toLatin1().data(),
429 TGroupMap::const_iterator aGroupMapIter = aGroupMap.begin();
430 for(; aGroupMapIter != aGroupMap.end(); aGroupMapIter++){
431 const string& aGroupName = aGroupMapIter->first;
432 const PGroup& aGroup = aGroupMapIter->second;
433 aComment = QString("myComment=GROUP;myMeshName=%1;myName=%2").arg(aMeshName.c_str()).arg(aGroupName.c_str());
434 aGroup->myEntry = CreateAttributes(theStudy,
435 aMesh->myGroupsEntry,
440 aComment.toLatin1().data(),
442 const TFamilySet& aFamilySet = aGroup->myFamilySet;
443 TFamilySet::const_iterator aFamilyIter = aFamilySet.begin();
444 for(; aFamilyIter != aFamilySet.end(); aFamilyIter++){
445 const PFamily& aFamily = (*aFamilyIter).second;
446 CreateReference(theStudy,
451 }else if(!theIsAtOnce)
452 RemoveSObject(theStudy,
453 aMesh->myGroupsEntry);
456 ProcessVoidEvent(new TUpdateObjBrowser(theStudy->StudyId(),theIsDone));
460 //----------------------------------------------------------------------------
462 BuildFields(Result_i* theResult,
463 Result_i::PInput theInput,
464 CORBA::Boolean* theIsDone,
465 CORBA::Boolean theIsBuild,
466 CORBA::Boolean theIsAtOnce,
467 _PTR(Study) theStudy)
469 if(!theIsBuild || *theIsDone)
472 TTimerLog aTimerLog(MYTIMEDEBUG,"Result_i::BuildFields");
473 TResultManager aResultManager(theResult);
474 TTransactionManager aTransactionManager(theStudy);
477 TTimerLog aTimerLog(MYTIMEDEBUG,"theInput->BuildFields");
478 theInput->BuildFields();
481 QString aComment,aTmp;
482 const TMeshMap& aMeshMap = theInput->GetMeshMap();
483 TMeshMap::const_iterator aMeshMapIter = aMeshMap.begin();
485 for(; aMeshMapIter != aMeshMap.end(); aMeshMapIter++)
487 const string& aMeshName = aMeshMapIter->first;
488 const PMesh& aMesh = aMeshMapIter->second;
490 const TMeshOnEntityMap& aMeshOnEntityMap = aMesh->myMeshOnEntityMap;
491 if(aMeshOnEntityMap.empty())
495 bool anIsFieldsEntryUpdated = false;
496 TMeshOnEntityMap::const_iterator aMeshOnEntityMapIter = aMeshOnEntityMap.begin();
498 for(; aMeshOnEntityMapIter != aMeshOnEntityMap.end(); aMeshOnEntityMapIter++)
500 const TEntity& anEntity = aMeshOnEntityMapIter->first;
501 const PMeshOnEntity& aMeshOnEntity = aMeshOnEntityMapIter->second;
502 const TFieldMap& aFieldMap = aMeshOnEntity->myFieldMap;
503 TFieldMap::const_iterator aFieldMapIter = aFieldMap.begin();
505 for(; aFieldMapIter != aFieldMap.end(); aFieldMapIter++)
507 if(!anIsFieldsEntryUpdated)
510 aComment.append("myComment=FIELDS;");
511 aComment.append("myMeshName=");aComment.append(aMeshName.c_str());
513 CreateAttributes(theStudy,
514 aMesh->myFieldsEntry,
519 aComment.toLatin1().data(),
521 anIsFieldsEntryUpdated = true;
524 const string& aFieldName = aFieldMapIter->first;
525 const PField& aField = aFieldMapIter->second;
526 const TValField& aValField = aField->myValField;
527 QString aFieldNameWithUnit = GenerateFieldName(aFieldName,aField->myUnitNames[0]);
528 aComment = QString("myComment=FIELD;myMeshName=%1;myEntityId=%2;myName=%3;myNbTimeStamps=%4;myNumComponent=%5");
529 aComment = aComment.arg(aMeshName.c_str());
530 aComment = aComment.arg(anEntity);
531 aComment = aComment.arg(aFieldName.c_str());
532 aComment = aComment.arg(aValField.size());
533 aComment = aComment.arg(aField->myNbComp);
535 aField->myEntry = CreateAttributes(theStudy,
536 aMesh->myFieldsEntry,
539 aFieldNameWithUnit.toLatin1().data(),
541 aComment.toLatin1().data(),
544 CreateReference(theStudy,
546 aMeshOnEntity->myEntry);
548 TValField::const_iterator aValFieldIter = aValField.begin();
550 for(; aValFieldIter != aValField.end(); aValFieldIter++)
552 int aTimeStamp = aValFieldIter->first;
553 const PValForTime& aValForTime = aValFieldIter->second;
554 aComment = QString("myComment=TIMESTAMP;myMeshName=%1;myEntityId=%2;myFieldName=%3;myTimeStampId=%4;myNumComponent=%5");
555 aComment = aComment.arg(aMeshName.c_str());
556 aComment = aComment.arg(anEntity);
557 aComment = aComment.arg(aFieldName.c_str());
558 aComment = aComment.arg(aTimeStamp);
559 aComment = aComment.arg(aField->myNbComp);
561 string aTimeStampId = VISU_Convertor::GenerateName(aValForTime->myTime);
563 aValForTime->myEntry = CreateAttributes(theStudy,
569 aComment.toLatin1().data(),
575 if(!anIsFieldsEntryUpdated && !theIsAtOnce)
576 RemoveSObject(theStudy, aMesh->myFieldsEntry);
579 ProcessVoidEvent(new TUpdateObjBrowser(theStudy->StudyId(),theIsDone));
583 //----------------------------------------------------------------------------
585 BuildMinMax(Result_i* theResult,
586 Result_i::PInput theInput,
587 CORBA::Boolean* theIsDone,
588 CORBA::Boolean theIsBuild)
590 if(!theIsBuild || *theIsDone)
593 TTimerLog aTimerLog(MYTIMEDEBUG,"Result_i::BuildMinMax");
594 TResultManager aResultManager(theResult);
596 theInput->BuildMinMax();
600 theResult->UpdateObservers();
604 //----------------------------------------------------------------------------
606 BuildFieldDataTree(Result_i* theResult,
607 Result_i::PInput theInput,
608 CORBA::Boolean* theIsFieldsDone,
609 CORBA::Boolean theIsBuildFields,
610 CORBA::Boolean* theIsMinMaxDone,
611 CORBA::Boolean theIsBuildMinMax,
612 _PTR(Study) theStudy)
614 BuildFields(theResult,
621 BuildMinMax(theResult,
628 //----------------------------------------------------------------------------
630 RemoveFile(const std::string& theFileName,
631 bool theRemoveEmptyDir)
633 QFileInfo aFileInfo(theFileName.c_str());
634 QFile(aFileInfo.absoluteFilePath()).remove();
636 if(theRemoveEmptyDir)
637 QDir().rmdir(aFileInfo.absolutePath());
639 return aFileInfo.exists();
643 //----------------------------------------------------------------------------
645 CopyFile(const std::string& theSourceFileName,
646 const std::string& theTargetFileName)
648 QString aSourcePath = theSourceFileName.c_str();
650 aSourcePath.replace( QString("/"), QString("\\") );
652 for ( int ind = 0; ind < aSourcePath.length(); ind ++ )
654 if ( aSourcePath.at( ind ) == '\\' )
656 if ( aSourcePath.at( ind ) == ' ' )
658 int nextSlash = aSourcePath.indexOf( '\\', ind);
659 if ( aSourcePath.at( nextSlash - 1 ) != '"' )
661 aSourcePath.insert( nextSlash, '"');
662 aSourcePath.insert( prevSlash + 1, '"');
669 QFileInfo aSourceFileInfo( aSourcePath );
670 QFileInfo aTargetFileInfo( theTargetFileName.c_str() );
671 if(aSourceFileInfo.absoluteFilePath() == aTargetFileInfo.absoluteFilePath())
675 aCommand.sprintf("%s %s %s", COPY_COMMAND,
676 aSourcePath.toLatin1().data(),
677 theTargetFileName.c_str());
679 return system(aCommand.toLatin1().data()) == 0;
683 //----------------------------------------------------------------------------