591 lines
26 KiB
C++
Executable File
591 lines
26 KiB
C++
Executable File
/**
|
||
* @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;
|
||
}
|