diff --git a/src/Frame.cpp b/src/Frame.cpp index 4efecfdbb2b0911d70fda7cd73da34109fec9792..de4c25a414beda97115f9f3eb6ae4d4e0eb52cf3 100644 --- a/src/Frame.cpp +++ b/src/Frame.cpp @@ -47,9 +47,10 @@ #define VTK_CREATE(type, name) \ vtkSmartPointer<type> name = vtkSmartPointer<type>::New() -Frame::Frame() +Frame::Frame(int id) { _elementCursor=0; + _id=id; //_polydata = vtkPolyData::New(); _polydata2D = vtkPolyData::New(); _polydata3D = vtkPolyData::New(); @@ -78,16 +79,16 @@ void Frame::addElement(FrameElement* point) _framePoints.push_back(point); } -void Frame::clear() -{ - while (!_framePoints.empty()) { - delete _framePoints.back(); - _framePoints.pop_back(); - } - _framePoints.clear(); +//void Frame::clear() +//{ +// while (!_framePoints.empty()) { +// delete _framePoints.back(); +// _framePoints.pop_back(); +// } +// _framePoints.clear(); - _elementCursor=0; -} +// _elementCursor=0; +//} FrameElement* Frame::getNextElement() { @@ -95,7 +96,8 @@ FrameElement* Frame::getNextElement() return NULL; } else { - return _framePoints.at(_elementCursor++); + //return _framePoints.at(_elementCursor++); + return _framePoints[_elementCursor++]; } //next test } diff --git a/src/Frame.h b/src/Frame.h index 19b34dbb0e0c3a1826bb0f149c27cdc5b52cc187..64ad60c52952da2fada97cc2efb24540073f0b5e 100644 --- a/src/Frame.h +++ b/src/Frame.h @@ -38,7 +38,7 @@ class vtkPolyData; class Frame { public: /// constructor - Frame(); + Frame(int id); /// destructor virtual ~Frame(); @@ -58,6 +58,8 @@ public: /// return the number of element in this frame int getSize(); + int GetID(){ return _id;} + /// reset the position of the cursor for reading the data void resetCursor(); @@ -91,6 +93,8 @@ private: /// points to the actual element in the frame unsigned int _elementCursor; + //the frame id + int _id; }; #endif /* Frame_H_ */ diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 3127cf2ca0b2a728206e44a42650e09d90e73de8..b2556f9f59213ee0c75529b99e0875dd81663821 100755 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -601,16 +601,16 @@ bool MainWindow::addPedestrianGroup(int groupID,QString fileName) "F:\\workspace\\JPSvis\\data", "Visualisation Files (*.dat *.trav *.xml);;All Files (*.*)"); + //the action was cancelled if (fileName.isNull()) { return false; } - - //get and set the working dir QFileInfo fileInfo(fileName); QString wd=fileInfo.absoluteDir().absolutePath(); SystemSettings::setWorkingDirectory(wd); + SystemSettings::setFilenamePrefix(QFileInfo ( fileName ).baseName()+"_"); //the geometry actor FacilityGeometry* geometry = visualisationThread->getGeometry(); @@ -656,7 +656,6 @@ bool MainWindow::addPedestrianGroup(int groupID,QString fileName) return false; } - SyncData* dataset=NULL; extern_trajectories_firstSet.clearFrames(); @@ -677,25 +676,34 @@ bool MainWindow::addPedestrianGroup(int groupID,QString fileName) break; } - + //no other geometry format was detected + if(geometry==NULL) + geometry=new FacilityGeometry(); double frameRate=15; //default frame rate statusBar()->showMessage(tr("parsing the file")); - QXmlInputSource source(&file); - QXmlSimpleReader reader; - //no other geometry format was detected - if(geometry==NULL) - geometry=new FacilityGeometry(); - SaxParser handler(geometry,dataset,&frameRate); - reader.setContentHandler(&handler); - reader.parse(source); - file.close(); - QString frameRateStr=QString::number(frameRate); - SystemSettings::setFilenamePrefix(QFileInfo ( fileName ).baseName()+"_"); + //parsing the xml file + if(fileName.endsWith(".xml",Qt::CaseInsensitive)) + { + QXmlInputSource source(&file); + QXmlSimpleReader reader; + SaxParser handler(geometry,dataset,&frameRate); + reader.setContentHandler(&handler); + reader.parse(source); + file.close(); + } + // try to parse the txt file + else + { + if(false==SaxParser::ParseTxtFormat(fileName, dataset,&frameRate)) + return false; + } + + QString frameRateStr=QString::number(frameRate); // set the visualisation window title visualisationThread->setWindowTitle(fileName); visualisationThread->slotSetFrameRate(frameRate); diff --git a/src/SyncData.cpp b/src/SyncData.cpp index 899727721af2f9ea3850ed4549ffcfa2fa825a9c..1e6e477731964419e71861d6286e7eae14e26cab 100644 --- a/src/SyncData.cpp +++ b/src/SyncData.cpp @@ -50,23 +50,25 @@ using namespace std; SyncData::SyncData() { - frameCursor=0; - numberOfAgents=0; - delay_ms_rel=0; //absolute - delay_s_abs=0; //relative - delay_us_abs=0; //absolute - frameCursorOffset=0; - + _frameCursor=0; + _numberOfAgents=0; + _frameCursorOffset=0; } SyncData::~SyncData() { - // trajectories.clear(); - while (!frames.empty()) { - delete frames.back(); - frames.pop_back(); + + //while (!_frames.empty()) { + // delete _frames.back(); + // _frames.pop_back(); + //} + // + + for(auto itr = _frames.begin(); itr != _frames.end(); itr++) + { + delete itr->second; } - frames.clear(); + _frames.clear(); } @@ -109,27 +111,28 @@ std::string SyncData::get() void SyncData::setFrameCursorOffset(int offset) { - frameCursorOffset=offset; + _frameCursorOffset=offset; } void SyncData::addFrame(Frame* frame) { - mutex.lock(); - frames.push_back(frame); - mutex.unlock(); + _mutex.lock(); + _frames[frame->GetID()]=frame; + //_frames.push_back(frame); + _mutex.unlock(); } Frame* SyncData::getFrame( int i) { - mutex.lock(); - i+=frameCursorOffset; + _mutex.lock(); + i+=_frameCursorOffset; - if((i<0) || (i>= (int)frames.size())) { - mutex.unlock(); + if((i<0) || (i>= (int)_frames.size())) { + _mutex.unlock(); return NULL; } else { - mutex.unlock(); - return frames.at(i); + _mutex.unlock(); + return _frames.at(i); } } @@ -138,38 +141,38 @@ Frame* SyncData::getNextFrame() { // this may be the case if the file only contains geometry, thus no trajectories available - if(frames.empty()) return NULL; + if(_frames.empty()) return NULL; // Navigation in the negative direction is also possible //review - mutex.lock(); + _mutex.lock(); - frameCursor+=extern_update_step; + _frameCursor+=extern_update_step; //FIXME: do I really need two variables to handle this? - int cursor =frameCursor+frameCursorOffset; + int cursor =_frameCursor+_frameCursorOffset; if (cursor<0) { //frameCursor=0; emit signal_controlSequences("STACK_REACHS_BEGINNING"); - mutex.unlock(); + _mutex.unlock(); return NULL; - } else if ((unsigned)cursor>=frames.size()) { + } else if ((unsigned)cursor>=_frames.size()) { //if(extern_offline_mode) emit signal_controlSequences("CONTROL_STACK_EMPTY"); //frameCursor=frames.size()-1; - mutex.unlock(); + _mutex.unlock(); // FIXME: check me, return the last frame, if in o //return frames.at(frames.size()-1); - frameCursor-=extern_update_step; - return frames.back(); - //return NULL; + _frameCursor-=extern_update_step; + //return _frames.back(); + return NULL; } - Frame* res =frames.at(cursor); - mutex.unlock(); + Frame* res =_frames.at(cursor); + _mutex.unlock(); return res; } @@ -182,152 +185,105 @@ Frame* SyncData::getNextFrame() */ Frame* SyncData::getPreviousFrame() { - - mutex.lock(); - frameCursor--; + _mutex.lock(); + _frameCursor--; //FIXME: do I really need two variables to handle this? - int cursor =frameCursor+frameCursorOffset; + int cursor =_frameCursor+_frameCursorOffset; if(cursor<0) { //emit signal_controlSequences("STACK_REACHS_BEGINNING"); //frameCursor=0; - mutex.unlock(); + _mutex.unlock(); return NULL; - } else if((unsigned)cursor>=frames.size() ) { + } else if((unsigned)cursor>=_frames.size() ) { //emit signal_controlSequences("CONTROL_STACK_EMPTY"); - mutex.unlock(); + _mutex.unlock(); //frameCursor=frames.size()-1; return NULL; } - Frame* res =frames.at(cursor); + Frame* res =_frames.at(cursor); - mutex.unlock(); + _mutex.unlock(); return res; } void SyncData::clearFrames() { - mutex.lock(); - - frameCursor=0; - numberOfAgents=0; - frameCursorOffset=0; - pedHeight.clear(); - pedColor.clear(); - - while (!frames.empty()) { - delete frames.back(); - frames.pop_back(); - } - frames.clear(); - - mutex.unlock(); + _mutex.lock(); + + _frameCursor=0; + _numberOfAgents=0; + _frameCursorOffset=0; + _pedHeight.clear(); + _pedColor.clear(); + +// while (!_frames.empty()) { +// delete _frames.back(); +// _frames.pop_back(); +// } + _frames.clear(); + _mutex.unlock(); } int SyncData::getFramesNumber() { //mutex.lock(); //FIXME - return frames.size(); + return _frames.size(); //mutex.unlock(); } void SyncData::resetFrameCursor() { - mutex.lock(); - frameCursor=0; - mutex.unlock(); + _mutex.lock(); + _frameCursor=0; + _mutex.unlock(); } int SyncData::getFrameCursor() { - return frameCursor; + return _frameCursor; } void SyncData::setFrameCursorTo(int position) { - mutex.lock(); + _mutex.lock(); //TODO: check the unsigned //if((unsigned)position>=frames.size()) frameCursor =frames.size()-1; //else if (position<0) frameCursor =0; //else - frameCursor=position; + _frameCursor=position; - mutex.unlock(); + _mutex.unlock(); } int SyncData::getNumberOfAgents() { - return numberOfAgents; + return _numberOfAgents; } void SyncData::setNumberOfAgents(int numberOfAgents) { - mutex.lock(); - this->numberOfAgents = numberOfAgents; - mutex.unlock(); -} - -void SyncData::setDelayAbsolute(unsigned long second, unsigned long microsecond=0) -{ - delay_s_abs=second; - delay_us_abs=microsecond; - -} - -///@warning only handle seconds, microseconds are ignored -void SyncData::computeDelayRelative(unsigned long* delays) -{ - unsigned long sec = delays[0]; - unsigned long usec = delays[1]; - long double delay_a = sec*1000 + (double)usec/1000.0; - long double delay_b = delay_s_abs*1000 + (double)delay_us_abs/1000.0; - - delay_ms_rel=delay_a-delay_b; - //std::cerr <<"the delay is: " << delay_ms_rel<<std::endl; - //delay_ms_rel=(sec-delay_s_abs)*1000; - - if (delay_ms_rel<0) { - Debug::Warning("warning: negative delay found"); - } - -} - -/// @warning the old value obtained from computeDelayRelative is just overwritten -// -void SyncData::setDelayRelative(signed long milliseconds) -{ - delay_ms_rel=milliseconds; - -} - - -void SyncData::getDelayAbsolute(unsigned long* delays) -{ - delays[0]=delay_s_abs; - delays[1]=delay_us_abs; -} - -signed long SyncData::getDelayRelative() -{ - return delay_ms_rel; + _mutex.lock(); + _numberOfAgents = numberOfAgents; + _mutex.unlock(); } void SyncData::setInitialHeights(const QStringList& pedHeight) { - this->pedHeight.clear(); - this->pedHeight=pedHeight; + _pedHeight.clear(); + _pedHeight=pedHeight; } unsigned int SyncData::getSize() { - if(frames.empty()) return 0; - else return frames.size(); + if(_frames.empty()) return 0; + else return _frames.size(); } diff --git a/src/SyncData.h b/src/SyncData.h index 3a7383b7a95761fada115fc626ce4d8ace24baee..05ba080f796461e186e8f62937f2a78c00235c27 100644 --- a/src/SyncData.h +++ b/src/SyncData.h @@ -35,10 +35,15 @@ #define SYNCDATA_H_ #include <QMutex> -#include <vector> + #include <QObject> #include <QStringList> +#include <memory> +#include <vector> +#include <map> + + class QObject; class QStringList; class Frame; @@ -56,9 +61,8 @@ public: void add(std::string newData); std::string get(); - //void clear(); - void resetFrameCursor(); + void resetFrameCursor(); /// get the size unsigned int getSize(); @@ -90,29 +94,10 @@ public: /// return the number of pedestrians involved in this dataset int getNumberOfAgents(); - /// set the number of pedestrians - void setNumberOfAgents(int numberOfAgents); - - /// set the absolute time (delay) after which, this dataset will start to play. - /// This is useful when loading several datasets, that needs to be synchronised. - /// @para second the number of seconds elapsed since midnight 1970 - /// @para microsecond the number of microsecond(in addition to the seconds) - void setDelayAbsolute(unsigned long second, unsigned long microsecond/*=0*/); + std::map <int, Frame*>& GetFrames() {return _frames;} - /// returns the arguments given in setDelay. - void getDelayAbsolute(unsigned long *); - - /// get the relative delays between the dataset in millisecond. - /// the delay of the first dataset/group will typically have the delay 0 ms. - signed long getDelayRelative(); - - /// set the relative delays - - void setDelayRelative(signed long milliseconds); - - /// compute the relative relative - /// @deprecated [should use setDelayRelative] - void computeDelayRelative(unsigned long* delays); + /// set the number of pedestrians + void setNumberOfAgents(int _numberOfAgents); /// set the offset. /// this is useful when several datasets needed @@ -122,12 +107,12 @@ public: /// \brief initialize the pedestrians height. /// the initialiation is a list, where the even terms are the IDs /// and the odd terms are the heights - void setInitialHeights(const QStringList& pedHeight); + void setInitialHeights(const QStringList& _pedHeight); /// \brief get initial heights QStringList getInitialHeights() { - return pedHeight; + return _pedHeight; } /** @@ -138,8 +123,8 @@ public: */ void setInitialColors(const QStringList& pedColor) { - this->pedColor.clear(); - this->pedColor=pedColor; + _pedColor.clear(); + _pedColor=pedColor; }; /** @@ -148,7 +133,7 @@ public: QStringList getInitialColors() { - return pedColor; + return _pedColor; } Q_SIGNALS: @@ -158,35 +143,29 @@ Q_SIGNALS: private: - //general information about this dataset - float frameRate; - char roomCaption[256]; - - // give the actual position of the frame beeing read, in the frame dataset + double _frameRate; + char _roomCaption[256]; // the actual position (real) of the frame - int frameCursor; + int _frameCursor; - // the offset. this is 0 when all dataets are synchronised - int frameCursorOffset; - - // relative delay in milliseconds - signed long delay_ms_rel; - // ablotute time elapsed since 1970 in sec - unsigned long delay_s_abs; - // absolute additional time in microsecond - unsigned long delay_us_abs; + // the offset. this is 0 when all datasets are synchronised + int _frameCursorOffset; // list containing the initial heights of pedestrians - QStringList pedHeight; + QStringList _pedHeight; /// list containing the initial colors of pedestrians - QStringList pedColor; + QStringList _pedColor; /// the number of agents - int numberOfAgents; - QMutex mutex; - std::vector<Frame*> frames; + int _numberOfAgents; + + ///used in online mode for syncronizing + QMutex _mutex; + //std::vector<Frame*> _frames; + std::map <int, Frame*> _frames; + //std::map<int, std::unique_ptr<Frame> > _frames; }; #endif /* SYNCDATA_H_ */ diff --git a/src/ThreadDataTransfert.cpp b/src/ThreadDataTransfert.cpp index b40dfb4ba7c39fe3d772522bebafb1eae1710c41..451df54b119edd38c7ccaa41e80a4a8948d5e5e6 100755 --- a/src/ThreadDataTransfert.cpp +++ b/src/ThreadDataTransfert.cpp @@ -289,10 +289,12 @@ QString ThreadDataTransfer::getTagValueFromElement(QDomNode node, void ThreadDataTransfer::parseDataNode(QDomNodeList frames) { - for (int i = 0; i < frames.length(); i++) { - Frame *newFrame = new Frame(); + for (int i = 0; i < frames.length(); i++) + { QDomElement el = frames.item(i).toElement(); QDomNodeList agents = el.elementsByTagName("agent"); + int frame_id=el.attribute("ID").toInt(); + Frame *newFrame = new Frame(frame_id); // TODO: get the right frame id for (int i = 0; i < agents.length(); i++) { bool ok=false; diff --git a/src/ThreadVisualisation.cpp b/src/ThreadVisualisation.cpp index 00c437c1d9f3517894ed9dddd0adb19c2b9deeba..f14586f7f7d5471b272ab5b1882b0ac47bd502fb 100644 --- a/src/ThreadVisualisation.cpp +++ b/src/ThreadVisualisation.cpp @@ -93,7 +93,7 @@ //#include <vector> #define VTK_CREATE(type, name) \ - vtkSmartPointer<type> name = vtkSmartPointer<type>::New() + vtkSmartPointer<type> name = vtkSmartPointer<type>::New() @@ -143,7 +143,7 @@ void ThreadVisualisation::run() { //deactivate the output windows - vtkObject::GlobalWarningDisplayOff(); + //vtkObject::GlobalWarningDisplayOff(); //emit signalStatusMessage("running"); @@ -359,7 +359,7 @@ void ThreadVisualisation::run() //emit signalStatusMessage("Idle"); - //emit signal_controlSequences("CONTROL_RESET"); + emit signal_controlSequences("CONTROL_RESET"); //clear some stuffs @@ -444,34 +444,34 @@ void ThreadVisualisation::initGlyphs2D() agentShape->SetInnerRadius(0); agentShape->SetOuterRadius(30); -// { -// //personal space -// VTK_CREATE (vtkDiskSource, perSpace); -// perSpace->SetCircumferentialResolution(20); -// perSpace->SetInnerRadius(0); -// perSpace->SetOuterRadius(30); -// //forehead -// perSpace->SetCircumferentialResolution(20); -// perSpace->SetInnerRadius(0); -// perSpace->SetOuterRadius(30); -// //backhead - -// //Append the two meshes -// VTK_CREATE (vtkAppendPolyData, appendFilter); -//#if VTK_MAJOR_VERSION <= 5 -// appendFilter->AddInputConnection(perSpace->GetProducerPort()); -// appendFilter->AddInputConnection(input2->GetProducerPort()); -//#else -// appendFilter->AddInputData(perSpace); -// appendFilter->AddInputData(input2); -//#endif -// appendFilter->Update(); - -// // Remove any duplicate points. -// VTK_CREATE (vtkCleanPolyData, cleanFilter); -// cleanFilter->SetInputConnection(appendFilter->GetOutputPort()); -// cleanFilter->Update(); -// } + // { + // //personal space + // VTK_CREATE (vtkDiskSource, perSpace); + // perSpace->SetCircumferentialResolution(20); + // perSpace->SetInnerRadius(0); + // perSpace->SetOuterRadius(30); + // //forehead + // perSpace->SetCircumferentialResolution(20); + // perSpace->SetInnerRadius(0); + // perSpace->SetOuterRadius(30); + // //backhead + + // //Append the two meshes + // VTK_CREATE (vtkAppendPolyData, appendFilter); + //#if VTK_MAJOR_VERSION <= 5 + // appendFilter->AddInputConnection(perSpace->GetProducerPort()); + // appendFilter->AddInputConnection(input2->GetProducerPort()); + //#else + // appendFilter->AddInputData(perSpace); + // appendFilter->AddInputData(input2); + //#endif + // appendFilter->Update(); + + // // Remove any duplicate points. + // VTK_CREATE (vtkCleanPolyData, cleanFilter); + // cleanFilter->SetInputConnection(appendFilter->GetOutputPort()); + // cleanFilter->Update(); + // } //speed the rendering using triangles stripers //vtkTriangleFilter *tris = vtkTriangleFilter::New(); @@ -488,7 +488,8 @@ void ThreadVisualisation::initGlyphs2D() //extern_glyphs_pedestrians->SetSourceConnection(agentShape->GetOutputPort()); //first frame - Frame * frame = extern_trajectories_firstSet.getFrame(0); + Frame * frame = extern_trajectories_firstSet.GetFrames().begin()->second; + vtkPolyData* pData=NULL; if(frame) pData=frame->GetPolyData2D(); @@ -523,8 +524,8 @@ void ThreadVisualisation::initGlyphs2D() extern_glyphs_pedestrians_actor_2D->SetMapper(mapper); //extern_glyphs_pedestrians_actor_2D->GetProperty()->BackfaceCullingOn(); - if(extern_trajectories_firstSet.getNumberOfAgents()>0) - renderer->AddActor(extern_glyphs_pedestrians_actor_2D); + //if(extern_trajectories_firstSet.getNumberOfAgents()>0) + renderer->AddActor(extern_glyphs_pedestrians_actor_2D); // structure for the labels VTK_CREATE(vtkLabeledDataMapper, labelMapper); @@ -579,7 +580,7 @@ void ThreadVisualisation::initGlyphs3D() extern_glyphs_pedestrians_3D->SetSourceConnection(agentShape->GetOutputPort()); //first frame - Frame * frame = extern_trajectories_firstSet.getFrame(0); + Frame * frame = extern_trajectories_firstSet.GetFrames().begin()->second; vtkPolyData* pData=NULL; if(frame) pData=frame->GetPolyData2D(); @@ -609,8 +610,8 @@ void ThreadVisualisation::initGlyphs3D() extern_glyphs_pedestrians_actor_3D->SetMapper(mapper); //extern_glyphs_pedestrians_actor_3D->GetProperty()->BackfaceCullingOn(); - if(extern_trajectories_firstSet.getNumberOfAgents()>0) - renderer->AddActor(extern_glyphs_pedestrians_actor_3D); + //if(extern_trajectories_firstSet.getNumberOfAgents()>0) + renderer->AddActor(extern_glyphs_pedestrians_actor_3D); extern_glyphs_pedestrians_actor_3D->SetVisibility(false); } @@ -718,7 +719,7 @@ void ThreadVisualisation::setCameraPerspective(int mode) //camera->Modified(); } - break; + break; } }