Files
qt5-legatus-legacy/Lts/Proxies/Buildings/BuildingControlUnit/VWM/test_vwm_xml.cpp
T
2026-08-13 18:33:10 +02:00

591 lines
26 KiB
C++
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* @RDE_HEADER@
* Read VWM and building xml to check if BSM positions are correct
* $Id$
* $HeadURL$
* $Author$
* Created by Gerlinde Rudolphus, SLSE, 2016-01-25
*/
#include "vwm_math.h"
#include "vwm_xml_reader.h"
#include "vwm_building_room_geometry.h"
#include "vwm_api.h"
#include <iostream>
#include <nglapplication/nglcoreapplication.h>
#include <NGLLogger/INGLLogger.h>
#include <bcu_xml_reader.h>
#include <QStringList>
#include <QFile>
#include <QPolygonF>
#include <QDomDocument>
#include <QDebug>
static QDomElement getChildElement(const QDomElement &parent, const QString &childTag, bool bThrow = true)
{
const QDomElement ret = parent.firstChildElement(childTag);
if (ret.isNull() && bThrow)
throw BuildingControlUnit::XmlReaderException(QStringLiteral("Invalid XML Structure - no '%1' tag").arg(childTag));
return ret;
}
static int getInteger(const QDomElement &element, const QString &attribute)
{
bool bOk = true;
const int ret = element.attribute(attribute).toInt(&bOk);
if (!bOk)
throw BuildingControlUnit::XmlReaderException(QStringLiteral("Can not find attribute %1 in xml element %2 (line %3:%4)")
.arg(attribute, element.tagName()).arg(element.lineNumber()).arg(element.columnNumber()));
return ret;
}
static inline bool checkRange(double d)
{
return (fabs(d) < 10000000);
}
static inline LtsUtils::QPoint3D positionFromElement(const QDomElement &elem)
{
bool bOkX, bOkY, bOkZ;
auto ret (LtsUtils::QPoint3D(elem.attribute(QStringLiteral("X")).toDouble(&bOkX),
elem.attribute(QStringLiteral("Y")).toDouble(&bOkY),
elem.attribute(QStringLiteral("Z")).toDouble(&bOkZ)));
if (!bOkX || !checkRange(ret.x()))
throw BuildingControlUnit::XmlReaderException(QStringLiteral("invalid value for X: %1 (line %2:%3)")
.arg(elem.attribute(QStringLiteral("X"))).arg(elem.lineNumber()).arg(elem.columnNumber()));
if (!bOkY || !checkRange(ret.y()))
throw BuildingControlUnit::XmlReaderException(QStringLiteral("invalid value for Y: %1 (line %2:%3)")
.arg(elem.attribute(QStringLiteral("Y"))).arg(elem.lineNumber()).arg(elem.columnNumber()));
if (!bOkZ || !checkRange(ret.z()))
throw BuildingControlUnit::XmlReaderException(QStringLiteral("invalid value for Z: %1 (line %2:%3)")
.arg(elem.attribute(QStringLiteral("Z"))).arg(elem.lineNumber()).arg(elem.columnNumber()));
return ret;
}
struct MyRoom
{
LtsUtils::QPoint3D bBoxMin;
LtsUtils::QPoint3D bBoxMax;
int id = 0;
LtsUtils::QPoint3D center() const
{
return (bBoxMin + bBoxMax) / 2;
}
double maxZ() const
{
return std::max(bBoxMax.z(), bBoxMin.z());
}
double minZ() const
{
return std::min(bBoxMax.z(), bBoxMin.z());
}
};
static BuildingControlUnit::Bsm getRefMod(const QDomElement &extRef)
{
BuildingControlUnit::Bsm bsm;
const QDomElement nameElement = getChildElement(extRef, QStringLiteral("Name"), false);
if (!nameElement.text().startsWith(QLatin1String("REF_MOD_AP_"), Qt::CaseInsensitive))
return bsm;
bsm.id = getInteger(getChildElement(extRef, QStringLiteral("SubId")), QStringLiteral("ID"));
bsm.position = positionFromElement(getChildElement(extRef, QStringLiteral("Coord")));
bsm.direction = positionFromElement(getChildElement(extRef, QStringLiteral("Dir"))); // xyz=hpr?
return bsm;
}
template <typename T>
static inline T positionFromElement(const QDomElement &elem)
{
return T(elem.attribute(QStringLiteral("X")).toDouble(),
elem.attribute(QStringLiteral("Y")).toDouble(),
elem.attribute(QStringLiteral("Z")).toDouble());
}
static void parseRooms(const QDomElement &domGroup,
BuildingControlUnit::BuildingBsmConfig &bsmConfig,
QMap<int, MyRoom> &rooms)
{
MyRoom room;
QDomElement domGroup1 = getChildElement(domGroup, QStringLiteral("Group"));
for ( ; !domGroup1.isNull(); domGroup1 = domGroup1.nextSiblingElement(domGroup1.tagName()))
{
const QDomElement nameElement = getChildElement(domGroup1, QStringLiteral("Name"), false);
if (!nameElement.text().startsWith(QLatin1String("floor_"), Qt::CaseInsensitive))
continue;
QDomElement domSwitch = getChildElement(domGroup1, QStringLiteral("Switch"), false);
for ( ; !domSwitch.isNull(); domSwitch = domSwitch.nextSiblingElement(domSwitch.tagName()))
{
const QDomElement roomNameElement = getChildElement(domSwitch, QStringLiteral("Name"), false);
if (!roomNameElement.text().startsWith(QLatin1String("SW_room_"), Qt::CaseInsensitive))
continue;
room.id = getInteger(getChildElement(domSwitch, QStringLiteral("SubId")), QStringLiteral("ID"));
QDomElement domGroup2 = getChildElement(domSwitch, QStringLiteral("Group"), false);
for ( ; !domGroup2.isNull(); domGroup2 = domGroup2.nextSiblingElement(domGroup2.tagName()))
{
const QDomElement domBBMin = getChildElement(domGroup2, QStringLiteral("BBox_Min"));
const QDomElement domBBMax = getChildElement(domGroup2, QStringLiteral("BBox_Max"));
room.bBoxMin = positionFromElement(domBBMin);
room.bBoxMax = positionFromElement(domBBMax);
rooms[room.id] = room;
QDomElement extRef = getChildElement(domGroup2, QStringLiteral("External_Reference"), false);
for ( ; !extRef.isNull(); extRef = extRef.nextSiblingElement(extRef.tagName()))
{
const BuildingControlUnit::Bsm bsm = getRefMod(extRef);
if (bsm.id)
bsmConfig.bsmMap.insert(bsm.id, bsm);
}
}
}
}
}
static bool parseFlt(NGL::INGLLogger &logger, const QString &fn,
BuildingControlUnit::BuildingBsmConfig &bsmConfig,
BuildingControlUnit::BuildingBsmConfig &bsmConfigOhneRaumbezug,
QMap<int, MyRoom> &rooms,
std::vector<LtsUtils::QPoint3D> &footprint_ref)
{
const QDomElement domRoot = BuildingControlUnit::readFile(fn, QStringLiteral("STREIF"));
if (domRoot.isNull())
{
WARNING_LOG(logger) << "domRoot isNull";
return false;
}
try
{
// main part
const QDomElement domHdr = domRoot.firstChildElement(QStringLiteral("Header"));
const QDomElement domGroup = domHdr.firstChildElement(QStringLiteral("Group"));
QDomElement extRef = getChildElement(domGroup, QStringLiteral("External_Reference"));
for ( ; !extRef.isNull(); extRef = extRef.nextSiblingElement(extRef.tagName()))
{
const BuildingControlUnit::Bsm bsm = getRefMod(extRef);
if (bsm.id)
bsmConfig.bsmMap.insert(bsm.id, bsm);
}
bsmConfigOhneRaumbezug = bsmConfig;
parseRooms(domGroup, bsmConfig, rooms);
// bldg-footprint
{
const QDomElement domHdrFootprint = domRoot.firstChildElement(QStringLiteral("Header"));
const QDomElement domGroupFootprint = domHdrFootprint.firstChildElement(QStringLiteral("Group"));
QDomElement groupElem = domGroupFootprint.firstChildElement(QStringLiteral("Group"));
footprint_ref.clear();
for (; !groupElem.isNull(); groupElem = groupElem.nextSiblingElement(groupElem.tagName()))
{
const QDomElement nameElement = getChildElement(groupElem, QStringLiteral("Name"), false);
if (!nameElement.text().startsWith(QLatin1String("FOOTPRINT"), Qt::CaseInsensitive))
continue;
const QDomElement polygonElem = getChildElement(groupElem, QStringLiteral("Polygon"), false);
if (polygonElem.isNull())
continue;
QDomElement vertexElem = polygonElem.firstChildElement(QStringLiteral("Vertex"));
for (; !vertexElem.isNull(); vertexElem = vertexElem.nextSiblingElement(vertexElem.tagName()))
{
// TODO: xml hat keine Reihenfolge! Man kann es anhand der Namen sortieren
const QDomElement coordElem = vertexElem.firstChildElement(QStringLiteral("Coord"));
if (coordElem.isNull())
continue;
footprint_ref.emplace_back(positionFromElement(coordElem));
}
break;
} // for
}
}
catch (const BuildingControlUnit::XmlReaderException &ex)
{
WARNING_LOG(logger) << ex.what();
return false;
}
return !bsmConfig.bsmMap.isEmpty();
}
/*
* Folgende Probleme werder ermittlt:
* VWM: doppelte Punkte in den Polygonen
*
* checkBsmPosition using rooms:
* VWM:
<< "Hit on center point for room " << myRoom.id << " will not hit building - no outterWalls"
* Beschuss von oben auf den CenterPoint eines jeden Raumes
* Hier machen die Aussentreppen Probleme (s.a. GUEZE-704)
* Diese Probleme werden durch Vergleich mit dem Footprint mittlerweile erkannt
* und nicht mehr als Fehler eingestuft.
*
* << "Hit on center point for room results in hit pos behind a wall ("
* // hitPos.distance negative
*
* FLT:
* checkBsmPosition using BSMs:
* << "Effect on bsm " << bsm.id << " will not hit building ! - position: "
*
* << "Effect on bsm " << bsm.id << " results in hit pos behind a wall ("
* BSM is not modelled in the correct place
*/
int main(int argc, char *argv[])
{
NGLCoreApplication app(argc, argv);
app.createLogger("BCU", 1);
// logcxx_bcu.props
if (app.arguments().size() != 3)
{
std::cerr << "Usage: " << app.arguments().constFirst().toStdString() << " <foo.flt.xml> <foo.vwm.xml>";
return -1;
}
const QString flt = app.arguments().at(1);
const QString vwm = app.arguments().at(2);
BuildingControlUnit::VWM::Building building;
if (!BuildingControlUnit::VWM::XmlReader::readBuilding(vwm, building))
{
WARNING_LOG(app.baseLogger()) << "parsing failed for '" << flt;
return 1;
}
bool bAllOk = true;
INFO_LOG(app.baseLogger()) << "******** Building '" << building.name() << "' -> checkPolygons for duplicate...";
int numberOfDuplicates = building.checkPolygons();
if (numberOfDuplicates == 0)
INFO_LOG(app.baseLogger()) << "Building '" << building.name() << "' -> " << "fine, no duplicates founds";
else
{
WARNING_LOG(app.baseLogger()) << "Building '" << building.name() << "' -> first search: " << numberOfDuplicates << " duplicates found";
bAllOk = false;
}
// cleanup
{
int numberOfRemoved = building.cleanupPolygons();
WARNING_LOG(app.baseLogger()) << "Building '" << building.name() << "' -> cleanupPolygons: " << numberOfRemoved << " removed";
int numberOfDuplicates2 = building.checkPolygons();
WARNING_LOG(app.baseLogger()) << "Building '" << building.name() << "' -> second search: " << numberOfDuplicates2 << " duplicates found"
<< " bAllOk=" << bAllOk;
bAllOk = true;
}
BuildingControlUnit::BuildingBsmConfig bsmConfig;
BuildingControlUnit::BuildingBsmConfig bsmConfigOhneRaumbezug;
QMap<int, MyRoom> rooms;
std::vector<LtsUtils::QPoint3D> footprint;
if (!parseFlt(app.baseLogger(), flt, bsmConfig, bsmConfigOhneRaumbezug, rooms, footprint) )
{
// Exception:
// bldg_BN_Kanaele.flt.xml does not have REF_MOD / BSM
// so parseFlt return false;
// Exception:
// bldg_BN_Kanaele.flt.xml does not have REF_MOD / BSM
if (flt.contains(QStringLiteral("bldg_BN_Kanaele"))
|| flt.contains(QStringLiteral("bldg_0910"))
|| flt.contains(QStringLiteral("bldg_2105"))
|| flt.contains(QStringLiteral("bldg_2106"))
|| flt.contains(QStringLiteral("bldg_2107"))
|| flt.contains(QStringLiteral("bldg_2108"))
|| flt.contains(QStringLiteral("bldg_2109"))
|| flt.contains(QStringLiteral("bldg_2110"))
|| flt.contains(QStringLiteral("bldg_2112"))
|| flt.contains(QStringLiteral("bldg_2116"))
|| flt.contains(QStringLiteral("bldg_2117"))
|| flt.contains(QStringLiteral("bldg_2118"))
|| flt.contains(QStringLiteral("bldg_2121"))
|| flt.contains(QStringLiteral("bldg_2122"))
)
{
// check rooms instead of bsmMap
if (rooms.empty())
{
WARNING_LOG(app.baseLogger()) << "parsing failed for '" << flt
<< " (" << rooms.size() << ")";
return 2;
}
}
else
{
WARNING_LOG(app.baseLogger()) << "parsing failed for '" << flt
<< " (" << rooms.size() << ")";
return 2;
}
}
// footprint des Bldgs:
QPolygonF footprintPoly;
footprintPoly.reserve(footprint.size());
for (auto coord : qAsConst(footprint))
footprintPoly << coord.toPointF();
double maxZ = 0;
for(const MyRoom &room : qAsConst(rooms))
{
TRACE_LOG(app.baseLogger()) << "Room: " << room.id
<< ", bboxMin: " << room.bBoxMin
<< ", bboxMax: " << room.bBoxMax
<< ", center: " << room.center()
<< ", zMax: " << room.maxZ();
maxZ = std::max(maxZ, room.maxZ());
}
const QDomElement domRoot = BuildingControlUnit::readFile(flt, QStringLiteral("STREIF"));
if (domRoot.isNull())
{
WARNING_LOG(app.baseLogger()) << "domRoot isNull";
return 2;
}
//#define USE_BUILDINGROOMGEOMETRY
#ifdef USE_BUILDINGROOMGEOMETRY
const QDomElement domHdr = domRoot.firstChildElement(QStringLiteral("Header"));
const QDomElement &domGroup = domHdr.firstChildElement(QStringLiteral("Group"));
BuildingControlUnit::VWM::BuildingRoomGeometry buildingRoomGeometry;
if (!buildingRoomGeometry.init(domGroup))
{
WARNING_LOG(app.baseLogger()) << " BuildingRoomGeometry failed for '" << flt;
return -2;
}
#endif // USE_BUILDINGROOMGEOMETRY
// Guez-Building 1114:
// 2021-07-02 12:21:41.600 INFO BCU::VWM::Math |#| Searching nearest room for bsm position (6.023,-4.634,8.556), bsmViewDirection (0,0,1), hit direction (-0,-0,-1), #rooms = 11 (ies/Buildings/BuildingControlUnit/VWM/vwm_math.cpp:452)
// 2021-07-02 12:21:41.600 INFO BCU::VWM::Math |#| HitPosition: 1, roomId = 2301, outerWallIndex = 11, exclusionZoneIndex = -1 (ies/Buildings/BuildingControlUnit/VWM/vwm_math.cpp:539)
// 2021-07-02 12:21:41.600 WARN BCU::main |#| Building 'bldg_1114' -> Hit on center point for room results in hit pos behind a wall (-7.41573e-16m) instead in front - looks like the house is more than 8.556m high!?!?, (hitPos=state = HitPosition::State::OuterWall, roomId = 2301, outerWallIdx = 11, exclusionZoneIdx = -1, distance = -7.41573e-16 (Buildings/BuildingControlUnit/VWM/test_vwm_xml.cpp:217)
// 2021-12-17 13:50:42.658 WARN BCU::main |#| Building 'bldg_3127' -> Hit on center point for room results in hit pos behind a wall (-0.00194683m) instead in front - looks like the house is more than 8.681m high!?!?, (hitPos=state = HitPosition::State::OuterWall, roomId = 2401, outerWallIdx = 4, exclusionZoneIdx = -1, distance = -0.00194683 (Buildings/BuildingControlUnit/VWM/test_vwm_xml.cpp:408)
// --> accept s small neg hitPos.distance: // if (hitPos.distance < -0.00001) //
INFO_LOG(app.baseLogger()) << "******** Building '" << building.name() << "' -> BSMs ohne Raumbezug " << "(maxZ=" << maxZ << ")" ;
if (bsmConfigOhneRaumbezug.bsmMap.isEmpty())
{
INFO_LOG(app.baseLogger()) << "Building '" << building.name() << "' -> no outdoor BSM";
} else {
WARNING_LOG(app.baseLogger()) << "Building '" << building.name() << "' -> has outdoor BSMs. Size=" << bsmConfigOhneRaumbezug.bsmMap.size();
for (auto bsm : bsmConfigOhneRaumbezug.bsmMap)
{
WARNING_LOG(app.baseLogger()) << "Building '" << building.name() << "' -> has outdoor BSMs:"
<< "bsm " << bsm.id << " ; position: " << bsm.position
<< " ; bsm direction: " << bsm.direction;
}
}
INFO_LOG(app.baseLogger()) << "******** Building '" << building.name() << "' -> checkBsmPosition using rooms";
for(const MyRoom &myRoom : qAsConst(rooms))
{
const int roomIdToCheck = myRoom.id;
LtsUtils::QPoint3D center = myRoom.center();
center.setZ(maxZ);
// Bldg 1147, Raum 2203 (r 5075)
// Maybe the BSM is on the edge of an triangle (wall/ceiling is modelled using 2 triangles)
// |-----|
// | / |
// | / |
// | / |
// |/ |
// |-----|
//
// Bldg 4127, Raum 101, 102, 201, 301: Hit is at the edge of the roof (y value)
// Could be moved one millimeter to overcome that detection.
// Since we simulate AWES here, it´s not realistic to hit the edge:
center.rx() -= 0.1; // For bldg 1147, 3127
center.ry() -= 0.2; // For bldg 4127, 3127
const LtsUtils::QPoint3D direction(0,0,1); // bsm dir -> looking upwards
auto hitPos = BuildingControlUnit::VWM::Math::checkBsmPosition(center, direction, building.rooms());
if (hitPos.state != BuildingControlUnit::VWM::HitPosition::State::OuterWall)
{
// find room at building to get number of OuterWalls:
int numberOuterWalls = -1;
const BuildingControlUnit::VWM::Room &room = building.room(roomIdToCheck);
if (room.id() == roomIdToCheck)
numberOuterWalls = room.outerWalls().size();
if (numberOuterWalls == 0)
WARNING_LOG(app.baseLogger()) << "Building '" << building.name() << "' -> "
<< "Hit on center point for room " << roomIdToCheck << " will not hit building - no outterWalls"
<< " - position: " << center << ", bsm direction: " << direction
<< ", (hitPos=" << hitPos << ")";
else
{
// possible reasons: wall vertical | Aussentreppe
const bool withinFootprint = footprintPoly.containsPoint(center.toPointF(), Qt::OddEvenFill);
if ((footprintPoly.size() >= 4) && // valid
withinFootprint)
{
// Aussentreppen haben oft keine Wände...
WARNING_LOG(app.baseLogger()) << "Building '" << building.name() << "' -> "
<< "Hit on center point for room " << roomIdToCheck << " will not hit building - "
<< " maybe according outterWalls (#=" << numberOuterWalls << ") are vertical?"
<< " - position: " << center << ", bsm direction: " << direction
<< ", (hitPos=" << hitPos << ")";
} else {
// Aussentreppen liegen oft ausserhalb...
WARNING_LOG(app.baseLogger()) << "Building '" << building.name() << "' -> "
<< "Hit on center point for room " << roomIdToCheck << " will not hit building - "
<< " it´s OUT OF FOOTPRINT"
<< " - position: " << center << ", bsm direction: " << direction;
bAllOk = false;
}
}
}
// Guez-Building 1114: (renoirRepo 4722)
// 2021-07-02 12:21:41.600 INFO BCU::VWM::Math |#| Searching nearest room for bsm position (6.023,-4.634,8.556), bsmViewDirection (0,0,1), hit direction (-0,-0,-1), #rooms = 11 (ies/Buildings/BuildingControlUnit/VWM/vwm_math.cpp:452)
// 2021-07-02 12:21:41.600 INFO BCU::VWM::Math |#| HitPosition: 1, roomId = 2301, outerWallIndex = 11, exclusionZoneIndex = -1 (ies/Buildings/BuildingControlUnit/VWM/vwm_math.cpp:539)
// 2021-07-02 12:21:41.600 WARN BCU::main |#| Building 'bldg_1114' -> Hit on center point for room results in hit pos behind a wall (-7.41573e-16m) instead in front - looks like the house is more than 8.556m high!?!?, (hitPos=state = HitPosition::State::OuterWall, roomId = 2301, outerWallIdx = 11, exclusionZoneIdx = -1, distance = -7.41573e-16 (Buildings/BuildingControlUnit/VWM/test_vwm_xml.cpp:217)
// 2021-07-02 12:21:41.600 INFO BCU::VWM::Math |#| Searching nearest room for bsm position (6.023,-4.634,8.556), bsmViewDirection (0,0,1), hit direction (-0,-0,-1), #rooms = 11 (ies/Buildings/BuildingControlUnit/VWM/vwm_math.cpp:452)
// 2021-07-02 12:21:41.601 INFO BCU::VWM::Math |#| HitPosition: 1, roomId = 2301, outerWallIndex = 11, exclusionZoneIndex = -1 (ies/Buildings/BuildingControlUnit/VWM/vwm_math.cpp:539)
// 2021-07-02 12:21:41.601 WARN BCU::main |#| Building 'bldg_1114' -> Hit on center point for room results in hit pos behind a wall (-7.41573e-16m) instead in front - looks like the house is more than 8.556m high!?!?, (hitPos=state = HitPosition::State::OuterWall, roomId = 2301, outerWallIdx = 11, exclusionZoneIdx = -1, distance = -7.41573e-16 (Buildings/BuildingControlUnit/VWM/test_vwm_xml.cpp:217)
// --> accept s small neg hitPos.distance: // if (hitPos.distance < -0.00001) //
else if (hitPos.distance < -0.02)
{
WARNING_LOG(app.baseLogger()) << " Building '" << building.name() << "' -> "
<< "Hit on center point for room results in hit pos behind a wall ("
<< QString::number(hitPos.distance) << "m) instead in front - looks like the house is more than "
<< center.z() << "m high!?!?"
<< ", (hitPos=" << hitPos;
bAllOk = false;
}
else
{
// set new Z to compare with room height of room which is hit
center.setZ(rooms.value(hitPos.roomId).maxZ());
// hit calc -> mirror direction
hitPos = BuildingControlUnit::VWM::Math::getHitPosition(center, direction * -1, building.rooms());
INFO_LOG(app.baseLogger()) << " Building '" << building.name() << "' -> "
<< "Hit on center point for room " << myRoom.id << " looks fine - room which will be hit: " << hitPos.roomId
<< ", " << QString::number(hitPos.distance) << "m away from outer wall"
<< ((hitPos.distance < 1) ? "" : " - to far away from ceiling!");
}
} // for all rooms
INFO_LOG(app.baseLogger()) << "******** Building '" << building.name() << "' -> checkBsmPosition using BSMs";
for (const BuildingControlUnit::Bsm &bsm : qAsConst(bsmConfig.bsmMap))
{
const auto hitPos = BuildingControlUnit::VWM::Math::checkBsmPosition(bsm.position, bsm.direction, building.rooms());
if (hitPos.state != BuildingControlUnit::VWM::HitPosition::State::OuterWall)
{
WARNING_LOG(app.baseLogger()) << "Building '" << building.name() << "' -> "
<< "Effect on bsm " << bsm.id << " will not hit building ! - position: "
<< bsm.position << ", bsm direction: " << bsm.direction << ", state: " << hitPos.state;
bAllOk = false;
}
else if (hitPos.distance < -0.02)
{
WARNING_LOG(app.baseLogger()) << "Building '" << building.name() << "' -> "
<< "Effect on bsm " << bsm.id << " results in hit pos behind a wall ("
<< QString::number(hitPos.distance) << "m) instead in front - BSM is not modelled in the correct place: "
<< bsm.position << ", bsm direction: " << bsm.direction << ", roomId which was hit: " << hitPos.roomId;
bAllOk = false;
}
else
{
INFO_LOG(app.baseLogger()) << "Building '" << building.name() << "' -> "
<< "BSM with id " << bsm.id << " looks fine - room which will be hit: " << hitPos.roomId
<< ", " << QString::number(hitPos.distance) << "m away from outer wall";
}
}
#ifdef USE_BUILDINGROOMGEOMETRY
int counterOk = 0;
int counterZero = 0;
int counterToMuch = 0;
INFO_LOG(app.baseLogger()) << "******** Building '" << building.name() << "' -> pointIsInWhichRooms using rooms";
int heightZOffset = 2;
for (int heightZ = 1; heightZ<maxZ; )
{
INFO_LOG(app.baseLogger()) << "**** Building '" << building.name() << "' heightZ = " << heightZ;
for(const MyRoom &myRoom : qAsConst(rooms))
{
const int roomIdToCheck = myRoom.id;
LtsUtils::QPoint3D center = myRoom.center(); // myRoom.center(); is z-aware
LtsUtils::QPoint3D delayedDetonationLocation = center; // center of current room
// withinFootprint (Aussentreppen sind ausserhalb)
const bool withinFootprint = footprintPoly.containsPoint(delayedDetonationLocation.toPointF(), Qt::OddEvenFill);
if ((footprintPoly.size() >= 4) && // valid
withinFootprint)
{
// search for delayedDetonationLocation
QVector<int> roomsWithDetonation = buildingRoomGeometry.pointIsInWhichRooms(delayedDetonationLocation);
if (roomsWithDetonation.isEmpty())
++counterZero;
else if (roomsWithDetonation.size()==1)
++counterOk;
else
++counterToMuch;
if (roomsWithDetonation.size() == 1)
{
INFO_LOG(app.baseLogger()) << " Building / pointIsInWhichRooms '" << building.name() << "' -> "
<< ", roomIdToCheck = " << roomIdToCheck
<< ", detoLoc = " << delayedDetonationLocation
<< " fine, found just one room: " << roomsWithDetonation.first();
} else {
QString roomIdsStr(QStringLiteral("roomIds("));
for (auto roomId : qAsConst(roomsWithDetonation))
roomIdsStr.append(QString(QStringLiteral("%1 ")).arg(roomId));
roomIdsStr.append(QStringLiteral(")"));
WARNING_LOG(app.baseLogger()) << " Building / pointIsInWhichRooms '" << building.name() << "'"
<< ", roomIdToCheck = " << roomIdToCheck
<< ", delayedDetonationLocation = " << delayedDetonationLocation
<< " wrongSize roomsWithDetonation.size() != 1 , size=" << roomsWithDetonation.size()
<< ", roomIds=" << roomIdsStr;
bAllOk = false;
}
}
} // // for all rooms
heightZ += heightZOffset;
} // for heightZ
INFO_LOG(app.baseLogger()) << "******** Building '" << building.name() << "' -> pointIsInWhichRooms using rooms RESULT"
<< ", counterZero = " << counterZero
<< ", counterOk = " << counterOk
<< ", counterToMuch = " << counterToMuch
<< ", percentOk = " << counterOk*100.0 / (counterZero+counterOk+counterToMuch);
#endif // USE_BUILDINGROOMGEOMETRY
return bAllOk ? 0 : 5;
}