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 // File : VISU_Evolution.cxx
23 // Author : Oleg UVAROV
26 #include "VISU_Evolution.h"
28 #include "VISU_Tools.h"
29 #include "VISU_Gen_i.hh"
30 #include "VISU_Result_i.hh"
31 #include "VISU_Table_i.hh"
32 #include "VISU_View_i.hh"
34 #include <VISU_MeshValue.hxx>
35 #include <VISU_Structures_impl.hxx>
36 #include <VISU_VTKTypeList.hxx>
38 #include <SUIT_Session.h>
40 #include <SalomeApp_Application.h>
41 #include <SalomeApp_Study.h>
43 #include <SALOME_Event.h>
45 //------------------------------------------------------------------------
46 template<int EDataType> bool ProcessValForTime( VISU::PValForTimeImpl theValForTime,
47 VISU::Elem2Comp2Value& theElem2Comp2Value )
49 theElem2Comp2Value.clear();
51 typedef typename VISU::TL::TEnum2VTKBasicType< EDataType >::TResult TVTKBasicType;
52 typedef VISU::TTMeshValue< TVTKBasicType > TMeshValue;
53 typedef MED::SharedPtr< TMeshValue > TMeshValuePtr;
55 const TMeshValuePtr aMeshValue = theValForTime->GetMeshValue( VISU::ePOINT1 );
59 vtkIdType aNbElem = aMeshValue->GetNbElem();
60 vtkIdType aNbComp = aMeshValue->GetNbComp();
61 vtkIdType aNbGauss = aMeshValue->GetNbGauss();
63 for( vtkIdType iElem = 0; iElem < aNbElem; iElem++ )
65 typename TMeshValue::TCValueSliceArr aMValueSliceArr = aMeshValue->GetCompValueSliceArr( iElem );
66 VISU::Comp2Value& aComp2Value = theElem2Comp2Value[ iElem ];
68 vtkFloatingPointType& aModulusValue = aComp2Value[ 0 ];
71 for( vtkIdType iComp = 0; iComp < aNbComp; iComp++ )
73 const typename TMeshValue::TCValueSlice& aMValueSlice = aMValueSliceArr[ iComp ];
75 vtkFloatingPointType& aValue = aComp2Value[ iComp+1 ];
78 for(vtkIdType iGauss = 0; iGauss < aNbGauss; iGauss++)
80 const vtkFloatingPointType& aVal = aMValueSlice[iGauss];
86 aModulusValue += aValue * aValue;
88 aModulusValue = sqrt( aModulusValue );
94 //------------------------------------------------------------------------
95 template<int EDataType> int GetNbPoints( VISU::PValForTimeImpl theValForTime )
97 typedef typename VISU::TL::TEnum2VTKBasicType< EDataType >::TResult TVTKBasicType;
98 typedef VISU::TTMeshValue< TVTKBasicType > TMeshValue;
99 typedef MED::SharedPtr< TMeshValue > TMeshValuePtr;
101 const TMeshValuePtr aMeshValue = theValForTime->GetMeshValue( VISU::ePOINT1 );
105 return aMeshValue->GetNbElem();
108 //------------------------------------------------------------------------
109 VISU_Evolution::VISU_Evolution( _PTR(Study) theStudy,
110 VISU::XYPlot_ptr theXYPlot )
115 if( !CORBA::is_nil( theXYPlot ) )
117 VISU::XYPlot_i* pPlot = dynamic_cast<VISU::XYPlot_i*>( GetServant( theXYPlot ).in() );
118 Plot2d_ViewFrame* aVF = pPlot->GetView();
123 myEvolutionEntry = "";
125 myEntity = VISU::NODE_ENTITY;
132 //------------------------------------------------------------------------
133 VISU_Evolution::~VISU_Evolution()
137 //------------------------------------------------------------------------
138 bool VISU_Evolution::setField( _PTR(SObject) theField )
144 myFieldEntry = theField->GetID();
146 VISU::Storable::TRestoringMap aRestoringMap = VISU::Storable::GetStorableMap( theField );
147 if( aRestoringMap.empty() )
150 VISU::VISUType aType = VISU::Storable::RestoringMap2Type( aRestoringMap );
151 if( aType != VISU::TFIELD )
154 myMeshName = aRestoringMap["myMeshName"].toStdString();
155 myEntity = VISU::TEntity( aRestoringMap["myEntityId"].toInt() );
156 myFieldName = aRestoringMap["myName"].toStdString();
158 if( myEntity != VISU::NODE_ENTITY )
161 VISU::Result_var aResult = VISU::FindResult( VISU::GetSObject( theField ).in() );
162 if( CORBA::is_nil( aResult.in() ) )
165 myResult = dynamic_cast<VISU::Result_i*>( VISU::GetServant( aResult ).in() );
169 const VISU::TMeshMap& aMeshMap = myResult->GetInput()->GetMeshMap();
170 if( aMeshMap.empty() )
173 VISU::TMeshMap::const_iterator aMeshIter = aMeshMap.find( myMeshName );
174 if( aMeshIter == aMeshMap.end() )
177 const VISU::PMesh& aMesh = aMeshIter->second;
178 const VISU::TMeshOnEntityMap& aMeshOnEntityMap = aMesh->myMeshOnEntityMap;
179 if( aMeshOnEntityMap.empty() )
182 VISU::TMeshOnEntityMap::const_iterator aMeshOnEntityIter = aMeshOnEntityMap.find( myEntity );
183 if( aMeshOnEntityIter == aMeshOnEntityMap.end() )
186 const VISU::PMeshOnEntity& aMeshOnEntity = aMeshOnEntityIter->second;
187 const VISU::TFieldMap& aFieldMap = aMeshOnEntity->myFieldMap;
188 if( aFieldMap.empty() )
191 VISU::TFieldMap::const_iterator aFieldIter = aFieldMap.find( myFieldName );
192 if( aFieldIter == aFieldMap.end() )
195 myFieldImpl = aFieldIter->second;
196 const VISU::TNames& aCompNames = myFieldImpl->myCompNames;
197 const VISU::TNames& aUnitNames = myFieldImpl->myUnitNames;
198 int aNbComp = myFieldImpl->myNbComp;
200 // fill myComponentDataList
201 myComponentDataList.clear();
203 QString aModulusComponent( "<Modulus>" );
204 myComponentDataList.append( VISU::ComponentData( aModulusComponent, "" ) );
205 for( int i = 0; i < aNbComp; i++ )
207 QString aComponent = QString( aCompNames[i].c_str() ).simplified();
208 if( aComponent.isEmpty() )
209 aComponent = "Component " + QString::number( i+1 );
211 QString anUnit = QString( aUnitNames[i].c_str() ).simplified();
213 myComponentDataList.append( VISU::ComponentData( aComponent, anUnit ) );
219 //------------------------------------------------------------------------
220 bool VISU_Evolution::setField( SALOMEDS::SObject_ptr theField )
222 SALOMEDS::SObject_var theFieldDup = SALOMEDS::SObject::_duplicate( theField );
223 _PTR(SObject) aField = VISU::GetClientSObject( theFieldDup, myStudy );
224 return setField( aField );
227 //------------------------------------------------------------------------
228 void VISU_Evolution::setPointId( int thePointId )
230 myPointId = thePointId;
233 //------------------------------------------------------------------------
234 void VISU_Evolution::setComponentId( int theComponentId )
236 myComponentId = theComponentId;
239 //------------------------------------------------------------------------
240 int VISU_Evolution::getNbPoints() const
245 vtkIdType aDataType = myFieldImpl->GetDataType();
246 const VISU::TValField& aValField = myFieldImpl->myValField;
247 if( aValField.empty() )
250 VISU::TValField::const_iterator aValFieldIter = aValField.begin();
251 for( ; aValFieldIter != aValField.end(); aValFieldIter++ )
253 const vtkIdType& aTimeStamp = aValFieldIter->first;
254 VISU::PValForTimeImpl aValForTime = aValFieldIter->second;
256 // to force method VISU::MedConvertor::FillValForTime() to be called
257 myResult->GetInput()->GetTimeStampOnMesh( myMeshName, myEntity, myFieldName, aTimeStamp );
261 case VTK_DOUBLE : return GetNbPoints<VTK_DOUBLE>( aValForTime );
262 case VTK_FLOAT : return GetNbPoints<VTK_FLOAT>( aValForTime );
263 case VTK_INT : return GetNbPoints<VTK_INT>( aValForTime );
264 case VTK_LONG: return GetNbPoints<VTK_LONG>( aValForTime );
272 //------------------------------------------------------------------------
273 bool VISU_Evolution::extractData( int thePointId,
275 VISU::TimeStampValueList& theTimeStampValueList )
277 theTimeStampValueList.clear();
278 myTimeStampDataList.clear();
283 vtkIdType aDataType = myFieldImpl->GetDataType();
284 const VISU::TValField& aValField = myFieldImpl->myValField;
285 if( aValField.empty() )
288 typedef QList< VISU::Elem2Comp2Value > TimeStamp2Elem2Comp2Value;
289 typedef QListIterator< VISU::Elem2Comp2Value > TimeStamp2Elem2Comp2ValueIterator;
290 TimeStamp2Elem2Comp2Value aData;
292 VISU::TValField::const_iterator aValFieldIter = aValField.begin();
293 for( ; aValFieldIter != aValField.end(); aValFieldIter++ )
295 const vtkIdType& aTimeStamp = aValFieldIter->first;
296 VISU::PValForTimeImpl aValForTime = aValFieldIter->second;
297 VISU::TTime aTime = aValForTime->myTime;
298 double aTimeValue = aTime.first;
299 std::string aTimeUnits = aTime.second;
301 // to force method VISU::MedConvertor::FillValForTime() to be called
302 // (we need data of all timestamps of the result)
303 myResult->GetInput()->GetTimeStampOnMesh( myMeshName, myEntity, myFieldName, aTimeStamp );
305 // data should be sorted by time value
307 VISU::TimeStampDataListIterator anIter( myTimeStampDataList );
308 while( anIter.hasNext() )
310 VISU::TimeStampData aTimeStampData = anIter.next();
311 if( aTimeValue > aTimeStampData.first )
315 VISU::Elem2Comp2Value anElem2Comp2Value;
320 case VTK_DOUBLE : ok = ProcessValForTime<VTK_DOUBLE>( aValForTime, anElem2Comp2Value ); break;
321 case VTK_FLOAT : ok = ProcessValForTime<VTK_FLOAT>( aValForTime, anElem2Comp2Value ); break;
322 case VTK_INT : ok = ProcessValForTime<VTK_INT>( aValForTime, anElem2Comp2Value ); break;
323 case VTK_LONG: ok = ProcessValForTime<VTK_LONG>( aValForTime, anElem2Comp2Value ); break;
330 aData.insert( anOrder, anElem2Comp2Value );
331 myTimeStampDataList.insert( anOrder, VISU::TimeStampData( aTimeValue, aTimeUnits ) );
334 if( theComponentId < 0 || theComponentId >= myComponentDataList.size() )
338 TimeStamp2Elem2Comp2ValueIterator it1( aData );
339 while( it1.hasNext() )
341 VISU::Elem2Comp2Value anElem2Comp2Value = it1.next();
342 VISU::Elem2Comp2Value::const_iterator it2 = anElem2Comp2Value.find( thePointId );
343 if( it2 != anElem2Comp2Value.end() )
345 VISU::Comp2Value aComp2Value = it2.value();
346 VISU::Comp2Value::const_iterator it3 = aComp2Value.find( theComponentId );
347 if( it3 != aComp2Value.end() )
349 vtkFloatingPointType aValue = it3.value();
350 theTimeStampValueList.append( aValue );
356 if( theTimeStampValueList.size() != myTimeStampDataList.size() )
362 //------------------------------------------------------------------------
363 bool VISU_Evolution::showEvolution()
365 return ProcessEvent(new TMemFunEvent<VISU_Evolution,bool>
366 (this,&VISU_Evolution::_showEvolution));
369 //------------------------------------------------------------------------
370 bool VISU_Evolution::_showEvolution()
372 bool isEdit = ( myEvolutionEntry != "" );
375 VISU::TimeStampValueList aTimeStampValueList;
376 if( !extractData( myPointId, myComponentId, aTimeStampValueList ) )
379 // 2) publish new objects in study (or edit them)
380 _PTR(StudyBuilder) aStudyBuilder = myStudy->NewBuilder();
381 aStudyBuilder->NewCommand(); // open transaction
383 QString anEvolutionComment;
384 anEvolutionComment.sprintf( "myComment=EVOLUTION;myPointId=%d;myComponentId=%d",
388 _PTR(SObject) anEvolutionObject, aFieldRefObject, aTableObject;
389 if( !isEdit ) // creation mode
391 _PTR(SComponent) aSComponent = VISU::ClientFindOrCreateVisuComponent( myStudy );
392 std::string aSComponentEntry = aSComponent->GetID();
394 // create an evolution object
395 myEvolutionEntry = VISU::CreateAttributes( myStudy,
396 aSComponentEntry.c_str(),
399 VISU::GenerateName( "Evolution", 0 ).toLatin1().constData(),
400 VISU::NO_PERFSITENT_REF,
401 anEvolutionComment.toLatin1().constData(),
403 anEvolutionObject = myStudy->FindObjectID( myEvolutionEntry.c_str() );
405 // create a reference to the field object
406 aFieldRefObject = aStudyBuilder->NewObject( anEvolutionObject );
407 aStudyBuilder->Addreference( aFieldRefObject, myField );
409 // create a table object
410 std::string aTableEntry = VISU::CreateAttributes( myStudy,
411 aFieldRefObject->GetID().c_str(),
414 VISU::GenerateName( "Table", 0 ).toLatin1().constData(),
415 VISU::NO_PERFSITENT_REF,
418 aTableObject = myStudy->FindObjectID( aTableEntry.c_str() );
422 // edit an evolution object
423 anEvolutionObject = myStudy->FindObjectID( myEvolutionEntry.c_str() );
424 _PTR(GenericAttribute) anAttr;
425 anAttr = aStudyBuilder->FindOrCreateAttribute( anEvolutionObject, "AttributeString" );
426 _PTR(AttributeString) aComment( anAttr );
427 aComment->SetValue( anEvolutionComment.toLatin1().constData() );
429 // get a reference to the field object
430 _PTR(ChildIterator) anIter = myStudy->NewChildIterator( anEvolutionObject );
433 aFieldRefObject = anIter->Value();
435 // get a table object
436 anIter = myStudy->NewChildIterator( aFieldRefObject );
439 aTableObject = anIter->Value();
442 aStudyBuilder->CommitCommand(); // commit transaction
444 // 3) update table attribute of the table object
445 _PTR(GenericAttribute) anAttr = aStudyBuilder->FindOrCreateAttribute( aTableObject, "AttributeTableOfReal" );
446 _PTR(AttributeTableOfReal) aTableOfReal( anAttr );
448 aTableOfReal->SetNbColumns( aTimeStampValueList.size() );
450 QString aTimeRowUnits;
452 VISU::TimeStampValueListIterator it( aTimeStampValueList );
453 while( it.hasNext() )
455 vtkFloatingPointType aValue = it.next();
457 VISU::TimeStampData aTimeStampData = myTimeStampDataList[ aTimeStamp ];
458 double aTimeValue = aTimeStampData.first;
459 std::string aTimeUnits = aTimeStampData.second;
461 if( aTimeRowUnits.isEmpty() )
462 aTimeRowUnits = QString( aTimeUnits.c_str() ).simplified();
464 aTableOfReal->SetColumnTitle( aTimeStamp+1, QString::number( aTimeStamp+1 ).toLatin1().constData() );
465 aTableOfReal->PutValue( aTimeValue, 1, aTimeStamp+1 );
466 aTableOfReal->PutValue( aValue, 2, aTimeStamp+1 );
471 if( aTimeRowUnits.isEmpty() )
474 aTableOfReal->SetRowTitle( 1, "Time" );
475 aTableOfReal->SetRowUnit( 1, aTimeRowUnits.toLatin1().constData() );
477 const VISU::ComponentData& aComponentData = myComponentDataList[ myComponentId ];
478 QString aValueTitle = QString( "Point %1" ).arg( myPointId );
479 aTableOfReal->SetRowTitle( 2, aValueTitle.toLatin1().constData() );
480 aTableOfReal->SetRowUnit( 2, aComponentData.second.toLatin1().constData() );
482 QString aTitle = QString( "%1, %2" ).arg( myFieldName.c_str() ).arg( aComponentData.first );
483 aTableOfReal->SetTitle( aTitle.toLatin1().constData() );
485 // 4) get active study
486 SalomeApp_Study* aSalomeStudy = NULL;
487 SUIT_Session* aSession = SUIT_Session::session();
488 QList<SUIT_Application*> anApplications = aSession->applications();
489 QList<SUIT_Application*>::Iterator anIter = anApplications.begin();
490 while ( anIter != anApplications.end() ) {
491 SUIT_Application* anApp = *anIter;
492 if (SUIT_Study* aSStudy = anApp->activeStudy()) {
493 if (SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>(aSStudy)) {
494 if (_PTR(Study) aCStudy = aStudy->studyDS()) {
495 if (aCStudy->Name() == myStudy->Name()) {
496 aSalomeStudy = aStudy;
505 // 5) create curves and plot
508 // 5.1) remove old curves (edition mode)
510 _PTR(GenericAttribute) anAttr;
511 if(aTableObject->FindAttribute( anAttr, "AttributeName" ) ) {
512 _PTR(ChildIterator) aChildIter = myStudy->NewChildIterator( aTableObject );
513 for( aChildIter->InitEx( false ); aChildIter->More(); aChildIter->Next() ) {
514 aSalomeStudy->deleteReferencesTo( aChildIter->Value() );
515 _PTR(SObject) aCurveObject = aChildIter->Value();
517 VISU::Storable::TRestoringMap aRestoringMap = VISU::Storable::GetStorableMap(aCurveObject);
518 if (aRestoringMap["myComment"] == "CURVE") {
519 CORBA::Object_var aCORBAObject = VISU::ClientSObjectToObject(aCurveObject);
520 if(!CORBA::is_nil(aCORBAObject)) {
521 PortableServer::ServantBase_var aServant = VISU::GetServant(aCORBAObject);
522 if(VISU::Curve_i* aCurve = dynamic_cast<VISU::Curve_i*>(aServant.in())){
523 if(SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>(aSalomeStudy->application()))
524 VISU::PlotRemoveCurve(anApp, aCurve);
528 aStudyBuilder->RemoveObject( aCurveObject );
534 // 5.2) create new curves
535 VISU::VISU_Gen_i* aVisuGen = VISU::VISU_Gen_i::GetVisuGenImpl();
536 aVisuGen->CreateTable( aTableObject->GetID().c_str() );
539 VISU::CreatePlot( aVisuGen, getViewer(), aTableObject );
545 //------------------------------------------------------------------------
546 void VISU_Evolution::restoreFromStudy( SALOMEDS::SObject_ptr theObj )
548 _PTR(SObject) anEvolutionObject = VISU::GetClientSObject( theObj, myStudy );
549 restoreFromStudy( anEvolutionObject );
552 //------------------------------------------------------------------------
553 void VISU_Evolution::restoreFromStudy( _PTR(SObject) theObj )
555 VISU::Storable::TRestoringMap aMap = VISU::Storable::GetStorableMap( theObj );
560 myPointId = VISU::Storable::FindValue( aMap, "myPointId", &isExist ).toInt();
561 myComponentId = VISU::Storable::FindValue( aMap, "myComponentId", &isExist ).toInt();
563 _PTR(ChildIterator) anIter = myStudy->NewChildIterator( theObj );
564 for( anIter->Init(); anIter->More(); anIter->Next() )
566 _PTR(SObject) aRefObj = anIter->Value();
567 _PTR(SObject) aFieldObj;
569 if( !aRefObj->ReferencedObject( aFieldObj ) )
572 int nbAttr = aFieldObj->GetAllAttributes().size();
576 setField( aFieldObj );
580 myEvolutionEntry = theObj->GetID();
583 //------------------------------------------------------------------------
584 struct TNewEvolutionEvent: public SALOME_Event
586 std::string myStudyName;
587 VISU::XYPlot_ptr myXYPlot;
589 typedef VISU_Evolution* TResult;
592 TNewEvolutionEvent (std::string theStudyName, VISU::XYPlot_ptr theXYPlot):
593 myStudyName(theStudyName),
594 myXYPlot(VISU::XYPlot::_duplicate(theXYPlot)),
602 SUIT_Session* aSession = SUIT_Session::session();
603 QList<SUIT_Application*> anApplications = aSession->applications();
604 QList<SUIT_Application*>::Iterator anIter = anApplications.begin();
605 while ( anIter != anApplications.end() ) {
606 SUIT_Application* anApp = *anIter;
607 if (SUIT_Study* aSStudy = anApp->activeStudy()) {
608 if (SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>(aSStudy)) {
609 if (_PTR(Study) aCStudy = aStudy->studyDS()) {
610 if (myStudyName == aCStudy->Name()) {
611 myResult = new VISU_Evolution (aCStudy, myXYPlot);
622 //------------------------------------------------------------------------
623 VISU_Evolution_i::VISU_Evolution_i( SALOMEDS::Study_ptr theStudy,
624 VISU::XYPlot_ptr theXYPlot )
626 std::string aStudyName = theStudy->Name();
627 myEngine = ProcessEvent( new TNewEvolutionEvent( aStudyName, theXYPlot ) );
630 //------------------------------------------------------------------------
631 VISU_Evolution_i::~VISU_Evolution_i()
636 //------------------------------------------------------------------------
637 bool VISU_Evolution_i::setField( SALOMEDS::SObject_ptr theField )
639 return myEngine->setField( theField );
642 //------------------------------------------------------------------------
643 void VISU_Evolution_i::setPointId( CORBA::Long thePointId )
645 myEngine->setPointId( thePointId );
648 //------------------------------------------------------------------------
649 void VISU_Evolution_i::setComponentId( CORBA::Long theComponentId )
651 myEngine->setComponentId( theComponentId );
654 //------------------------------------------------------------------------
655 CORBA::Boolean VISU_Evolution_i::showEvolution()
657 return myEngine->showEvolution();
660 //------------------------------------------------------------------------
661 void VISU_Evolution_i::restoreFromStudy( SALOMEDS::SObject_ptr theObj )
663 myEngine->restoreFromStudy( theObj );