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 // File : VISU_Evolution.cxx
21 // Author : Oleg UVAROV
24 #include "VISU_Evolution.h"
26 #include "VISU_Tools.h"
27 #include "VISU_Gen_i.hh"
28 #include "VISU_Result_i.hh"
29 #include "VISU_Table_i.hh"
30 #include "VISU_View_i.hh"
32 #include <VISU_MeshValue.hxx>
33 #include <VISU_Structures_impl.hxx>
34 #include <VISU_VTKTypeList.hxx>
36 #include <SUIT_Session.h>
38 #include <SalomeApp_Application.h>
39 #include <SalomeApp_Study.h>
41 #include <SALOME_Event.h>
43 //------------------------------------------------------------------------
44 template<int EDataType> bool ProcessValForTime( VISU::PValForTimeImpl theValForTime,
45 VISU::Elem2Comp2Value& theElem2Comp2Value )
47 theElem2Comp2Value.clear();
49 typedef typename VISU::TL::TEnum2VTKBasicType< EDataType >::TResult TVTKBasicType;
50 typedef VISU::TTMeshValue< TVTKBasicType > TMeshValue;
51 typedef MED::SharedPtr< TMeshValue > TMeshValuePtr;
53 const TMeshValuePtr aMeshValue = theValForTime->GetMeshValue( VISU::ePOINT1 );
57 vtkIdType aNbElem = aMeshValue->GetNbElem();
58 vtkIdType aNbComp = aMeshValue->GetNbComp();
59 vtkIdType aNbGauss = aMeshValue->GetNbGauss();
61 for( vtkIdType iElem = 0; iElem < aNbElem; iElem++ )
63 typename TMeshValue::TCValueSliceArr aMValueSliceArr = aMeshValue->GetCompValueSliceArr( iElem );
64 VISU::Comp2Value& aComp2Value = theElem2Comp2Value[ iElem ];
66 vtkFloatingPointType& aModulusValue = aComp2Value[ 0 ];
69 for( vtkIdType iComp = 0; iComp < aNbComp; iComp++ )
71 const typename TMeshValue::TCValueSlice& aMValueSlice = aMValueSliceArr[ iComp ];
73 vtkFloatingPointType& aValue = aComp2Value[ iComp+1 ];
76 for(vtkIdType iGauss = 0; iGauss < aNbGauss; iGauss++)
78 const vtkFloatingPointType& aVal = aMValueSlice[iGauss];
84 aModulusValue += aValue * aValue;
86 aModulusValue = sqrt( aModulusValue );
92 //------------------------------------------------------------------------
93 template<int EDataType> int GetNbPoints( VISU::PValForTimeImpl theValForTime )
95 typedef typename VISU::TL::TEnum2VTKBasicType< EDataType >::TResult TVTKBasicType;
96 typedef VISU::TTMeshValue< TVTKBasicType > TMeshValue;
97 typedef MED::SharedPtr< TMeshValue > TMeshValuePtr;
99 const TMeshValuePtr aMeshValue = theValForTime->GetMeshValue( VISU::ePOINT1 );
103 return aMeshValue->GetNbElem();
106 //------------------------------------------------------------------------
107 VISU_Evolution::VISU_Evolution( _PTR(Study) theStudy,
108 VISU::XYPlot_ptr theXYPlot )
113 if( !CORBA::is_nil( theXYPlot ) )
115 VISU::XYPlot_i* pPlot = dynamic_cast<VISU::XYPlot_i*>( GetServant( theXYPlot ).in() );
116 Plot2d_ViewFrame* aVF = pPlot->GetView();
121 myEvolutionEntry = "";
123 myEntity = VISU::NODE_ENTITY;
130 //------------------------------------------------------------------------
131 VISU_Evolution::~VISU_Evolution()
135 //------------------------------------------------------------------------
136 bool VISU_Evolution::setField( _PTR(SObject) theField )
142 myFieldEntry = theField->GetID();
144 VISU::Storable::TRestoringMap aRestoringMap = VISU::Storable::GetStorableMap( theField );
145 if( aRestoringMap.empty() )
148 VISU::VISUType aType = VISU::Storable::RestoringMap2Type( aRestoringMap );
149 if( aType != VISU::TFIELD )
152 myMeshName = aRestoringMap["myMeshName"].toStdString();
153 myEntity = VISU::TEntity( aRestoringMap["myEntityId"].toInt() );
154 myFieldName = aRestoringMap["myName"].toStdString();
156 if( myEntity != VISU::NODE_ENTITY )
159 VISU::Result_var aResult = VISU::FindResult( VISU::GetSObject( theField ).in() );
160 if( CORBA::is_nil( aResult.in() ) )
163 myResult = dynamic_cast<VISU::Result_i*>( VISU::GetServant( aResult ).in() );
167 const VISU::TMeshMap& aMeshMap = myResult->GetInput()->GetMeshMap();
168 if( aMeshMap.empty() )
171 VISU::TMeshMap::const_iterator aMeshIter = aMeshMap.find( myMeshName );
172 if( aMeshIter == aMeshMap.end() )
175 const VISU::PMesh& aMesh = aMeshIter->second;
176 const VISU::TMeshOnEntityMap& aMeshOnEntityMap = aMesh->myMeshOnEntityMap;
177 if( aMeshOnEntityMap.empty() )
180 VISU::TMeshOnEntityMap::const_iterator aMeshOnEntityIter = aMeshOnEntityMap.find( myEntity );
181 if( aMeshOnEntityIter == aMeshOnEntityMap.end() )
184 const VISU::PMeshOnEntity& aMeshOnEntity = aMeshOnEntityIter->second;
185 const VISU::TFieldMap& aFieldMap = aMeshOnEntity->myFieldMap;
186 if( aFieldMap.empty() )
189 VISU::TFieldMap::const_iterator aFieldIter = aFieldMap.find( myFieldName );
190 if( aFieldIter == aFieldMap.end() )
193 myFieldImpl = aFieldIter->second;
194 const VISU::TNames& aCompNames = myFieldImpl->myCompNames;
195 const VISU::TNames& aUnitNames = myFieldImpl->myUnitNames;
196 int aNbComp = myFieldImpl->myNbComp;
198 // fill myComponentDataList
199 myComponentDataList.clear();
201 QString aModulusComponent( "<Modulus>" );
202 myComponentDataList.append( VISU::ComponentData( aModulusComponent, "" ) );
203 for( int i = 0; i < aNbComp; i++ )
205 QString aComponent = QString( aCompNames[i].c_str() ).simplified();
206 if( aComponent.isEmpty() )
207 aComponent = "Component " + QString::number( i+1 );
209 QString anUnit = QString( aUnitNames[i].c_str() ).simplified();
211 myComponentDataList.append( VISU::ComponentData( aComponent, anUnit ) );
217 //------------------------------------------------------------------------
218 bool VISU_Evolution::setField( SALOMEDS::SObject_ptr theField )
220 SALOMEDS::SObject_var theFieldDup = SALOMEDS::SObject::_duplicate( theField );
221 _PTR(SObject) aField = VISU::GetClientSObject( theFieldDup, myStudy );
222 return setField( aField );
225 //------------------------------------------------------------------------
226 void VISU_Evolution::setPointId( int thePointId )
228 myPointId = thePointId;
231 //------------------------------------------------------------------------
232 void VISU_Evolution::setComponentId( int theComponentId )
234 myComponentId = theComponentId;
237 //------------------------------------------------------------------------
238 int VISU_Evolution::getNbPoints() const
243 vtkIdType aDataType = myFieldImpl->GetDataType();
244 const VISU::TValField& aValField = myFieldImpl->myValField;
245 if( aValField.empty() )
248 VISU::TValField::const_iterator aValFieldIter = aValField.begin();
249 for( ; aValFieldIter != aValField.end(); aValFieldIter++ )
251 const vtkIdType& aTimeStamp = aValFieldIter->first;
252 VISU::PValForTimeImpl aValForTime = aValFieldIter->second;
254 // to force method VISU::MedConvertor::FillValForTime() to be called
255 myResult->GetInput()->GetTimeStampOnMesh( myMeshName, myEntity, myFieldName, aTimeStamp );
259 case VTK_DOUBLE : return GetNbPoints<VTK_DOUBLE>( aValForTime );
260 case VTK_FLOAT : return GetNbPoints<VTK_FLOAT>( aValForTime );
261 case VTK_INT : return GetNbPoints<VTK_INT>( aValForTime );
262 case VTK_LONG: return GetNbPoints<VTK_LONG>( aValForTime );
270 //------------------------------------------------------------------------
271 bool VISU_Evolution::extractData( int thePointId,
273 VISU::TimeStampValueList& theTimeStampValueList )
275 theTimeStampValueList.clear();
276 myTimeStampDataList.clear();
281 vtkIdType aDataType = myFieldImpl->GetDataType();
282 const VISU::TValField& aValField = myFieldImpl->myValField;
283 if( aValField.empty() )
286 typedef QList< VISU::Elem2Comp2Value > TimeStamp2Elem2Comp2Value;
287 typedef QListIterator< VISU::Elem2Comp2Value > TimeStamp2Elem2Comp2ValueIterator;
288 TimeStamp2Elem2Comp2Value aData;
290 VISU::TValField::const_iterator aValFieldIter = aValField.begin();
291 for( ; aValFieldIter != aValField.end(); aValFieldIter++ )
293 const vtkIdType& aTimeStamp = aValFieldIter->first;
294 VISU::PValForTimeImpl aValForTime = aValFieldIter->second;
295 VISU::TTime aTime = aValForTime->myTime;
296 double aTimeValue = aTime.first;
297 std::string aTimeUnits = aTime.second;
299 // to force method VISU::MedConvertor::FillValForTime() to be called
300 // (we need data of all timestamps of the result)
301 myResult->GetInput()->GetTimeStampOnMesh( myMeshName, myEntity, myFieldName, aTimeStamp );
303 // data should be sorted by time value
305 VISU::TimeStampDataListIterator anIter( myTimeStampDataList );
306 while( anIter.hasNext() )
308 VISU::TimeStampData aTimeStampData = anIter.next();
309 if( aTimeValue > aTimeStampData.first )
313 VISU::Elem2Comp2Value anElem2Comp2Value;
318 case VTK_DOUBLE : ok = ProcessValForTime<VTK_DOUBLE>( aValForTime, anElem2Comp2Value ); break;
319 case VTK_FLOAT : ok = ProcessValForTime<VTK_FLOAT>( aValForTime, anElem2Comp2Value ); break;
320 case VTK_INT : ok = ProcessValForTime<VTK_INT>( aValForTime, anElem2Comp2Value ); break;
321 case VTK_LONG: ok = ProcessValForTime<VTK_LONG>( aValForTime, anElem2Comp2Value ); break;
328 aData.insert( anOrder, anElem2Comp2Value );
329 myTimeStampDataList.insert( anOrder, VISU::TimeStampData( aTimeValue, aTimeUnits ) );
332 if( theComponentId < 0 || theComponentId >= myComponentDataList.size() )
336 TimeStamp2Elem2Comp2ValueIterator it1( aData );
337 while( it1.hasNext() )
339 VISU::Elem2Comp2Value anElem2Comp2Value = it1.next();
340 VISU::Elem2Comp2Value::const_iterator it2 = anElem2Comp2Value.find( thePointId );
341 if( it2 != anElem2Comp2Value.end() )
343 VISU::Comp2Value aComp2Value = it2.value();
344 VISU::Comp2Value::const_iterator it3 = aComp2Value.find( theComponentId );
345 if( it3 != aComp2Value.end() )
347 vtkFloatingPointType aValue = it3.value();
348 theTimeStampValueList.append( aValue );
354 if( theTimeStampValueList.size() != myTimeStampDataList.size() )
360 //------------------------------------------------------------------------
361 bool VISU_Evolution::showEvolution()
363 return ProcessEvent(new TMemFunEvent<VISU_Evolution,bool>
364 (this,&VISU_Evolution::_showEvolution));
367 //------------------------------------------------------------------------
368 bool VISU_Evolution::_showEvolution()
370 bool isEdit = ( myEvolutionEntry != "" );
373 VISU::TimeStampValueList aTimeStampValueList;
374 if( !extractData( myPointId, myComponentId, aTimeStampValueList ) )
377 // 2) publish new objects in study (or edit them)
378 _PTR(StudyBuilder) aStudyBuilder = myStudy->NewBuilder();
379 aStudyBuilder->NewCommand(); // open transaction
381 QString anEvolutionComment;
382 anEvolutionComment.sprintf( "myComment=EVOLUTION;myPointId=%d;myComponentId=%d",
386 _PTR(SObject) anEvolutionObject, aFieldRefObject, aTableObject;
387 if( !isEdit ) // creation mode
389 _PTR(SComponent) aSComponent = VISU::ClientFindOrCreateVisuComponent( myStudy );
390 std::string aSComponentEntry = aSComponent->GetID();
392 // create an evolution object
393 myEvolutionEntry = VISU::CreateAttributes( myStudy,
394 aSComponentEntry.c_str(),
397 VISU::GenerateName( "Evolution", 0 ).toLatin1().constData(),
398 VISU::NO_PERFSITENT_REF,
399 anEvolutionComment.toLatin1().constData(),
401 anEvolutionObject = myStudy->FindObjectID( myEvolutionEntry.c_str() );
403 // create a reference to the field object
404 aFieldRefObject = aStudyBuilder->NewObject( anEvolutionObject );
405 aStudyBuilder->Addreference( aFieldRefObject, myField );
407 // create a table object
408 std::string aTableEntry = VISU::CreateAttributes( myStudy,
409 aFieldRefObject->GetID().c_str(),
412 VISU::GenerateName( "Table", 0 ).toLatin1().constData(),
413 VISU::NO_PERFSITENT_REF,
416 aTableObject = myStudy->FindObjectID( aTableEntry.c_str() );
420 // edit an evolution object
421 anEvolutionObject = myStudy->FindObjectID( myEvolutionEntry.c_str() );
422 _PTR(GenericAttribute) anAttr;
423 anAttr = aStudyBuilder->FindOrCreateAttribute( anEvolutionObject, "AttributeString" );
424 _PTR(AttributeString) aComment( anAttr );
425 aComment->SetValue( anEvolutionComment.toLatin1().constData() );
427 // get a reference to the field object
428 _PTR(ChildIterator) anIter = myStudy->NewChildIterator( anEvolutionObject );
431 aFieldRefObject = anIter->Value();
433 // get a table object
434 anIter = myStudy->NewChildIterator( aFieldRefObject );
437 aTableObject = anIter->Value();
440 aStudyBuilder->CommitCommand(); // commit transaction
442 // 3) update table attribute of the table object
443 _PTR(GenericAttribute) anAttr = aStudyBuilder->FindOrCreateAttribute( aTableObject, "AttributeTableOfReal" );
444 _PTR(AttributeTableOfReal) aTableOfReal( anAttr );
446 aTableOfReal->SetNbColumns( aTimeStampValueList.size() );
448 QString aTimeRowUnits;
450 VISU::TimeStampValueListIterator it( aTimeStampValueList );
451 while( it.hasNext() )
453 vtkFloatingPointType aValue = it.next();
455 VISU::TimeStampData aTimeStampData = myTimeStampDataList[ aTimeStamp ];
456 double aTimeValue = aTimeStampData.first;
457 std::string aTimeUnits = aTimeStampData.second;
459 if( aTimeRowUnits.isEmpty() )
460 aTimeRowUnits = QString( aTimeUnits.c_str() ).simplified();
462 aTableOfReal->SetColumnTitle( aTimeStamp+1, QString::number( aTimeStamp+1 ).toLatin1().constData() );
463 aTableOfReal->PutValue( aTimeValue, 1, aTimeStamp+1 );
464 aTableOfReal->PutValue( aValue, 2, aTimeStamp+1 );
469 if( aTimeRowUnits.isEmpty() )
472 aTableOfReal->SetRowTitle( 1, "Time" );
473 aTableOfReal->SetRowUnit( 1, aTimeRowUnits.toLatin1().constData() );
475 const VISU::ComponentData& aComponentData = myComponentDataList[ myComponentId ];
476 QString aValueTitle = QString( "Point %1" ).arg( myPointId );
477 aTableOfReal->SetRowTitle( 2, aValueTitle.toLatin1().constData() );
478 aTableOfReal->SetRowUnit( 2, aComponentData.second.toLatin1().constData() );
480 QString aTitle = QString( "%1, %2" ).arg( myFieldName.c_str() ).arg( aComponentData.first );
481 aTableOfReal->SetTitle( aTitle.toLatin1().constData() );
483 // 4) get active study
484 SalomeApp_Study* aSalomeStudy = NULL;
485 SUIT_Session* aSession = SUIT_Session::session();
486 QList<SUIT_Application*> anApplications = aSession->applications();
487 QList<SUIT_Application*>::Iterator anIter = anApplications.begin();
488 while ( anIter != anApplications.end() ) {
489 SUIT_Application* anApp = *anIter;
490 if (SUIT_Study* aSStudy = anApp->activeStudy()) {
491 if (SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>(aSStudy)) {
492 if (_PTR(Study) aCStudy = aStudy->studyDS()) {
493 if (aCStudy->Name() == myStudy->Name()) {
494 aSalomeStudy = aStudy;
503 // 5) create curves and plot
506 // 5.1) remove old curves (edition mode)
508 _PTR(GenericAttribute) anAttr;
509 if(aTableObject->FindAttribute( anAttr, "AttributeName" ) ) {
510 _PTR(ChildIterator) aChildIter = myStudy->NewChildIterator( aTableObject );
511 for( aChildIter->InitEx( false ); aChildIter->More(); aChildIter->Next() ) {
512 aSalomeStudy->deleteReferencesTo( aChildIter->Value() );
513 _PTR(SObject) aCurveObject = aChildIter->Value();
515 VISU::Storable::TRestoringMap aRestoringMap = VISU::Storable::GetStorableMap(aCurveObject);
516 if (aRestoringMap["myComment"] == "CURVE") {
517 CORBA::Object_var aCORBAObject = VISU::ClientSObjectToObject(aCurveObject);
518 if(!CORBA::is_nil(aCORBAObject)) {
519 PortableServer::ServantBase_var aServant = VISU::GetServant(aCORBAObject);
520 if(VISU::Curve_i* aCurve = dynamic_cast<VISU::Curve_i*>(aServant.in())){
521 if(SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>(aSalomeStudy->application()))
522 VISU::PlotRemoveCurve(anApp, aCurve);
526 aStudyBuilder->RemoveObject( aCurveObject );
532 // 5.2) create new curves
533 VISU::VISU_Gen_i* aVisuGen = VISU::VISU_Gen_i::GetVisuGenImpl();
534 aVisuGen->CreateTable( aTableObject->GetID().c_str() );
537 VISU::CreatePlot( aVisuGen, getViewer(), aTableObject );
543 //------------------------------------------------------------------------
544 void VISU_Evolution::restoreFromStudy( SALOMEDS::SObject_ptr theObj )
546 _PTR(SObject) anEvolutionObject = VISU::GetClientSObject( theObj, myStudy );
547 restoreFromStudy( anEvolutionObject );
550 //------------------------------------------------------------------------
551 void VISU_Evolution::restoreFromStudy( _PTR(SObject) theObj )
553 VISU::Storable::TRestoringMap aMap = VISU::Storable::GetStorableMap( theObj );
558 myPointId = VISU::Storable::FindValue( aMap, "myPointId", &isExist ).toInt();
559 myComponentId = VISU::Storable::FindValue( aMap, "myComponentId", &isExist ).toInt();
561 _PTR(ChildIterator) anIter = myStudy->NewChildIterator( theObj );
562 for( anIter->Init(); anIter->More(); anIter->Next() )
564 _PTR(SObject) aRefObj = anIter->Value();
565 _PTR(SObject) aFieldObj;
567 if( !aRefObj->ReferencedObject( aFieldObj ) )
570 int nbAttr = aFieldObj->GetAllAttributes().size();
574 setField( aFieldObj );
578 myEvolutionEntry = theObj->GetID();
581 //------------------------------------------------------------------------
582 struct TNewEvolutionEvent: public SALOME_Event
584 std::string myStudyName;
585 VISU::XYPlot_ptr myXYPlot;
587 typedef VISU_Evolution* TResult;
590 TNewEvolutionEvent (std::string theStudyName, VISU::XYPlot_ptr theXYPlot):
591 myStudyName(theStudyName),
592 myXYPlot(VISU::XYPlot::_duplicate(theXYPlot)),
600 SUIT_Session* aSession = SUIT_Session::session();
601 QList<SUIT_Application*> anApplications = aSession->applications();
602 QList<SUIT_Application*>::Iterator anIter = anApplications.begin();
603 while ( anIter != anApplications.end() ) {
604 SUIT_Application* anApp = *anIter;
605 if (SUIT_Study* aSStudy = anApp->activeStudy()) {
606 if (SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>(aSStudy)) {
607 if (_PTR(Study) aCStudy = aStudy->studyDS()) {
608 if (myStudyName == aCStudy->Name()) {
609 myResult = new VISU_Evolution (aCStudy, myXYPlot);
620 //------------------------------------------------------------------------
621 VISU_Evolution_i::VISU_Evolution_i( SALOMEDS::Study_ptr theStudy,
622 VISU::XYPlot_ptr theXYPlot )
624 std::string aStudyName = theStudy->Name();
625 myEngine = ProcessEvent( new TNewEvolutionEvent( aStudyName, theXYPlot ) );
628 //------------------------------------------------------------------------
629 VISU_Evolution_i::~VISU_Evolution_i()
634 //------------------------------------------------------------------------
635 bool VISU_Evolution_i::setField( SALOMEDS::SObject_ptr theField )
637 return myEngine->setField( theField );
640 //------------------------------------------------------------------------
641 void VISU_Evolution_i::setPointId( CORBA::Long thePointId )
643 myEngine->setPointId( thePointId );
646 //------------------------------------------------------------------------
647 void VISU_Evolution_i::setComponentId( CORBA::Long theComponentId )
649 myEngine->setComponentId( theComponentId );
652 //------------------------------------------------------------------------
653 CORBA::Boolean VISU_Evolution_i::showEvolution()
655 return myEngine->showEvolution();
658 //------------------------------------------------------------------------
659 void VISU_Evolution_i::restoreFromStudy( SALOMEDS::SObject_ptr theObj )
661 myEngine->restoreFromStudy( theObj );