diff --git a/math/GCFMModel.cpp b/math/GCFMModel.cpp index 0bfa62f3cbb87489234f8feea84171de046aa2fb..ab77883b51beae245c0bc5f4b06c9c719ac762e9 100644 --- a/math/GCFMModel.cpp +++ b/math/GCFMModel.cpp @@ -102,13 +102,16 @@ bool GCFMModel::Init (Building* building) } const vector< Pedestrian* >& allPeds = building->GetAllPedestrians(); - for(unsigned int p=0;p<allPeds.size();p++) + size_t peds_size = allPeds.size(); + for(unsigned int p=0;p<peds_size;p++) { Pedestrian* ped = allPeds[p]; double cosPhi, sinPhi; //a destination could not be found for that pedestrian if (ped->FindRoute() == -1) { building->DeletePedestrian(ped); + p--; + peds_size--; continue; } diff --git a/math/GompertzModel.cpp b/math/GompertzModel.cpp index 5f3637ac71861de0b65a81760dfce1622e2457b2..9ef661e1fb81e0c79607d1d03dd19b747bf050ad 100644 --- a/math/GompertzModel.cpp +++ b/math/GompertzModel.cpp @@ -102,8 +102,8 @@ bool GompertzModel::Init(Building *building) { } const vector<Pedestrian *> &allPeds = building->GetAllPedestrians(); - - for (unsigned int p = 0; p < allPeds.size(); p++) { + size_t peds_size = allPeds.size(); + for (unsigned int p = 0; p < peds_size; p++) { Pedestrian *ped = allPeds[p]; double cosPhi, sinPhi; //a destination could not be found for that pedestrian @@ -111,6 +111,8 @@ bool GompertzModel::Init(Building *building) { Log->Write( "ERROR:\tGompertzModel::Init() cannot initialise route. ped %d is deleted.\n", ped->GetID()); building->DeletePedestrian(ped); + --p; + --peds_size; continue; } Point target = ped->GetExitLine()->LotPoint(ped->GetPos()); diff --git a/math/KrauszModel.cpp b/math/KrauszModel.cpp index 1dd774508562ec388594ca5cb649575a8b9d5fbc..c33ea602709f2505236d07d512ec1650a7ca19f8 100644 --- a/math/KrauszModel.cpp +++ b/math/KrauszModel.cpp @@ -102,13 +102,16 @@ bool KrauszModel::Init (Building* building) } const vector< Pedestrian* >& allPeds = building->GetAllPedestrians(); - for(unsigned int p=0;p<allPeds.size();p++) + size_t peds_size = allPeds.size(); + for(unsigned int p=0;p<peds_size;p++) { Pedestrian* ped = allPeds[p]; double cosPhi, sinPhi; //a destination could not be found for that pedestrian if (ped->FindRoute() == -1) { building->DeletePedestrian(ped); + --p; + --peds_size; continue; } diff --git a/pedestrian/Pedestrian.cpp b/pedestrian/Pedestrian.cpp index fce31355371b4181ea9593e04ed90e3420be47b3..9bdc9594dc99ff3d5c2856f49c8e0a6e8c98c1be 100644 --- a/pedestrian/Pedestrian.cpp +++ b/pedestrian/Pedestrian.cpp @@ -251,7 +251,7 @@ void Pedestrian::SetExitIndex(int i) //_destHistory.push_back(i); } -void Pedestrian::SetExitLine(const NavLine* l) //FIXME? argraf : _navLine = new NavLine(*l); this would have a navLine with consistent uid (done below) +void Pedestrian::SetExitLine(const NavLine* l) { if(_navLine) delete _navLine; diff --git a/routing/DirectionStrategy.cpp b/routing/DirectionStrategy.cpp index e51586b1a01f1fa04be2f2d54f5d91d446a6f921..348664d9c18ee9443d3237d5663d8e057d36745e 100644 --- a/routing/DirectionStrategy.cpp +++ b/routing/DirectionStrategy.cpp @@ -525,19 +525,21 @@ void DirectionSubLocalFloorfield::Init(Building* buildingArg, double stepsize, _initDone = true; //write floorfields to file, one file per subroom //ar.graf: [SWITCH writevtk ON/OFF] -// for(unsigned int i = 0; i < subUIDs.size(); ++i) { -// std::vector<int> targets = {}; -// targets.clear(); -// int subroomUID = subUIDs[i]; -// -// for (auto pair : subAndTarget) { -// if (pair.first == subroomUID) { -// targets.emplace_back(pair.second); -// } -// } -// std::string filename1 = "floorfield" + std::to_string(subroomUID) + ".vtk"; -// locffviafm[subroomUID]->writeFF(filename1, targets); -// } + for(unsigned int i = 0; i < subUIDs.size(); ++i) { + std::vector<int> targets = {}; + targets.clear(); + int subroomUID = subUIDs[i]; + if (subroomUID != 26) continue; + + for (auto pair : subAndTarget) { + if (pair.first == subroomUID) { + targets.emplace_back(pair.second); + } + } + std::string filename1 = "floorfield" + std::to_string(subroomUID) + ".vtk"; + if (targets.size() > 0) + _locffviafm[subroomUID]->writeFF(filename1, targets); + } } DirectionSubLocalFloorfield::DirectionSubLocalFloorfield() { diff --git a/routing/ff_router/UnivFFviaFM.cpp b/routing/ff_router/UnivFFviaFM.cpp index b540dc4f288cf5004991c5dc38dd029c399fd3ee..6c363f8bcfd667d7190eddd8eb69219d80105ae8 100644 --- a/routing/ff_router/UnivFFviaFM.cpp +++ b/routing/ff_router/UnivFFviaFM.cpp @@ -2,6 +2,7 @@ // Created by arne on 5/9/17. // +#include <unordered_set> #include "UnivFFviaFM.h" #include "../../geometry/Line.h" #include "../../geometry/Building.h" @@ -67,8 +68,8 @@ UnivFFviaFM::UnivFFviaFM(Room* roomArg, Configuration* const confArg, double hx, } } - //create(lines, tmpDoors, wantedDoors, FF_HOMO_SPEED, hx, wallAvoid, useWallAvoid); - create(lines, tmpDoors, wantedDoors, FF_WALL_AVOID, hx, wallAvoid, useWallAvoid); + create(lines, tmpDoors, wantedDoors, FF_HOMO_SPEED, hx, wallAvoid, useWallAvoid); + //create(lines, tmpDoors, wantedDoors, FF_WALL_AVOID, hx, wallAvoid, useWallAvoid); } UnivFFviaFM::UnivFFviaFM(SubRoom* sr, Configuration* const conf, double hx, double wallAvoid, bool useWallAvoid) @@ -220,6 +221,81 @@ void UnivFFviaFM::processGeometry(std::vector<Line>&walls, std::map<int, Line>& drawLinesOnGrid(doors, _gridCode); //UIDs of doors will be drawn on _gridCode } +void UnivFFviaFM::markSubroom(const Point& insidePoint, SubRoom* const value) { + //value must not be nullptr. it would lead to infinite loop + if (!value) return; + //alloc mem if needed + if (!_subrooms) { + _subrooms = new SubRoom*[_nPoints]; + for (long i = 0; i < _nPoints; ++i) { + _subrooms[i] = nullptr; + } + } + + //init start + _subrooms[_grid->getKeyAtPoint(insidePoint)] = value; + _gridCode[_grid->getKeyAtPoint(insidePoint)] = INSIDE; + + std::unordered_set<long> wavefront; + wavefront.reserve(_nPoints); + + directNeighbor _neigh = _grid->getNeighbors(_grid->getKeyAtPoint(insidePoint)); + long aux = _neigh.key[0]; + if ((aux != -2) && (_gridCode[aux] == INSIDE || _gridCode[aux] == OUTSIDE)) { + wavefront.insert(aux); + _subrooms[aux] = value; + } + + aux = _neigh.key[1]; + if ((aux != -2) && (_gridCode[aux] == INSIDE || _gridCode[aux] == OUTSIDE)) { + wavefront.insert(aux); + _subrooms[aux] = value; + } + + aux = _neigh.key[2]; + if ((aux != -2) && (_gridCode[aux] == INSIDE || _gridCode[aux] == OUTSIDE)) { + wavefront.insert(aux); + _subrooms[aux] = value; + } + + aux = _neigh.key[3]; + if ((aux != -2) && (_gridCode[aux] == INSIDE || _gridCode[aux] == OUTSIDE)) { + wavefront.insert(aux); + _subrooms[aux] = value; + } + + while(!wavefront.empty()) { + long current = *(wavefront.begin()); + wavefront.erase(current); + _gridCode[current] = INSIDE; + + directNeighbor _neigh = _grid->getNeighbors(current); + long aux = _neigh.key[0]; + if ((aux != -2) && (_gridCode[aux] == INSIDE || _gridCode[aux] == OUTSIDE) && _subrooms[aux] == nullptr) { + wavefront.insert(aux); + _subrooms[aux] = value; + } + + aux = _neigh.key[1]; + if ((aux != -2) && (_gridCode[aux] == INSIDE || _gridCode[aux] == OUTSIDE) && _subrooms[aux] == nullptr) { + wavefront.insert(aux); + _subrooms[aux] = value; + } + + aux = _neigh.key[2]; + if ((aux != -2) && (_gridCode[aux] == INSIDE || _gridCode[aux] == OUTSIDE) && _subrooms[aux] == nullptr) { + wavefront.insert(aux); + _subrooms[aux] = value; + } + + aux = _neigh.key[3]; + if ((aux != -2) && (_gridCode[aux] == INSIDE || _gridCode[aux] == OUTSIDE) && _subrooms[aux] == nullptr) { + wavefront.insert(aux); + _subrooms[aux] = value; + } + } +} + void UnivFFviaFM::createReduWallSpeed(double* reduWallSpeed){ double factor = 1/_wallAvoidDistance; double* wallDstAlias = _costFieldWithKey[0]; @@ -443,9 +519,9 @@ void UnivFFviaFM::drawLinesOnWall(Line& line, T* const target, const T value) { } //drawLinesOnWall void UnivFFviaFM::calcFF(double* costOutput, Point* directionOutput, const double *const speed) { - CompareCost comp = CompareCost(costOutput); + //CompareCost comp = CompareCost(costOutput); std::priority_queue<long int, std::vector<long int>, CompareCost> trialfield(costOutput); //pass the argument for the constr of CompareCost - std::priority_queue<long int, std::vector<long int>, CompareCost> trialfield2(comp); //pass the CompareCost object directly + //std::priority_queue<long int, std::vector<long int>, CompareCost> trialfield2(comp); //pass the CompareCost object directly directNeighbor local_neighbor = _grid->getNeighbors(0); long int aux = 0; @@ -460,25 +536,25 @@ void UnivFFviaFM::calcFF(double* costOutput, Point* directionOutput, const doubl if ((aux != -2) && (_gridCode[aux] != WALL) && (costOutput[aux] < 0.0)) { calcCost(aux, costOutput, directionOutput, speed); trialfield.emplace(aux); - trialfield2.emplace(aux); + //trialfield2.emplace(aux); } aux = local_neighbor.key[1]; if ((aux != -2) && (_gridCode[aux] != WALL) && (costOutput[aux] < 0.0)) { calcCost(aux, costOutput, directionOutput, speed); trialfield.emplace(aux); - trialfield2.emplace(aux); + //trialfield2.emplace(aux); } aux = local_neighbor.key[2]; if ((aux != -2) && (_gridCode[aux] != WALL) && (costOutput[aux] < 0.0)) { calcCost(aux, costOutput, directionOutput, speed); trialfield.emplace(aux); - trialfield2.emplace(aux); + //trialfield2.emplace(aux); } aux = local_neighbor.key[3]; if ((aux != -2) && (_gridCode[aux] != WALL) && (costOutput[aux] < 0.0)) { calcCost(aux, costOutput, directionOutput, speed); trialfield.emplace(aux); - trialfield2.emplace(aux); + //trialfield2.emplace(aux); } } } @@ -492,25 +568,25 @@ void UnivFFviaFM::calcFF(double* costOutput, Point* directionOutput, const doubl if ((aux != -2) && (_gridCode[aux] != WALL) && (costOutput[aux] < 0.0)) { calcCost(aux, costOutput, directionOutput, speed); trialfield.emplace(aux); - trialfield2.emplace(aux); + //trialfield2.emplace(aux); } aux = local_neighbor.key[1]; if ((aux != -2) && (_gridCode[aux] != WALL) && (costOutput[aux] < 0.0)) { calcCost(aux, costOutput, directionOutput, speed); trialfield.emplace(aux); - trialfield2.emplace(aux); + //trialfield2.emplace(aux); } aux = local_neighbor.key[2]; if ((aux != -2) && (_gridCode[aux] != WALL) && (costOutput[aux] < 0.0)) { calcCost(aux, costOutput, directionOutput, speed); trialfield.emplace(aux); - trialfield2.emplace(aux); + //trialfield2.emplace(aux); } aux = local_neighbor.key[3]; if ((aux != -2) && (_gridCode[aux] != WALL) && (costOutput[aux] < 0.0)) { calcCost(aux, costOutput, directionOutput, speed); trialfield.emplace(aux); - trialfield2.emplace(aux); + //trialfield2.emplace(aux); } } } @@ -635,9 +711,9 @@ void UnivFFviaFM::calcCost(const long int key, double* cost, Point* dir, const d } void UnivFFviaFM::calcDF(double* costOutput, Point* directionOutput, const double *const speed) { - CompareCost comp = CompareCost(costOutput); + //CompareCost comp = CompareCost(costOutput); std::priority_queue<long int, std::vector<long int>, CompareCost> trialfield(costOutput); //pass the argument for the constr of CompareCost - std::priority_queue<long int, std::vector<long int>, CompareCost> trialfield2(comp); //pass the CompareCost object directly + //std::priority_queue<long int, std::vector<long int>, CompareCost> trialfield2(comp); //pass the CompareCost object directly directNeighbor local_neighbor = _grid->getNeighbors(0); long int aux = 0; @@ -652,25 +728,25 @@ void UnivFFviaFM::calcDF(double* costOutput, Point* directionOutput, const doubl if ((aux != -2) && (_gridCode[aux] != WALL) && (costOutput[aux] < 0.0)) { calcDist(aux, costOutput, directionOutput, speed); trialfield.emplace(aux); - trialfield2.emplace(aux); + //trialfield2.emplace(aux); } aux = local_neighbor.key[1]; if ((aux != -2) && (_gridCode[aux] != WALL) && (costOutput[aux] < 0.0)) { calcDist(aux, costOutput, directionOutput, speed); trialfield.emplace(aux); - trialfield2.emplace(aux); + //trialfield2.emplace(aux); } aux = local_neighbor.key[2]; if ((aux != -2) && (_gridCode[aux] != WALL) && (costOutput[aux] < 0.0)) { calcDist(aux, costOutput, directionOutput, speed); trialfield.emplace(aux); - trialfield2.emplace(aux); + //trialfield2.emplace(aux); } aux = local_neighbor.key[3]; if ((aux != -2) && (_gridCode[aux] != WALL) && (costOutput[aux] < 0.0)) { calcDist(aux, costOutput, directionOutput, speed); trialfield.emplace(aux); - trialfield2.emplace(aux); + //trialfield2.emplace(aux); } } } @@ -684,25 +760,25 @@ void UnivFFviaFM::calcDF(double* costOutput, Point* directionOutput, const doubl if ((aux != -2) && (_gridCode[aux] != WALL) && (costOutput[aux] < 0.0)) { calcDist(aux, costOutput, directionOutput, speed); trialfield.emplace(aux); - trialfield2.emplace(aux); + //trialfield2.emplace(aux); } aux = local_neighbor.key[1]; if ((aux != -2) && (_gridCode[aux] != WALL) && (costOutput[aux] < 0.0)) { calcDist(aux, costOutput, directionOutput, speed); trialfield.emplace(aux); - trialfield2.emplace(aux); + //trialfield2.emplace(aux); } aux = local_neighbor.key[2]; if ((aux != -2) && (_gridCode[aux] != WALL) && (costOutput[aux] < 0.0)) { calcDist(aux, costOutput, directionOutput, speed); trialfield.emplace(aux); - trialfield2.emplace(aux); + //trialfield2.emplace(aux); } aux = local_neighbor.key[3]; if ((aux != -2) && (_gridCode[aux] != WALL) && (costOutput[aux] < 0.0)) { calcDist(aux, costOutput, directionOutput, speed); trialfield.emplace(aux); - trialfield2.emplace(aux); + //trialfield2.emplace(aux); } } } @@ -857,7 +933,7 @@ void UnivFFviaFM::addTarget(const int uid, double* costarrayDBL, Point* gradarra newArrayPt = (gradarrayPt)? gradarrayPt : new Point[_nPoints]; } - if (_costFieldWithKey[uid] && !costarrayDBL) + if ((_costFieldWithKey[uid]) && (_costFieldWithKey[uid] != costarrayDBL)) delete[] _costFieldWithKey[uid]; _costFieldWithKey[uid] = newArrayDBL; @@ -870,7 +946,7 @@ void UnivFFviaFM::addTarget(const int uid, double* costarrayDBL, Point* gradarra } } - if (_directionFieldWithKey[uid] && !gradarrayPt) + if ((_directionFieldWithKey[uid]) && (_directionFieldWithKey[uid] != gradarrayPt)) delete[] _directionFieldWithKey[uid]; if (newArrayPt) _directionFieldWithKey[uid] = newArrayPt; @@ -882,7 +958,7 @@ void UnivFFviaFM::addTarget(const int uid, double* costarrayDBL, Point* gradarra if (_mode == CENTERPOINT) { newArrayDBL[_grid->getKeyAtPoint(tempCenterPoint)] = magicnum(TARGET_REGION); } - + //the following condition is not clean: we have _speedmode and _useWallAvoidance which are redundant if (_speedmode == FF_WALL_AVOID) { calcFF(newArrayDBL, newArrayPt, _speedFieldSelector[REDU_WALL_SPEED]); } else if (_speedmode == FF_HOMO_SPEED) { @@ -937,6 +1013,18 @@ void UnivFFviaFM::addAllTargetsParallel() { }; } +SubRoom** UnivFFviaFM::getSubRoomFF(){ + return _subrooms; +} + +SubRoom* UnivFFviaFM::getSubRoom(const Point& pos){ + if (!_subrooms) return nullptr; + if (!_grid->includesPoint(pos)) return nullptr; + + long key = _grid->getKeyAtPoint(pos); + return _subrooms[key]; +} + std::vector<int> UnivFFviaFM::getKnownDoorUIDs(){ return _uids; } @@ -998,15 +1086,18 @@ void UnivFFviaFM::writeFF(const std::string& filename, std::vector<int> targetID } } -// file << "SCALARS SubroomPtr float 1" << std::endl; -// file << "LOOKUP_TABLE default" << std::endl; -// for (long int i = 0; i < _grid->GetnPoints(); ++i) { -// if (_subrooms[i]) { -// file << _subrooms[i]->GetUID() << std::endl; -// } else { -// file << 0.0 << std::endl; -// } -// } + if (_subrooms) { + file << "SCALARS SubroomPtr float 1" << std::endl; + file << "LOOKUP_TABLE default" << std::endl; + for (long int i = 0; i < _grid->GetnPoints(); ++i) { + if (_subrooms[i]) { + file << _subrooms[i]->GetUID() << std::endl; + } else { + file << 0.0 << std::endl; + } + } + } + if (!targetID.empty()) { for (unsigned int iTarget = 0; iTarget < targetID.size(); ++iTarget) { Log->Write("%s: target number %d: UID %d", filename.c_str(), iTarget, targetID[iTarget]); @@ -1146,4 +1237,5 @@ void UnivFFviaFM::getDirectionToUID(int destID, const long int key, Point& direc * - error treatment will be advantageous, if calculation of FFs can be postponed * to be done in Simulation::RunBody, where * all cores are available - * - (WIP) fill subroom* array with correct values \ No newline at end of file + * - (WIP) fill subroom* array with correct values + * */ \ No newline at end of file diff --git a/routing/ff_router/UnivFFviaFM.h b/routing/ff_router/UnivFFviaFM.h index cdfdb4c62bf25ec762482231162d0804a5a46095..e54b646dd98bf11490fac67934a41b3d5fac5d80 100644 --- a/routing/ff_router/UnivFFviaFM.h +++ b/routing/ff_router/UnivFFviaFM.h @@ -89,7 +89,7 @@ public: double spacing, double wallAvoidDist, bool useWallAvoid); UnivFFviaFM() {}; UnivFFviaFM(UnivFFviaFM&){}; - ~UnivFFviaFM(){}; + virtual ~UnivFFviaFM(){}; void addTarget(const int uid, Line* door, double* costarray = nullptr, Point* gradarray = nullptr); void addTarget(const int uid, double* costarray = nullptr, Point* gradarray = nullptr); @@ -98,6 +98,8 @@ public: std::vector<int> getKnownDoorUIDs(); void setUser(int userArg); void setMode(int modeArg); + SubRoom** getSubRoomFF(); + SubRoom* getSubRoom(const Point& pos); double getCostToDestination(const int destID, const Point& position, int mode); double getCostToDestination(const int destID, const Point& position); @@ -108,6 +110,7 @@ public: void createRectGrid(std::vector<Line>& walls, std::map<int, Line>& doors, double spacing); void processGeometry(std::vector<Line>&walls, std::map<int, Line>& doors); + void markSubroom(const Point& insidePoint, SubRoom* const value); void createReduWallSpeed(double* reduWallSpeed); void drawLinesOnGrid(std::map<int, Line>& doors, int *const grid); @@ -141,6 +144,7 @@ private: long int _nPoints = 0; std::vector<double*> _speedFieldSelector; int* _gridCode = nullptr; + SubRoom* * _subrooms = nullptr; // this is an array (first asterisk) of pointers (second asterisk) double _wallAvoidDistance = 0.; bool _useWallAvoidance = false; diff --git a/routing/ff_router/ffRouter.cpp b/routing/ff_router/ffRouter.cpp index 93ea1a8746ec156004470c6f069567c072de43e1..4b3abef12487c5a922140f8b31d5d3e012a4df8d 100644 --- a/routing/ff_router/ffRouter.cpp +++ b/routing/ff_router/ffRouter.cpp @@ -187,10 +187,10 @@ bool FFRouter::Init(Building* building) // } else { // locffptr = new LocalFloorfieldViaFM(pairRoomIt->second.get(), building, 0.125, 0.125, 0.0, false); // } - locffptr->setUser(DISTANCE_MEASUREMENTS_ONLY); + locffptr->setUser(DISTANCE_AND_DIRECTIONS_USED); locffptr->setMode(CENTERPOINT); locffptr->addAllTargetsParallel(); - locffptr->writeFF("UnivFF.vtk", locffptr->getKnownDoorUIDs()); + locffptr->writeFF("UnivFF"+std::to_string(pairRoomIt->first)+".vtk", locffptr->getKnownDoorUIDs()); Log->Write("INFO: \tAdding distances in Room %d to matrix", (*pairRoomIt).first); //#pragma omp critical(_locffviafm) _locffviafm.insert(std::make_pair((*pairRoomIt).first, locffptr)); @@ -320,13 +320,14 @@ bool FFRouter::Init(Building* building) //int roomTest = (*(_locffviafm.begin())).first; //int transTest = (building->GetRoom(roomTest)->GetAllTransitionsIDs())[0]; + //auto test = _CroTrByUID.at(1253); - for (unsigned int i = 0; i < _locffviafm.size(); ++i) { - auto iter = _locffviafm.begin(); - std::advance(iter, i); - int roomNr = iter->first; - iter->second->writeFF("testFF" + std::to_string(roomNr) + ".vtk", _allDoorUIDs); - } +// for (unsigned int i = 0; i < _locffviafm.size(); ++i) { +// auto iter = _locffviafm.begin(); +// std::advance(iter, i); +// int roomNr = iter->first; +// iter->second->writeFF("testFF" + std::to_string(roomNr) + ".vtk", _allDoorUIDs); +// } std::ofstream matrixfile; matrixfile.open("Matrix.txt");