diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..d2398cc --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +jupedsim \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/AUTHORS b/AUTHORS index 89b7a4a..a56f59a 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,11 +1,23 @@ JuPedSim contributors: +(Date: 27.01.2016) Erik Andresen Mohcine Chraibi +Arne Graf David Haensel +Weichen Liao Ulrich Kemloh +Maximilian Osterkamp Andrea Portz Oliver Schmidts +Benjamin Schröder Denis Shhikhalev +Antoine Tordeux Jun Zhang +JPSeditor contributors: +(Date: 27.01.2016) + +Erik Andresen +Maximilian Osterkamp + diff --git a/CHANGELOG.md b/CHANGELOG.md index bab618f..b781b14 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,32 @@ All notable changes to this project will be documented in this file. +## v0.8.0 [Unreleased] + +### Added +#### JPSEDITOR +- 1.2.16 Undo/Redo when Line was edited +- 1.2.16 Change Info Text +- 1.2.16 Load HLines +- 1.2.16 Create and save HLines +- First approaches of an undo/redo framework + - Undo/Redo working when line added or deleted +- DXF import with different layers - Not working properly with AutoCAD ?! +- Bug fixes +- CAD features + - Point and line grid + - object snap + - Orthomode + - Zooming + - Line editing + - Length of line is displayed + - Show origin + - ... +- Room and door declarations +# Change Log +All notable changes to this project will be documented in this file. + + ## v0.8.0 [Unreleased] diff --git a/CMakeLists.txt b/CMakeLists.txt index fa6befb..69f0f49 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,13 +7,21 @@ #================ # 1. CMAKE_BUILD_TYPE=Release (default Debug) # 2. DESIRED_QT_VERSION=5 (default 4) +# example: >> cmake -DDESIRED_QT_VERSION=5 -DCMAKE_PREFIX_PATH=~/Qt/5.5/clang_64 .. +# Flags for VS: -G "Visual Studio ..." -DCMAKE_PREFIX_PATH=... -DCMAKE_C_FLAGS="-mwindows" +cmake_minimum_required(VERSION 2.8.9) IF (POLICY CMP0048) # in CMake 3.0.0+ CMAKE_POLICY (SET CMP0048 OLD) # keep PROJECT() from clearing VERSION variables ENDIF (POLICY CMP0048) - +IF (POLICY CMP0043) # in CMake 3.0.0+ + CMAKE_POLICY (SET CMP0043 OLD) # keep PROJECT() from clearing VERSION variables +ENDIF (POLICY CMP0043) +IF (POLICY CMP0020) +CMAKE_POLICY (SET CMP0020 OLD) # keep old POLICY (2.8.10 and lower) The OLD behavior for this policy is not to link executables to +ENDIF (POLICY CMP0020) #qtmain.lib automatically when they link to the QtCore IMPORTEDtarget project(JPSeditor) -cmake_minimum_required(VERSION 2.8.9) + set(README_FILE "${CMAKE_SOURCE_DIR}/README.md") @@ -66,6 +74,7 @@ message(STATUS "${PROJECT_NAME} will be installed to ${CMAKE_INSTALL_PREFIX}") #-------------------- +if (NOT MSVC) include(CheckCXXCompilerFlag) CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11) CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X) @@ -77,13 +86,14 @@ else() message(AUTHOR_WARNING "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.") endif() message(STATUS "Checking for C++11 compiler - available") - +endif() #--------------------- set( SRCS src/mainWindow.cpp src/main.cpp src/GraphicView.cpp + src/graphicscene.cpp src/roomwidget.cpp src/rooms.cpp src/datamanager.cpp @@ -91,9 +101,12 @@ set( SRCS src/jpsLineItem.cpp src/jpsexit.cpp src/jpsobstacle.cpp - src/jpslandmark.cpp - src/jpswaypoint.cpp - src/widgetlandmark.cpp + src/jpslandmark.cpp + src/jpswaypoint.cpp + src/widgetlandmark.cpp + src/widgetsettings.cpp + src/jpsyahpointer.cpp + src/jpsconnection.cpp dxflib/src/dl_writer_ascii.cpp dxflib/src/dl_dxf.cpp ) @@ -101,6 +114,7 @@ set( SRCS set( HDR src/mainWindow.h src/GraphicView.h + src/graphicscene.h src/roomwidget.h src/rooms.h src/datamanager.h @@ -108,9 +122,12 @@ set( HDR src/jpsLineItem.h src/jpsexit.h src/jpsobstacle.h - src/jpslandmark.h - src/jpswaypoint.h - src/widgetlandmark.h + src/jpslandmark.h + src/jpswaypoint.h + src/widgetlandmark.h + src/widgetsettings.h + src/jpsyahpointer.h + src/jpsconnection.h dxflib/src/dl_writer_ascii.h dxflib/src/dl_writer.h dxflib/src/dl_global.h @@ -129,7 +146,8 @@ set( HDR set( UIS forms/mainwindow.ui forms/roomwidget.ui - forms/widgetlandmark.ui + forms/widgetlandmark.ui + forms/widgetsettings.ui ) # and finally a resource file @@ -153,7 +171,7 @@ ENDIF (WIN32) message(STATUS "QT_Qmake_executable " ${QT_QMAKE_EXECUTABLE}) if($QT_QMAKE_EXECUTABLE STREQUAL "") FIND_PROGRAM(QT_QMAKE_EXECUTABLE NAMES qmake) - if (NOT QT_QMAKE_EXECUTABL) + if (NOT QT_QMAKE_EXECUTABLE) message(WARNING "QT not found - abort.") endif() endif() @@ -186,7 +204,7 @@ elseif("${DESIRED_QT_VERSION}" STREQUAL "4") # QT4_INSTALLED is set to TRUE if qt4 is found and # QT3_INSTALLED is set to TRUE if qt3 is found. FIND_PACKAGE(Qt COMPONENTS QtXml QT_USE_QTNETWORK QtXmlPatterns REQUIRED) - + set(QT4_INSTALLED TRUE) endif() diff --git a/README.md b/README.md index 4c04dd7..c99fd77 100644 --- a/README.md +++ b/README.md @@ -1,29 +1,33 @@ -JuPedSim v0.6 alpha +JuPedSim v0.8 alpha +JPSeditor v0.8 alpha ==================== -Ulrich Kemloh drafted this on 25 Jun 2014 +Erik Andresen drafted this on 27 Jun 2016 -We are proud to announce the first alpha release of our software JuPedSim for simulating pedestrians evacuations. Please note that it is a pre release version for developers only. We are working hard towards the final release for this version. Two modules are shipped with this pre-release: +We are proud to announce the first alpha release of our software JPSeditor (part of JuPedSim for simulating pedestrians evacuations). Please note that it is a pre release version for developers only. We are working hard towards the final release for this version. + +JPSeditor is a graphical user interface to create the geometry of a scenario simulated by JuPedSim. It comes with set of CAD- and further tools to simplify the creation of proper xml-files +incorporating information about the scenario' geometry. -- *jpscore*: command line simulation core -- *jpsvis*: visualization module Features ======== -- Simulate pedestrians movement in a space continuous geometry -- Forces-based models for describing the pedestrians interactions -- Shortest and quickest path route choice strategies -- Loading and visualizing trajectories and geometries -- Easy to use visualization interface -- Making high quality videos directly from the visualization interface or generating png screenshots -- XML based input files +- DXF Import / Export +- CAD features + - Point and line grid + - object snap + - Orthomode + - Zooming + - Line editing + - ... +- Tools for room and door declarations -Showcase +Tutorial ======== -To highlight some features of JuPedSim we have uploaded some videos on our [YouTube channel](https://www.youtube.com/user/JuPedSim). +To highlight some features of JuPedSim we have uploaded some videos on our [YouTube channel](https://www.youtube.com/user/JuPedSim) including a tutorial showing how to use the editor. Installing @@ -39,39 +43,7 @@ As JuPedSim comes with no installer, you just need to delete the unziped directo Running ======= - jpscore.exe my_simulation_ini.xml - -from the command line (or also dropping the file on the executable) will generate a trajectory file, which you can visualize with `jpsvis`. -You will find some projects samples in the downloaded files and further information in the manual. - -Compiling from sources -====================== - -You can compile the simulation core for your specific platform with the supplied cmake script. -The only requirement is a compiler supporting the new standard c++11. - -Windows (tested on Win7 with MinGW 4.8) ---------------------------------------- - - cmake -G "MinGW Makefiles" CMakeList.txt - make-mingw32.exe - -Linux (tested on Ubuntu 14.04 with gcc 4.8) ---------------- - - cmake CMakeList.txt - make - -OSX (tested on OSX Maverick with clang 5.1 and Yosemite with clang 6.1) ---------------------- - - cmake CMakeList.txt - make - -Note that the OpenMP acceleration might be missing under OSX - -For the visualization module (`jpsvis`) at least Qt version 4.5 and VTK version 4.8 are required. -You can download the latest version of QT [here](https://www.qt.io/download/) and the latest version of VTK [here](http://www.vtk.org/download/). +Start the application by clicking on the binary file. (For example .exe) System Requirements ============== @@ -79,11 +51,6 @@ System Requirements There is no special hardware/software requirements for running JuPedSim. The distributed binaries however, are only available for windows at the moment. For compiling from sources you need a compiler with c++11 support is needed for the core. Qt version >=4.5 and VTK >5.8 are needed for the visualization. -Known Issues -============ - -Some verification tests are still failing. The actual cdash-board can be found [here](http://my.cdash.org/index.php?project=JuPedSim) -Occasionaly jpscore crashes if the input file is not valid. Make sure to validate your XML input files with the supplied XSD files. Frequently Asked Questions =========================== diff --git a/forms/HLine.png b/forms/HLine.png new file mode 100644 index 0000000..81b9f3d Binary files /dev/null and b/forms/HLine.png differ diff --git a/forms/Redo-Icon.png b/forms/Redo-Icon.png new file mode 100644 index 0000000..6d9e0d4 Binary files /dev/null and b/forms/Redo-Icon.png differ diff --git a/forms/Ressource.qrc b/forms/Ressource.qrc index 04ae408..239132d 100644 --- a/forms/Ressource.qrc +++ b/forms/Ressource.qrc @@ -38,5 +38,9 @@ jupedsim.png statue.jpg statue_specs.jpg + anglesnap.PNG + Undo-icon.png + Redo-Icon.png + HLine.png diff --git a/forms/Undo-icon.png b/forms/Undo-icon.png new file mode 100644 index 0000000..b9994fc Binary files /dev/null and b/forms/Undo-icon.png differ diff --git a/forms/anglesnap.PNG b/forms/anglesnap.PNG new file mode 100644 index 0000000..97fd814 Binary files /dev/null and b/forms/anglesnap.PNG differ diff --git a/forms/mainwindow.ui b/forms/mainwindow.ui index 855d0bc..8e958db 100644 --- a/forms/mainwindow.ui +++ b/forms/mainwindow.ui @@ -11,7 +11,7 @@ - JuPedSim + JPSeditor @@ -36,6 +36,9 @@ + + + @@ -50,11 +53,16 @@ + + + + - + + @@ -65,6 +73,7 @@ View + @@ -84,21 +93,27 @@ + + + + - + + + - + @@ -156,7 +171,7 @@ F1 - + true @@ -168,10 +183,10 @@ :/Grid.png:/Grid.png - Angle snap + Gridmode - Angle snap + Gridmode Ctrl+G @@ -391,7 +406,7 @@ true - true + false @@ -403,13 +418,16 @@ Landmark + + false + true - true + false @@ -421,6 +439,126 @@ LandmarkSpecs + + false + + + + + true + + + true + + + + :/anglesnap.PNG:/anglesnap.PNG + + + Orthomode + + + Orthomode + + + Ctrl+H + + + + + true + + + Settings + + + Settings + + + Ctrl+E + + + + + + :/open.png:/open.png + + + Load CognitiveMap + + + Load CognitiveMap + + + + + Run visualisation + + + + + Show Point of Origin + + + + + true + + + + :/Undo-icon.png:/Undo-icon.png + + + Undo + + + Undo PaintEvent + + + Ctrl+Z + + + true + + + + + + :/Redo-Icon.png:/Redo-Icon.png + + + Redo + + + Redo PaintEvent + + + Ctrl+Y + + + + + true + + + true + + + + :/HLine.png:/HLine.png + + + HLine + + + HLine + + + H + + + true + diff --git a/forms/roomwidget.ui b/forms/roomwidget.ui index 6810467..e1225f7 100644 --- a/forms/roomwidget.ui +++ b/forms/roomwidget.ui @@ -7,7 +7,7 @@ 0 0 320 - 678 + 725 @@ -42,7 +42,7 @@ 20 - 510 + 560 291 31 @@ -55,7 +55,7 @@ 10 - 330 + 380 291 171 @@ -65,7 +65,7 @@ 110 - 610 + 660 93 28 @@ -78,7 +78,7 @@ 30 - 550 + 600 112 34 @@ -91,7 +91,7 @@ 170 - 550 + 600 112 34 @@ -117,7 +117,7 @@ 10 - 290 + 340 191 31 @@ -199,7 +199,7 @@ -10 - 270 + 320 341 20 @@ -212,7 +212,7 @@ 10 - 240 + 280 121 28 @@ -225,7 +225,7 @@ 202 - 240 + 280 101 28 @@ -234,6 +234,37 @@ Highlight Room + + + true + + + + 100 + 240 + 111 + 21 + + + + + + + 10 + 240 + 91 + 16 + + + + + 9 + + + + Roomtype: + + diff --git a/forms/widgetsettings.ui b/forms/widgetsettings.ui new file mode 100644 index 0000000..95e275b --- /dev/null +++ b/forms/widgetsettings.ui @@ -0,0 +1,100 @@ + + + WidgetSettings + + + + 0 + 0 + 400 + 330 + + + + TabWidget + + + + View Settings + + + + + 10 + 10 + 171 + 241 + + + + Grid Settings + + + + + 10 + 30 + 95 + 20 + + + + Point Grid + + + false + + + + + + 10 + 60 + 95 + 20 + + + + Line Grid + + + true + + + + + + 0 + 90 + 171 + 16 + + + + Qt::Horizontal + + + + + + + 150 + 260 + 101 + 28 + + + + Apply and Close + + + + + + Tab 2 + + + + + + diff --git a/jpseditor.pro b/jpseditor.pro index 71f932d..7186b31 100644 --- a/jpseditor.pro +++ b/jpseditor.pro @@ -27,7 +27,8 @@ QMAKE_CXXFLAGS += -std=c++11 FORMS += \ forms/mainwindow.ui \ forms/roomwidget.ui \ - forms/widgetlandmark.ui + forms/widgetlandmark.ui \ + forms/widgetsettings.ui HEADERS += \ src/mainWindow.h \ @@ -52,7 +53,14 @@ HEADERS += \ dxflib/src/dl_codes.h \ dxflib/src/dl_attributes.h \ src/jpswaypoint.h \ - src/widgetlandmark.h + src/widgetlandmark.h \ + src/graphicscene.h \ + src/widgetsettings.h \ + src/jpsyahpointer.h \ + src/jpsconnection.h \ + src/UndoFramework/actionstack.h \ + src/UndoFramework/action.h \ + src/UndoFramework/lineaction.h SOURCES += \ @@ -70,7 +78,14 @@ SOURCES += \ dxflib/src/dl_writer_ascii.cpp \ dxflib/src/dl_dxf.cpp \ src/jpswaypoint.cpp \ - src/widgetlandmark.cpp + src/widgetlandmark.cpp \ + src/graphicscene.cpp \ + src/widgetsettings.cpp \ + src/jpsyahpointer.cpp \ + src/jpsconnection.cpp \ + src/UndoFramework/actionstack.cpp \ + src/UndoFramework/action.cpp \ + src/UndoFramework/lineaction.cpp RESOURCES += forms/Ressource.qrc diff --git a/src/GraphicView.cpp b/src/GraphicView.cpp index b98f0cc..dcb7784 100644 --- a/src/GraphicView.cpp +++ b/src/GraphicView.cpp @@ -45,8 +45,11 @@ jpsGraphicsView::jpsGraphicsView(QWidget* parent):QGraphicsView(parent) midbutton_hold=false; translation_x=0; translation_y=0;//this->height(); - gridmode=false; - gl_scale_f=.01; + anglesnap=false; + id_counter=0; + _scaleFactor=1.0; + _gridSize=1.0; + gl_scale_f=.01*_scaleFactor; //scale(10,10); catch_radius=10*gl_scale_f; catch_line_distance=10*gl_scale_f; @@ -56,10 +59,13 @@ jpsGraphicsView::jpsGraphicsView(QWidget* parent):QGraphicsView(parent) line_tracked=-1; current_rect=nullptr; currentSelectRect=nullptr; + gridmap=nullptr; objectsnap=false; + _gridmode=false; statWall=false; statDoor=false; statExit=false; + _statHLine=false; statLandmark=false; markedLandmark=nullptr; currentLandmarkRect=nullptr; @@ -68,16 +74,16 @@ jpsGraphicsView::jpsGraphicsView(QWidget* parent):QGraphicsView(parent) this->scale(1/gl_scale_f,-1/gl_scale_f); _currentTrackedPoint=nullptr; _statLineEdit=false; + intersection_point=nullptr; lines_collided=false; _assoDef=false; - //gl_min_x=1e6; - //gl_min_y=1e6; + //m_graphView->setFixedSize(1600, 900); //m_graphView->setScene(m_graphScen); - setCacheMode(QGraphicsView::CacheBackground); + //setCacheMode(QGraphicsView::CacheBackground); setViewportUpdateMode(QGraphicsView::FullViewportUpdate); @@ -93,16 +99,11 @@ jpsGraphicsView::jpsGraphicsView(QWidget* parent):QGraphicsView(parent) //Set-up the scene - Scene = new QGraphicsScene(this); + Scene = new GraphicScene(this); + setScene(Scene); setSceneRect(0, 0, 1920, 1080); - //create_grid(); - - ///Origin - - //origin.push_back(Scene->addLine(1,1,1/gl_scale_f*0.02,1,QPen(Qt::black,0))); - //origin.push_back(Scene->addLine(1,1,1,1/gl_scale_f*0.02,QPen(Qt::black,0))); } jpsGraphicsView::~jpsGraphicsView() @@ -127,18 +128,18 @@ void jpsGraphicsView::mouseMoveEvent(QMouseEvent *mouseEvent) pos=mapToScene(mouseEvent->pos()); - if (gridmode==true) + if (anglesnap==true) { if (current_line!=nullptr) { - use_gridmode(current_line,5); + use_anglesnap(current_line,5); } } if (_currentVLine!=nullptr) { - /// vline will be deleted if it is not thrown horizontally or vertically - if(!use_gridmode(_currentVLine,15)) + // vline will be deleted if it is not thrown horizontally or vertically + if(!use_anglesnap(_currentVLine,15)) { delete _currentVLine; _currentVLine=nullptr; @@ -161,11 +162,14 @@ void jpsGraphicsView::mouseMoveEvent(QMouseEvent *mouseEvent) translated_pos.setX(pos.x()-translation_x); translated_pos.setY(pos.y()-translation_y); + if (_gridmode) + use_gridmode(); + if (objectsnap) { catch_points(); - ///VLine + //VLine if (point_tracked && (statWall==true || statDoor==true || statExit==true)) { SetVLine(); @@ -180,6 +184,8 @@ void jpsGraphicsView::mouseMoveEvent(QMouseEvent *mouseEvent) current_line->setLine(current_line->line().x1(),current_line->line().y1(),translated_pos.x(),translated_pos.y()); //} + //As line length has changed + emit LineLengthChanged(); } if (_currentVLine!=nullptr) { @@ -187,7 +193,7 @@ void jpsGraphicsView::mouseMoveEvent(QMouseEvent *mouseEvent) _currentVLine->setLine(_currentVLine->line().x1(),_currentVLine->line().y1(),translated_pos.x(),translated_pos.y()); } - /// see if two lines collided FIX ME!!! + // see if two lines collided FIX ME!!! //line_collision(); emit mouse_moved(); @@ -202,9 +208,22 @@ void jpsGraphicsView::mousePressEvent(QMouseEvent *mouseEvent) if (mouseEvent->button() == Qt::LeftButton) { - if (statWall==true || statDoor==true || statExit==true) + if (statWall || statDoor || statExit || _statHLine) { - drawLine(); + // If line is edited currently + if (_statLineEdit) + { + for (jpsLineItem* line:line_vector) + { + locate_intersection(marked_lines.first(),line); + } + current_line=nullptr; + _statLineEdit=false; + line_tracked=1; + emit no_drawing(); + } + else + drawLine(); } else if (statLandmark==true) { @@ -212,7 +231,7 @@ void jpsGraphicsView::mousePressEvent(QMouseEvent *mouseEvent) } else { - ///LineEdit + //LineEdit if (_currentTrackedPoint!=nullptr && line_tracked==1) { EditLine(_currentTrackedPoint); @@ -221,7 +240,7 @@ void jpsGraphicsView::mousePressEvent(QMouseEvent *mouseEvent) } else { - ///Select_mode + //Select_mode currentSelectRect=Scene->addRect(translated_pos.x(),translated_pos.y(),0,0,QPen(Qt::blue,0)); currentSelectRect->setTransform(QTransform::fromTranslate(translation_x,translation_y), true); leftbutton_hold=true; @@ -241,7 +260,13 @@ void jpsGraphicsView::mousePressEvent(QMouseEvent *mouseEvent) void jpsGraphicsView::mouseDoubleClickEvent(QMouseEvent *event) { if (event->button()==Qt::LeftButton) + { /// To avoid deleting of edited line + if (line_tracked==1) + { + current_line=nullptr; + } emit no_drawing(); + } } @@ -298,32 +323,106 @@ QGraphicsRectItem *jpsGraphicsView::GetCurrentSelectRect() return currentSelectRect; } -void jpsGraphicsView::ShowWaypoints(QList waypoints) +void jpsGraphicsView::ShowWaypoints(QList waypoints) { ClearWaypoints(); - for (jpsWaypoint* waypoint:waypoints) + for (ptrWaypoint waypoint:waypoints) { QGraphicsEllipseItem* ellipse = Scene->addEllipse(waypoint->GetRect(),QPen(Qt::blue,0)); ellipse->setTransform(QTransform::fromTranslate(translation_x,translation_y), true); + QString string = waypoint->GetType() + "\n" + waypoint->GetCaption()+ "\n" + waypoint->GetText(); + QGraphicsTextItem* text = Scene->addText(string); + text->setPos(waypoint->GetPos().x()+translation_x,waypoint->GetPos().y()+translation_y); + //text->setScale(gl_scale_f); + text->setData(0,gl_scale_f); + text->setTransform(QTransform::fromScale(gl_scale_f,-gl_scale_f),true); _waypoints.push_back(ellipse); + _waypointLabels.push_back(text); } } +void jpsGraphicsView::ShowYAHPointer(const QPointF &pos, const qreal &dir) +{ + for (QGraphicsLineItem* lineItem:_yahPointer) + { + delete lineItem; + } + _yahPointer.clear(); + + _yahPointer.push_back(Scene->addLine(pos.x(),pos.y(),pos.x()+0.5*std::cos(dir),pos.y()+0.5*std::sin(dir),QPen(Qt::blue,0))); + _yahPointer.push_back(Scene->addLine(pos.x()+0.5*std::cos(dir),pos.y()+0.5*std::sin(dir),pos.x()+0.2*std::cos(dir+M_PI/4.0),pos.y()+0.2*std::sin(dir+M_PI/4.0),QPen(Qt::blue,0))); + _yahPointer.push_back(Scene->addLine(pos.x()+0.5*std::cos(dir),pos.y()+0.5*std::sin(dir),pos.x()+0.2*std::cos(dir-M_PI/4.0),pos.y()+0.2*std::sin(dir-M_PI/4.0),QPen(Qt::blue,0))); + + for (QGraphicsLineItem* lineItem:_yahPointer) + { + lineItem->setTransform(QTransform::fromTranslate(translation_x,translation_y), true); + } + + +} + +void jpsGraphicsView::ClearWaypointLabels() +{ + for (QGraphicsTextItem* label:_waypointLabels) + { + delete label; + } + _waypointLabels.clear(); +} + +void jpsGraphicsView::ShowConnections(QList cons) +{ + ClearConnections(); + for (ptrConnection con:cons) + { + QGraphicsLineItem* line = Scene->addLine(QLineF(con->GetWaypoints().first->GetPos(),con->GetWaypoints().second->GetPos()),QPen(Qt::blue,0)); + _connections.push_back(line); + + + line->setTransform(QTransform::fromTranslate(translation_x,translation_y), true); + + + } +} + +void jpsGraphicsView::ClearConnections() +{ + for (QGraphicsLineItem* line:_connections) + { + delete line; + } + _connections.clear(); +} + void jpsGraphicsView::ClearWaypoints() { - ///Waypoints + //Waypoints for (QGraphicsEllipseItem* old_waypoint:_waypoints) { delete old_waypoint; } _waypoints.clear(); + ClearWaypointLabels(); + +} + +void jpsGraphicsView::ActivateLineGrid() +{ + Scene->SetGrid("Line"); + +} + +void jpsGraphicsView::ActivatePointGrid() +{ + Scene->SetGrid("Point"); + } @@ -341,7 +440,7 @@ void jpsGraphicsView::mouseReleaseEvent(QMouseEvent *event) if (event->button() == Qt::LeftButton) { - /// Select lines that are located within the rectangle + // Select lines that are located within the rectangle if (!(statWall==true || statDoor==true || statExit==true || statLandmark==true)) { leftbutton_hold=false; @@ -350,17 +449,18 @@ void jpsGraphicsView::mouseReleaseEvent(QMouseEvent *event) { if (_assoDef) { - ///Waypoint definition + //Waypoint definition emit AssoDefCompleted(); + _assoDef=false; } else { - /// Select lines by creating a rect with the cursor + // Select lines by creating a rect with the cursor catch_lines(); - /// unmark Landmark is possible + // unmark Landmark is possible unmarkLandmark(); - /// Look for landmarks with position in the currentSelectRect + // Look for landmarks with position in the currentSelectRect catch_landmark(); } delete currentSelectRect; @@ -368,7 +468,7 @@ void jpsGraphicsView::mouseReleaseEvent(QMouseEvent *event) } - ///unmark selected line(s) + //unmark selected line(s) if (line_tracked==-1) { unmark_all_lines(); @@ -455,7 +555,7 @@ void jpsGraphicsView::delete_all(bool final) update(); } -bool jpsGraphicsView::use_gridmode(QGraphicsLineItem* currentline, int accuracy) +bool jpsGraphicsView::use_anglesnap(QGraphicsLineItem* currentline, int accuracy) { // if a current line is in the drawing procedure (i. e. starting point is determined but not the ending point) @@ -487,54 +587,128 @@ bool jpsGraphicsView::use_gridmode(QGraphicsLineItem* currentline, int accuracy) return false; } +void jpsGraphicsView::use_gridmode() +{ + if ((std::fmod(std::fabs(translated_pos.x()),_gridSize)<=_gridSize*0.1 || std::fmod(std::fabs(translated_pos.x()),_gridSize)>=_gridSize*0.9) && + (std::fmod(std::fabs(translated_pos.y()),_gridSize)<=_gridSize*0.1 || std::fmod(std::fabs(translated_pos.y()),_gridSize)>=_gridSize*0.9)) + { + bool posx_positiv=true; + bool posy_positiv=true; + if (translated_pos.x()<0) + { + translated_pos.setX(std::fabs(translated_pos.x())); + posx_positiv=false; + } + + if (translated_pos.y()<0) + { + translated_pos.setY(std::fabs(translated_pos.y())); + posy_positiv=false; + } + + if (std::fmod(translated_pos.x(),_gridSize)<=_gridSize*0.1) + translated_pos.setX(translated_pos.x()-std::fmod(translated_pos.x(),_gridSize)); + else + translated_pos.setX(translated_pos.x()+(_gridSize-std::fmod(translated_pos.x(),_gridSize))); + + if (std::fmod(translated_pos.y(),_gridSize)<=_gridSize*0.1) + translated_pos.setY(translated_pos.y()-std::fmod(translated_pos.y(),_gridSize)); + else + translated_pos.setY(translated_pos.y()+(_gridSize-std::fmod(translated_pos.y(),_gridSize))); + + if (!posx_positiv) + translated_pos.setX(translated_pos.x()*(-1)); + + if (!posy_positiv) + translated_pos.setY(translated_pos.y()*(-1)); + + current_rect=Scene->addRect(translated_pos.x()+translation_x-10*gl_scale_f,translated_pos.y()+translation_y-10*gl_scale_f,20*gl_scale_f,20*gl_scale_f,QPen(Qt::red,0)); + point_tracked=true; + _currentTrackedPoint= &translated_pos; + + + } + else + point_tracked=false; +} + void jpsGraphicsView::catch_points() { - ///Searching for startpoints of all lines near the current cursor position - for (signed int i=0; iget_line()->line().x1()>=(translated_pos.x()-catch_radius) && line_vector[i]->get_line()->line().x1()<=(translated_pos.x()+catch_radius) && line_vector[i]->get_line()->line().y1()>=(translated_pos.y()-catch_radius) && line_vector[i]->get_line()->line().y1()<=(translated_pos.y()+catch_radius)){ - /// in this case the cursor is working with global coordinates. So the method 'mapToGlobal' must be used + // in this case the cursor is working with global coordinates. So the method 'mapToGlobal' must be used + + //to avoid the tracking of the coords of an edited line + if (line_vector[i]->get_line()==current_line) + { + continue; + } + translated_pos.setX(line_vector[i]->get_line()->line().x1()); translated_pos.setY(line_vector[i]->get_line()->line().y1()); //cursor.setPos(mapToGlobal(QPoint(translate_back_x(line_vector[i].x1()),translate_back_y(line_vector[i].y1())))); - ///bool is used to tell paint device to draw a red rect if a point was tracked + //bool is used to tell paint device to draw a red rect if a point was tracked point_tracked=true; _currentTrackedPoint= &translated_pos; //QPen pen; //pen.setColor('red'); - current_rect=Scene->addRect(translated_pos.x()+translation_x-10*gl_scale_f,translated_pos.y()+translation_y-10*gl_scale_f,20*gl_scale_f,20*gl_scale_f,QPen(Qt::red,0)); - /// if a point was tracked there is no need to look for further points ( only one point can be tracked) + if (current_rect==nullptr) + current_rect=Scene->addRect(translated_pos.x()+translation_x-10*gl_scale_f,translated_pos.y()+translation_y-10*gl_scale_f,20*gl_scale_f,20*gl_scale_f,QPen(Qt::red,0)); + // if a point was tracked there is no need to look for further points ( only one point can be tracked) return; } - ///Searching for endpoints of all lines near the current cursor position + //Searching for endpoints of all lines near the current cursor position else if (line_vector[i]->get_line()->line().x2()>=(translated_pos.x()-catch_radius) && line_vector[i]->get_line()->line().x2()<=(translated_pos.x()+catch_radius) && line_vector[i]->get_line()->line().y2()>=(translated_pos.y()-catch_radius) && line_vector[i]->get_line()->line().y2()<=(translated_pos.y()+catch_radius)){ // see above + + //to avoid the tracking of the coords of an edited line + if (line_vector[i]->get_line()==current_line) + { + continue; + } + + translated_pos.setX(line_vector[i]->get_line()->line().x2()); translated_pos.setY(line_vector[i]->get_line()->line().y2()); //cursor.setPos(mapToGlobal(QPoint(translate_back_x(line_vector[i].x2()),translate_back_y(line_vector[i].y2())))); point_tracked=true; - current_rect=Scene->addRect(translated_pos.x()+translation_x-10*gl_scale_f,translated_pos.y()+translation_y-10*gl_scale_f,20*gl_scale_f,20*gl_scale_f,QPen(Qt::red,0)); + if (current_rect==nullptr) + current_rect=Scene->addRect(translated_pos.x()+translation_x-10*gl_scale_f,translated_pos.y()+translation_y-10*gl_scale_f,20*gl_scale_f,20*gl_scale_f,QPen(Qt::red,0)); _currentTrackedPoint= &translated_pos; return; } } - /// if no start- or endpoint was tracked it is searched for intersections- Points + // if no start- or endpoint was tracked it is searched for intersections- Points - /// see above + // see above for (int j=0; jx()>=(translated_pos.x()-catch_radius) && intersect_point_vector[j]->x()<=(translated_pos.x()+catch_radius) && intersect_point_vector[j]->y()>=(translated_pos.y()-catch_radius) && intersect_point_vector[j]->y()<=(translated_pos.y()+catch_radius)) { translated_pos.setX(intersect_point_vector[j]->x()); translated_pos.setY(intersect_point_vector[j]->y()); + if (current_rect==nullptr) current_rect=Scene->addRect(translated_pos.x()+translation_x-10*gl_scale_f,translated_pos.y()+translation_y-10*gl_scale_f,20*gl_scale_f,20*gl_scale_f,QPen(Qt::red,0)); - point_tracked=true; + point_tracked=true; return; } } + + // Catch origin + if (!_origin.isEmpty()) + if (std::fabs(translated_pos.x())<=catch_radius && std::fabs(translated_pos.y())<=catch_radius) + { + translated_pos.setX(0); + translated_pos.setY(0); + if (current_rect==nullptr) + current_rect=Scene->addRect(translated_pos.x()+translation_x-10*gl_scale_f,translated_pos.y()+translation_y-10*gl_scale_f,20*gl_scale_f,20*gl_scale_f,QPen(Qt::red,0)); + + } //Look for gridpoints // for (auto &gridpoint: grid_point_vector) @@ -559,33 +733,33 @@ void jpsGraphicsView::catch_points() // } // } - /// if no point was tracked bool is set back to false + // if no point was tracked bool is set back to false point_tracked=false; return; } void jpsGraphicsView::catch_lines() { - ///catch lines (only possible if wall is disabled) - /// if current rect was build up moving the cursor to the left -> - /// whole line has to be within the rect to select the line + //catch lines (only possible if wall is disabled) + // if current rect was build up moving the cursor to the left -> + // whole line has to be within the rect to select the line line_tracked=-1; if (currentSelectRect->rect().width()<0) { - for (auto &item:line_vector) - { - if (currentSelectRect->contains(item->get_line()->line().p1()) - && currentSelectRect->contains(item->get_line()->line().p2())) + for (auto &item:line_vector) { - select_line(item); - line_tracked=1; + if (currentSelectRect->contains(item->get_line()->line().p1()) + && currentSelectRect->contains(item->get_line()->line().p2())) + { + select_line(item); + + } } } - } - /// if current rect was build up moving the cursor to the right -> - /// throwing the select rect only over a part of a line is sufficent to select it + // if current rect was build up moving the cursor to the right -> + // throwing the select rect only over a part of a line is sufficent to select it else if (currentSelectRect->rect().width()>0) { for (auto &item:line_vector) @@ -602,11 +776,11 @@ void jpsGraphicsView::catch_lines() void jpsGraphicsView::drawLine() { - if (current_line==nullptr) /// if the mouse was pressed first of two times + if (current_line==nullptr) // if the mouse was pressed first of two times { - ///Determining first point of line + //Determining first point of line - /// all two points of the line are inited with the cursorcoordinates + // all two points of the line are inited with the cursorcoordinates current_line = Scene->addLine(translated_pos.x(),translated_pos.y(),translated_pos.x(),translated_pos.y(),currentPen); //current_line->translate(translation_x,translation_y); current_line->setTransform(QTransform::fromTranslate(translation_x,translation_y), true); @@ -617,7 +791,10 @@ void jpsGraphicsView::drawLine() // if the mouse was pressed secondly of two times else { + jpsLineItem* lineItem= new jpsLineItem(current_line); + lineItem->set_id(id_counter); + id_counter++; // if there is already a drawn line if (line_vector.size()>=1) @@ -631,27 +808,22 @@ void jpsGraphicsView::drawLine() } } - lineItem->set_type(statWall,statDoor,statExit); + lineItem->set_type(statWall,statDoor,statExit,_statHLine); line_vector.push_back(lineItem); - ///reset pointer + //reset pointer current_line=nullptr; - if (_statLineEdit) - { + //Undo + RecordUndoLineAction("LineAdded",lineItem->GetType(),lineItem->get_id(),lineItem->get_line()->line()); + + //drawLine(); - select_line(lineItem); - _statLineEdit=false; - line_tracked=1; - emit no_drawing(); - } - else - drawLine(); } - ///Vline + //Vline if (_currentVLine!=nullptr) { delete _currentVLine; @@ -667,6 +839,7 @@ void jpsGraphicsView::select_line(jpsLineItem *mline) { mline->get_line()->setPen(QPen(Qt::red,0)); marked_lines.push_back(mline); + line_tracked=1; } else { @@ -683,16 +856,16 @@ void jpsGraphicsView::disable_drawing() statExit=false; statLandmark=false; _statLineEdit=false; - /// if drawing was canceled by pushing ESC + // if drawing was canceled by pushing ESC if (current_line!=nullptr) { - ///not completed line will be deleted + //not completed line will be deleted delete current_line; current_line=nullptr; } if (_currentVLine!=nullptr) { - ///VLine will be deleted + //VLine will be deleted delete _currentVLine; _currentVLine=nullptr; } @@ -705,6 +878,8 @@ jpsLineItem* jpsGraphicsView::addLineItem(const qreal &x1,const qreal &y1,const current_line=Scene->addLine(x1,y1,x2,y2); current_line->setTransform(QTransform::fromTranslate(translation_x,translation_y), true); jpsLineItem* newLine = new jpsLineItem(current_line); + newLine->set_id(id_counter); + id_counter++; if (type=="Door") { @@ -714,6 +889,10 @@ jpsLineItem* jpsGraphicsView::addLineItem(const qreal &x1,const qreal &y1,const { newLine->set_Exit(); } + else if (type=="HLine") + { + newLine->SetHLine(); + } else { newLine->set_Wall(); @@ -744,6 +923,11 @@ jpsLineItem* jpsGraphicsView::addLineItem(const qreal &x1,const qreal &y1,const } +jpsLineItem *jpsGraphicsView::addLineItem(const QLineF &line, const QString &type) +{ + return addLineItem(line.p1().x(),line.p1().y(),line.p2().x(),line.p2().y(),type); +} + void jpsGraphicsView::locate_intersection(jpsLineItem *item1, jpsLineItem *item2) { @@ -797,19 +981,31 @@ void jpsGraphicsView::EditLine(QPointF* point) if (marked_lines.size()==1) { + delete current_rect; + current_rect=nullptr; + + point_tracked=false; + if (marked_lines.first()->get_line()->line().p1()==*point) { - current_line=Scene->addLine(marked_lines[0]->get_line()->line().p2().x(), - marked_lines[0]->get_line()->line().p2().y(),translated_pos.x(),translated_pos.y(),QPen(Qt::red,0)); - current_line->setTransform(QTransform::fromTranslate(translation_x,translation_y), true); + RecordUndoLineAction("LineEdited",marked_lines.first()->GetType(),marked_lines.first()->get_id(),marked_lines.first()->get_line()->line()); + current_line=marked_lines[0]->get_line(); + marked_lines[0]->get_line()->setLine(marked_lines[0]->get_line()->line().x2(),marked_lines[0]->get_line()->line().y2(),translated_pos.x(),translated_pos.y()); + //current_line=Scene->addLine(marked_lines[0]->get_line()->line().p2().x(), + // marked_lines[0]->get_line()->line().p2().y(),translated_pos.x(),translated_pos.y(),QPen(Qt::red,0)); + //current_line->setTransform(QTransform::fromTranslate(translation_x,translation_y), true); emit set_focus_textedit(); } else if (marked_lines.first()->get_line()->line().p2()==*point) { - current_line=Scene->addLine(marked_lines[0]->get_line()->line().p1().x(), - marked_lines[0]->get_line()->line().p1().y(),translated_pos.x(),translated_pos.y(),QPen(Qt::red,0)); - current_line->setTransform(QTransform::fromTranslate(translation_x,translation_y), true); + RecordUndoLineAction("LineEdited",marked_lines.first()->GetType(),marked_lines.first()->get_id(),marked_lines.first()->get_line()->line()); + current_line=marked_lines[0]->get_line(); + marked_lines[0]->get_line()->setLine(marked_lines[0]->get_line()->line().x1(),marked_lines[0]->get_line()->line().y1(),translated_pos.x(),translated_pos.y()); + + //->get_line()->line().p1().x(), + //marked_lines[0]->get_line()->line().p1().y(),translated_pos.x(),translated_pos.y(),QPen(Qt::red,0); + //current_line->setTransform(QTransform::fromTranslate(translation_x,translation_y), true); emit set_focus_textedit(); } @@ -817,13 +1013,20 @@ void jpsGraphicsView::EditLine(QPointF* point) return; //line_tracked=1; + RemoveIntersections(marked_lines.first()); _statLineEdit=true; - delete_marked_lines(); + + //delete_marked_lines(); en_disableWall(); } } +qreal jpsGraphicsView::ReturnLineLength() +{ + return current_line->line().length(); +} + bool jpsGraphicsView::show_hide_roomCaption(QString name, qreal x, qreal y) { // if caption exits, it is supposed to be hided: @@ -857,7 +1060,102 @@ bool jpsGraphicsView::show_hide_roomCaption(QString name, qreal x, qreal y) return true; } -void jpsGraphicsView::line_collision() ///FIX ME!!! +void jpsGraphicsView::RecordUndoLineAction(const QString& name, const QString& type, const int& itemID, const QLineF &oldLine) +{ + _undoStack.PushNewAction(LineAction(name,type,itemID,oldLine)); +} + +void jpsGraphicsView::RecordRedoLineAction(const QString &name, const QString &type, const int& itemID, const QLineF &oldLine) +{ + _redoStack.PushNewAction(LineAction(name,type,itemID,oldLine)); +} + +void jpsGraphicsView::UndoLineEdit(const int& lineID, const QLineF& old_line) +{ + for (jpsLineItem* lineItem:line_vector) + { + if (lineItem->get_id()==lineID) + { + RecordRedoLineAction("LineEdited",lineItem->GetType(),lineItem->get_id(),lineItem->get_line()->line()); + lineItem->get_line()->setLine(old_line); + break; + } + } +} + +void jpsGraphicsView::RedoLineEdit(const int &lineID, const QLineF &old_line) +{ + for (jpsLineItem* lineItem:line_vector) + { + if (lineItem->get_id()==lineID) + { + RecordUndoLineAction("LineEdited",lineItem->GetType(),lineItem->get_id(),lineItem->get_line()->line()); + lineItem->get_line()->setLine(old_line); + break; + } + } +} + +void jpsGraphicsView::Undo() +{ + if (!_undoStack.IsEmpty()) + { + const LineAction recentAction = _undoStack.GetRecentAction(); + + if (recentAction.GetName()=="LineDeleted") + { + addLineItem(recentAction.GetOldLine().p1().x(),recentAction.GetOldLine().p1().y(),recentAction.GetOldLine().p2().x(), + recentAction.GetOldLine().p2().y(),recentAction.GetType()); + + RecordRedoLineAction("LineAdded",recentAction.GetType(),id_counter-1,QLineF(0,0,0,0)); + } + else if (recentAction.GetName()=="LineAdded") + { + RecordRedoLineAction("LineDeleted",line_vector.back()->GetType(),line_vector.back()->get_id(), + line_vector.back()->get_line()->line()); + RemoveLineItem(line_vector.back()); + } + else if (recentAction.GetName()=="LineEdited") + { + UndoLineEdit(recentAction.GetItemID(),recentAction.GetOldLine()); + } + } + +} + +void jpsGraphicsView::Redo() +{ + if (!_redoStack.IsEmpty()) + { + const LineAction recentAction = _redoStack.GetRecentAction(); + + if (recentAction.GetName()=="LineDeleted") + { + addLineItem(recentAction.GetOldLine().p1().x(),recentAction.GetOldLine().p1().y(),recentAction.GetOldLine().p2().x(), + recentAction.GetOldLine().p2().y(),recentAction.GetType()); + + RecordUndoLineAction("LineAdded",recentAction.GetType(),id_counter-1,QLineF(0,0,0,0)); + } + + else if (recentAction.GetName()=="LineAdded") + { + RecordUndoLineAction("LineDeleted",line_vector.back()->GetType(),line_vector.back()->get_id(), + line_vector.back()->get_line()->line()); + RemoveLineItem(line_vector.back()); + + } + else if (recentAction.GetName()=="LineEdited") + { + RedoLineEdit(recentAction.GetItemID(),recentAction.GetOldLine()); + + } + + + } +} + + +void jpsGraphicsView::line_collision() //FIX ME!!! { /// if no lines collided yet if (!lines_collided && current_line!=nullptr) @@ -891,84 +1189,15 @@ void jpsGraphicsView::line_collision() ///FIX ME!!! } } -void jpsGraphicsView::create_grid() /// FIX ME!!!! -{ - //QPointF sceneViewBottomLeft = mapToScene(QPoint(this->sceneRect().bottomLeft())); - //QPointF sceneViewTopRight = mapToScene(QPoint(this->sceneRect().topRight())); - //QRectF rect = this->sceneRect(); - //for (QGraphicsLineItem *gridpoint: grid_point_vector) - //{ - // delete gridpoint; - //} - grid_point_vector.clear(); - - //std::cout << rect.bottomRight().y() << std::endl; - - //QPointF leftdown = mapToScene(this->sceneRect().bottomLeft().x(),this->sceneRect().bottomLeft().y()); - - //QPointF leftup = mapToScene(Scene->sceneRect().bottomLeft().x(),Scene->sceneRect().bottomLeft().y()); - //std::cout << leftup.x()-translation_x << std::endl; - qreal rightx = translated_pos.x()+1920*gl_scale_f; - qreal upy = translated_pos.y()+1080*gl_scale_f; - qreal leftx = translated_pos.x()-1920*gl_scale_f; - qreal downy = translated_pos.y()-1080*gl_scale_f; - //QGraphicsEllipseItem* point = Scene->addEllipse(0,0,10,10,QPen(Qt::red)); - //point->setTransform(Scene->sceneRect().); - //point->setTransform(QTransform::fromTranslate(translation_x,translation_y)); - //grid_point_vector.push_back(point); - //std::cout << translation_y << std::endl; - //std::cout << this->height() << std::endl; - //qreal leftdownx = leftdown.x();//+translation_x; - //qreal leftdowny = leftdown.y();//+translation_y; - - //QPointF topRight = mapToScene(this->sceneRect().topRight().x(),this->sceneRect().topRight().y()); - //qreal rightupx = topRight.x();//+translation_x; - //qreal rightupy = topRight.y();//+translation_y; - - //std::cout << rightupx << std::endl; - //std::cout << rightupy << std::endl; - int intervall=100*gl_scale_f; - int ileftx = leftx/intervall; - ileftx*=intervall; - int idowny = downy/intervall; - idowny*=intervall; - //int ileftdowny = std::floor(leftdowny); - //int irightupx = std::floor(rightupx); - //int irightupy = std::floor(rightupy); - //std::cout << ileftupx << std::endl; - //std::cout << rightdownx << std::endl; - //QGraphicsTextItem* point = Scene->addText("Hallo Welt"); - //point->setX(ileftupx); - //point->setY(ileftupy); - //std::cout << ileftdownx << std::endl; - //std::cout << irightupy << std::endl; - - for (int i=ileftx; iaddLine(i,j-5*gl_scale_f,i,j+5*gl_scale_f,QPen(Qt::red,0)); - line1->setTransform(QTransform::fromTranslate(translation_x,translation_y), true); - grid_point_vector.push_back(line1); - QGraphicsLineItem* line2 = Scene->addLine(i-5*gl_scale_f,j,i+5*gl_scale_f,j,QPen(Qt::red,0)); - line2->setTransform(QTransform::fromTranslate(translation_x,translation_y), true); - grid_point_vector.push_back(line2); - */ - QPointF gridpoint(i,j); - grid_point_vector.push_back(gridpoint); - } - } - - //std::cout << leftup-translation_x << std::endl; -} void jpsGraphicsView::zoom(int delta) { setTransformationAnchor(QGraphicsView::AnchorUnderMouse); + //exclude origin from scaling + ShowOrigin(); + // Scale the view / do the zoom double scaleFactor = 1.15; if(delta > 0) @@ -979,23 +1208,30 @@ void jpsGraphicsView::zoom(int delta) // { // caption_list[i]->setTransform(QTransform::fromScale(1/gl_scale_f,1/gl_scale_f)); //} + _scaleFactor*=1/1.15; gl_scale_f*=1/1.15; scale(scaleFactor, scaleFactor); catch_radius=10*gl_scale_f; catch_line_distance=10*gl_scale_f; + Scene->ChangeGridSize(this->CalcGridSize()); //create_grid(); } else { // Zooming out + _scaleFactor*=1.15; gl_scale_f*=1.15; scale(1.0 / scaleFactor, 1.0 / scaleFactor); catch_radius=10*gl_scale_f; catch_line_distance=10*gl_scale_f; + Scene->ChangeGridSize(this->CalcGridSize()); //create_grid(); } + //set origin back to the scene + ShowOrigin(); + } void jpsGraphicsView::translations(QPointF old_pos) @@ -1003,6 +1239,9 @@ void jpsGraphicsView::translations(QPointF old_pos) translation_x+=pos.x()-old_pos.x(); translation_y+=pos.y()-old_pos.y(); + /// translate the background grid + Scene->ChangeTranslation(translation_x,translation_y); + if (current_line!=nullptr) { //current_line->translate(pos.x()-old_pos.x(),pos.y()-old_pos.y()); @@ -1019,6 +1258,11 @@ void jpsGraphicsView::translations(QPointF old_pos) for (int i=0; iget_line()->translate(pos.x()-old_pos.x(),pos.y()-old_pos.y()); + /// To avoid double sized translation of edited line + if (current_line==line_vector[i]->get_line()) + { + continue; + } line_vector[i]->get_line()->setTransform(QTransform::fromTranslate(pos.x()-old_pos.x(),pos.y()-old_pos.y()), true); } @@ -1031,13 +1275,13 @@ void jpsGraphicsView::translations(QPointF old_pos) caption_list[i]->setTransform(QTransform::fromScale(scalef,scalef),true); } - for (int i=0; iget_line()->translate(pos.x()-old_pos.x(),pos.y()-old_pos.y()); - //grid_point_vector[i]->setTransform(QTransform::fromTranslate(pos.x()-old_pos.x(),pos.y()-old_pos.y()), true); - grid_point_vector[i].setX(pos.x()); - grid_point_vector[i].setY(pos.y()); - } +// for (int i=0; iget_line()->translate(pos.x()-old_pos.x(),pos.y()-old_pos.y()); +// //grid_point_vector[i]->setTransform(QTransform::fromTranslate(pos.x()-old_pos.x(),pos.y()-old_pos.y()), true); +// grid_point_vector[i].setX(pos.x()); +// grid_point_vector[i].setY(pos.y()); +// } for (jpsLandmark* landmark:LLandmarks) { @@ -1048,11 +1292,35 @@ void jpsGraphicsView::translations(QPointF old_pos) { currentLandmarkRect->setTransform(QTransform::fromTranslate(pos.x()-old_pos.x(),pos.y()-old_pos.y()), true); } + if (gridmap!=nullptr) + { + gridmap->setTransform(QTransform::fromTranslate(pos.x()-old_pos.x(),pos.y()-old_pos.y()), true); + } for (QGraphicsEllipseItem* ellipse:_waypoints) { ellipse->setTransform(QTransform::fromTranslate(pos.x()-old_pos.x(),pos.y()-old_pos.y()), true); } + for (QGraphicsLineItem* lineItem:_yahPointer) + { + lineItem->setTransform(QTransform::fromTranslate(pos.x()-old_pos.x(),pos.y()-old_pos.y()), true); + } + for (QGraphicsTextItem* item:_waypointLabels) + { + qreal scalef = item->data(0).toReal(); + item->setTransform(QTransform::fromScale(1.0/scalef,1.0/scalef),true); // without this line translations won't work + item->setTransform(QTransform::fromTranslate(pos.x()-old_pos.x(),-pos.y()+old_pos.y()), true); + item->setTransform(QTransform::fromScale(scalef,scalef),true); + } + + for (QGraphicsLineItem* lineItem:_connections) + { + lineItem->setTransform(QTransform::fromTranslate(pos.x()-old_pos.x(),pos.y()-old_pos.y()), true); + } + for (QGraphicsLineItem* lineItem:_origin) + { + lineItem->setTransform(QTransform::fromTranslate(pos.x()-old_pos.x(),pos.y()-old_pos.y()), true); + } } void jpsGraphicsView::AutoZoom() @@ -1063,8 +1331,8 @@ void jpsGraphicsView::AutoZoom() line_vector[0]->get_line()->line().p1().y()); for (jpsLineItem* line:line_vector) { - ///x - ///p1 + //x + //p1 if (line->get_line()->line().p1().x()get_line()->line().p1().x()); @@ -1074,7 +1342,7 @@ void jpsGraphicsView::AutoZoom() max.setX(line->get_line()->line().p1().x()); } - ///p2 + //p2 if (line->get_line()->line().p2().x()get_line()->line().p2().x()); @@ -1084,8 +1352,8 @@ void jpsGraphicsView::AutoZoom() max.setX(line->get_line()->line().p2().x()); } - ///y - ///p1 + //y + //p1 if (line->get_line()->line().p1().y()get_line()->line().p1().y()); @@ -1108,17 +1376,17 @@ void jpsGraphicsView::AutoZoom() //QPointF center((min.x()+max.x())/2.0,(min.y()+max.y())/2.0); - ///scaling + //scaling qreal width = (max.x()-min.x()); qreal height = (max.y()-min.y()); - /// To ensure the functionality of fitInView + // To ensure the functionality of fitInView this->setSceneRect(min.x(),min.y(),width,height); this->fitInView(min.x(),min.y(),width,height,Qt::KeepAspectRatio); - ///adapting gl_scale_f + //adapting gl_scale_f gl_scale_f=1/this->transform().m11(); - ///translations + //translations QPointF old_pos; old_pos.setX(pos.x()+translation_x); old_pos.setY(pos.y()+translation_y); @@ -1126,6 +1394,66 @@ void jpsGraphicsView::AutoZoom() } +qreal jpsGraphicsView::CalcGridSize() +{ + int cFactor; + if (_scaleFactor<1.0) + { + cFactor = std::round(1/_scaleFactor);//std::round(_scaleFactor); + } + else + cFactor = std::round(_scaleFactor); + + int n=0; + while (cFactor>std::pow(2,n)) + { + n++; + } + qreal gridSize; + if (_scaleFactor<1.0) + gridSize=1/std::pow(2,n); + else + gridSize=std::pow(2,n); + + _gridSize=gridSize; + return gridSize; + +} + +void jpsGraphicsView::ShowOrigin() +{ + if (_origin.isEmpty()) + { + //Scene->DrawOrigin(); + _origin.push_back(Scene->addLine(0,0,0,0+gl_scale_f*100,QPen(Qt::black,gl_scale_f*2))); + _origin.push_back(Scene->addLine(0,0+gl_scale_f*100,0-gl_scale_f*10,0+gl_scale_f*100-gl_scale_f*10,QPen(Qt::black,gl_scale_f*2))); + _origin.push_back(Scene->addLine(0,0+gl_scale_f*100,0+gl_scale_f*10,0+gl_scale_f*100-gl_scale_f*10,QPen(Qt::black,gl_scale_f*2))); + _origin.push_back(Scene->addLine(0,0,0+gl_scale_f*100,0,QPen(Qt::black,gl_scale_f*2))); + _origin.push_back(Scene->addLine(0+gl_scale_f*100,0,gl_scale_f*100-gl_scale_f*10,-gl_scale_f*10,QPen(Qt::black,gl_scale_f*2))); + _origin.push_back(Scene->addLine(0+gl_scale_f*100,0,gl_scale_f*100-gl_scale_f*10,+gl_scale_f*10,QPen(Qt::black,gl_scale_f*2))); + //Y + _origin.push_back(Scene->addLine(0-gl_scale_f*10,gl_scale_f*100-gl_scale_f*50,0-gl_scale_f*5,gl_scale_f*100-gl_scale_f*45,QPen(Qt::black,gl_scale_f*2))); + _origin.push_back(Scene->addLine(0-gl_scale_f*10,gl_scale_f*100-gl_scale_f*50,0-gl_scale_f*15,gl_scale_f*100-gl_scale_f*45,QPen(Qt::black,gl_scale_f*2))); + _origin.push_back(Scene->addLine(0-gl_scale_f*10,gl_scale_f*100-gl_scale_f*50,0-gl_scale_f*10,gl_scale_f*100-gl_scale_f*60,QPen(Qt::black,gl_scale_f*2))); + //X + _origin.push_back(Scene->addLine(0+gl_scale_f*40,0-gl_scale_f*15,gl_scale_f*50,-gl_scale_f*5,QPen(Qt::black,gl_scale_f*2))); + _origin.push_back(Scene->addLine(0+gl_scale_f*40,0-gl_scale_f*5,gl_scale_f*50,-gl_scale_f*15,QPen(Qt::black,gl_scale_f*2))); + + for (QGraphicsLineItem* lineItem:_origin) + { + lineItem->setTransform(QTransform::fromTranslate(translation_x,translation_y), true); + } + } + else + { + for (QGraphicsLineItem* line:_origin) + { + delete line; + } + _origin.clear(); + } +} + void jpsGraphicsView::StatAssoDef() { _assoDef=!_assoDef; @@ -1152,9 +1480,6 @@ qreal jpsGraphicsView::calc_d_point(const QLineF &line,const qreal &x, const qre } - - - // Delete single line void jpsGraphicsView::delete_marked_lines() @@ -1166,30 +1491,10 @@ void jpsGraphicsView::delete_marked_lines() for (int i=0; i points = marked_lines[i]->get_intersectionVector(); - - for (int j=0; jget_intersectLineVector().size(); ++k) - { - // removing the intersectionPoint pointer from all lines which includes the point - marked_lines[i]->get_intersectLineVector()[k]->remove_intersectionPoint(points[j]); - - // as marked_lines is removed it is has no intersections with any other line anymore - // so pointers of possible intersectionsLine have to be removed - - } + RecordUndoLineAction("LineDeleted",marked_lines[i]->GetType(),marked_lines[i]->get_id(),marked_lines[i]->get_line()->line()); - } - - - for (int k=0; kget_intersectLineVector().size(); ++k) - { - marked_lines[i]->get_intersectLineVector()[k]->remove_interLine(marked_lines[i]); - } + RemoveIntersections(marked_lines[i]); delete marked_lines[i]->get_line(); @@ -1198,7 +1503,9 @@ void jpsGraphicsView::delete_marked_lines() line_vector.removeOne(marked_lines[i]); + } + marked_lines.clear(); //intersect_point_vector.clear(); @@ -1209,6 +1516,65 @@ void jpsGraphicsView::delete_marked_lines() } +void jpsGraphicsView::RemoveLineItem(jpsLineItem *mline) +{ + RemoveIntersections(mline); + line_vector.removeOne(mline); + delete mline->get_line(); + delete mline; + emit lines_deleted(); + +} + +void jpsGraphicsView::RemoveLineItem(const QLineF &line) +{ + for (jpsLineItem* lineItem:line_vector) + { + if (lineItem->get_line()->line()==line) + { + unmark_all_lines(); + select_line(lineItem); + delete_marked_lines(); + } + } + +} + +void jpsGraphicsView::RemoveIntersections(jpsLineItem *lineItem) +{ + QList points = lineItem->get_intersectionVector(); + + for (int j=0; jget_intersectLineVector().size(); ++k) + { + // removing the intersectionPoint pointer from all lines which includes the point + lineItem->get_intersectLineVector()[k]->remove_intersectionPoint(points[j]); + + // as marked_lines is removed it has no intersections with any other line anymore + // so pointers of possible intersectionsLine have to be removed + + } + } + + + for (int k=0; kget_intersectLineVector().size(); ++k) + { + lineItem->get_intersectLineVector()[k]->remove_interLine(lineItem); + } +} + +void jpsGraphicsView::SelectAllLines() +{ + marked_lines.clear(); + for (jpsLineItem* line:line_vector) + { + select_line(line); + } +} + void jpsGraphicsView::delete_landmark() { if (markedLandmark!=nullptr) @@ -1254,6 +1620,8 @@ void jpsGraphicsView::take_l_from_lineEdit(const qreal &length) line.setLength(length); current_line->setLine(line); jpsLineItem* jpsline = new jpsLineItem(current_line); + jpsline->set_id(id_counter); + id_counter++; jpsline->set_type(statWall,statDoor,statExit); line_vector.push_back(jpsline); current_line=nullptr; @@ -1306,11 +1674,19 @@ bool jpsGraphicsView::get_objectsnap() return objectsnap; } +void jpsGraphicsView::change_gridmode() +{ + _gridmode=!_gridmode; + Scene->ChangeGridmode(_gridmode); + Scene->update(); +} + void jpsGraphicsView::en_disableWall() { statWall=!statWall; statDoor=false; statExit=false; + _statHLine=false; statLandmark=false; if (statWall==false) { @@ -1328,14 +1704,14 @@ bool jpsGraphicsView::statusWall() return statWall; } -void jpsGraphicsView::change_gridmode() +void jpsGraphicsView::change_stat_anglesnap() { - gridmode=!gridmode; + anglesnap=!anglesnap; } -bool jpsGraphicsView::get_gridmode() +bool jpsGraphicsView::get_stat_anglesnap() { - return gridmode; + return anglesnap; } void jpsGraphicsView::en_disableDoor() @@ -1344,6 +1720,7 @@ void jpsGraphicsView::en_disableDoor() statExit=false; statWall=false; statLandmark=false; + _statHLine=false; if (statDoor==false) { emit no_drawing(); @@ -1365,6 +1742,7 @@ void jpsGraphicsView::en_disableExit() statExit=!statExit; statDoor=false; statWall=false; + _statHLine=false; statLandmark=false; if (statExit==false) { @@ -1376,6 +1754,28 @@ void jpsGraphicsView::en_disableExit() } } +bool jpsGraphicsView::statusHLine() +{ + return _statHLine; +} + +void jpsGraphicsView::en_disableHLine() +{ + _statHLine=!_statHLine; + statExit=false; + statDoor=false; + statWall=false; + statLandmark=false; + if (_statHLine==false) + { + emit no_drawing(); + } + else + { + currentPen.setColor(Qt::darkCyan); + } +} + bool jpsGraphicsView::statusLandmark() { return statLandmark; diff --git a/src/GraphicView.h b/src/GraphicView.h index 6e2d468..e72eb84 100644 --- a/src/GraphicView.h +++ b/src/GraphicView.h @@ -30,97 +30,130 @@ #include -#include +//#include +#include "graphicscene.h" #include #include "jpsLineItem.h" #include "jpslandmark.h" +#include "jpsconnection.h" +#include "./UndoFramework/actionstack.h" +using ptrConnection = std::shared_ptr; class jpsGraphicsView: public QGraphicsView { Q_OBJECT public: - ///Constructor + //Constructor jpsGraphicsView(QWidget* parent = nullptr); - ///Destructor + //Destructor ~jpsGraphicsView(); - ///Change modes - void change_gridmode(); - bool get_gridmode(); - bool use_gridmode(QGraphicsLineItem *currentline, int accuracy); + //Change modes + void change_stat_anglesnap(); + bool get_stat_anglesnap(); void change_objectsnap(); bool get_objectsnap(); + void change_gridmode(); bool statusWall(); void en_disableWall(); bool statusDoor(); void en_disableDoor(); bool statusExit(); void en_disableExit(); + bool statusHLine(); + void en_disableHLine(); bool statusLandmark(); void en_disableLandmark(); - ///Pos + // global functions + qreal get_scale_f(); + void take_l_from_lineEdit(const qreal &length); + void disable_drawing(); + bool use_anglesnap(QGraphicsLineItem *currentline, int accuracy); + void use_gridmode(); + + //View + void zoom(int delta); + void translations(QPointF old_pos); + void AutoZoom(); + qreal CalcGridSize(); + void ShowOrigin(); + + //Pos QPointF return_Pos(); - ///Catch points + //Catch lines, points and intersections void catch_points(); + void locate_intersection(jpsLineItem* item1, jpsLineItem* item2); + void line_collision(); + void catch_lines(); - ///Delete all + //Delete all void delete_all(bool final=false); - ///Line operations - void catch_lines(); + //Line operations void drawLine(); qreal calc_d_point(const QLineF &line, const qreal &x, const qreal &y); void delete_marked_lines(); + void RemoveLineItem(jpsLineItem *mline); + void RemoveLineItem(const QLineF &line); + void RemoveIntersections(jpsLineItem* lineItem); + // lines read from dxf-file + jpsLineItem *addLineItem(const qreal &x1, const qreal &y1, const qreal &x2, const qreal &y2, const QString &type=""); + jpsLineItem *addLineItem(const QLineF &line, const QString &type=""); + QList get_markedLines(); + QList get_line_vector(); + void unmark_all_lines(); + void select_line(jpsLineItem *mline); + void SetVLine(); + void EditLine(QPointF* point); + qreal ReturnLineLength(); - /// Landmark + // Landmark void delete_landmark(); void catch_landmark(); void select_landmark(jpsLandmark *landmark); void addLandmark(); - void unmarkLandmark(); + // unmark Landmarks see slots QList get_landmarks(); - ///Waypoints + //Waypoints/Connections and YAHPointer QGraphicsRectItem* GetCurrentSelectRect(); - void ShowWaypoints(QList waypoints); - - - /// Lines - void take_l_from_lineEdit(const qreal &length); - QList get_markedLines(); - QList get_line_vector(); - qreal get_scale_f(); - void unmark_all_lines(); - void select_line(jpsLineItem *mline); - void disable_drawing(); - jpsLineItem *addLineItem(const qreal &x1, const qreal &y1, const qreal &x2, const qreal &y2, const QString &type=""); - void locate_intersection(jpsLineItem* item1, jpsLineItem* item2); - void SetVLine(); - void EditLine(QPointF* point); + void ShowWaypoints(QList waypoints); + void ShowYAHPointer(const QPointF& pos, const qreal& dir); + void ClearWaypointLabels(); + void ShowConnections(QList cons); + void ClearConnections(); - ///RoomCaption + //RoomCaption bool show_hide_roomCaption(QString name, qreal x, qreal y); - void line_collision(); - void create_grid(); - - ///View - void zoom(int delta); - void translations(QPointF old_pos); - void AutoZoom(); + //Undo Framework + void RecordUndoLineAction(const QString &name, const QString &type, const int &itemID, const QLineF &oldLine); + void RecordRedoLineAction(const QString &name, const QString &type, const int &itemID, const QLineF &oldLine); + void UndoLineEdit(const int &lineID, const QLineF &old_line); + void RedoLineEdit(const int &lineID, const QLineF &old_line); public slots: - ///Waypoints + //Waypoints void StatAssoDef(); void ClearWaypoints(); - + //GridSettings + void ActivateLineGrid(); + void ActivatePointGrid(); + //Landmarks + void unmarkLandmark(); + //Line operations + void SelectAllLines(); + //Undo Redo + void Undo(); + void Redo(); protected: + //Mouse events virtual void mouseMoveEvent(QMouseEvent * mouseEvent); //void paintEvent(QPaintEvent* event); virtual void mousePressEvent(QMouseEvent *event); @@ -130,27 +163,31 @@ public slots: private: QGraphicsLineItem* current_line; + QPolygonF polygon; //std::vector line_vector; QList intersect_point_vector; - QList grid_point_vector; + //QList grid_point_vector; QList line_vector; - QList origin; + QList _origin; //QList *> mainlist; QPointF pos; //QPointF* intersection_point; - QGraphicsScene* Scene; + GraphicScene* Scene; bool midbutton_hold; bool leftbutton_hold; qreal translation_x; qreal translation_y; QPointF translated_pos; - bool gridmode; + bool anglesnap; bool statWall; bool statDoor; bool statExit; bool statLandmark; + bool _statHLine; qreal catch_radius; + qreal _scaleFactor; qreal gl_scale_f; + qreal _gridSize; bool point_tracked; QGraphicsItem* current_rect; QGraphicsRectItem* currentSelectRect; @@ -162,20 +199,29 @@ public slots: QList marked_lines; QGraphicsTextItem* current_caption; QList caption_list; + int id_counter; + + //Landmark and waypoints QList LLandmarks; jpsLandmark* markedLandmark; QGraphicsRectItem* currentLandmarkRect; QList _waypoints; + QList _connections; + QList _yahPointer; + QList _waypointLabels; + QGraphicsLineItem* _currentVLine; QPointF* _currentTrackedPoint; - + QGraphicsPixmapItem* gridmap; bool _statLineEdit; - bool lines_collided; bool _assoDef; + bool _gridmode; + + //Undo/Redo + ActionStack _undoStack; + ActionStack _redoStack; - //qreal gl_min_x; - //qreal gl_min_y; signals: void mouse_moved(); @@ -186,11 +232,9 @@ public slots: void remove_all(); void landmark_added(); void AssoDefCompleted(); + void LineLengthChanged(); //void DoubleClick(); - - - }; diff --git a/src/UndoFramework/action.cpp b/src/UndoFramework/action.cpp new file mode 100644 index 0000000..43f7b4b --- /dev/null +++ b/src/UndoFramework/action.cpp @@ -0,0 +1,30 @@ +#include "action.h" + +Action::Action() +{ + +} + +Action::Action(const QString &name, const QString &type) +{ + _name=name; + _type=type; + + +} + +Action::~Action() +{ + +} + +const QString &Action::GetName() const +{ + return _name; + +} + +const QString &Action::GetType() const +{ + return _type; +} diff --git a/src/UndoFramework/action.h b/src/UndoFramework/action.h new file mode 100644 index 0000000..c38c6d6 --- /dev/null +++ b/src/UndoFramework/action.h @@ -0,0 +1,23 @@ +#ifndef ACTION_H +#define ACTION_H +#include + +class Action +{ +public: + Action(); + Action(const QString& name, const QString& type); + ~Action(); + //Getter + const QString& GetName() const; + const QString& GetType() const; + + +private: + QString _name; + QString _type; + + +}; + +#endif // ACTION_H diff --git a/src/UndoFramework/actionstack.cpp b/src/UndoFramework/actionstack.cpp new file mode 100644 index 0000000..84bf454 --- /dev/null +++ b/src/UndoFramework/actionstack.cpp @@ -0,0 +1,28 @@ +#include "actionstack.h" + +ActionStack::ActionStack() +{ + +} + +ActionStack::~ActionStack() +{ + +} + +LineAction ActionStack::GetRecentAction() +{ + return _actionstack.pop(); +} + +void ActionStack::PushNewAction(const LineAction &action) +{ + _actionstack.push_back(action); + +} + +bool ActionStack::IsEmpty() +{ + return _actionstack.isEmpty(); +} + diff --git a/src/UndoFramework/actionstack.h b/src/UndoFramework/actionstack.h new file mode 100644 index 0000000..364f7f5 --- /dev/null +++ b/src/UndoFramework/actionstack.h @@ -0,0 +1,21 @@ +#ifndef ACTIONSTACK_H +#define ACTIONSTACK_H + +#include +#include "action.h" +#include "lineaction.h" + +class ActionStack +{ +public: + ActionStack(); + ~ActionStack(); + + LineAction GetRecentAction(); + void PushNewAction(const LineAction& action); + bool IsEmpty(); +private: + QStack _actionstack; +}; + +#endif // ACTIONSTACK_H diff --git a/src/UndoFramework/lineaction.cpp b/src/UndoFramework/lineaction.cpp new file mode 100644 index 0000000..9bc9523 --- /dev/null +++ b/src/UndoFramework/lineaction.cpp @@ -0,0 +1,28 @@ +#include "lineaction.h" + +LineAction::LineAction() +{ + +} + +LineAction::LineAction(const QString &name, const QString &type, const int &itemID, const QLineF &oldLine) : Action(name,type) +{ + _oldLine=oldLine; + _itemID=itemID; +} + +LineAction::~LineAction() +{ + +} + +QLineF LineAction::GetOldLine() const +{ + return _oldLine; +} + +int LineAction::GetItemID() const +{ + return _itemID; +} + diff --git a/src/UndoFramework/lineaction.h b/src/UndoFramework/lineaction.h new file mode 100644 index 0000000..e61f266 --- /dev/null +++ b/src/UndoFramework/lineaction.h @@ -0,0 +1,21 @@ +#ifndef LINEACTION_H +#define LINEACTION_H + +#include "action.h" +#include + +class LineAction : public Action +{ +public: + LineAction(); + LineAction(const QString& name, const QString& type, const int& itemID, const QLineF& oldLine); + ~LineAction(); + + QLineF GetOldLine() const; + int GetItemID() const; +private: + QLineF _oldLine; + int _itemID; +}; + +#endif // PAINTACTION_H diff --git a/src/datamanager.cpp b/src/datamanager.cpp index 45ed66c..5f35521 100644 --- a/src/datamanager.cpp +++ b/src/datamanager.cpp @@ -29,6 +29,7 @@ #include "datamanager.h" #include +#include @@ -38,6 +39,8 @@ jpsDatamanager::jpsDatamanager(QWidget *parent, jpsGraphicsView *view) mView=view; room_id_counter=0; obs_id_counter=0; + _yahPointer=nullptr; + _frameRate=0; } @@ -57,8 +60,14 @@ void jpsDatamanager::remove_room(jpsRoom *room) { //if (roomlist.size()>0) //{ + int roomID=room->get_id(); roomlist.removeOne(room); delete room; + //change IDs of other room with ID greater than roomID + for (jpsRoom* otherroom:roomlist) + if (otherroom->get_id()>roomID) + otherroom->set_id(otherroom->get_id()-1); + room_id_counter-=1; //} } @@ -257,9 +266,9 @@ void jpsDatamanager::writeXML(QFile &file) exitList.clear(); stream->writeEndElement();//transitions - //stream->writeStartElement("landmarks"); - //writeLandmarks(stream,landmarks); - //stream->writeEndElement();//landmarks + stream->writeStartElement("landmarks"); + writeLandmarks(stream,landmarks); + stream->writeEndElement();//landmarks stream->writeEndElement();//geometry @@ -268,6 +277,32 @@ void jpsDatamanager::writeXML(QFile &file) delete stream; } +void jpsDatamanager::writeRoutingXML(QFile &file) // Construction side +{ + QXmlStreamWriter* stream = new QXmlStreamWriter(&file); + QList hLines; + + for (jpsLineItem* line:mView->get_line_vector()) + { + if (line->IsHLine()) + { + hLines.push_back(line); + } + } + + + writeRoutingHeader(stream); + + stream->writeStartElement("Hlines"); + writeHLines(stream,hLines); + stream->writeEndElement();//Hlines + + stream->writeEndDocument(); + + delete stream; + +} + void jpsDatamanager::AutoSaveXML(QFile &file) { QXmlStreamWriter* stream = new QXmlStreamWriter(&file); @@ -284,9 +319,9 @@ void jpsDatamanager::AutoSaveXML(QFile &file) exitList.clear(); stream->writeEndElement();//transitions - //stream->writeStartElement("landmarks"); - //writeLandmarks(stream,landmarks); - //stream->writeEndElement();//landmarks + stream->writeStartElement("landmarks"); + writeLandmarks(stream,landmarks); + stream->writeEndElement();//landmarks stream->writeEndElement();//geometry @@ -301,13 +336,91 @@ void jpsDatamanager::writeHeader(QXmlStreamWriter *stream) stream->writeStartDocument("1.0",true); stream->writeStartElement("geometry"); - stream->writeAttribute("version", "0.5"); + stream->writeAttribute("version", "0.8"); stream->writeAttribute("caption","corner"); stream->writeAttribute("xmlns:xsi","http://www.w3.org/2001/XMLSchema-instance"); stream->writeAttribute("xsi:noNamespaceSchemaLocation","http://xsd.jupedsim.org/jps_geometry.xsd"); stream->writeAttribute("unit","m"); } +void jpsDatamanager::writeRoutingHeader(QXmlStreamWriter *stream) +{ + stream->setAutoFormatting(true); + stream->writeStartDocument("1.0",true); + + stream->writeStartElement("routing"); + stream->writeAttribute("version", "0.8"); + //stream->writeAttribute("caption","corner"); + stream->writeAttribute("xmlns:xsi","http://www.w3.org/2001/XMLSchema-instance"); + stream->writeAttribute("xsi:noNamespaceSchemaLocation","http://xsd.jupedsim.org/jps_routing.xsd"); + stream->writeAttribute("unit","m"); +} + +void jpsDatamanager::writeHLines(QXmlStreamWriter *stream, QList &hLines) +{ + // to be sure that id is unique (considering crossings, transitions) + int id=1000; + for (jpsLineItem *lineItem:hLines) + { + stream->writeStartElement("Hline"); + stream->writeAttribute("id",QString::number(id)); + stream->writeAttribute("room_id","0"); + QString rid = RoomIDHLine(lineItem); + if (rid.contains("Warning")) + { + QMessageBox::critical(mView, + "WriteHLines", + rid, + QMessageBox::Ok); + } + stream->writeAttribute("subroom_id",rid); + + //Vertices + stream->writeStartElement("vertex"); + stream->writeAttribute("px",QString::number(lineItem->get_line()->line().p1().x())); + stream->writeAttribute("py",QString::number(lineItem->get_line()->line().p1().y())); + stream->writeEndElement(); //vertex + + stream->writeStartElement("vertex"); + stream->writeAttribute("px",QString::number(lineItem->get_line()->line().p2().x())); + stream->writeAttribute("py",QString::number(lineItem->get_line()->line().p2().y())); + stream->writeEndElement(); //vertex + + stream->writeEndElement(); //Hline + id++; + } +} + +QString jpsDatamanager::RoomIDHLine(jpsLineItem *lineItem) +{ + + for (jpsRoom* room:roomlist) + { + QPolygonF rPolygon = room->RoomAsSortedPolygon(); + if (rPolygon.containsPoint(lineItem->get_line()->line().p1(),Qt::OddEvenFill) || + rPolygon.contains(lineItem->get_line()->line().p1())) + { + if (rPolygon.containsPoint(lineItem->get_line()->line().p2(),Qt::OddEvenFill)|| + rPolygon.contains(lineItem->get_line()->line().p2())) + return QString::number(room->get_id()); + else + return "Warning! HLine intersects walls"; + } +// else if (rPolygon.containsPoint(lineItem->get_line()->line().p2(),Qt::OddEvenFill)|| +// rPolygon.contains(lineItem->get_line()->line().p2())) +// { +// if (rPolygon.containsPoint(lineItem->get_line()->line().p1(),Qt::OddEvenFill)|| +// rPolygon.contains(lineItem->get_line()->line().p1())) +// return QString::number(room->get_id()); +// else +// return "Warning! HLine intersects walls"; +// } + + } + return "Warning! HLine outside geometry"; + +} + void jpsDatamanager::writeRooms(QXmlStreamWriter *stream, QList &lines) { ///rooms @@ -320,7 +433,7 @@ void jpsDatamanager::writeRooms(QXmlStreamWriter *stream, QList & stream->writeStartElement("subroom"); stream->writeAttribute("id",QString::number(roomlist[i]->get_id())); stream->writeAttribute("caption",roomlist[i]->get_name()); - stream->writeAttribute("class","subroom"); + stream->writeAttribute("class",roomlist[i]->get_type()); //walls QList wallList=roomlist[i]->get_listWalls(); @@ -356,7 +469,7 @@ void jpsDatamanager::writeRooms(QXmlStreamWriter *stream, QList & } - ///Crossings + //Crossings writeCrossings(stream,lines); stream->writeEndElement();//crossings @@ -666,8 +779,8 @@ void jpsDatamanager::writeLandmarks(QXmlStreamWriter *stream, QListwriteAttribute("px",QString::number(landmark->get_pos().x())); stream->writeAttribute("py",QString::number(landmark->get_pos().y())); stream->writeStartElement("associations"); - m=0; - for (jpsWaypoint* waypoint:landmark->GetWaypoints()) + + for (ptrWaypoint waypoint:landmark->GetWaypoints()) { stream->writeStartElement("association"); stream->writeAttribute("id",QString::number(m)); @@ -747,29 +860,29 @@ jpsGraphicsView * jpsDatamanager::get_view() return mView; } -void jpsDatamanager::AutoAssignCrossings() -{ - QList crossings = crossingList; +//void jpsDatamanager::AutoAssignCrossings() +//{ +// QList crossings = crossingList; - for (jpsCrossing *crossing: crossings) - { - int roomCounter=0; - for (jpsRoom *room : roomlist) - { - if (room->ContainsDoor(crossing->get_cLine()) && roomCounter==0) - { - crossing->add_rooms(room); - roomCounter++; +// for (jpsCrossing *crossing: crossings) +// { +// int roomCounter=0; +// for (jpsRoom *room : roomlist) +// { +// if (room->ContainsDoor(crossing->get_cLine()) && roomCounter==0) +// { +// crossing->add_rooms(room); +// roomCounter++; - } - else if (room->ContainsDoor(crossing->get_cLine()) && roomCounter==1) - { - crossing->add_rooms(crossing->get_roomList()[0],room); - crossings.removeOne(crossing); - break; - } - } - } +// } +// else if (room->ContainsDoor(crossing->get_cLine()) && roomCounter==1) +// { +// crossing->add_rooms(crossing->get_roomList()[0],room); +// crossings.removeOne(crossing); +// break; +// } +// } +// } @@ -813,44 +926,52 @@ void jpsDatamanager::AutoAssignCrossings() -} +//} -void jpsDatamanager::AutoAssignExits() -{ - for (jpsExit *exit: exitList) - { - for (jpsRoom *room: roomlist) - { - QList walls = room->get_listWalls(); +//void jpsDatamanager::AutoAssignExits() +//{ +// for (jpsExit *exit: exitList) +// { +// for (jpsRoom *room: roomlist) +// { +// QList walls = room->get_listWalls(); - int pointCounter = 0; +// int pointCounter = 0; - for (jpsLineItem* wall: walls) - { - if (wall->get_line()->line().p1()==exit->get_cLine()->get_line()->line().p1() || - wall->get_line()->line().p1()==exit->get_cLine()->get_line()->line().p2() || - wall->get_line()->line().p2()==exit->get_cLine()->get_line()->line().p1() || - wall->get_line()->line().p2()==exit->get_cLine()->get_line()->line().p2()) - { - pointCounter++; - } - } +// for (jpsLineItem* wall: walls) +// { +// if (wall->get_line()->line().p1()==exit->get_cLine()->get_line()->line().p1() || +// wall->get_line()->line().p1()==exit->get_cLine()->get_line()->line().p2() || +// wall->get_line()->line().p2()==exit->get_cLine()->get_line()->line().p1() || +// wall->get_line()->line().p2()==exit->get_cLine()->get_line()->line().p2()) +// { +// pointCounter++; +// } +// } - if (pointCounter==2) - { - exit->add_rooms(room); - break; - } - } - } +// if (pointCounter==2) +// { +// exit->add_rooms(room); +// break; +// } +// } +// } -} +//} bool jpsDatamanager::readXML(QFile &file) { QXmlStreamReader xmlReader(&file); + // skip header + xmlReader.readNext(); + xmlReader.readNext(); + + // see if file starts with geometry + if (xmlReader.name() != "geometry") + return false; + while(!xmlReader.atEnd() && !xmlReader.hasError()) { /* Read next element.*/ @@ -913,12 +1034,92 @@ bool jpsDatamanager::readXML(QFile &file) * and resets its internal state to the initial state. */ xmlReader.clear(); - ///AutoZoom to drawing - mView->AutoZoom(); + return true; +} + +bool jpsDatamanager::readRoutingXML(QFile &file) +{ + QXmlStreamReader xmlReader(&file); + + // skip header + xmlReader.readNext(); + xmlReader.readNext(); + + // see if file starts with geometry + if (xmlReader.name() != "routing") + return false; + + while(!xmlReader.atEnd() && !xmlReader.hasError()) + { + /* Read next element.*/ + QXmlStreamReader::TokenType token = xmlReader.readNext(); + /* If token is just StartDocument, we'll go to next.*/ + if(token == QXmlStreamReader::StartDocument) + { + continue; + } + + /* If token is StartElement, we'll see if we can read it.*/ + if(token == QXmlStreamReader::StartElement) + { + /* If it's named Hlines, we'll go to the next.*/ + if(xmlReader.name() == "Hlines") + { + continue; + } + + if(xmlReader.name() == "Hline") + { + this->parseHline(xmlReader); + } + } + } + /* Error handling. */ + if(xmlReader.hasError()) + { + QMessageBox::critical(mView, + "QXSRExample::parseXML", + xmlReader.errorString(), + QMessageBox::Ok); + return false; + } + /* Removes any device() or data from the reader + * and resets its internal state to the initial state. */ + xmlReader.clear(); return true; } +void jpsDatamanager::parseHline(QXmlStreamReader &xmlReader) +{ + + while(!(xmlReader.tokenType() == QXmlStreamReader::EndElement && + xmlReader.name() == "Hline")) + { + xmlReader.readNext(); + + if (xmlReader.tokenType()==QXmlStreamReader::StartElement && + xmlReader.name() == "vertex") + { + + // get coords from vertices + qreal x1=xmlReader.attributes().value("px").toString().toFloat(); + qreal y1=xmlReader.attributes().value("py").toString().toFloat(); + + // go to next vertex + xmlReader.readNext(); + xmlReader.readNext(); + xmlReader.readNext(); + + qreal x2=xmlReader.attributes().value("px").toString().toFloat(); + qreal y2=xmlReader.attributes().value("py").toString().toFloat(); + // add Line to graphview + mView->addLineItem(x1,y1,x2,y2,"HLine"); + } + + } +} + void jpsDatamanager::parseSubRoom(QXmlStreamReader &xmlReader) { // new subroom @@ -935,8 +1136,10 @@ void jpsDatamanager::parseSubRoom(QXmlStreamReader &xmlReader) if(attributes.hasAttribute("class")) { - /* We'll add it to the room. */ - roomlist.last()->set_type(attributes.value("class").toString()); + if (attributes.value("class").toString()=="subroom") + roomlist.last()->set_type("Not specified"); + else + roomlist.last()->set_type(attributes.value("class").toString()); } this->parseWalls(xmlReader,roomlist.last()); this->parseObstacles(xmlReader,roomlist.last()); @@ -1181,9 +1384,15 @@ bool jpsDatamanager::readDXF(std::string filename) void jpsDatamanager::addLine(const DL_LineData &d) { - - mView->addLineItem(d.x1,d.y1,d.x2,d.y2); - + DL_Attributes attributes = DL_CreationInterface::getAttributes(); + std::string layername = attributes.getLayer(); + std::transform(layername.begin(), layername.end(), layername.begin(), ::tolower); + if (layername=="wall") + mView->addLineItem(d.x1,d.y1,d.x2,d.y2,"Wall"); + else if (layername=="door") + mView->addLineItem(d.x1,d.y1,d.x2,d.y2,"Door"); + else + mView->addLineItem(d.x1,d.y1,d.x2,d.y2); } @@ -1441,6 +1650,269 @@ QString jpsDatamanager::check_printAbility() return ""; } +bool jpsDatamanager::ParseCogMap(QFile &file) +{ + QXmlStreamReader xmlReader(&file); + + while(!xmlReader.atEnd() && !xmlReader.hasError()) + { + /* Read next element.*/ + QXmlStreamReader::TokenType token = xmlReader.readNext(); + /* If token is just StartDocument, we'll go to next.*/ + if(token == QXmlStreamReader::StartDocument) + { + continue; + } + + /* If token is StartElement, we'll see if we can read it.*/ + if(token == QXmlStreamReader::StartElement) + { + /* If it's named rooms, we'll go to the next.*/ + if(xmlReader.name() == "cognitiveMap") + { + continue; + } + if(xmlReader.name() == "header") + { + continue; + } + if(xmlReader.name() == "frameRate") + { + _frameRate=xmlReader.readElementText().toFloat(); + } + if(xmlReader.name() == "frame") + { + ParseFrames(xmlReader); + } + } + } + /* Error handling. */ + if(xmlReader.hasError()) + { + QMessageBox::critical(mView, + "QXSRExample::parseXML", + xmlReader.errorString(), + QMessageBox::Ok); + return false; + } + /* Removes any device() or data from the reader + * and resets its internal state to the initial state. */ + + + xmlReader.clear(); + return true; +} + +void jpsDatamanager::ParseFrames(QXmlStreamReader &xmlReader) +{ + int frameID= xmlReader.attributes().value("ID").toString().toInt(); + + while(!(xmlReader.tokenType() == QXmlStreamReader::EndElement && + xmlReader.name() == "frame")) + { + if (xmlReader.tokenType()==QXmlStreamReader::StartElement && + xmlReader.name() == "YAHPointer") + { + ParseYAHPointer(xmlReader, frameID); + } + else if (xmlReader.tokenType()==QXmlStreamReader::StartElement && + xmlReader.name() == "landmark") + { + ParseLandmarksInCMap(xmlReader, frameID); + } + else if (xmlReader.tokenType()==QXmlStreamReader::StartElement && + xmlReader.name() == "waypoint") + { + ParseWaypointInCMap(xmlReader, frameID); + } + else if (xmlReader.tokenType()==QXmlStreamReader::StartElement && + xmlReader.name() == "connection") + { + ParseConnectionsInCMap(xmlReader, frameID); + } + xmlReader.readNext(); + + } + + _lastCMapFrame=frameID; +} + +void jpsDatamanager::ParseYAHPointer(QXmlStreamReader &xmlReader, const int& frame) +{ + qreal x = xmlReader.attributes().value("x").toString().toFloat(); + qreal y = xmlReader.attributes().value("y").toString().toFloat(); + qreal angle = xmlReader.attributes().value("dir").toString().toFloat(); + if (_yahPointer==nullptr) + { + _yahPointer = new jpsYAHPointer(x,y,angle); + _yahPointer->SetFirstFrame(frame); + _yahPointer->SetLastFrame(frame); + } + else + { + _yahPointer->SetPos(QPointF(x,y)); + _yahPointer->SetDirection(angle); + _yahPointer->SetLastFrame(frame); + } + +} + +void jpsDatamanager::ParseLandmarksInCMap(QXmlStreamReader &xmlReader, const int& frame) +{ + + bool wayPInList=false; + + int id = xmlReader.attributes().value("ID").toString().toInt(); + qreal x = xmlReader.attributes().value("x").toString().toFloat(); + qreal y = xmlReader.attributes().value("y").toString().toFloat(); + qreal rA = xmlReader.attributes().value("rA").toString().toFloat(); + qreal rB = xmlReader.attributes().value("rB").toString().toFloat(); + QString caption = xmlReader.attributes().value("caption").toString(); + + for (ptrWaypoint waypoint:_waypointsInCMap) + { + if (waypoint->GetId()==id && waypoint->GetType()=="Landmark") + { + wayPInList = true; + waypoint->SetLastFrame(frame); + } + } + + if (!wayPInList) + { + _waypointsInCMap.push_back(std::make_shared(QPointF(x,y),rA,rB,id,"Landmark")); + _waypointsInCMap.back()->SetFirstFrame(frame); + _waypointsInCMap.back()->SetLastFrame(frame); + _waypointsInCMap.back()->SetCaption(caption); + } +} + +void jpsDatamanager::ParseWaypointInCMap(QXmlStreamReader &xmlReader, const int& frame) +{ + bool wayPInList=false; + + int id = xmlReader.attributes().value("ID").toString().toInt(); + qreal x = xmlReader.attributes().value("x").toString().toFloat(); + qreal y = xmlReader.attributes().value("y").toString().toFloat(); + qreal rA = xmlReader.attributes().value("rA").toString().toFloat(); + qreal rB = xmlReader.attributes().value("rB").toString().toFloat(); + QString caption = xmlReader.attributes().value("caption").toString(); + bool current = xmlReader.attributes().value("current").toString().toInt(); + + for (ptrWaypoint waypoint:_waypointsInCMap) + { + if (waypoint->GetId()==id && waypoint->GetType()=="Waypoint") + { + wayPInList = true; + waypoint->SetLastFrame(frame); + + if (current!=waypoint->IsCurrent()) + { + waypoint->ChangeCurrentness(frame); + + } + + } + } + + if (!wayPInList) + { + _waypointsInCMap.push_back(std::make_shared(QPointF(x,y),rA,rB,id,"Waypoint")); + _waypointsInCMap.back()->SetFirstFrame(frame); + _waypointsInCMap.back()->SetLastFrame(frame); + _waypointsInCMap.back()->SetCurrentness(current,frame); + _waypointsInCMap.back()->SetCaption(caption); + } + +} + +void jpsDatamanager::ParseConnectionsInCMap(QXmlStreamReader &xmlReader, const int &frame) +{ + int id1 = xmlReader.attributes().value("Landmark_WaypointID1").toString().toInt(); + int id2 = xmlReader.attributes().value("Landmark_WaypointID2").toString().toInt(); + std::shared_ptr waypoint1 = nullptr; + std::shared_ptr waypoint2 = nullptr; + + + for (ptrWaypoint waypoint:_waypointsInCMap) + { + if (waypoint->GetId()==id1) + { + waypoint1=waypoint; + + } + else if (waypoint->GetId()==id2) + { + waypoint2=waypoint; + + } + + } + + ptrConnection con = std::make_shared(waypoint1,waypoint2,frame); + if (waypoint1!=nullptr && waypoint2!=nullptr) + { + for (ptrConnection conInMap : _connectionsInCMap) + { + if (con->operator ==(conInMap)) + { + conInMap->SetLastFrame(frame); + + return; + } + } + + _connectionsInCMap.push_back(con); + } + + +} + +void jpsDatamanager::ShowCMapFrame(const int& frame) const +{ + mView->ShowYAHPointer(_yahPointer->GetPosWhenFrame(frame),_yahPointer->GetDirWhenFrame(frame)); + + QList wayPCandidates; + + for (ptrWaypoint waypoint:_waypointsInCMap) + { + if (waypoint->OccursInFrame(frame)) + { + wayPCandidates.push_back(waypoint); + + if (waypoint->IsCurrentInFrame(frame)) + waypoint->SetText("Next target"); + else if (waypoint->Visited(frame)) + waypoint->SetText("Already visited"); + else + waypoint->SetText(""); + } + } + QList conCandidates; + for (ptrConnection connection:_connectionsInCMap) + { + if (connection->OccursInFrame(frame)) + { + conCandidates.push_back(connection); + } + } + + mView->ShowConnections(conCandidates); + mView->ShowWaypoints(wayPCandidates); + +} + + +const double &jpsDatamanager::GetCMapFrameRate() const +{ + return _frameRate; +} + +const int &jpsDatamanager::GetLastCMapFrame() const +{ + return _lastCMapFrame; +} + diff --git a/src/datamanager.h b/src/datamanager.h index d5e77e0..d1a14ca 100644 --- a/src/datamanager.h +++ b/src/datamanager.h @@ -30,7 +30,7 @@ #ifndef DATAMANAGER_H #define DATAMANAGER_H -#include +#include #include #include #include @@ -40,63 +40,71 @@ #include "jpsexit.h" #include "jpsobstacle.h" #include "GraphicView.h" +#include "jpsyahpointer.h" +#include "jpsconnection.h" #include "../dxflib/src/dl_creationadapter.h" #include "../dxflib/src/dl_dxf.h" +using ptrConnection = std::shared_ptr; +using ptrWaypoint = std::shared_ptr; + + class jpsDatamanager: public DL_CreationAdapter { public: jpsDatamanager(QWidget* parent=0L, jpsGraphicsView* view=0L); ~jpsDatamanager(); - ///Room + //Room QList get_roomlist(); void new_room(); void remove_room(jpsRoom* room); void change_roomName(jpsRoom* room, QString name); void remove_all_rooms(); - ///Obstacle + //Obstacle QList get_obstaclelist(); void new_obstacle(); void remove_obstacle(jpsObstacle* obs); void change_obstacleName(jpsObstacle* obs, QString name); void remove_all_obstacles(); - ///Crossing + //Crossing QList get_crossingList(); void new_crossing(QList newCrossing); void new_crossing(jpsLineItem* newCrossing); void remove_crossing(jpsCrossing* crossing); void change_crossingName(jpsCrossing* crossing, QString name); void remove_all_crossings(); - ///Exit + //Exit QList get_exitList(); void new_exit(QList newExits); void new_exit(jpsLineItem* newExit); void remove_exit(jpsExit* exit); void change_exitName(jpsExit* exit, QString name); void remove_all_exits(); - ///Landmark + //Landmark QList get_landmarks(); void new_landmark(jpsLandmark * newlandmark); void remove_landmark(jpsLandmark* landmark); void change_LandmarkName(jpsLandmark* landmark, QString name); void remove_all_landmarks(); - /// + // void remove_all(); void remove_marked_lines(); void set_view(jpsGraphicsView* view); jpsGraphicsView* get_view(); - /// Auto Assign - void AutoAssignCrossings(); - void AutoAssignExits(); + // Auto Assign +// void AutoAssignCrossings(); +// void AutoAssignExits(); - /// Read XML + // Read XML bool readXML(QFile &file); + bool readRoutingXML(QFile &file); + void parseHline(QXmlStreamReader &xmlReader); void parseSubRoom(QXmlStreamReader &xmlReader); void parseWalls(QXmlStreamReader &xmlReader,jpsRoom* room); void parseWalls(QXmlStreamReader &xmlReader,jpsObstacle* room); @@ -104,10 +112,14 @@ class jpsDatamanager: public DL_CreationAdapter void parseTransitions(QXmlStreamReader &xmlReader); void parseObstacles(QXmlStreamReader &xmlReader, jpsRoom *room); - /// Write XML + // Write XML void writeXML(QFile &file); + void writeRoutingXML(QFile &file); void AutoSaveXML(QFile &file); void writeHeader(QXmlStreamWriter *stream); + void writeRoutingHeader(QXmlStreamWriter *stream); + void writeHLines(QXmlStreamWriter *stream, QList& hLines); + QString RoomIDHLine(jpsLineItem* lineItem); void writeRooms(QXmlStreamWriter *stream, QList& lines); void AutoSaveRooms(QXmlStreamWriter *stream, QList& lines); void writeCrossings(QXmlStreamWriter *stream, QList& lines); @@ -118,10 +130,10 @@ class jpsDatamanager: public DL_CreationAdapter void writeNotAssignedExits(QXmlStreamWriter *stream, QList& lines); void writeLandmarks(QXmlStreamWriter *stream, QList &landmarks); - /// Read DXF + // Read DXF bool readDXF(std::string filename); virtual void addLine(const DL_LineData& d); - /// write DXF + // write DXF void writeDXF(std::string filename); void writeDXFHeader(DL_Dxf* dxf, DL_WriterA *dw); void writeDXFTables(DL_Dxf* dxf, DL_WriterA *dw); @@ -131,7 +143,21 @@ class jpsDatamanager: public DL_CreationAdapter QString check_printAbility(); + //Parse Cognitive Map + bool ParseCogMap(QFile &file); + void ParseFrames(QXmlStreamReader &xmlReader); + void ParseYAHPointer(QXmlStreamReader &xmlReader, const int &frame); + void ParseLandmarksInCMap(QXmlStreamReader &xmlReader, const int &frame); + void ParseWaypointInCMap(QXmlStreamReader &xmlReader, const int &frame); + void ParseConnectionsInCMap(QXmlStreamReader &xmlReader, const int &frame); + + //Show Cognitive Map + void ShowCMapFrame(const int& frame) const; + const double& GetCMapFrameRate() const; + const int& GetLastCMapFrame() const; + private: + //Geometry QList roomlist; QList obstaclelist; QList crossingList; @@ -142,6 +168,14 @@ class jpsDatamanager: public DL_CreationAdapter QWidget* parent_widget; jpsGraphicsView* mView; + //CognitiveMap + QList _landmarksInCMap; + QList _waypointsInCMap; + QList _connectionsInCMap; + jpsYAHPointer* _yahPointer; + double _frameRate; + int _lastCMapFrame; + }; diff --git a/src/graphicscene.cpp b/src/graphicscene.cpp new file mode 100644 index 0000000..3600b99 --- /dev/null +++ b/src/graphicscene.cpp @@ -0,0 +1,97 @@ +#include "graphicscene.h" +#include +#include + + +GraphicScene::GraphicScene(QObject *parent) : QGraphicsScene(parent) +{ + _translationX=0.0; + _translationY=0.0; + _gridmode=false; + _statgrid="Line"; + _gridSize=1.0; +} + +GraphicScene::~GraphicScene() +{ + +} + +void GraphicScene::ChangeGridmode(const bool &stat) +{ + _gridmode=stat; +} + +bool GraphicScene::GetGridmode() const +{ + return _gridmode; +} + +void GraphicScene::ChangeTranslation(qreal x, qreal y) +{ + _translationX=x; + _translationY=y; +} + +void GraphicScene::SetGrid(QString grid) +{ + _statgrid=grid; +} + +void GraphicScene::ChangeGridSize(const qreal &gridSize) +{ + _gridSize=gridSize; +} + +void GraphicScene::drawBackground(QPainter *painter, const QRectF &rect) +{ + if (_gridmode) + { + if (_statgrid=="Line") + DrawLineGrid(painter,rect); + else + DrawPointGrid(painter,rect); + } +} + +void GraphicScene::DrawLineGrid(QPainter *painter, const QRectF &rect) +{ + //gridSize=1.0; + qreal left = int(rect.left()-_translationX) - std::fmod(int(rect.left()-_translationX), _gridSize); + qreal top = int(rect.top()-_translationY)- std::fmod(int(rect.top()-_translationY) , _gridSize); + + QVarLengthArray lines; + + for (qreal x = left; x < rect.right()-_translationX; x += _gridSize) + lines.append(QLineF(x+_translationX, rect.top(), x+_translationX, rect.bottom())); + for (qreal y = top; y < rect.bottom()-_translationY; y += _gridSize) + lines.append(QLineF(rect.left(), y+_translationY, rect.right(), y+_translationY)); + + //qDebug() << lines.size(); + painter->setPen(QPen(Qt::gray,0)); + painter->drawLines(lines.data(), lines.size()); +} + +void GraphicScene::DrawPointGrid(QPainter *painter, const QRectF &rect) +{ + + + qreal left = int(rect.left()-_translationX) - std::fmod(int(rect.left()-_translationX), _gridSize); + qreal top = int(rect.top()-_translationY)- std::fmod(int(rect.top()-_translationY) , _gridSize); + + QVarLengthArray points; + + for (qreal x = left; x < rect.right()-_translationX; x += _gridSize) + { + for (qreal y = top; y < rect.bottom()-_translationY; y += _gridSize) + { + points.append(QPointF(x+_translationX, y+_translationY)); + } + } + //qDebug() << lines.size(); + painter->setPen(QPen(Qt::black,0)); + painter->drawPoints(points.data(), points.size()); +} + + + diff --git a/src/graphicscene.h b/src/graphicscene.h new file mode 100644 index 0000000..91da5da --- /dev/null +++ b/src/graphicscene.h @@ -0,0 +1,37 @@ +#ifndef GRAPHICSCENE_H +#define GRAPHICSCENE_H + +#include +#include + +class GraphicScene : public QGraphicsScene +{ + Q_OBJECT + +public: + + GraphicScene(QObject* parent=nullptr); + GraphicScene(qreal x, qreal y, qreal w, qreal h) + : QGraphicsScene(x, y, w, h) + { } + ~GraphicScene(); + void ChangeGridmode(const bool& stat); + bool GetGridmode() const; + void ChangeTranslation(qreal x, qreal y); + void SetGrid(QString grid); + void ChangeGridSize(const qreal& factor); + +protected: + void drawBackground(QPainter *painter, const QRectF &rect) override; + void DrawLineGrid(QPainter *painter, const QRectF &rect); + void DrawPointGrid(QPainter *painter, const QRectF &rect); +private: + bool _gridmode; + qreal _translationX; + qreal _translationY; + QString _statgrid; + qreal _gridSize; + +}; + +#endif // GRAPHICSCENE_H diff --git a/src/jpsLineItem.cpp b/src/jpsLineItem.cpp index 2089667..10301c4 100644 --- a/src/jpsLineItem.cpp +++ b/src/jpsLineItem.cpp @@ -58,6 +58,16 @@ QString jpsLineItem::get_name() return mName; } +QString jpsLineItem::GetType() +{ + if (is_Door()) + return "Door"; + else if (is_Wall()) + return "Wall"; + else if (IsHLine()) + return "HLine"; +} + void jpsLineItem::set_id(int id) { mId=id; @@ -68,7 +78,7 @@ void jpsLineItem::set_name(QString name) mName=name; } -void jpsLineItem::set_type(bool wall, bool door, bool exit) +void jpsLineItem::set_type(bool wall, bool door, bool exit, bool hline) { if (wall==true) { @@ -82,6 +92,8 @@ void jpsLineItem::set_type(bool wall, bool door, bool exit) { set_Exit(); } + else + SetHLine(); } void jpsLineItem::set_Wall() @@ -89,6 +101,7 @@ void jpsLineItem::set_Wall() wall=true; door=false; exit=false; + _hLine=false; defaultColor="black"; } @@ -97,6 +110,7 @@ void jpsLineItem::set_Door() door=true; wall=false; exit=false; + _hLine=false; defaultColor="blue"; } @@ -105,10 +119,21 @@ void jpsLineItem::set_Exit() exit=true; wall=false; door=false; + _hLine=false; defaultColor="darkMagenta"; } +void jpsLineItem::SetHLine() +{ + exit=false; + wall=false; + door=false; + _hLine=true; + defaultColor="darkCyan"; + +} + void jpsLineItem::set_defaultColor(QString color) { defaultColor=color; @@ -129,6 +154,11 @@ bool jpsLineItem::is_Exit() return exit; } +bool jpsLineItem::IsHLine() +{ + return _hLine; +} + void jpsLineItem::add_intersectionPoint(QPointF *point) { intersectionVector.push_back(point); diff --git a/src/jpsLineItem.h b/src/jpsLineItem.h index d381b61..3ebb525 100644 --- a/src/jpsLineItem.h +++ b/src/jpsLineItem.h @@ -42,16 +42,19 @@ class jpsLineItem int get_id(); QString get_defaultColor(); QString get_name(); + QString GetType(); void set_id(int id); void set_name(QString name); - void set_type(bool wall, bool door, bool exit); + void set_type(bool wall, bool door, bool exit, bool hline=false); void set_Wall(); void set_Door(); void set_Exit(); + void SetHLine(); void set_defaultColor(QString color); bool is_Wall(); bool is_Door(); bool is_Exit(); + bool IsHLine(); void add_intersectionPoint(QPointF *point); void remove_intersectionPoint(QPointF *point); QList get_intersectionVector(); @@ -70,6 +73,7 @@ class jpsLineItem bool wall; bool door; bool exit; + bool _hLine; QList intersectionVector; QList intersectLineVector; /* diff --git a/src/jpsconnection.cpp b/src/jpsconnection.cpp new file mode 100644 index 0000000..a2ccecc --- /dev/null +++ b/src/jpsconnection.cpp @@ -0,0 +1,61 @@ +#include "jpsconnection.h" + +jpsConnection::jpsConnection(ptrWaypoint waypoint1, ptrWaypoint waypoint2, const int &frameID) +{ + _waypoint1=waypoint1; + _waypoint2=waypoint2; + _firstFrame=frameID; + _lastFrame=frameID; +} + +jpsConnection::~jpsConnection() +{ + +} + +std::pair jpsConnection::GetWaypoints() const +{ + return std::make_pair(_waypoint1,_waypoint2); +} + +bool jpsConnection::OccursInFrame(const int& frameID) const +{ + if (frameID>=_firstFrame && frameID<=_lastFrame) + { + return true; + } + else + return false; +} + +void jpsConnection::SetFirstFrame(const int &frameID) +{ + _firstFrame=frameID; +} + +void jpsConnection::SetLastFrame(const int &frameID) +{ + _lastFrame=frameID; +} + +const int &jpsConnection::GetFirstFrame() const +{ + return _firstFrame; +} + +const int &jpsConnection::GetLastFrame() const +{ + return _lastFrame; +} + +bool jpsConnection::operator == (const ptrConnection con2) const +{ + if ((con2->GetWaypoints().first==_waypoint1 && con2->GetWaypoints().second==_waypoint2) + || (con2->GetWaypoints().second==_waypoint1 && con2->GetWaypoints().first==_waypoint2)) + { + return true; + } + else + return false; +} + diff --git a/src/jpsconnection.h b/src/jpsconnection.h new file mode 100644 index 0000000..8359d4e --- /dev/null +++ b/src/jpsconnection.h @@ -0,0 +1,33 @@ +#ifndef JPSCONNECTION_H +#define JPSCONNECTION_H + +#include +#include +#include "jpswaypoint.h" + +using ptrWaypoint = std::shared_ptr; + + +class jpsConnection +{ +using ptrConnection = std::shared_ptr; +public: + jpsConnection(ptrWaypoint waypoint1, ptrWaypoint waypoint2, const int& frameID=-1); + ~jpsConnection(); + std::pair GetWaypoints() const; + //Occurence + bool OccursInFrame(const int &frameID) const; + void SetFirstFrame(const int &frameID); + void SetLastFrame(const int &frameID); + const int& GetFirstFrame() const; + const int& GetLastFrame() const; + // Operator overload + bool operator ==(const ptrConnection con2) const; +private: + ptrWaypoint _waypoint1; + ptrWaypoint _waypoint2; + int _firstFrame; + int _lastFrame; +}; + +#endif // JPSCONNECTION_H diff --git a/src/jpscrossing.cpp b/src/jpscrossing.cpp index 9fb5198..a5f7e9a 100644 --- a/src/jpscrossing.cpp +++ b/src/jpscrossing.cpp @@ -70,9 +70,11 @@ void jpsCrossing::add_rooms(jpsRoom *room1, jpsRoom *room2) { roomList.clear(); roomList.push_back(room1); + room1->AddDoor(this); if (room2!=0L) { roomList.push_back(room2); + room2->AddDoor(this); } diff --git a/src/jpslandmark.cpp b/src/jpslandmark.cpp index 637b737..b109cf3 100644 --- a/src/jpslandmark.cpp +++ b/src/jpslandmark.cpp @@ -100,27 +100,27 @@ int jpsLandmark::get_visibility() return _visibility; } -void jpsLandmark::AddWaypoint(jpsWaypoint *waypoint) +void jpsLandmark::AddWaypoint(ptrWaypoint waypoint) { _waypoints.push_back(waypoint); } -void jpsLandmark::RemoveWaypoint(jpsWaypoint *waypoint) +void jpsLandmark::RemoveWaypoint(ptrWaypoint waypoint) { - delete waypoint; + delete waypoint.get(); _waypoints.removeOne(waypoint); } -QList jpsLandmark::GetWaypoints() +QList jpsLandmark::GetWaypoints() { return _waypoints; } void jpsLandmark::RemoveAllWaypoints() { - for (jpsWaypoint* waypoint:_waypoints) + for (ptrWaypoint waypoint:_waypoints) { - delete waypoint; + delete waypoint.get(); } _waypoints.clear(); } diff --git a/src/jpslandmark.h b/src/jpslandmark.h index 9b3306f..8bbf20f 100644 --- a/src/jpslandmark.h +++ b/src/jpslandmark.h @@ -29,9 +29,11 @@ #ifndef JPSLANDMARK_H #define JPSLANDMARK_H #include +#include #include "rooms.h" #include "jpswaypoint.h" +using ptrWaypoint = std::shared_ptr; class jpsLandmark { @@ -39,22 +41,22 @@ class jpsLandmark jpsLandmark(); jpsLandmark(QGraphicsPixmapItem* pixmap, QString name, QPointF point); ~jpsLandmark(); - ///Setter + //Setter void set_pixmap(QGraphicsPixmapItem* pixmap); void set_name(QString name); void set_pos(QPointF pos); void set_room(jpsRoom* room); void set_visibility(int visibility); - ///Getter + //Getter QGraphicsPixmapItem* get_pixmap(); QString get_name(); const QPointF& get_pos(); jpsRoom *get_room(); int get_visibility(); - ///Waypoint handling - void AddWaypoint(jpsWaypoint* waypoint); - void RemoveWaypoint(jpsWaypoint* waypoint); - QList GetWaypoints(); + //Waypoint handling + void AddWaypoint(ptrWaypoint waypoint); + void RemoveWaypoint(ptrWaypoint waypoint); + QList GetWaypoints(); void RemoveAllWaypoints(); @@ -64,7 +66,7 @@ class jpsLandmark jpsRoom* _room; int _visibility; QGraphicsPixmapItem* _pixmapItem; - QList _waypoints; + QList _waypoints; }; diff --git a/src/jpsobstacle.cpp b/src/jpsobstacle.cpp index 3b4d710..2b8b52e 100644 --- a/src/jpsobstacle.cpp +++ b/src/jpsobstacle.cpp @@ -44,3 +44,4 @@ jpsRoom* jpsObstacle::get_room() { return _room; } + diff --git a/src/jpswaypoint.cpp b/src/jpswaypoint.cpp index f9778cd..109c26b 100644 --- a/src/jpswaypoint.cpp +++ b/src/jpswaypoint.cpp @@ -28,27 +28,56 @@ #include "jpswaypoint.h" #include +#include jpsWaypoint::jpsWaypoint() { } -jpsWaypoint::jpsWaypoint(QRectF rect) +jpsWaypoint::jpsWaypoint(const QPointF &point, const qreal &rA, const qreal &rB, const int &id, const QString &type) +{ + _pos=point; + _a=rA; + _b=rB; + _id=id; + _type=type; + _rect=QRectF(point.x()-rA,point.y()-rB,rA*2,rB*2); + _currentness=false; + _FFcurrentness=-1; + _LFcurrentness=-1; + _lastFrame=-1; + _firstFrame=-1; + _caption=""; +} + +jpsWaypoint::jpsWaypoint(QRectF rect, const int &id) { _rect=rect; _pos=_rect.center(); _a=std::abs(_rect.width()/2.0); _b=std::abs(_rect.height()/2.0); _ellipseItem=nullptr; + _id=id; + _currentness=false; + _FFcurrentness=-1; + _LFcurrentness=-1; + _lastFrame=-1; + _firstFrame=-1; } -jpsWaypoint::jpsWaypoint(QGraphicsEllipseItem* ellipseItem) +jpsWaypoint::jpsWaypoint(QGraphicsEllipseItem* ellipseItem, const int &id) { _ellipseItem=ellipseItem; _rect=_ellipseItem->rect(); _pos=_rect.center(); _a=_rect.width(); _b=_rect.height(); + _id=id; + _currentness=false; + _FFcurrentness=-1; + _LFcurrentness=-1; + _lastFrame=-1; + _firstFrame=-1; } jpsWaypoint::~jpsWaypoint() @@ -56,32 +85,47 @@ jpsWaypoint::~jpsWaypoint() } -const QPointF &jpsWaypoint::GetPos() +const QPointF &jpsWaypoint::GetPos() const { return _pos; } -const QRectF &jpsWaypoint::GetRect() +const QRectF &jpsWaypoint::GetRect() const { return _rect; } -double jpsWaypoint::GetA() +const double& jpsWaypoint::GetA() const { return _a; } -double jpsWaypoint::GetB() +const double& jpsWaypoint::GetB() const { return _b; } +const int &jpsWaypoint::GetId() const +{ + return _id; +} + QGraphicsEllipseItem *jpsWaypoint::GetEllipseItem() { return _ellipseItem; } +const QString &jpsWaypoint::GetCaption() const +{ + return _caption; +} + +const QString &jpsWaypoint::GetType() const +{ + return _type; +} + void jpsWaypoint::SetPos(QPointF point) { @@ -102,6 +146,112 @@ void jpsWaypoint::SetEllipseItem(QGraphicsEllipseItem *ellipseItem) _ellipseItem=ellipseItem; } +void jpsWaypoint::SetId(const int &id) +{ + _id=id; +} + +void jpsWaypoint::SetCaption(const QString &string) +{ + _caption=string; +} + +void jpsWaypoint::SetType(const QString &type) +{ + _type=type; +} + +const int &jpsWaypoint::GetFirstFrame() const +{ + return _firstFrame; +} + +const int &jpsWaypoint::GetLastFrame() const +{ + return _lastFrame; +} + +void jpsWaypoint::SetFirstFrame(const int &frame) +{ + _firstFrame=frame; + +} + +void jpsWaypoint::SetLastFrame(const int &frame) +{ + _lastFrame=frame; + +} + +bool jpsWaypoint::OccursInFrame(const int &frame) const +{ + if (frame>=_firstFrame && frame<=_lastFrame) + { + return true; + } + return false; +} + +bool jpsWaypoint::IsCurrent() const +{ + return _currentness; +} + +bool jpsWaypoint::IsCurrentInFrame(const int &frameID) +{ + if (_FFcurrentness<= frameID && _LFcurrentness>=frameID) + return true; + else + return false; +} + +void jpsWaypoint::SetCurrentness(bool stat, const int& frameID) +{ + _currentness=stat; + if (stat) + _FFcurrentness=frameID; +} + +const int &jpsWaypoint::GetFirstFrameCurrent() const +{ + return _FFcurrentness; +} + +const int &jpsWaypoint::GetLastFrameCurrent() const +{ + return _LFcurrentness; +} + +void jpsWaypoint::ChangeCurrentness(const int& frameID) +{ + _currentness=!_currentness; + if (_currentness) + _FFcurrentness=frameID; + else + _LFcurrentness=frameID; +} + +const QString &jpsWaypoint::GetText() +{ + return _text; +} + +void jpsWaypoint::SetText(const QString &text) +{ + _text=text; +} + +bool jpsWaypoint::Visited(const int &frameID) const +{ + if (frameID > _LFcurrentness && _LFcurrentness!=-1) + return true; + + else + return false; +} + + + diff --git a/src/jpswaypoint.h b/src/jpswaypoint.h index fda1f7d..39bb917 100644 --- a/src/jpswaypoint.h +++ b/src/jpswaypoint.h @@ -35,20 +35,46 @@ class jpsWaypoint { public: jpsWaypoint(); - jpsWaypoint(QRectF rect); - jpsWaypoint(QGraphicsEllipseItem* ellipseItem); + jpsWaypoint(const QPointF& point,const qreal& rA, const qreal& rB, const int& id=0, const QString& type="Waypoint"); + jpsWaypoint(QRectF rect, const int& id=0); + jpsWaypoint(QGraphicsEllipseItem* ellipseItem, const int& id=0); ~jpsWaypoint(); - ///Getter - const QPointF& GetPos(); - const QRectF &GetRect(); - double GetA(); - double GetB(); + //Getter + const QPointF& GetPos() const; + const QRectF &GetRect() const; + const double& GetA() const; + const double& GetB() const; + const int& GetId() const; QGraphicsEllipseItem* GetEllipseItem(); + const QString& GetCaption() const; + const QString& GetType() const; - ///Setter + //Setter void SetPos(QPointF point); void SetRect(QRect rect); void SetEllipseItem(QGraphicsEllipseItem* ellipseItem); + void SetId(const int& id); + void SetCaption(const QString& string); + void SetType(const QString& type); + + //Occurence + const int& GetFirstFrame() const; + const int& GetLastFrame() const; + void SetFirstFrame(const int& frame); + void SetLastFrame(const int& frame); + bool OccursInFrame(const int& frame) const; + + //Currency + bool IsCurrent() const; + bool IsCurrentInFrame(const int& frameID); + void SetCurrentness(bool stat, const int &frameID=1); + const int& GetFirstFrameCurrent() const; + const int& GetLastFrameCurrent() const; + void ChangeCurrentness(const int& frameID); + const QString& GetText(); + void SetText(const QString& text); + + bool Visited(const int& frameID) const; private: @@ -57,6 +83,19 @@ class jpsWaypoint QRectF _rect; double _a; double _b; + int _id; + QString _caption; + QString _type; + + //Occurence + int _firstFrame; + int _lastFrame; + + //Currentness + int _FFcurrentness; + int _LFcurrentness; + bool _currentness; + QString _text; }; diff --git a/src/jpsyahpointer.cpp b/src/jpsyahpointer.cpp new file mode 100644 index 0000000..4c0b90f --- /dev/null +++ b/src/jpsyahpointer.cpp @@ -0,0 +1,77 @@ +#include "jpsyahpointer.h" + +jpsYAHPointer::jpsYAHPointer(const QPointF &point, const qreal &angle) +{ + _cPos=point; + _cDirection=angle; + _allPos.push_back(point); + _allDir.push_back(angle); +} + +jpsYAHPointer::jpsYAHPointer(const qreal &x, const qreal &y, const qreal &angle) +{ + _cPos.setX(x); + _cPos.setY(y); + _cDirection=angle; + _allPos.push_back(_cPos); + _allDir.push_back(angle); +} + +jpsYAHPointer::~jpsYAHPointer() +{ + +} + +const QPointF &jpsYAHPointer::GetPos() const +{ + return _cPos; +} + +const qreal &jpsYAHPointer::GetDirection() const +{ + return _cDirection; +} + +void jpsYAHPointer::SetPos(const QPointF &point) +{ + _cPos=point; + _allPos.push_back(point); +} + +void jpsYAHPointer::SetDirection(const qreal &angle) +{ + _cDirection=angle; + _allDir.push_back(angle); +} + + +const int &jpsYAHPointer::GetFirstFrame() const +{ + return _firstFrame; +} + +const int &jpsYAHPointer::GetLastFrame() const +{ + return _lastFrame; +} + +void jpsYAHPointer::SetFirstFrame(const int &frame) +{ + _firstFrame=frame; +} + +void jpsYAHPointer::SetLastFrame(const int &frame) +{ + _lastFrame=frame; +} + +const QPointF &jpsYAHPointer::GetPosWhenFrame(const int &frame) +{ + return _allPos[frame-1]; +} + +const qreal &jpsYAHPointer::GetDirWhenFrame(const int &frame) +{ + return _allDir[frame-1]; +} + diff --git a/src/jpsyahpointer.h b/src/jpsyahpointer.h new file mode 100644 index 0000000..ef1e002 --- /dev/null +++ b/src/jpsyahpointer.h @@ -0,0 +1,39 @@ +#ifndef JPSYAHPOINTER_H +#define JPSYAHPOINTER_H +#include +#include +class jpsYAHPointer +{ +public: + jpsYAHPointer(const QPointF& point, const qreal& angle=0.0); + jpsYAHPointer(const qreal& x, const qreal& y, const qreal& angle=0.0); + ~jpsYAHPointer(); + + const QPointF& GetPos() const; + const qreal& GetDirection() const; + + void SetPos(const QPointF& point); + void SetDirection(const qreal& angle); + + //Occurence + const int& GetFirstFrame() const; + const int& GetLastFrame() const; + void SetFirstFrame(const int& frame); + void SetLastFrame(const int& frame); + + // + const QPointF& GetPosWhenFrame(const int& frame); + const qreal& GetDirWhenFrame(const int& frame); + +private: + QPointF _cPos; + qreal _cDirection; + std::vector _allPos; + std::vector _allDir; + + //Occurence + int _firstFrame; + int _lastFrame; +}; + +#endif // JPSYAHPOINTER_H diff --git a/src/main.cpp b/src/main.cpp index 047ade3..b76ab58 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -27,6 +27,16 @@ //main.cpp +/* for compiling a standalone windows exe with VS +#ifdef _MSC_VER +# ifdef NDEBUG +# pragma comment(linker, "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup") +# else +# pragma comment(linker, "/SUBSYSTEM:CONSOLE") +# endif +#endif +*/ + #include "mainWindow.h" #include "GraphicView.h" diff --git a/src/mainWindow.cpp b/src/mainWindow.cpp index 5456168..39293e9 100644 --- a/src/mainWindow.cpp +++ b/src/mainWindow.cpp @@ -36,6 +36,7 @@ #include #include +#include MWindow :: MWindow() { @@ -47,13 +48,15 @@ MWindow :: MWindow() { mview = new jpsGraphicsView(this); dmanager = new jpsDatamanager(this,mview); - ///Roomwidget + //Roomwidget rwidget=nullptr; - ///Landmarkwidget + //Landmarkwidget lwidget=nullptr; + //WidgetSettings + _settings=nullptr; length_edit = new QLineEdit(); - length_edit->setMaximumWidth(55); + length_edit->setMaximumWidth(75); label1 = new QLabel(); label1->setMinimumWidth(90); label1->setText("Length of Line :"); @@ -63,9 +66,11 @@ MWindow :: MWindow() { infoLabel= new QLabel(); infoLabel->setMinimumWidth(135); - ///filename of saved project + //filename of saved project _filename=""; + //WindowTitle + this->setWindowTitle("JPSeditor"); setCentralWidget(mview); //this->setMaximumSize(1920,1080); @@ -75,27 +80,33 @@ MWindow :: MWindow() { statusBar()->addPermanentWidget(length_edit); statusBar()->addPermanentWidget(label2); - ///Timer needed for autosave function - /// timer will trigger autosave every 5th minute + //Timer needed for autosave function + // timer will trigger autosave every 5th minute timer = new QTimer(this); timer->setInterval(300000); timer->start(); + _cMapTimer = new QTimer(this); + //_cMapTimer=nullptr; - ///Signals and Slots - /// Tab File - connect(actionBeenden, SIGNAL(triggered(bool)),qApp,SLOT(quit())); + //Signals and Slots + // Tab File + connect(actionBeenden, SIGNAL(triggered(bool)),this,SLOT(close())); connect(action_ffnen,SIGNAL(triggered(bool)),this,SLOT(openFile())); connect(action_ffnen_xml,SIGNAL(triggered(bool)),this,SLOT(openFileXML())); connect(actionSpeichern,SIGNAL(triggered(bool)),this,SLOT(saveFile())); connect(actionSpeichern_dxf,SIGNAL(triggered(bool)),this,SLOT(saveAsDXF())); - /// Tab Help + connect(actionSettings,SIGNAL(triggered(bool)),this,SLOT(Settings())); + connect(action_ffnen_CogMap,SIGNAL(triggered(bool)),this,SLOT(openFileCMap())); + // Tab Help connect(action_ber,SIGNAL(triggered(bool)),this,SLOT(info())); - /// Tab Tools - connect(actionanglesnap,SIGNAL(triggered(bool)),this,SLOT(gridmode())); + // Tab Tools + connect(actionanglesnap,SIGNAL(triggered(bool)),this,SLOT(anglesnap())); + connect(actiongridmode,SIGNAL(triggered(bool)),this,SLOT(gridmode())); connect(actionWall,SIGNAL(triggered(bool)),this,SLOT(en_disableWall())); connect(actionDoor,SIGNAL(triggered(bool)),this,SLOT(en_disableDoor())); connect(actionExit,SIGNAL(triggered(bool)),this,SLOT(en_disableExit())); + connect(actionHLine,SIGNAL(triggered(bool)),this,SLOT(en_disableHLine())); connect(actionObjectsnap,SIGNAL(triggered(bool)),this,SLOT(objectsnap())); connect(actionDelete_lines,SIGNAL(triggered(bool)),this,SLOT(delete_lines())); connect(actionDelete_single_line,SIGNAL(triggered(bool)),this,SLOT(delete_marked_lines())); @@ -104,26 +115,38 @@ MWindow :: MWindow() { connect(actionWall,SIGNAL(triggered(bool)),this,SLOT(dis_selectMode())); connect(actionDoor,SIGNAL(triggered(bool)),this,SLOT(dis_selectMode())); connect(actionExit,SIGNAL(triggered(bool)),this,SLOT(dis_selectMode())); - /// Tab View + // Tab View connect(actionRotate_90_deg_clockwise,SIGNAL(triggered(bool)),this,SLOT(rotate())); - /// Length edit + connect(actionShow_Point_of_Origin,SIGNAL(triggered(bool)),this,SLOT(ShowOrigin())); + // Length edit connect(length_edit,SIGNAL(returnPressed()),this,SLOT(send_length())); - /// mview + // mview connect(mview,SIGNAL(no_drawing()),this,SLOT(en_selectMode())); connect(mview,SIGNAL(remove_marked_lines()),this,SLOT(lines_deleted())); connect(mview,SIGNAL(remove_all()),this,SLOT(remove_all_lines())); connect(mview,SIGNAL(set_focus_textedit()),length_edit,SLOT(setFocus())); connect(mview,SIGNAL(mouse_moved()),this,SLOT(show_coords())); connect(mview,SIGNAL(landmark_added()),this,SLOT(add_landmark())); + connect(mview,SIGNAL(LineLengthChanged()),this,SLOT(ShowLineLength())); + // Mark all lines + QAction *str_a = new QAction(this); + str_a->setShortcut(Qt::Key_A | Qt::CTRL); + connect(str_a, SIGNAL(triggered(bool)), mview, SLOT(SelectAllLines())); + this->addAction(str_a); //connect(mview,SIGNAL(DoubleClick()),this,SLOT(en_selectMode())); - ///Autosave + // Autosave connect(timer, SIGNAL(timeout()), this, SLOT(AutoSave())); - ///Landmarks + //Landmarks connect(actionLandmark,SIGNAL(triggered(bool)),this,SLOT(en_disableLandmark())); connect(actionLandmark,SIGNAL(triggered(bool)),this,SLOT(dis_selectMode())); - ///Landmark specifications + // Landmark specifications connect(actionLandmarkWidget,SIGNAL(triggered(bool)),this,SLOT(define_landmark())); - + //CMap + connect(actionRun_visualisation,SIGNAL(triggered(bool)),this,SLOT(RunCMap())); + connect(_cMapTimer,SIGNAL(timeout()),this,SLOT(UpdateCMap())); + //Undo Redo + connect(actionUndo,SIGNAL(triggered(bool)),mview,SLOT(Undo())); + connect(actionRedo,SIGNAL(triggered(bool)),mview,SLOT(Redo())); } MWindow::~MWindow() @@ -135,6 +158,7 @@ MWindow::~MWindow() delete label2; delete infoLabel; delete timer; + delete _cMapTimer; } void MWindow::AutoSave() @@ -159,7 +183,40 @@ void MWindow::AutoSave() dmanager->AutoSaveXML(file); //file.write(coord_string.toUtf8());//textEdit->toPlainText().toUtf8()); statusBar()->showMessage(tr("Backup file generated!"),10000); + + //routing (hlines) + QString fileNameRouting = file.fileName(); + fileNameRouting=fileNameRouting.split(".").first()+"_routing.xml"; + QFile routingFile(fileNameRouting); + if (routingFile.open(QIODevice::WriteOnly|QIODevice::Text)) + dmanager->writeRoutingXML(routingFile); + } +} + +void MWindow::RunCMap() +{ + + double frameRate = dmanager->GetCMapFrameRate(); + _cMapFrame=1; + if (frameRate==0) + { + statusBar()->showMessage(tr("No cognitive map has been loaded!"),10000); + return; + } + _cMapTimer->setInterval(1/frameRate*1000); + _cMapTimer->start(); +} + +void MWindow::UpdateCMap() +{ + _cMapFrame++; + if (_cMapFrame>dmanager->GetLastCMapFrame()) + { + _cMapTimer->stop(); + dmanager->ShowCMapFrame(1); + return; } + dmanager->ShowCMapFrame(_cMapFrame); } void MWindow::add_landmark() @@ -168,6 +225,29 @@ void MWindow::add_landmark() dmanager->new_landmark(landmark); } +void MWindow::Settings() +{ + if (_settings==nullptr) + { + _settings = new WidgetSettings(this,mview); + _settings->setAttribute(Qt::WA_DeleteOnClose); + _settings->setGeometry(QRect(QPoint(5,75), _settings->size())); + _settings->show(); + } + + else + { + _settings->close(); + _settings=nullptr; + } + +} + +void MWindow::ShowOrigin() +{ + mview->ShowOrigin(); +} + void MWindow::openFile(){ QString fileName=QFileDialog::getOpenFileName(this,tr("Open DXF"),"",tr("DXF-Drawings (*.dxf)")); @@ -190,6 +270,41 @@ void MWindow::openFile(){ } void MWindow::openFileXML() +{ + QString fileName=QFileDialog::getOpenFileName(this,tr("Open XML"),"",tr("XML-Files (*.xml)")); + QFile file(fileName); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) + { + return; + } + + //RoutingFile + QString fileNameRouting= fileName.split(".").first()+"_routing.xml"; + QFile fileRouting(fileNameRouting); + if (!fileRouting.open(QIODevice::ReadOnly | QIODevice::Text)) + { + return; + } + + if (!dmanager->readXML(file) || !dmanager->readRoutingXML(fileRouting)) + { + QMessageBox::critical(this, + "OpenFileXML", + "Couldn't open xml-file", + QMessageBox::Ok); + statusBar()->showMessage("XML-File could not be parsed!",10000); + } + + else + { + //AutoZoom to drawing + mview->AutoZoom(); + statusBar()->showMessage("XML-File successfully loaded!",10000); + } + +} + +void MWindow::openFileCMap() { QString fileName=QFileDialog::getOpenFileName(this,tr("Open XML"),"",tr("XML-Files (*.xml)")); QFile file(fileName); @@ -203,7 +318,7 @@ void MWindow::openFileXML() } - if (!dmanager->readXML(file)) + if (!dmanager->ParseCogMap(file)) { statusBar()->showMessage("XML-File could not be parsed!",10000); } @@ -211,9 +326,9 @@ void MWindow::openFileXML() else { - statusBar()->showMessage("XML-File successfully loaded!",10000); + statusBar()->showMessage("Cognitive map successfully loaded!",10000); + dmanager->ShowCMapFrame(1); } - } void MWindow::saveFile(){ @@ -236,6 +351,14 @@ void MWindow::saveFile(){ return; } dmanager->writeXML(file); + + //routing (hlines) + QString fileNameRouting=fileName.split(".").first()+"_routing.xml"; + + QFile routingFile(fileNameRouting); + if (routingFile.open(QIODevice::WriteOnly|QIODevice::Text)) + dmanager->writeRoutingXML(routingFile); + //file.write(coord_string.toUtf8());//textEdit->toPlainText().toUtf8()); statusBar()->showMessage(tr("XML-File successfully saved!"),10000); } @@ -261,13 +384,31 @@ void MWindow::saveAsDXF() void MWindow::info(){ - QMessageBox::information( - 0,tr("About..."),tr("JuPedSim; Interface for generating and editing geometry(XML)-files necessary for using JPScore; Manual and tutorial coming soon!")); + + + QString info = "JuPedSim v0.8 alpha\n\ + JPSeditor v0.8 alpha\n\ + ====================\n\ + \n\ + Erik Andresen drafted this on 27 Jun 2016\n\ + \n\ + We are proud to announce the first alpha release of our software JPSeditor (part of JuPedSim for simulating pedestrians evacuations). Please note that it is a pre release version for developers only. We are working hard towards the final release for this version.\n\ + \n\ + JPSeditor is a graphical user interface to create the geometry of a scenario simulated by JuPedSim. It comes with set of CAD- and further tools to simplify the creation of proper xml-files incorporating information about the scenario' geometry.\n\ + \n\ + Tutorial\n\ + ========\n\ + \n\ + To highlight some features of JuPedSim we have uploaded some videos on our [YouTube channel](https://www.youtube.com/user/JuPedSim) including a tutorial showing how to use the editor."; + + QMessageBox messageBox; + messageBox.information(0,tr("About..."),info); + } -void MWindow::gridmode() +void MWindow::anglesnap() { - mview->change_gridmode(); + mview->change_stat_anglesnap(); } void MWindow::en_disableWall() @@ -300,12 +441,20 @@ void MWindow::en_disableLandmark() mview->en_disableLandmark(); } +void MWindow::en_disableHLine() +{ + this->disableDrawing(); + actionHLine->setChecked(true); + mview->en_disableHLine(); +} + void MWindow::disableDrawing() { this->actionWall->setChecked(false); this->actionDoor->setChecked(false); this->actionExit->setChecked(false); this->actionLandmark->setChecked(false); + this->actionHLine->setChecked(false); } void MWindow::objectsnap() @@ -313,6 +462,11 @@ void MWindow::objectsnap() mview->change_objectsnap(); } +void MWindow::gridmode() +{ + mview->change_gridmode(); +} + void MWindow::show_coords() { QPointF point = mview->return_Pos(); @@ -345,26 +499,29 @@ void MWindow::send_length() void MWindow::define_room() { - if (rwidget==0L) + if (rwidget==nullptr) { rwidget = new roomWidget(this,this->dmanager,this->mview); rwidget->setGeometry(QRect(QPoint(5,75), rwidget->size())); + rwidget->setAttribute(Qt::WA_DeleteOnClose); rwidget->show(); + } else { rwidget->close(); - rwidget=0L; + rwidget=nullptr; actionRoom->setChecked(false); } } void MWindow::define_landmark() { - if (lwidget==0L) + if (lwidget==nullptr) { lwidget = new widgetLandmark(this,this->dmanager,this->mview); lwidget->setGeometry(QRect(QPoint(5,75), lwidget->size())); + lwidget->setAttribute(Qt::WA_DeleteOnClose); lwidget->show(); } else @@ -384,6 +541,7 @@ void MWindow::en_selectMode() actionWall->setChecked(false); actionDoor->setChecked(false); actionExit->setChecked(false); + actionHLine->setChecked(false); actionLandmark->setChecked(false); length_edit->clearFocus(); } @@ -407,11 +565,34 @@ void MWindow::remove_all_lines() dmanager->remove_all(); } +void MWindow::ShowLineLength() +{ + length_edit->setText(QString::number(mview->ReturnLineLength())); + length_edit->selectAll(); +} + void MWindow::rotate() { mview->rotate(-90); } +void MWindow::closeEvent(QCloseEvent *event) +{ + int ret = QMessageBox::warning( + this, "Quit?", + "Do you really want to quit?", + QMessageBox::Yes | QMessageBox::No ); + + if (ret == QMessageBox::Yes) + { + QMainWindow::closeEvent(event); + } + else + { + event->ignore(); + } +} + diff --git a/src/mainWindow.h b/src/mainWindow.h index 3d76676..75e99c3 100644 --- a/src/mainWindow.h +++ b/src/mainWindow.h @@ -37,6 +37,7 @@ #include "ui_mainwindow.h" #include "roomwidget.h" #include "widgetlandmark.h" +#include "widgetsettings.h" #include "GraphicView.h" #include "datamanager.h" #include "rooms.h" @@ -53,6 +54,7 @@ class MWindow : public QMainWindow, private Ui::MainWindow { private: roomWidget* rwidget; widgetLandmark* lwidget; + WidgetSettings* _settings; jpsDatamanager* dmanager; jpsGraphicsView* mview; //QVBoxLayout* VBox; @@ -63,33 +65,64 @@ class MWindow : public QMainWindow, private Ui::MainWindow { QString _filename; QTimer *timer; + //CMap + QTimer *_cMapTimer; + int _cMapFrame; + protected slots: + + //parseFiles void openFile(); void openFileXML(); + void openFileCMap(); void saveFile(); void saveAsDXF(); + + //about void info(); - void gridmode(); + + //drawing options + void anglesnap(); void en_disableWall(); void en_disableDoor(); void en_disableExit(); void en_disableLandmark(); + void en_disableHLine(); void disableDrawing(); void objectsnap(); + + //Line operations void show_coords(); void delete_lines(); void delete_marked_lines(); void send_length(); - void define_room(); - void define_landmark(); void en_selectMode(); void dis_selectMode(); void lines_deleted(); void remove_all_lines(); + void ShowLineLength(); + + //Room and landmark def + void define_room(); + void define_landmark(); + void add_landmark(); + + //view options + void gridmode(); void rotate(); + void Settings(); + void ShowOrigin(); + + //autosave void AutoSave(); - void add_landmark(); + + //CMap + void RunCMap(); + void UpdateCMap(); + + //quit + void closeEvent(QCloseEvent *event); }; diff --git a/src/rooms.cpp b/src/rooms.cpp index a373338..146555e 100644 --- a/src/rooms.cpp +++ b/src/rooms.cpp @@ -30,6 +30,7 @@ #include #include #include +#include "jpscrossing.h" jpsRoom::jpsRoom(int id_room) @@ -38,6 +39,7 @@ jpsRoom::jpsRoom(int id_room) QString string="Room "; name=string.append(QString::number(id)); highlighted=false; + _type="Not specified"; } @@ -87,9 +89,9 @@ void jpsRoom::activate() } } -QList jpsRoom::get_vertices() +QVector jpsRoom::get_vertices() const { - QList vertices; + QVector vertices; for (int i=0; i jpsRoom::get_vertices() vertices.push_back(item_list[i]->get_line()->line().p2()); } } + for (jpsCrossing* crossing:_doorList) + { + if (vertices.contains(crossing->get_cLine()->get_line()->line().p1())==false) + { + vertices.push_back(crossing->get_cLine()->get_line()->line().p1()); + } + + if (vertices.contains(crossing->get_cLine()->get_line()->line().p1())==false) + { + vertices.push_back(crossing->get_cLine()->get_line()->line().p1()); + } + + } return vertices; } QPointF jpsRoom::get_center() { - QList vertices = get_vertices(); + QVector vertices = get_vertices(); qreal sum_x=0; qreal sum_y=0; @@ -197,21 +212,76 @@ QList jpsRoom::GetDoorVertices() const return vertices; } -bool jpsRoom::ContainsDoor(jpsLineItem *lineItem) const +void jpsRoom::AddDoor(jpsCrossing *door) +{ + _doorList.push_back(door); +} + +QPolygonF jpsRoom::RoomAsPolygon() const +{ + + return QPolygonF(get_vertices()); +} + +QPolygonF jpsRoom::RoomAsSortedPolygon() const { - QList vertices = GetDoorVertices(); + QList lines = item_list; + for (jpsCrossing* crossing:_doorList) + { + lines.push_back(crossing->get_cLine()); + } +// std::cout << lines.size() << std::endl; + QVector points; + + points.push_back(lines.first()->get_line()->line().p1()); + points.push_back(lines.first()->get_line()->line().p2()); - for (QPointF vertex:vertices) + lines.pop_front(); + + for (int i=0; iget_line()->contains(vertex)) + if (lines[i]->get_line()->line().p1() == points.last()) + { + //points.push_back(line->get_line()->line().p1()); + points.push_back(lines[i]->get_line()->line().p2()); + lines.removeOne(lines[i]); + i=-1; + } + else if (lines[i]->get_line()->line().p2() == points.last()) { - return true; + //points.push_back(line->get_line()->line().p1()); + points.push_back(lines[i]->get_line()->line().p1()); + lines.removeOne(lines[i]); + i=-1; } } - return false; + + for (QPointF point:points) + { + std::cout << point.x() << " " << point.y() << std::endl; + + } + std::cout << "----------------------------" << std::endl; + + return QPolygonF(points); } +//bool jpsRoom::ContainsDoor(jpsLineItem *lineItem) const +//{ +// QList vertices = GetDoorVertices(); + +// for (QPointF vertex:vertices) +// { +// if (lineItem->get_line()->contains(vertex)) +// { +// return true; +// } +// } +// return false; + +//} + void jpsRoom::set_id(int id_room) diff --git a/src/rooms.h b/src/rooms.h index f39baba..88f2be0 100644 --- a/src/rooms.h +++ b/src/rooms.h @@ -32,6 +32,8 @@ #include #include "jpsLineItem.h" +class jpsCrossing; + class jpsRoom { @@ -45,7 +47,7 @@ class jpsRoom void change_name(QString name); QList get_listWalls(); void activate(); - QList get_vertices(); + QVector get_vertices() const; void set_id(int id_room); int get_id(); QPointF get_center(); @@ -53,7 +55,14 @@ class jpsRoom QString get_type(); void set_type(const QString &string); QList GetDoorVertices() const; - bool ContainsDoor(jpsLineItem* lineItem) const; + //bool ContainsDoor(jpsLineItem* lineItem) const; + void AddDoor(jpsCrossing *door); + QPolygonF RoomAsPolygon() const; + /** + * @brief RoomAsSortedPolygon + * @return SortedPolygon: QPolygonF + */ + QPolygonF RoomAsSortedPolygon() const; private: @@ -62,6 +71,8 @@ class jpsRoom QString name; QList item_list; QString _type; + QList _doorList; + }; diff --git a/src/roomwidget.cpp b/src/roomwidget.cpp index 221a45a..2b705cd 100644 --- a/src/roomwidget.cpp +++ b/src/roomwidget.cpp @@ -47,11 +47,16 @@ roomWidget::roomWidget(QWidget *parent, jpsDatamanager *dmanager, jpsGraphicsVie show_exits(); show_obstacles(); - ///temporary uncommented + //temporary uncommented ui->auto_assign_doors->setVisible(false); //ui->auto_assign_exits->setVisible(false); - + // roomClasses + ui->classBox->addItem("Not specified"); + ui->classBox->addItem("Corridor"); + ui->classBox->addItem("Office"); + ui->classBox->addItem("Lobby"); + ui->classBox->addItem("Entrance"); //SIGNALS AND SLOTS @@ -65,12 +70,14 @@ roomWidget::roomWidget(QWidget *parent, jpsDatamanager *dmanager, jpsGraphicsVie connect(ui->delete_room,SIGNAL(clicked(bool)),this,SLOT(delete_room())); connect(ui->apply_name_button,SIGNAL(clicked(bool)),this,SLOT(change_roomname())); connect(ui->add_button,SIGNAL(clicked(bool)),this,SLOT(addWall())); - connect(ui->list_rooms,SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)),this,SLOT(showWalls())); - connect(ui->list_rooms,SIGNAL(itemClicked(QListWidgetItem*)),this,SLOT(showWalls())); + connect(ui->list_rooms,SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)),this,SLOT(showWallsAndType())); + connect(ui->list_rooms,SIGNAL(itemClicked(QListWidgetItem*)),this,SLOT(showWallsAndType())); connect(ui->listWalls,SIGNAL(itemClicked(QListWidgetItem*)),this,SLOT(selectWall())); connect(ui->remove_button,SIGNAL(clicked(bool)),this,SLOT(removeWall())); connect(ui->caption,SIGNAL(clicked(bool)),this,SLOT(shhi_roomCaption())); connect(ui->highlight,SIGNAL(clicked(bool)),this,SLOT(highlight_room())); + connect(ui->classBox,SIGNAL(activated(int)),this,SLOT(ChangeRoomType())); + connect(ui->classBox,SIGNAL(currentIndexChanged(int)),this,SLOT(ChangeRoomType())); //tab crossing connect(ui->addCrossingButton,SIGNAL(clicked(bool)),this,SLOT(new_crossing())); connect(ui->crossingList,SIGNAL(itemClicked(QListWidgetItem*)),this,SLOT(enable_roomSelectionCrossings())); @@ -78,7 +85,7 @@ roomWidget::roomWidget(QWidget *parent, jpsDatamanager *dmanager, jpsGraphicsVie connect(ui->roomBox2,SIGNAL(activated(int)),this,SLOT(add_rooms_to_crossing())); connect(ui->removeCrossingButton,SIGNAL(clicked(bool)),this,SLOT(delete_crossing())); connect(ui->crossingList,SIGNAL(itemClicked(QListWidgetItem*)),this,SLOT(select_crossing())); - connect(ui->auto_assign_doors,SIGNAL(clicked(bool)),this,SLOT(autoAssignDoors())); + //connect(ui->auto_assign_doors,SIGNAL(clicked(bool)),this,SLOT(autoAssignDoors())); //tab exit // connect(ui->addExitButton,SIGNAL(clicked(bool)),this,SLOT(new_exit())); // connect(ui->exitList,SIGNAL(itemClicked(QListWidgetItem*)),this,SLOT(enable_roomSelectionExits())); @@ -244,7 +251,7 @@ void roomWidget::addWall() int crow=ui->list_rooms->currentRow(); datamanager->get_roomlist()[crow]->addWall(graphview->get_markedLines()); - this->showWalls(); + this->showWallsAndType(); } } @@ -259,12 +266,12 @@ void roomWidget::removeWall() int crow=ui->list_rooms->currentRow(); datamanager->get_roomlist()[crow]->removeWall(graphview->get_markedLines()); - this->showWalls(); + this->showWallsAndType(); } } } -void roomWidget::showWalls() +void roomWidget::showWallsAndType() { ui->listWalls->clear(); @@ -285,6 +292,8 @@ void roomWidget::showWalls() string.append(" y2:"+QString::number(walllist[i]->get_line()->line().y2())); ui->listWalls->addItem(string); } + + ShowRoomType(crow); } } } @@ -558,7 +567,7 @@ void roomWidget::show_all() show_crossings(); show_exits(); show_obstacles(); - showWalls(); + showWallsAndType(); showWallsObs(); } @@ -758,18 +767,40 @@ void roomWidget::highlight_obs() } -void roomWidget::autoAssignDoors() +//void roomWidget::autoAssignDoors() +//{ +// datamanager->AutoAssignCrossings(); +// show_all(); +// enable_roomSelectionCrossings(); +//} + +//void roomWidget::autoAssignExits() +//{ +// datamanager->AutoAssignExits(); +// show_all(); +// enable_roomSelectionExits(); + +//} + +void roomWidget::ChangeRoomType() { - datamanager->AutoAssignCrossings(); - show_all(); - enable_roomSelectionCrossings(); + if (ui->list_rooms->currentItem()!=0L) + { + int cRoomRow=ui->list_rooms->currentRow(); + int cClassRow=ui->classBox->currentIndex(); + if (cClassRow!=-1) + { + datamanager->get_roomlist()[cRoomRow]->set_type(ui->classBox->currentText()); + } + } + } -void roomWidget::autoAssignExits() +void roomWidget::ShowRoomType(int& cRow) const { - datamanager->AutoAssignExits(); - show_all(); - enable_roomSelectionExits(); + QString type = datamanager->get_roomlist()[cRow]->get_type(); + int itemindex = ui->classBox->findText(type); + ui->classBox->setCurrentIndex(itemindex); } diff --git a/src/roomwidget.h b/src/roomwidget.h index e37ae17..ba13658 100644 --- a/src/roomwidget.h +++ b/src/roomwidget.h @@ -57,7 +57,7 @@ protected slots: void change_roomname(); void addWall(); void removeWall(); - void showWalls(); + void showWallsAndType(); void selectWall(); void new_crossing(); void enable_roomSelectionCrossings(); @@ -85,8 +85,9 @@ protected slots: bool shhi_roomCaption(); void highlight_room(); void highlight_obs(); - void autoAssignDoors(); - void autoAssignExits(); +// void autoAssignDoors(); +// void autoAssignExits(); + void ChangeRoomType(); private: @@ -94,6 +95,9 @@ protected slots: jpsDatamanager *datamanager; jpsGraphicsView *graphview; + // + void ShowRoomType(int &cRow) const; + }; #endif // ROOMWIDGET_H diff --git a/src/widgetlandmark.cpp b/src/widgetlandmark.cpp index 4dcf877..6e2ce75 100644 --- a/src/widgetlandmark.cpp +++ b/src/widgetlandmark.cpp @@ -40,6 +40,7 @@ widgetLandmark::widgetLandmark(QWidget *parent, jpsDatamanager *dmanager, jpsGra ui->setupUi(this); _dmanager=dmanager; _gview=gview; + _waypointIDCounter=0; show_landmarks(); @@ -47,6 +48,7 @@ widgetLandmark::widgetLandmark(QWidget *parent, jpsDatamanager *dmanager, jpsGra connect(ui->apply_name_button,SIGNAL(clicked(bool)),this,SLOT(change_name())); connect(ui->closeButton,SIGNAL(clicked(bool)),this->parentWidget(),SLOT(define_landmark())); connect(ui->list_landmarks,SIGNAL(activated(int)),this,SLOT(enable_room_selection())); + connect(ui->list_landmarks,SIGNAL(currentIndexChanged(int)),_gview,SLOT(unmarkLandmark())); connect(ui->roomBox_landmarks,SIGNAL(activated(int)),this,SLOT(add_room_to_landmark())); connect(ui->add_button,SIGNAL(clicked(bool)),_gview,SLOT(StatAssoDef())); connect(_gview,SIGNAL(AssoDefCompleted()),this,SLOT(AddAssociation())); @@ -162,8 +164,11 @@ void widgetLandmark::AddAssociation() { int cLanRow=ui->list_landmarks->currentIndex(); - _dmanager->get_landmarks()[cLanRow]->AddWaypoint(new jpsWaypoint(_gview->GetCurrentSelectRect()->rect())); + _dmanager->get_landmarks()[cLanRow]->AddWaypoint(std::make_shared(_gview->GetCurrentSelectRect()->rect(),_waypointIDCounter)); + ShowAssociations(); + _waypointIDCounter++; + ui->add_button->setChecked(false); } } @@ -173,9 +178,9 @@ void widgetLandmark::ShowAssociations() if (ui->list_landmarks->currentIndex()!=-1) { int cLanRow=ui->list_landmarks->currentIndex(); - QList waypoints = _dmanager->get_landmarks()[cLanRow]->GetWaypoints(); + QList waypoints = _dmanager->get_landmarks()[cLanRow]->GetWaypoints(); - for (jpsWaypoint* waypoint:waypoints) + for (ptrWaypoint waypoint:waypoints) { QPointF pos = waypoint->GetPos(); QString name = "Waypoint: x: "+QString::number(pos.x())+"y: "+QString::number(pos.y()); diff --git a/src/widgetlandmark.h b/src/widgetlandmark.h index b4f678d..71369c7 100644 --- a/src/widgetlandmark.h +++ b/src/widgetlandmark.h @@ -60,6 +60,7 @@ protected slots: Ui::widgetLandmark *ui; jpsDatamanager* _dmanager; jpsGraphicsView* _gview; + int _waypointIDCounter; }; #endif // WIDGETLANDMARK_H diff --git a/src/widgetsettings.cpp b/src/widgetsettings.cpp new file mode 100644 index 0000000..7c556e9 --- /dev/null +++ b/src/widgetsettings.cpp @@ -0,0 +1,31 @@ +#include "widgetsettings.h" +#include "ui_widgetsettings.h" + +WidgetSettings::WidgetSettings(QWidget *parent, jpsGraphicsView *view) : + QTabWidget(parent), + ui(new Ui::WidgetSettings) +{ + ui->setupUi(this); + _view=view; + connect(ui->pushButtoncloseSettings,SIGNAL(clicked(bool)),QTabWidget::parent(),SLOT(Settings())); + connect(ui->en_lineGrid,SIGNAL(toggled(bool)),this,SLOT(changeGridRadio(bool))); + connect(ui->en_pointGrid,SIGNAL(toggled(bool)),this,SLOT(changeGridRadio(bool))); + +} + +WidgetSettings::~WidgetSettings() +{ + delete ui; +} + +void WidgetSettings::changeGridRadio(bool status) +{ + if (status) + { + if (ui->en_lineGrid->isChecked()) + _view->ActivateLineGrid(); + + else + _view->ActivatePointGrid(); + } +} diff --git a/src/widgetsettings.h b/src/widgetsettings.h new file mode 100644 index 0000000..604d8cf --- /dev/null +++ b/src/widgetsettings.h @@ -0,0 +1,29 @@ +#ifndef WIDGETSETTINGS_H +#define WIDGETSETTINGS_H + +#include +#include "GraphicView.h" + +namespace Ui { +class WidgetSettings; +} + +class WidgetSettings : public QTabWidget +{ + Q_OBJECT + +public: + explicit WidgetSettings(QWidget *parent = nullptr, jpsGraphicsView* view = nullptr); + ~WidgetSettings(); + +public slots: + void changeGridRadio(bool status); + +private: + Ui::WidgetSettings *ui; + jpsGraphicsView* _view; + + +}; + +#endif // WIDGETSETTINGS_H