Initial commit

This commit is contained in:
torsten committed 2026-08-13 18:33:10 +02:00
commit b7d90b9afe
16245 files changed
+3396666

No files matched your search

@@ -0,0 +1,590 @@
/**
* @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;
}