LCOV - code coverage report
Current view: top level - src/guisim - GUIContainer.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 36.4 % 198 72
Test Date: 2024-11-22 15:46:21 Functions: 43.3 % 30 13

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2001-2024 German Aerospace Center (DLR) and others.
       4              : // This program and the accompanying materials are made available under the
       5              : // terms of the Eclipse Public License 2.0 which is available at
       6              : // https://www.eclipse.org/legal/epl-2.0/
       7              : // This Source Code may also be made available under the following Secondary
       8              : // Licenses when the conditions for such availability set forth in the Eclipse
       9              : // Public License 2.0 are satisfied: GNU General Public License, version 2
      10              : // or later which is available at
      11              : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
      12              : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
      13              : /****************************************************************************/
      14              : /// @file    GUIContainer.cpp
      15              : /// @author  Melanie Weber
      16              : /// @author  Andreas Kendziorra
      17              : /// @date    Wed, 01.08.2014
      18              : ///
      19              : // A MSContainer extended by some values for usage within the gui
      20              : /****************************************************************************/
      21              : #include <config.h>
      22              : 
      23              : #include <cmath>
      24              : #include <vector>
      25              : #include <string>
      26              : #include <microsim/logging/CastingFunctionBinding.h>
      27              : #include <microsim/logging/FunctionBinding.h>
      28              : #include <microsim/MSLane.h>
      29              : #include <microsim/MSVehicleControl.h>
      30              : #include <microsim/lcmodels/MSAbstractLaneChangeModel.h>
      31              : #include <microsim/devices/MSDevice_Vehroutes.h>
      32              : #include <utils/common/MsgHandler.h>
      33              : #include <utils/common/StringUtils.h>
      34              : #include <utils/vehicle/SUMOVehicleParameter.h>
      35              : #include <utils/geom/GeomHelper.h>
      36              : #include <utils/gui/images/GUITexturesHelper.h>
      37              : #include <utils/gui/windows/GUISUMOAbstractView.h>
      38              : #include <utils/gui/windows/GUIAppEnum.h>
      39              : #include <utils/gui/div/GUIParameterTableWindow.h>
      40              : #include <utils/gui/div/GUIGlobalSelection.h>
      41              : #include <utils/gui/div/GLHelper.h>
      42              : #include <utils/gui/div/GLObjectValuePassConnector.h>
      43              : #include <utils/geom/PositionVector.h>
      44              : #include <gui/GUIApplicationWindow.h>
      45              : #include <gui/GUIGlobals.h>
      46              : #include <utils/gui/globjects/GLIncludes.h>
      47              : #include <utils/gui/div/GUIDesigns.h>
      48              : 
      49              : #include "GUIContainer.h"
      50              : #include "GUINet.h"
      51              : #include "GUIEdge.h"
      52              : 
      53              : //#define GUIContainer_DEBUG_DRAW_WALKING_AREA_SHAPE
      54              : 
      55              : // ===========================================================================
      56              : // FOX callback mapping
      57              : // ===========================================================================
      58              : FXDEFMAP(GUIContainer::GUIContainerPopupMenu) GUIContainerPopupMenuMap[] = {
      59              :     FXMAPFUNC(SEL_COMMAND, MID_START_TRACK, GUIContainer::GUIContainerPopupMenu::onCmdStartTrack),
      60              :     FXMAPFUNC(SEL_COMMAND, MID_STOP_TRACK,  GUIContainer::GUIContainerPopupMenu::onCmdStopTrack),
      61              :     FXMAPFUNC(SEL_COMMAND, MID_SHOWPLAN,    GUIContainer::GUIContainerPopupMenu::onCmdShowPlan),
      62              : };
      63              : 
      64              : // Object implementation
      65            0 : FXIMPLEMENT(GUIContainer::GUIContainerPopupMenu, GUIGLObjectPopupMenu, GUIContainerPopupMenuMap, ARRAYNUMBER(GUIContainerPopupMenuMap))
      66              : 
      67              : #define WATER_WAY_OFFSET 6.0
      68              : 
      69              : // ===========================================================================
      70              : // method definitions
      71              : // ===========================================================================
      72              : /* -------------------------------------------------------------------------
      73              :  * GUIContainer::GUIContainerPopupMenu - methods
      74              :  * ----------------------------------------------------------------------- */
      75            0 : GUIContainer::GUIContainerPopupMenu::GUIContainerPopupMenu(
      76            0 :     GUIMainWindow& app, GUISUMOAbstractView& parent, GUIGlObject& o)
      77            0 :     : GUIGLObjectPopupMenu(app, parent, o) {
      78            0 : }
      79              : 
      80              : 
      81            0 : GUIContainer::GUIContainerPopupMenu::~GUIContainerPopupMenu() {}
      82              : 
      83              : 
      84              : long
      85            0 : GUIContainer::GUIContainerPopupMenu::onCmdShowPlan(FXObject*, FXSelector, void*) {
      86            0 :     GUIContainer* p = dynamic_cast<GUIContainer*>(myObject);
      87            0 :     if (p == nullptr) {
      88              :         return 1;
      89              :     }
      90            0 :     GUIParameterTableWindow* ret = new GUIParameterTableWindow(*myApplication, *p);
      91              :     // add items
      92            0 :     for (int stage = 1; stage < p->getNumStages(); stage++) {
      93            0 :         ret->mkItem(toString(stage).c_str(), false, p->getStageSummary(stage));
      94              :     }
      95              :     // close building (use an object that is not Parameterised as argument)
      96            0 :     Parameterised dummy;
      97            0 :     ret->closeBuilding(&dummy);
      98              :     return 1;
      99            0 : }
     100              : 
     101              : 
     102              : long
     103            0 : GUIContainer::GUIContainerPopupMenu::onCmdStartTrack(FXObject*, FXSelector, void*) {
     104              :     assert(myObject->getType() == GLO_PERSON);
     105            0 :     if (myParent->getTrackedID() != static_cast<GUIContainer*>(myObject)->getGlID()) {
     106            0 :         myParent->startTrack(static_cast<GUIContainer*>(myObject)->getGlID());
     107              :     }
     108            0 :     return 1;
     109              : }
     110              : 
     111              : long
     112            0 : GUIContainer::GUIContainerPopupMenu::onCmdStopTrack(FXObject*, FXSelector, void*) {
     113              :     assert(myObject->getType() == GLO_PERSON);
     114            0 :     myParent->stopTrack();
     115            0 :     return 1;
     116              : }
     117              : 
     118              : 
     119              : 
     120              : 
     121              : /* -------------------------------------------------------------------------
     122              :  * GUIContainer - methods
     123              :  * ----------------------------------------------------------------------- */
     124          422 : GUIContainer::GUIContainer(const SUMOVehicleParameter* pars, MSVehicleType* vtype, MSTransportable::MSTransportablePlan* plan) :
     125              :     MSTransportable(pars, vtype, plan, false),
     126          422 :     GUIGlObject(GLO_CONTAINER, pars->id, GUIIconSubSys::getIcon(GUIIcon::CONTAINER)) {
     127          422 : }
     128              : 
     129              : 
     130          844 : GUIContainer::~GUIContainer() {
     131         1266 : }
     132              : 
     133              : 
     134              : GUIGLObjectPopupMenu*
     135            0 : GUIContainer::getPopUpMenu(GUIMainWindow& app,
     136              :                            GUISUMOAbstractView& parent) {
     137            0 :     GUIGLObjectPopupMenu* ret = new GUIContainerPopupMenu(app, parent, *this);
     138            0 :     buildPopupHeader(ret, app);
     139            0 :     buildCenterPopupEntry(ret);
     140            0 :     buildNameCopyPopupEntry(ret);
     141            0 :     buildSelectionPopupEntry(ret);
     142            0 :     new FXMenuSeparator(ret);
     143            0 :     if (parent.getTrackedID() != getGlID()) {
     144            0 :         GUIDesigns::buildFXMenuCommand(ret, "Start Tracking", nullptr, ret, MID_START_TRACK);
     145              :     } else {
     146            0 :         GUIDesigns::buildFXMenuCommand(ret, "Stop Tracking", nullptr, ret, MID_STOP_TRACK);
     147              :     }
     148              :     //
     149              : 
     150            0 :     buildShowParamsPopupEntry(ret);
     151            0 :     buildShowTypeParamsPopupEntry(ret);
     152            0 :     GUIDesigns::buildFXMenuCommand(ret, "Show Plan", GUIIconSubSys::getIcon(GUIIcon::APP_TABLE), ret, MID_SHOWPLAN);
     153            0 :     new FXMenuSeparator(ret);
     154            0 :     buildPositionCopyEntry(ret, app);
     155            0 :     return ret;
     156              : }
     157              : 
     158              : 
     159              : GUIParameterTableWindow*
     160            0 : GUIContainer::getParameterWindow(GUIMainWindow& app,
     161              :                                  GUISUMOAbstractView&) {
     162            0 :     GUIParameterTableWindow* ret = new GUIParameterTableWindow(app, *this);
     163              :     // add items
     164            0 :     ret->mkItem(TL("stage"), false, getCurrentStageDescription());
     165              :     // there is always the "start" stage which we do not count here because it is not strictly part of the plan
     166            0 :     ret->mkItem(TL("stage index"), false, toString(getCurrentStageIndex()) + " of " + toString(getNumStages() - 1));
     167            0 :     ret->mkItem(TL("start edge [id]"), false, getFromEdge()->getID());
     168            0 :     ret->mkItem(TL("dest edge [id]"), false, getDestination()->getID());
     169            0 :     ret->mkItem(TL("arrivalPos [m]"), false, toString(getCurrentStage()->getArrivalPos()));
     170            0 :     ret->mkItem(TL("edge [id]"), false, getEdge()->getID());
     171            0 :     ret->mkItem(TL("position [m]"), true, new FunctionBinding<GUIContainer, double>(this, &GUIContainer::getEdgePos));
     172            0 :     ret->mkItem(TL("speed [m/s]"), true, new FunctionBinding<GUIContainer, double>(this, &GUIContainer::getSpeed));
     173            0 :     ret->mkItem(TL("speed factor"), false, getChosenSpeedFactor());
     174            0 :     ret->mkItem(TL("angle [degree]"), true, new FunctionBinding<GUIContainer, double>(this, &GUIContainer::getAngle));
     175            0 :     ret->mkItem(TL("waiting time [s]"), true, new FunctionBinding<GUIContainer, double>(this, &GUIContainer::getWaitingSeconds));
     176            0 :     ret->mkItem(TL("desired depart [s]"), false, time2string(getParameter().depart));
     177              :     // close building
     178            0 :     ret->closeBuilding(&getParameter());
     179            0 :     return ret;
     180              : }
     181              : 
     182              : 
     183              : GUIParameterTableWindow*
     184            0 : GUIContainer::getTypeParameterWindow(GUIMainWindow& app, GUISUMOAbstractView&) {
     185            0 :     GUIParameterTableWindow* ret = new GUIParameterTableWindow(app, *this, "vType:" + myVType->getID());
     186            0 :     ret->mkItem(TL("length"), false, myVType->getLength());
     187            0 :     ret->mkItem(TL("width"), false, myVType->getWidth());
     188            0 :     ret->mkItem(TL("height"), false, myVType->getHeight());
     189            0 :     ret->mkItem(TL("minGap"), false, myVType->getMinGap());
     190            0 :     ret->mkItem(TL("mass [kg]"), false, myVType->getMass());
     191            0 :     ret->mkItem(TL("maximum speed [m/s]"), false, myVType->getMaxSpeed());
     192            0 :     ret->closeBuilding(&(myVType->getParameter()));
     193            0 :     return ret;
     194              : }
     195              : 
     196              : 
     197              : double
     198        22127 : GUIContainer::getExaggeration(const GUIVisualizationSettings& s) const {
     199        22127 :     return s.containerSize.getExaggeration(s, this);
     200              : }
     201              : 
     202              : 
     203              : Boundary
     204            0 : GUIContainer::getCenteringBoundary() const {
     205            0 :     Boundary b;
     206              :     // ensure that the vehicle is drawn, otherwise myPositionInVehicle will not be updated
     207            0 :     b.add(getPosition());
     208            0 :     b.grow(20);
     209            0 :     return b;
     210            0 : }
     211              : 
     212              : 
     213              : void
     214        22127 : GUIContainer::drawGL(const GUIVisualizationSettings& s) const {
     215        22127 :     GLHelper::pushName(getGlID());
     216        22127 :     GLHelper::pushMatrix();
     217        22127 :     Position p1 = getPosition();
     218        22127 :     double angle = getAngle();
     219        44079 :     if (getCurrentStageType() == MSStageType::DRIVING && !isWaiting4Vehicle()) {
     220         5850 :         p1 = myPositionInVehicle.pos;
     221         5850 :         angle = myPositionInVehicle.angle;
     222              :     }
     223        22127 :     glTranslated(p1.x(), p1.y(), getType());
     224        22127 :     glRotated(RAD2DEG(angle), 0, 0, 1);
     225              :     // set container color
     226        22127 :     setColor(s);
     227              :     // scale
     228        22127 :     const double upscale = getExaggeration(s);
     229        22127 :     glScaled(upscale, upscale, 1);
     230        22127 :     switch (s.containerQuality) {
     231        22127 :         case 0:
     232              :         case 1:
     233              :         case 2:
     234        22127 :             drawAction_drawAsPoly(s);
     235              :             break;
     236            0 :         case 3:
     237              :         default:
     238            0 :             drawAction_drawAsImage(s);
     239              :             break;
     240              :     }
     241        22127 :     GLHelper::popMatrix();
     242              : 
     243        22127 :     drawName(p1, s.scale, s.containerName, s.angle);
     244        22127 :     GLHelper::popName();
     245        22127 : }
     246              : 
     247              : 
     248              : void
     249            0 : GUIContainer::drawGLAdditional(GUISUMOAbstractView* const /* parent */, const GUIVisualizationSettings& /* s */) const {
     250            0 :     GLHelper::pushName(getGlID());
     251            0 :     GLHelper::pushMatrix();
     252              :     /*
     253              :     glTranslated(0, 0, getType() - .1); // don't draw on top of other cars
     254              :     if (hasActiveAddVisualisation(parent, VO_SHOW_BEST_LANES)) {
     255              :         drawBestLanes();
     256              :     }
     257              :     if (hasActiveAddVisualisation(parent, VO_SHOW_ROUTE)) {
     258              :         drawRoute(s, 0, 0.25);
     259              :     }
     260              :     if (hasActiveAddVisualisation(parent, VO_SHOW_ALL_ROUTES)) {
     261              :         if (getNumberReroutes() > 0) {
     262              :             const int noReroutePlus1 = getNumberReroutes() + 1;
     263              :             for (int i = noReroutePlus1 - 1; i >= 0; i--) {
     264              :                 double darken = double(0.4) / double(noReroutePlus1) * double(i);
     265              :                 drawRoute(s, i, darken);
     266              :             }
     267              :         } else {
     268              :             drawRoute(s, 0, 0.25);
     269              :         }
     270              :     }
     271              :     if (hasActiveAddVisualisation(parent, VO_SHOW_LFLINKITEMS)) {
     272              :         for (DriveItemVector::const_iterator i = myLFLinkLanes.begin(); i != myLFLinkLanes.end(); ++i) {
     273              :             if((*i).myLink==0) {
     274              :                 continue;
     275              :             }
     276              :             MSLink* link = (*i).myLink;
     277              :             MSLane *via = link->getViaLane();
     278              :             if (via == 0) {
     279              :                 via = link->getLane();
     280              :             }
     281              :             if (via != 0) {
     282              :                 Position p = via->getShape()[0];
     283              :                 if((*i).mySetRequest) {
     284              :                     glColor3f(0, 1, 0);
     285              :                 } else {
     286              :                     glColor3f(1, 0, 0);
     287              :                 }
     288              :                 glTranslated(p.x(), p.y(), -.1);
     289              :                 GLHelper::drawFilledCircle(1);
     290              :                 glTranslated(-p.x(), -p.y(), .1);
     291              :             }
     292              :         }
     293              :     }
     294              :     */
     295            0 :     GLHelper::popMatrix();
     296            0 :     GLHelper::popName();
     297            0 : }
     298              : 
     299              : 
     300              : 
     301              : 
     302              : void
     303        22127 : GUIContainer::setColor(const GUIVisualizationSettings& s) const {
     304              :     const GUIColorer& c = s.containerColorer;
     305        22127 :     if (!setFunctionalColor(c.getActive())) {
     306        19413 :         GLHelper::setColor(c.getScheme().getColor(getColorValue(s, c.getActive())));
     307              :     }
     308        22127 : }
     309              : 
     310              : 
     311              : bool
     312        22127 : GUIContainer::setFunctionalColor(int activeScheme) const {
     313        22127 :     switch (activeScheme) {
     314        22127 :         case 0: {
     315        22127 :             if (getParameter().wasSet(VEHPARS_COLOR_SET)) {
     316         2712 :                 GLHelper::setColor(getParameter().color);
     317         2712 :                 return true;
     318              :             }
     319        19415 :             if (getVehicleType().wasSet(VTYPEPARS_COLOR_SET)) {
     320            2 :                 GLHelper::setColor(getVehicleType().getColor());
     321            2 :                 return true;
     322              :             }
     323              :             return false;
     324              :         }
     325            0 :         case 2: {
     326            0 :             if (getParameter().wasSet(VEHPARS_COLOR_SET)) {
     327            0 :                 GLHelper::setColor(getParameter().color);
     328            0 :                 return true;
     329              :             }
     330              :             return false;
     331              :         }
     332            0 :         case 3: {
     333            0 :             if (getVehicleType().wasSet(VTYPEPARS_COLOR_SET)) {
     334            0 :                 GLHelper::setColor(getVehicleType().getColor());
     335            0 :                 return true;
     336              :             }
     337              :             return false;
     338              :         }
     339            0 :         case 8: { // color by angle
     340            0 :             double hue = GeomHelper::naviDegree(getAngle());
     341            0 :             GLHelper::setColor(RGBColor::fromHSV(hue, 1., 1.));
     342            0 :             return true;
     343              :         }
     344            0 :         case 9: { // color randomly (by pointer)
     345            0 :             const double hue = (double)((long long int)this % 360); // [0-360]
     346            0 :             const double sat = (double)(((long long int)this / 360) % 67) / 100. + 0.33; // [0.33-1]
     347            0 :             GLHelper::setColor(RGBColor::fromHSV(hue, sat, 1.));
     348            0 :             return true;
     349              :         }
     350              :         default:
     351              :             return false;
     352              :     }
     353              : }
     354              : 
     355              : 
     356              : double
     357        19413 : GUIContainer::getColorValue(const GUIVisualizationSettings& /* s */, int activeScheme) const {
     358        19413 :     switch (activeScheme) {
     359            0 :         case 4:
     360            0 :             return getSpeed();
     361            0 :         case 5:
     362            0 :             if (isWaiting4Vehicle()) {
     363              :                 return 5;
     364              :             } else {
     365            0 :                 return (double)getCurrentStageType();
     366              :             }
     367            0 :         case 6:
     368            0 :             return getWaitingSeconds();
     369            0 :         case 7:
     370            0 :             return gSelected.isSelected(GLO_CONTAINER, getGlID());
     371              :     }
     372              :     return 0;
     373              : }
     374              : 
     375              : 
     376              : double
     377         4885 : GUIContainer::getEdgePos() const {
     378         4885 :     FXMutexLock locker(myLock);
     379         9770 :     return MSTransportable::getEdgePos();
     380              : }
     381              : 
     382              : int
     383            0 : GUIContainer::getDirection() const {
     384            0 :     FXMutexLock locker(myLock);
     385            0 :     return MSTransportable::getDirection();
     386              : }
     387              : 
     388              : 
     389              : Position
     390        24291 : GUIContainer::getPosition() const {
     391        24291 :     FXMutexLock locker(myLock);
     392        24291 :     if (getCurrentStageType() == MSStageType::WAITING && getEdge()->getPermissions() == SVC_SHIP) {
     393            0 :         MSLane* lane = getEdge()->getLanes().front();   //the most right lane of the water way
     394              :         PositionVector laneShape = lane->getShape();
     395            0 :         return laneShape.positionAtOffset2D(getEdgePos(), WATER_WAY_OFFSET);
     396            0 :     }
     397        24291 :     return MSTransportable::getPosition();
     398              : }
     399              : 
     400              : 
     401              : double
     402        24605 : GUIContainer::getAngle() const {
     403        24605 :     FXMutexLock locker(myLock);
     404        49210 :     return MSTransportable::getAngle();
     405              : }
     406              : 
     407              : 
     408              : double
     409            0 : GUIContainer::getWaitingSeconds() const {
     410            0 :     FXMutexLock locker(myLock);
     411            0 :     return MSTransportable::getWaitingSeconds();
     412              : }
     413              : 
     414              : 
     415              : double
     416         2164 : GUIContainer::getSpeed() const {
     417         2164 :     FXMutexLock locker(myLock);
     418         4328 :     return MSTransportable::getSpeed();
     419              : }
     420              : 
     421              : 
     422              : void
     423        22127 : GUIContainer::drawAction_drawAsPoly(const GUIVisualizationSettings& /* s */) const {
     424              :     // draw pedestrian shape
     425        22127 :     glScaled(getVehicleType().getLength(), getVehicleType().getWidth(), 1);
     426        22127 :     glBegin(GL_QUADS);
     427        22127 :     glVertex2d(0, 0.5);
     428        22127 :     glVertex2d(0, -0.5);
     429        22127 :     glVertex2d(-1, -0.5);
     430        22127 :     glVertex2d(-1, 0.5);
     431        22127 :     glEnd();
     432        22127 :     GLHelper::setColor(GLHelper::getColor().changedBrightness(-30));
     433        22127 :     glTranslated(0, 0, .045);
     434        22127 :     glBegin(GL_QUADS);
     435        22127 :     glVertex2d(-0.1, 0.4);
     436        22127 :     glVertex2d(-0.1, -0.4);
     437        22127 :     glVertex2d(-0.9, -0.4);
     438        22127 :     glVertex2d(-0.9, 0.4);
     439        22127 :     glEnd();
     440        22127 : }
     441              : 
     442              : 
     443              : void
     444            0 : GUIContainer::drawAction_drawAsImage(const GUIVisualizationSettings& s) const {
     445            0 :     const std::string& file = getVehicleType().getImgFile();
     446            0 :     if (file != "") {
     447              :         // @todo invent an option for controlling whether images should be rotated or not
     448              :         //if (getVehicleType().getGuiShape() == SVS_CONTAINER) {
     449              :         //    glRotated(RAD2DEG(getAngle() + M_PI / 2.), 0, 0, 1);
     450              :         //}
     451            0 :         int textureID = GUITexturesHelper::getTextureID(file);
     452            0 :         if (textureID > 0) {
     453            0 :             const double exaggeration = s.personSize.getExaggeration(s, this);
     454            0 :             const double halfLength = getVehicleType().getLength() / 2.0 * exaggeration;
     455            0 :             const double halfWidth = getVehicleType().getWidth() / 2.0 * exaggeration;
     456            0 :             GUITexturesHelper::drawTexturedBox(textureID, -halfWidth, -halfLength, halfWidth, halfLength);
     457              :         }
     458              :     } else {
     459              :         // fallback if no image is defined
     460            0 :         drawAction_drawAsPoly(s);
     461              :     }
     462            0 : }
     463              : 
     464              : bool
     465            0 : GUIContainer::isSelected() const {
     466            0 :     return gSelected.isSelected(GLO_CONTAINER, getGlID());
     467              : }
     468              : 
     469              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1