1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // VISU OBJECT : interactive object for VISU entities implementation
23 // File : VISU_ResultUtils.cc
24 // Author : Alexey PETROV
27 #include "VISU_ResultUtils.hh"
29 #include "SUIT_Session.h"
30 #include "SALOME_Event.h"
31 #include "SalomeApp_Study.h"
32 #include "SalomeApp_Application.h"
34 #include "VISU_Convertor.hxx"
35 #include "VISU_ConvertorUtils.hxx"
41 #include <boost/thread/recursive_mutex.hpp>
42 #include <boost/thread/thread.hpp>
43 #include <boost/bind.hpp>
46 static int MYTIMEDEBUG = 0;
48 static int MYTIMEDEBUG = 0;
55 //----------------------------------------------------------------------------
56 typedef boost::recursive_mutex TMutex;
57 typedef TMutex::scoped_lock TLock;
59 static TMutex myMutex;
61 //----------------------------------------------------------------------------
63 ::TResultManager(Result_i* theResult):
70 //----------------------------------------------------------------------------
78 //----------------------------------------------------------------------------
80 ::TTransactionManager(_PTR(Study) theStudyDocument):
81 myStudyBuilder(theStudyDocument->NewBuilder())
84 myStudyBuilder->NewCommand();
88 //----------------------------------------------------------------------------
90 ::~TTransactionManager()
93 myStudyBuilder->CommitCommand();
97 //----------------------------------------------------------------------------
99 ::TUpdateObjBrowser(const int theStudyId, CORBA::Boolean* theIsDone):
100 myStudyId(theStudyId),
105 //----------------------------------------------------------------------------
110 TLock aLock(myMutex);
111 SUIT_Session* aSession = SUIT_Session::session();
112 QList<SUIT_Application*> anApplications = aSession->applications();
113 QListIterator<SUIT_Application*> anIter (anApplications);
114 while (anIter.hasNext()) {
115 SUIT_Application* aSApp = anIter.next();
116 if(SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>(aSApp)){
117 if (SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>(anApp->activeStudy())) {
118 if (_PTR(Study) aCStudy = aStudy->studyDS()) {
119 if (myStudyId == aCStudy->StudyId()) {
120 TTimerLog aTimerLog(MYTIMEDEBUG,"Result_i::updateObjectBrowser");
121 anApp->updateObjectBrowser();
132 //----------------------------------------------------------------------------
134 GenerateName(const std::string& theName)
136 TLock aLock(myMutex);
138 typedef std::map<std::string, int> TNameMap;
139 static TNameMap aMap;
141 TNameMap::const_iterator anIter = aMap.find(theName);
143 if (anIter == aMap.end()) {
145 aResult = theName.c_str();
147 aResult = GenerateName(theName,++aMap[theName]);
153 //----------------------------------------------------------------------------
155 SplitName(const std::string& theName,
156 std::string& theBase,
157 std::string& theSuffix,
160 size_t aPosition = theName.rfind(theDelimeter);
161 if(aPosition == std::string::npos){
167 theBase = theName.substr(0, aPosition);
168 theSuffix = theName.substr(aPosition);
173 //----------------------------------------------------------------------------
175 MakeFileName(const std::string& theName,
176 const void* thePointer)
178 std::ostringstream aStream;
179 aStream<<theName<<":"<<thePointer;
180 return aStream.str();
184 //----------------------------------------------------------------------------
186 GenerateFieldName(const std::string& theName,
187 const std::string& theUnits)
190 const string tmp (theUnits.size(),' ');
191 if (theUnits == "" || theUnits == tmp)
192 aName = QString("%1, -").arg(theName.c_str());
194 aName = QString("%1, %2").arg(theName.c_str()).arg(theUnits.c_str());
195 aName = aName.simplified();
200 //----------------------------------------------------------------------------
202 CreateReference(_PTR(Study) theStudyDocument,
203 const std::string& theFatherEntry,
204 const std::string& theRefEntry)
206 _PTR(StudyBuilder) aStudyBuilder = theStudyDocument->NewBuilder();
207 _PTR(SObject) aFather = theStudyDocument->FindObjectID(theFatherEntry);
208 _PTR(SObject) aNewObj = aStudyBuilder->NewObject(aFather);
209 _PTR(SObject) aRefSObj = theStudyDocument->FindObjectID(theRefEntry);
210 aStudyBuilder->Addreference(aNewObj,aRefSObj);
214 //----------------------------------------------------------------------------
216 RemoveSObject(_PTR(Study) theStudyDocument,
217 const string& theEntry)
219 _PTR(StudyBuilder) aStudyBuilder = theStudyDocument->NewBuilder();
220 _PTR(SObject) aSObject = theStudyDocument->FindObjectID(theEntry);
221 aStudyBuilder->RemoveObject(aSObject);
225 //----------------------------------------------------------------------------
227 BuildEntities(Result_i* theResult,
228 Result_i::PInput theInput,
229 CORBA::Boolean* theIsDone,
230 const std::string& theResultEntry,
231 CORBA::Boolean theIsAtOnce,
232 CORBA::Boolean theIsBuildGroups,
233 CORBA::Boolean theIsBuildFields,
234 CORBA::Boolean theIsBuildParts,
235 _PTR(Study) theStudy)
240 TTimerLog aTimerLog(MYTIMEDEBUG,"Result_i::BuildEntities");
241 TResultManager aResultManager(theResult);
242 TTransactionManager aTransactionManager(theStudy);
245 TTimerLog aTimerLog(MYTIMEDEBUG,"theInput->BuildEntities");
246 theInput->BuildEntities();
249 QString aComment,aTmp;
250 const TMeshMap& aMeshMap = theInput->GetMeshMap();
251 TMeshMap::const_iterator aMeshMapIter = aMeshMap.begin();
252 for(; aMeshMapIter != aMeshMap.end(); aMeshMapIter++){
253 const string& aMeshName = aMeshMapIter->first;
254 const PMesh& aMesh = aMeshMapIter->second;
255 const TMeshOnEntityMap& aMeshOnEntityMap = aMesh->myMeshOnEntityMap;
256 if(aMeshOnEntityMap.empty())
258 aComment = QString("myComment=MESH;myName=%1;myDim=%2");
259 aComment = aComment.arg(aMeshName.c_str());
260 aComment = aComment.arg(aMesh->myDim);
262 CreateAttributes(theStudy,
268 aComment.toLatin1().data(),
271 aComment = QString("myComment=FAMILIES;myMeshName=%1").arg(aMeshName.c_str());
272 std::string aSubMeshesEntry =
273 CreateAttributes(theStudy,
279 aComment.toLatin1().data(),
282 if(theIsBuildGroups){
283 aMesh->myGroupsEntry =
284 CreateAttributes(theStudy,
294 if(theIsBuildFields){
295 aMesh->myFieldsEntry =
296 CreateAttributes(theStudy,
307 aMesh->myPartsEntry =
308 CreateAttributes(theStudy,
319 TMeshOnEntityMap::const_iterator aMeshOnEntityMapIter = aMeshOnEntityMap.begin();
320 for(; aMeshOnEntityMapIter != aMeshOnEntityMap.end(); aMeshOnEntityMapIter++){
321 const TEntity& anEntity = aMeshOnEntityMapIter->first;
322 const PMeshOnEntity& aMeshOnEntity = aMeshOnEntityMapIter->second;
327 anEntityName = "onNodes";
330 anEntityName = "onEdges";
333 anEntityName = "onFaces";
336 anEntityName = "onCells";
342 aComment = QString("myComment=ENTITY;myMeshName=%1;myId=%2");
343 aComment = aComment.arg(aMeshName.c_str());
344 aComment = aComment.arg(anEntity);
346 aMeshOnEntity->myEntry =
347 CreateAttributes(theStudy,
351 anEntityName.c_str(),
353 aComment.toLatin1().data(),
358 ProcessVoidEvent(new TUpdateObjBrowser(theStudy->StudyId(),theIsDone));
362 //----------------------------------------------------------------------------
364 BuildGroups(Result_i* theResult,
365 Result_i::PInput theInput,
366 CORBA::Boolean* theIsDone,
367 CORBA::Boolean theIsBuild,
368 CORBA::Boolean theIsAtOnce,
369 _PTR(Study) theStudy)
371 if(!theIsBuild || *theIsDone)
374 TTimerLog aTimerLog(MYTIMEDEBUG,"Result_i::BuildGroups");
375 TResultManager aResultManager(theResult);
376 TTransactionManager aTransactionManager(theStudy);
379 TTimerLog aTimerLog(MYTIMEDEBUG,"theInput->BuildGroups");
380 theInput->BuildGroups();
383 QString aComment,aTmp;
384 const TMeshMap& aMeshMap = theInput->GetMeshMap();
385 TMeshMap::const_iterator aMeshMapIter = aMeshMap.begin();
386 for(; aMeshMapIter != aMeshMap.end(); aMeshMapIter++){
387 const string& aMeshName = aMeshMapIter->first;
388 const PMesh& aMesh = aMeshMapIter->second;
390 const TMeshOnEntityMap& aMeshOnEntityMap = aMesh->myMeshOnEntityMap;
391 if(aMeshOnEntityMap.empty())
394 TMeshOnEntityMap::const_iterator aMeshOnEntityMapIter = aMeshOnEntityMap.begin();
395 for(; aMeshOnEntityMapIter != aMeshOnEntityMap.end(); aMeshOnEntityMapIter++){
396 const TEntity& anEntity = aMeshOnEntityMapIter->first;
397 const PMeshOnEntity& aMeshOnEntity = aMeshOnEntityMapIter->second;
399 const TFamilyMap& aFamilyMap = aMeshOnEntity->myFamilyMap;
400 TFamilyMap::const_iterator aFamilyMapIter = aFamilyMap.begin();
401 for(; aFamilyMapIter != aFamilyMap.end(); aFamilyMapIter++){
402 const string& aFamilyName = aFamilyMapIter->first;
403 const PFamily& aFamily = aFamilyMapIter->second;
404 aComment=QString("myComment=FAMILY;myMeshName=%1;myEntityId=%2;myName=%3");
405 aComment=aComment.arg(aMeshName.c_str());
406 aComment=aComment.arg(anEntity);
407 aComment=aComment.arg(aFamilyName.c_str());
409 CreateAttributes(theStudy,
410 aMeshOnEntity->myEntry,
415 aComment.toLatin1().data(),
420 const TGroupMap& aGroupMap = aMesh->myGroupMap;
421 if(!aGroupMap.empty()){
422 aComment = QString("myComment=GROUPS;myMeshName=%1").arg(aMeshName.c_str());
424 CreateAttributes(theStudy,
425 aMesh->myGroupsEntry,
430 aComment.toLatin1().data(),
433 TGroupMap::const_iterator aGroupMapIter = aGroupMap.begin();
434 for(; aGroupMapIter != aGroupMap.end(); aGroupMapIter++){
435 const string& aGroupName = aGroupMapIter->first;
436 const PGroup& aGroup = aGroupMapIter->second;
437 aComment = QString("myComment=GROUP;myMeshName=%1;myName=%2").arg(aMeshName.c_str()).arg(aGroupName.c_str());
439 CreateAttributes(theStudy,
440 aMesh->myGroupsEntry,
445 aComment.toLatin1().data(),
447 const TFamilySet& aFamilySet = aGroup->myFamilySet;
448 TFamilySet::const_iterator aFamilyIter = aFamilySet.begin();
449 for(; aFamilyIter != aFamilySet.end(); aFamilyIter++){
450 const PFamily& aFamily = *aFamilyIter;
451 CreateReference(theStudy,
456 }else if(!theIsAtOnce)
457 RemoveSObject(theStudy,
458 aMesh->myGroupsEntry);
461 ProcessVoidEvent(new TUpdateObjBrowser(theStudy->StudyId(),theIsDone));
465 //----------------------------------------------------------------------------
467 BuildFields(Result_i* theResult,
468 Result_i::PInput theInput,
469 CORBA::Boolean* theIsDone,
470 CORBA::Boolean theIsBuild,
471 CORBA::Boolean theIsAtOnce,
472 _PTR(Study) theStudy)
474 if(!theIsBuild || *theIsDone)
477 TTimerLog aTimerLog(MYTIMEDEBUG,"Result_i::BuildFields");
478 TResultManager aResultManager(theResult);
479 TTransactionManager aTransactionManager(theStudy);
482 TTimerLog aTimerLog(MYTIMEDEBUG,"theInput->BuildFields");
483 theInput->BuildFields();
486 QString aComment,aTmp;
487 const TMeshMap& aMeshMap = theInput->GetMeshMap();
488 TMeshMap::const_iterator aMeshMapIter = aMeshMap.begin();
490 for(; aMeshMapIter != aMeshMap.end(); aMeshMapIter++)
492 const string& aMeshName = aMeshMapIter->first;
493 const PMesh& aMesh = aMeshMapIter->second;
495 const TMeshOnEntityMap& aMeshOnEntityMap = aMesh->myMeshOnEntityMap;
496 if(aMeshOnEntityMap.empty())
500 bool anIsFieldsEntryUpdated = false;
501 TMeshOnEntityMap::const_iterator aMeshOnEntityMapIter = aMeshOnEntityMap.begin();
503 for(; aMeshOnEntityMapIter != aMeshOnEntityMap.end(); aMeshOnEntityMapIter++)
505 const TEntity& anEntity = aMeshOnEntityMapIter->first;
506 const PMeshOnEntity& aMeshOnEntity = aMeshOnEntityMapIter->second;
507 const TFieldMap& aFieldMap = aMeshOnEntity->myFieldMap;
508 TFieldMap::const_iterator aFieldMapIter = aFieldMap.begin();
510 for(; aFieldMapIter != aFieldMap.end(); aFieldMapIter++)
512 if(!anIsFieldsEntryUpdated)
515 aComment.append("myComment=FIELDS;");
516 aComment.append("myMeshName=");aComment.append(aMeshName.c_str());
518 CreateAttributes(theStudy,
519 aMesh->myFieldsEntry,
524 aComment.toLatin1().data(),
527 anIsFieldsEntryUpdated = true;
530 const string& aFieldName = aFieldMapIter->first;
531 const PField& aField = aFieldMapIter->second;
532 const TValField& aValField = aField->myValField;
533 QString aFieldNameWithUnit = GenerateFieldName(aFieldName,aField->myUnitNames[0]);
534 aComment = QString("myComment=FIELD;myMeshName=%1;myEntityId=%2;myName=%3;myNbTimeStamps=%4;myNumComponent=%5");
535 aComment = aComment.arg(aMeshName.c_str());
536 aComment = aComment.arg(anEntity);
537 aComment = aComment.arg(aFieldName.c_str());
538 aComment = aComment.arg(aValField.size());
539 aComment = aComment.arg(aField->myNbComp);
541 aField->myEntry = CreateAttributes(theStudy,
542 aMesh->myFieldsEntry,
545 aFieldNameWithUnit.toLatin1().data(),
547 aComment.toLatin1().data(),
550 CreateReference(theStudy,
552 aMeshOnEntity->myEntry);
554 TValField::const_iterator aValFieldIter = aValField.begin();
556 for(; aValFieldIter != aValField.end(); aValFieldIter++)
558 int aTimeStamp = aValFieldIter->first;
559 const PValForTime& aValForTime = aValFieldIter->second;
560 aComment = QString("myComment=TIMESTAMP;myMeshName=%1;myEntityId=%2;myFieldName=%3;myTimeStampId=%4;myNumComponent=%5");
561 aComment = aComment.arg(aMeshName.c_str());
562 aComment = aComment.arg(anEntity);
563 aComment = aComment.arg(aFieldName.c_str());
564 aComment = aComment.arg(aTimeStamp);
565 aComment = aComment.arg(aField->myNbComp);
567 string aTimeStampId = VISU_Convertor::GenerateName(aValForTime->myTime);
569 aValForTime->myEntry = CreateAttributes(theStudy,
575 aComment.toLatin1().data(),
581 if(!anIsFieldsEntryUpdated && !theIsAtOnce)
582 RemoveSObject(theStudy, aMesh->myFieldsEntry);
585 ProcessVoidEvent(new TUpdateObjBrowser(theStudy->StudyId(),theIsDone));
589 //----------------------------------------------------------------------------
591 BuildMinMax(Result_i* theResult,
592 Result_i::PInput theInput,
593 CORBA::Boolean* theIsDone,
594 CORBA::Boolean theIsBuild)
596 if(!theIsBuild || *theIsDone)
599 TTimerLog aTimerLog(MYTIMEDEBUG,"Result_i::BuildMinMax");
600 TResultManager aResultManager(theResult);
602 theInput->BuildMinMax();
606 theResult->UpdateObservers();
610 //----------------------------------------------------------------------------
612 BuildFieldDataTree(Result_i* theResult,
613 Result_i::PInput theInput,
614 CORBA::Boolean* theIsFieldsDone,
615 CORBA::Boolean theIsBuildFields,
616 CORBA::Boolean* theIsMinMaxDone,
617 CORBA::Boolean theIsBuildMinMax,
618 _PTR(Study) theStudy)
620 BuildFields(theResult,
627 BuildMinMax(theResult,
634 //----------------------------------------------------------------------------
636 RemoveFile(const std::string& theFileName,
637 bool theRemoveEmptyDir)
639 QFileInfo aFileInfo(theFileName.c_str());
640 QFile(aFileInfo.absoluteFilePath()).remove();
642 if(theRemoveEmptyDir)
643 QDir().rmdir(aFileInfo.absolutePath());
645 return aFileInfo.exists();
649 //----------------------------------------------------------------------------
651 CopyFile(const std::string& theSourceFileName,
652 const std::string& theTargetFileName)
654 QFileInfo aSourceFileInfo(theSourceFileName.c_str());
655 QFileInfo aTargetFileInfo(theTargetFileName.c_str());
656 if(aSourceFileInfo.absoluteFilePath() == aTargetFileInfo.absoluteFilePath())
660 aCommand.sprintf("%s %s %s",
662 aSourceFileInfo.filePath().toLatin1().data(),
663 aTargetFileInfo.filePath().toLatin1().data());
665 return system(aCommand.toLatin1().data()) == 0;
669 //----------------------------------------------------------------------------