1 // Copyright (C) 2007-2010 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 //----------------------------------------------------------------------------
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;
397 const TFamilyMap& aFamilyMap = aMeshOnEntity->myFamilyMap;
398 TFamilyMap::const_iterator aFamilyMapIter = aFamilyMap.begin();
399 for(; aFamilyMapIter != aFamilyMap.end(); aFamilyMapIter++){
400 const string& aFamilyName = aFamilyMapIter->first;
401 const PFamily& aFamily = aFamilyMapIter->second;
402 aComment=QString("myComment=FAMILY;myMeshName=%1;myEntityId=%2;myName=%3");
403 aComment=aComment.arg(aMeshName.c_str());
404 aComment=aComment.arg(anEntity);
405 aComment=aComment.arg(aFamilyName.c_str());
407 CreateAttributes(theStudy,
408 aMeshOnEntity->myEntry,
413 aComment.toLatin1().data(),
418 const TGroupMap& aGroupMap = aMesh->myGroupMap;
419 if(!aGroupMap.empty()){
420 aComment = QString("myComment=GROUPS;myMeshName=%1").arg(aMeshName.c_str());
422 CreateAttributes(theStudy,
423 aMesh->myGroupsEntry,
428 aComment.toLatin1().data(),
431 TGroupMap::const_iterator aGroupMapIter = aGroupMap.begin();
432 for(; aGroupMapIter != aGroupMap.end(); aGroupMapIter++){
433 const string& aGroupName = aGroupMapIter->first;
434 const PGroup& aGroup = aGroupMapIter->second;
435 aComment = QString("myComment=GROUP;myMeshName=%1;myName=%2").arg(aMeshName.c_str()).arg(aGroupName.c_str());
437 CreateAttributes(theStudy,
438 aMesh->myGroupsEntry,
443 aComment.toLatin1().data(),
445 const TFamilySet& aFamilySet = aGroup->myFamilySet;
446 TFamilySet::const_iterator aFamilyIter = aFamilySet.begin();
447 for(; aFamilyIter != aFamilySet.end(); aFamilyIter++){
448 const PFamily& aFamily = (*aFamilyIter).second;
449 CreateReference(theStudy,
454 }else if(!theIsAtOnce)
455 RemoveSObject(theStudy,
456 aMesh->myGroupsEntry);
459 ProcessVoidEvent(new TUpdateObjBrowser(theStudy->StudyId(),theIsDone));
463 //----------------------------------------------------------------------------
465 BuildFields(Result_i* theResult,
466 Result_i::PInput theInput,
467 CORBA::Boolean* theIsDone,
468 CORBA::Boolean theIsBuild,
469 CORBA::Boolean theIsAtOnce,
470 _PTR(Study) theStudy)
472 if(!theIsBuild || *theIsDone)
475 TTimerLog aTimerLog(MYTIMEDEBUG,"Result_i::BuildFields");
476 TResultManager aResultManager(theResult);
477 TTransactionManager aTransactionManager(theStudy);
480 TTimerLog aTimerLog(MYTIMEDEBUG,"theInput->BuildFields");
481 theInput->BuildFields();
484 QString aComment,aTmp;
485 const TMeshMap& aMeshMap = theInput->GetMeshMap();
486 TMeshMap::const_iterator aMeshMapIter = aMeshMap.begin();
488 for(; aMeshMapIter != aMeshMap.end(); aMeshMapIter++)
490 const string& aMeshName = aMeshMapIter->first;
491 const PMesh& aMesh = aMeshMapIter->second;
493 const TMeshOnEntityMap& aMeshOnEntityMap = aMesh->myMeshOnEntityMap;
494 if(aMeshOnEntityMap.empty())
498 bool anIsFieldsEntryUpdated = false;
499 TMeshOnEntityMap::const_iterator aMeshOnEntityMapIter = aMeshOnEntityMap.begin();
501 for(; aMeshOnEntityMapIter != aMeshOnEntityMap.end(); aMeshOnEntityMapIter++)
503 const TEntity& anEntity = aMeshOnEntityMapIter->first;
504 const PMeshOnEntity& aMeshOnEntity = aMeshOnEntityMapIter->second;
505 const TFieldMap& aFieldMap = aMeshOnEntity->myFieldMap;
506 TFieldMap::const_iterator aFieldMapIter = aFieldMap.begin();
508 for(; aFieldMapIter != aFieldMap.end(); aFieldMapIter++)
510 if(!anIsFieldsEntryUpdated)
513 aComment.append("myComment=FIELDS;");
514 aComment.append("myMeshName=");aComment.append(aMeshName.c_str());
516 CreateAttributes(theStudy,
517 aMesh->myFieldsEntry,
522 aComment.toLatin1().data(),
525 anIsFieldsEntryUpdated = true;
528 const string& aFieldName = aFieldMapIter->first;
529 const PField& aField = aFieldMapIter->second;
530 const TValField& aValField = aField->myValField;
531 QString aFieldNameWithUnit = GenerateFieldName(aFieldName,aField->myUnitNames[0]);
532 aComment = QString("myComment=FIELD;myMeshName=%1;myEntityId=%2;myName=%3;myNbTimeStamps=%4;myNumComponent=%5");
533 aComment = aComment.arg(aMeshName.c_str());
534 aComment = aComment.arg(anEntity);
535 aComment = aComment.arg(aFieldName.c_str());
536 aComment = aComment.arg(aValField.size());
537 aComment = aComment.arg(aField->myNbComp);
539 aField->myEntry = CreateAttributes(theStudy,
540 aMesh->myFieldsEntry,
543 aFieldNameWithUnit.toLatin1().data(),
545 aComment.toLatin1().data(),
548 CreateReference(theStudy,
550 aMeshOnEntity->myEntry);
552 TValField::const_iterator aValFieldIter = aValField.begin();
554 for(; aValFieldIter != aValField.end(); aValFieldIter++)
556 int aTimeStamp = aValFieldIter->first;
557 const PValForTime& aValForTime = aValFieldIter->second;
558 aComment = QString("myComment=TIMESTAMP;myMeshName=%1;myEntityId=%2;myFieldName=%3;myTimeStampId=%4;myNumComponent=%5");
559 aComment = aComment.arg(aMeshName.c_str());
560 aComment = aComment.arg(anEntity);
561 aComment = aComment.arg(aFieldName.c_str());
562 aComment = aComment.arg(aTimeStamp);
563 aComment = aComment.arg(aField->myNbComp);
565 string aTimeStampId = VISU_Convertor::GenerateName(aValForTime->myTime);
567 aValForTime->myEntry = CreateAttributes(theStudy,
573 aComment.toLatin1().data(),
579 if(!anIsFieldsEntryUpdated && !theIsAtOnce)
580 RemoveSObject(theStudy, aMesh->myFieldsEntry);
583 ProcessVoidEvent(new TUpdateObjBrowser(theStudy->StudyId(),theIsDone));
587 //----------------------------------------------------------------------------
589 BuildMinMax(Result_i* theResult,
590 Result_i::PInput theInput,
591 CORBA::Boolean* theIsDone,
592 CORBA::Boolean theIsBuild)
594 if(!theIsBuild || *theIsDone)
597 TTimerLog aTimerLog(MYTIMEDEBUG,"Result_i::BuildMinMax");
598 TResultManager aResultManager(theResult);
600 theInput->BuildMinMax();
604 theResult->UpdateObservers();
608 //----------------------------------------------------------------------------
610 BuildFieldDataTree(Result_i* theResult,
611 Result_i::PInput theInput,
612 CORBA::Boolean* theIsFieldsDone,
613 CORBA::Boolean theIsBuildFields,
614 CORBA::Boolean* theIsMinMaxDone,
615 CORBA::Boolean theIsBuildMinMax,
616 _PTR(Study) theStudy)
618 BuildFields(theResult,
625 BuildMinMax(theResult,
632 //----------------------------------------------------------------------------
634 RemoveFile(const std::string& theFileName,
635 bool theRemoveEmptyDir)
637 QFileInfo aFileInfo(theFileName.c_str());
638 QFile(aFileInfo.absoluteFilePath()).remove();
640 if(theRemoveEmptyDir)
641 QDir().rmdir(aFileInfo.absolutePath());
643 return aFileInfo.exists();
647 //----------------------------------------------------------------------------
649 CopyFile(const std::string& theSourceFileName,
650 const std::string& theTargetFileName)
652 QString aSourcePath = theSourceFileName.c_str();
654 aSourcePath.replace( QString("/"), QString("\\") );
656 for ( int ind = 0; ind < aSourcePath.length(); ind ++ )
658 if ( aSourcePath.at( ind ) == '\\' )
660 if ( aSourcePath.at( ind ) == ' ' )
662 int nextSlash = aSourcePath.indexOf( '\\', ind);
663 if ( aSourcePath.at( nextSlash - 1 ) != '"' )
665 aSourcePath.insert( nextSlash, '"');
666 aSourcePath.insert( prevSlash + 1, '"');
673 QFileInfo aSourceFileInfo( aSourcePath );
674 QFileInfo aTargetFileInfo( theTargetFileName.c_str() );
675 if(aSourceFileInfo.absoluteFilePath() == aTargetFileInfo.absoluteFilePath())
679 aCommand.sprintf("%s %s %s", COPY_COMMAND,
680 aSourcePath.toLatin1().data(),
681 theTargetFileName.c_str());
683 return system(aCommand.toLatin1().data()) == 0;
687 //----------------------------------------------------------------------------