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 aValForTime,
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 = aValForTime->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 VISU_Evolution::VISU_Evolution( _PTR(Study) theStudy,
96 VISU::XYPlot_ptr theXYPlot )
101 if( !CORBA::is_nil( theXYPlot ) )
103 VISU::XYPlot_i* pPlot = dynamic_cast<VISU::XYPlot_i*>( GetServant( theXYPlot ).in() );
104 Plot2d_ViewFrame* aVF = pPlot->GetView();
109 myEvolutionEntry = "";
111 myEntity = VISU::NODE_ENTITY;
118 //------------------------------------------------------------------------
119 VISU_Evolution::~VISU_Evolution()
123 //------------------------------------------------------------------------
124 bool VISU_Evolution::setField( _PTR(SObject) theField )
130 myFieldEntry = theField->GetID();
132 VISU::Storable::TRestoringMap aRestoringMap = VISU::Storable::GetStorableMap( theField );
133 if( aRestoringMap.empty() )
136 VISU::VISUType aType = VISU::Storable::RestoringMap2Type( aRestoringMap );
137 if( aType != VISU::TFIELD )
140 myMeshName = aRestoringMap["myMeshName"].toStdString();
141 myEntity = VISU::TEntity( aRestoringMap["myEntityId"].toInt() );
142 myFieldName = aRestoringMap["myName"].toStdString();
144 if( myEntity != VISU::NODE_ENTITY )
147 VISU::Result_var aResult = VISU::FindResult( VISU::GetSObject( theField ).in() );
148 if( CORBA::is_nil( aResult.in() ) )
151 myResult = dynamic_cast<VISU::Result_i*>( VISU::GetServant( aResult ).in() );
155 const VISU::TMeshMap& aMeshMap = myResult->GetInput()->GetMeshMap();
156 if( aMeshMap.empty() )
159 VISU::TMeshMap::const_iterator aMeshIter = aMeshMap.find( myMeshName );
160 if( aMeshIter == aMeshMap.end() )
163 const VISU::PMesh& aMesh = aMeshIter->second;
164 const VISU::TMeshOnEntityMap& aMeshOnEntityMap = aMesh->myMeshOnEntityMap;
165 if( aMeshOnEntityMap.empty() )
168 VISU::TMeshOnEntityMap::const_iterator aMeshOnEntityIter = aMeshOnEntityMap.find( myEntity );
169 if( aMeshOnEntityIter == aMeshOnEntityMap.end() )
172 const VISU::PMeshOnEntity& aMeshOnEntity = aMeshOnEntityIter->second;
173 const VISU::TFieldMap& aFieldMap = aMeshOnEntity->myFieldMap;
174 if( aFieldMap.empty() )
177 VISU::TFieldMap::const_iterator aFieldIter = aFieldMap.find( myFieldName );
178 if( aFieldIter == aFieldMap.end() )
181 myFieldImpl = aFieldIter->second;
182 const VISU::TNames& aCompNames = myFieldImpl->myCompNames;
183 const VISU::TNames& aUnitNames = myFieldImpl->myUnitNames;
184 int aNbComp = myFieldImpl->myNbComp;
186 // fill myComponentDataList
187 myComponentDataList.clear();
189 QString aModulusComponent( "<Modulus>" );
190 myComponentDataList.append( VISU::ComponentData( aModulusComponent, "" ) );
191 for( int i = 0; i < aNbComp; i++ )
193 QString aComponent = QString( aCompNames[i].c_str() ).simplified();
194 if( aComponent.isEmpty() )
195 aComponent = "Component " + QString::number( i+1 );
197 QString anUnit = QString( aUnitNames[i].c_str() ).simplified();
199 myComponentDataList.append( VISU::ComponentData( aComponent, anUnit ) );
205 //------------------------------------------------------------------------
206 bool VISU_Evolution::setField( SALOMEDS::SObject_ptr theField )
208 SALOMEDS::SObject_var theFieldDup = SALOMEDS::SObject::_duplicate( theField );
209 _PTR(SObject) aField = VISU::GetClientSObject( theFieldDup, myStudy );
210 return setField( aField );
213 //------------------------------------------------------------------------
214 void VISU_Evolution::setPointId( int thePointId )
216 myPointId = thePointId;
219 //------------------------------------------------------------------------
220 void VISU_Evolution::setComponentId( int theComponentId )
222 myComponentId = theComponentId;
225 //------------------------------------------------------------------------
226 bool VISU_Evolution::extractData( int thePointId,
228 VISU::TimeStampValueList& theTimeStampValueList )
230 theTimeStampValueList.clear();
231 myTimeStampDataList.clear();
236 vtkIdType aDataType = myFieldImpl->GetDataType();
237 const VISU::TValField& aValField = myFieldImpl->myValField;
238 if( aValField.empty() )
241 typedef QList< VISU::Elem2Comp2Value > TimeStamp2Elem2Comp2Value;
242 typedef QListIterator< VISU::Elem2Comp2Value > TimeStamp2Elem2Comp2ValueIterator;
243 TimeStamp2Elem2Comp2Value aData;
245 VISU::TValField::const_iterator aValFieldIter = aValField.begin();
246 for( ; aValFieldIter != aValField.end(); aValFieldIter++ )
248 const vtkIdType& aTimeStamp = aValFieldIter->first;
249 VISU::PValForTimeImpl aValForTime = aValFieldIter->second;
250 VISU::TTime aTime = aValForTime->myTime;
251 double aTimeValue = aTime.first;
252 std::string aTimeUnits = aTime.second;
254 // to force method VISU::MedConvertor::FillValForTime() to be called
255 // (we need data of all timestamps of the result)
256 myResult->GetInput()->GetTimeStampOnMesh( myMeshName, myEntity, myFieldName, aTimeStamp );
258 // data should be sorted by time value
260 VISU::TimeStampDataListIterator anIter( myTimeStampDataList );
261 while( anIter.hasNext() )
263 VISU::TimeStampData aTimeStampData = anIter.next();
264 if( aTimeValue > aTimeStampData.first )
268 VISU::Elem2Comp2Value anElem2Comp2Value;
273 case VTK_DOUBLE : ok = ProcessValForTime<VTK_DOUBLE>( aValForTime, anElem2Comp2Value ); break;
274 case VTK_FLOAT : ok = ProcessValForTime<VTK_FLOAT>( aValForTime, anElem2Comp2Value ); break;
275 case VTK_INT : ok = ProcessValForTime<VTK_INT>( aValForTime, anElem2Comp2Value ); break;
276 case VTK_LONG: ok = ProcessValForTime<VTK_LONG>( aValForTime, anElem2Comp2Value ); break;
283 aData.insert( anOrder, anElem2Comp2Value );
284 myTimeStampDataList.insert( anOrder, VISU::TimeStampData( aTimeValue, aTimeUnits ) );
287 if( theComponentId < 0 || theComponentId >= myComponentDataList.size() )
291 TimeStamp2Elem2Comp2ValueIterator it1( aData );
292 while( it1.hasNext() )
294 VISU::Elem2Comp2Value anElem2Comp2Value = it1.next();
295 VISU::Elem2Comp2Value::const_iterator it2 = anElem2Comp2Value.find( thePointId );
296 if( it2 != anElem2Comp2Value.end() )
298 VISU::Comp2Value aComp2Value = it2.value();
299 VISU::Comp2Value::const_iterator it3 = aComp2Value.find( theComponentId );
300 if( it3 != aComp2Value.end() )
302 vtkFloatingPointType aValue = it3.value();
303 theTimeStampValueList.append( aValue );
309 if( theTimeStampValueList.size() != myTimeStampDataList.size() )
315 //------------------------------------------------------------------------
316 bool VISU_Evolution::showEvolution()
318 return ProcessEvent(new TMemFunEvent<VISU_Evolution,bool>
319 (this,&VISU_Evolution::_showEvolution));
322 //------------------------------------------------------------------------
323 bool VISU_Evolution::_showEvolution()
325 bool isEdit = ( myEvolutionEntry != "" );
328 VISU::TimeStampValueList aTimeStampValueList;
329 if( !extractData( myPointId, myComponentId, aTimeStampValueList ) )
332 // 2) publish new objects in study (or edit them)
333 _PTR(StudyBuilder) aStudyBuilder = myStudy->NewBuilder();
334 aStudyBuilder->NewCommand(); // open transaction
336 QString anEvolutionComment;
337 anEvolutionComment.sprintf( "myComment=EVOLUTION;myPointId=%d;myComponentId=%d",
341 _PTR(SObject) anEvolutionObject, aFieldRefObject, aTableObject;
342 if( !isEdit ) // creation mode
344 _PTR(SComponent) aSComponent = VISU::ClientFindOrCreateVisuComponent( myStudy );
345 std::string aSComponentEntry = aSComponent->GetID();
347 // create an evolution object
348 myEvolutionEntry = VISU::CreateAttributes( myStudy,
349 aSComponentEntry.c_str(),
352 VISU::GenerateName( "Evolution", 0 ).toLatin1().constData(),
353 VISU::NO_PERFSITENT_REF,
354 anEvolutionComment.toLatin1().constData(),
356 anEvolutionObject = myStudy->FindObjectID( myEvolutionEntry.c_str() );
358 // create a reference to the field object
359 aFieldRefObject = aStudyBuilder->NewObject( anEvolutionObject );
360 aStudyBuilder->Addreference( aFieldRefObject, myField );
362 // create a table object
363 std::string aTableEntry = VISU::CreateAttributes( myStudy,
364 aFieldRefObject->GetID().c_str(),
367 VISU::GenerateName( "Table", 0 ).toLatin1().constData(),
368 VISU::NO_PERFSITENT_REF,
371 aTableObject = myStudy->FindObjectID( aTableEntry.c_str() );
375 // edit an evolution object
376 anEvolutionObject = myStudy->FindObjectID( myEvolutionEntry.c_str() );
377 _PTR(GenericAttribute) anAttr;
378 anAttr = aStudyBuilder->FindOrCreateAttribute( anEvolutionObject, "AttributeString" );
379 _PTR(AttributeString) aComment( anAttr );
380 aComment->SetValue( anEvolutionComment.toLatin1().constData() );
382 // get a reference to the field object
383 _PTR(ChildIterator) anIter = myStudy->NewChildIterator( anEvolutionObject );
386 aFieldRefObject = anIter->Value();
388 // get a table object
389 anIter = myStudy->NewChildIterator( aFieldRefObject );
392 aTableObject = anIter->Value();
395 aStudyBuilder->CommitCommand(); // commit transaction
397 // 3) update table attribute of the table object
398 _PTR(GenericAttribute) anAttr = aStudyBuilder->FindOrCreateAttribute( aTableObject, "AttributeTableOfReal" );
399 _PTR(AttributeTableOfReal) aTableOfReal( anAttr );
401 aTableOfReal->SetNbColumns( aTimeStampValueList.size() );
403 QString aTimeRowUnits;
405 VISU::TimeStampValueListIterator it( aTimeStampValueList );
406 while( it.hasNext() )
408 vtkFloatingPointType aValue = it.next();
410 VISU::TimeStampData aTimeStampData = myTimeStampDataList[ aTimeStamp ];
411 double aTimeValue = aTimeStampData.first;
412 std::string aTimeUnits = aTimeStampData.second;
414 if( aTimeRowUnits.isEmpty() )
415 aTimeRowUnits = QString( aTimeUnits.c_str() ).simplified();
417 aTableOfReal->SetColumnTitle( aTimeStamp+1, QString::number( aTimeStamp+1 ).toLatin1().constData() );
418 aTableOfReal->PutValue( aTimeValue, 1, aTimeStamp+1 );
419 aTableOfReal->PutValue( aValue, 2, aTimeStamp+1 );
424 if( aTimeRowUnits.isEmpty() )
427 aTableOfReal->SetRowTitle( 1, "Time" );
428 aTableOfReal->SetRowUnit( 1, aTimeRowUnits.toLatin1().constData() );
430 const VISU::ComponentData& aComponentData = myComponentDataList[ myComponentId ];
431 QString aValueTitle = QString( "Point %1" ).arg( myPointId );
432 aTableOfReal->SetRowTitle( 2, aValueTitle.toLatin1().constData() );
433 aTableOfReal->SetRowUnit( 2, aComponentData.second.toLatin1().constData() );
435 QString aTitle = QString( "%1, %2" ).arg( myFieldName.c_str() ).arg( aComponentData.first );
436 aTableOfReal->SetTitle( aTitle.toLatin1().constData() );
438 // 4) get active study
439 SalomeApp_Study* aSalomeStudy = NULL;
440 SUIT_Session* aSession = SUIT_Session::session();
441 QList<SUIT_Application*> anApplications = aSession->applications();
442 QList<SUIT_Application*>::Iterator anIter = anApplications.begin();
443 while ( anIter != anApplications.end() ) {
444 SUIT_Application* anApp = *anIter;
445 if (SUIT_Study* aSStudy = anApp->activeStudy()) {
446 if (SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>(aSStudy)) {
447 if (_PTR(Study) aCStudy = aStudy->studyDS()) {
448 if (aCStudy->Name() == myStudy->Name()) {
449 aSalomeStudy = aStudy;
458 // 5) create curves and plot
461 // 5.1) remove old curves (edition mode)
463 _PTR(GenericAttribute) anAttr;
464 if(aTableObject->FindAttribute( anAttr, "AttributeName" ) ) {
465 _PTR(ChildIterator) aChildIter = myStudy->NewChildIterator( aTableObject );
466 for( aChildIter->InitEx( false ); aChildIter->More(); aChildIter->Next() ) {
467 aSalomeStudy->deleteReferencesTo( aChildIter->Value() );
468 _PTR(SObject) aCurveObject = aChildIter->Value();
470 VISU::Storable::TRestoringMap aRestoringMap = VISU::Storable::GetStorableMap(aCurveObject);
471 if (aRestoringMap["myComment"] == "CURVE") {
472 CORBA::Object_var aCORBAObject = VISU::ClientSObjectToObject(aCurveObject);
473 if(!CORBA::is_nil(aCORBAObject)) {
474 PortableServer::ServantBase_var aServant = VISU::GetServant(aCORBAObject);
475 if(VISU::Curve_i* aCurve = dynamic_cast<VISU::Curve_i*>(aServant.in())){
476 if(SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>(aSalomeStudy->application()))
477 VISU::PlotRemoveCurve(anApp, aCurve);
481 aStudyBuilder->RemoveObject( aCurveObject );
487 // 5.2) create new curves
488 VISU::VISU_Gen_i* aVisuGen = VISU::VISU_Gen_i::GetVisuGenImpl();
489 aVisuGen->CreateTable( aTableObject->GetID().c_str() );
492 VISU::CreatePlot( aVisuGen, getViewer(), aTableObject );
498 //------------------------------------------------------------------------
499 void VISU_Evolution::restoreFromStudy( SALOMEDS::SObject_ptr theObj )
501 _PTR(SObject) anEvolutionObject = VISU::GetClientSObject( theObj, myStudy );
502 restoreFromStudy( anEvolutionObject );
505 //------------------------------------------------------------------------
506 void VISU_Evolution::restoreFromStudy( _PTR(SObject) theObj )
508 VISU::Storable::TRestoringMap aMap = VISU::Storable::GetStorableMap( theObj );
513 myPointId = VISU::Storable::FindValue( aMap, "myPointId", &isExist ).toInt();
514 myComponentId = VISU::Storable::FindValue( aMap, "myComponentId", &isExist ).toInt();
516 _PTR(ChildIterator) anIter = myStudy->NewChildIterator( theObj );
517 for( anIter->Init(); anIter->More(); anIter->Next() )
519 _PTR(SObject) aRefObj = anIter->Value();
520 _PTR(SObject) aFieldObj;
522 if( !aRefObj->ReferencedObject( aFieldObj ) )
525 int nbAttr = aFieldObj->GetAllAttributes().size();
529 setField( aFieldObj );
533 myEvolutionEntry = theObj->GetID();
536 //------------------------------------------------------------------------
537 struct TNewEvolutionEvent: public SALOME_Event
539 std::string myStudyName;
540 VISU::XYPlot_ptr myXYPlot;
542 typedef VISU_Evolution* TResult;
545 TNewEvolutionEvent (std::string theStudyName, VISU::XYPlot_ptr theXYPlot):
546 myStudyName(theStudyName),
547 myXYPlot(VISU::XYPlot::_duplicate(theXYPlot)),
555 SUIT_Session* aSession = SUIT_Session::session();
556 QList<SUIT_Application*> anApplications = aSession->applications();
557 QList<SUIT_Application*>::Iterator anIter = anApplications.begin();
558 while ( anIter != anApplications.end() ) {
559 SUIT_Application* anApp = *anIter;
560 if (SUIT_Study* aSStudy = anApp->activeStudy()) {
561 if (SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>(aSStudy)) {
562 if (_PTR(Study) aCStudy = aStudy->studyDS()) {
563 if (myStudyName == aCStudy->Name()) {
564 myResult = new VISU_Evolution (aCStudy, myXYPlot);
575 //------------------------------------------------------------------------
576 VISU_Evolution_i::VISU_Evolution_i( SALOMEDS::Study_ptr theStudy,
577 VISU::XYPlot_ptr theXYPlot )
579 std::string aStudyName = theStudy->Name();
580 myEngine = ProcessEvent( new TNewEvolutionEvent( aStudyName, theXYPlot ) );
583 //------------------------------------------------------------------------
584 VISU_Evolution_i::~VISU_Evolution_i()
589 //------------------------------------------------------------------------
590 bool VISU_Evolution_i::setField( SALOMEDS::SObject_ptr theField )
592 return myEngine->setField( theField );
595 //------------------------------------------------------------------------
596 void VISU_Evolution_i::setPointId( CORBA::Long thePointId )
598 myEngine->setPointId( thePointId );
601 //------------------------------------------------------------------------
602 void VISU_Evolution_i::setComponentId( CORBA::Long theComponentId )
604 myEngine->setComponentId( theComponentId );
607 //------------------------------------------------------------------------
608 CORBA::Boolean VISU_Evolution_i::showEvolution()
610 return myEngine->showEvolution();
613 //------------------------------------------------------------------------
614 void VISU_Evolution_i::restoreFromStudy( SALOMEDS::SObject_ptr theObj )
616 myEngine->restoreFromStudy( theObj );