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

324 lines
10 KiB
C++
Executable File

/**
* @RDE_HEADER@
* Building VWM info
* $Id$
* $HeadURL$
* $Author$
* Created by Gerlinde Rudolphus, SLSA, 2017-01-15
*/
#pragma once
#include <QString>
#include <QMap>
#include <QVector>
#include <LtsUtilsCore/qpoint3d.h>
#include <logger.h>
#include "vwm_types.h"
#include <VWM/buildingcontrolvwm_export.h>
namespace BuildingControlUnit
{
namespace VWM
{
//
// class NeighbourRoom
//
class NeighbourRoom
{
public:
void setId(int id) { m_id = id; }
int id() const { return m_id; }
void setTransitionFactor(double transitionFactor) { m_transitionFactor = transitionFactor; }
double transitionFactor() const { return m_transitionFactor; }
private:
// static data from config
int m_id = 0;
double m_transitionFactor = 0;
};
using WallElement = QVector<LtsUtils::QPoint3D>;
using ExclusionZoneElement = QVector<LtsUtils::QPoint3D>;
// some helper functions
void wallElementToBottomLeftTopRight3D(const WallElement &wallElement,
LtsUtils::QPoint3D &bottomLeftOut,
LtsUtils::QPoint3D &topRightOut);
LtsUtils::QPoint3D centerOfWallElement3D(const WallElement &wallElement);
//
// class WallExclusionZoneBase
//
class WallExclusionZoneBase
{
public:
// from config
void setProtectiveFactor(double protectiveFactor) { m_protectiveFactor = protectiveFactor; }
double protectiveFactor() const { return m_protectiveFactor; }
// calculated from config
void setInitalProtection(double initialProtection, bool bResetProtection);
double initialProtection() const { return m_initialProtection; }
double protectionPercent() const {
if (m_initialProtection<=0.0)
return 0.0; // avoid nan (not-a-number)
return m_protection / m_initialProtection * 100;
} // for debug purposes
// calculated on hit
void updateProtection(const double RW, const double ZF, const double TF);
void setProtection(double protection) { m_protection = protection; }
double protection() const { return m_protection; }
protected:
WallExclusionZoneBase() = default;
// static data from config
double m_protectiveFactor = 0;
// initial data (Wall: BGPL * OWPL * OWPF, ExclusionZone: BGPL * EZPL * EZPF)
double m_initialProtection = 0;
// calculated data
double m_protection = 0;
};
//
// class ExclusionZone
//
class ExclusionZone : public WallExclusionZoneBase
{
public:
QVector<ExclusionZoneElement> &elements() { return m_elements; }
const QVector<ExclusionZoneElement> &elements() const { return m_elements; }
private:
QVector<ExclusionZoneElement> m_elements;
};
//
// class OuterWall
//
class OuterWall : public WallExclusionZoneBase
{
public:
QVector<WallElement> &elements() { return m_elements; }
const QVector<WallElement> &elements() const { return m_elements; }
QVector<ExclusionZone> &exclusionZones() { return m_exclusionZones; }
const QVector<ExclusionZone> &exclusionZones() const { return m_exclusionZones; }
bool isDummyWall() const { return m_elements.isEmpty(); }
private:
QVector<ExclusionZone> m_exclusionZones;
QVector<WallElement> m_elements;
};
//
// class Room
//
class Room
{
public:
void setId(int id) { m_id = id; }
int id() const { return m_id; }
bool isValid() const { return m_id != 0; }
bool isDirectHit() const { return m_directHit; }
void setDirectHit(bool directHit) { m_directHit = directHit; }
QMap<int, NeighbourRoom> &neighbours() { return m_neighbours; }
const QMap<int, NeighbourRoom> &neighbours() const { return m_neighbours; }
QVector<OuterWall> &outerWalls() { return m_outerWalls; }
const QVector<OuterWall> &outerWalls() const { return m_outerWalls; }
// Verstärkte Räume
void setFortifyFactor(double factorNew, bool bRecalcValues = true);
double fortifyFactor() const { return m_fortifyFactor; }
// calculated values
double damagePercent() const; // TODO: cache calculated value?
void setRemainingEffect(double remainingEffect) { m_remainingEffect = remainingEffect; }
double remainingEffect() const { return m_remainingEffect; }
// effect calculation
double calcRemainingEffect(const HitPosition &hitPos, const Charge &ammu) const;
void updateProtectionDirectHit(const HitPosition &hitPos, const Charge &ammu);
void updateProtectionIndirectHit(const HitPosition &hitPos, const Charge &ammu, double remainingEffect);
// returns false when the calculated effect is too low for a real change
bool updateProtectionNeighbourHit(const HitPosition &hitPos, const Charge &ammu, double remainingEffect, double transitionFactor);
// effects on Room
void init();
void destroy();
private:
// static data from config
int m_id = 0;
double m_remainingEffect = 0;
QMap<int, NeighbourRoom> m_neighbours;
QVector<OuterWall> m_outerWalls;
// dynamic data from excon
double m_fortifyFactor = 1.0;
bool m_directHit = false;
double protectionForHitPosition(const HitPosition &hitPos) const;
void setProtectionForHitPosition(const HitPosition &hitPos, double SG_neu);
static double calcRemainingEffect(double SG_alt, double ZF, double WF);
};
// exported for test xml reader
class BUILDINGCONTROLVWM_EXPORT Building
{
public:
Building();
int cleanupPolygons();
// used for xml file testing
int checkPolygons();
QString name() const { return m_name; }
void setName(const QString &name) { m_name = name; }
int modelId() const { return m_modelId; }
void setModelId(int modelId) { m_modelId = modelId; }
double buildingProtectionLevel() const { return m_buildingProtectionLevel; }
void setBuildingProtectionLevel(double buildingProtectionLevel) { m_buildingProtectionLevel = buildingProtectionLevel; }
int exclusionZoneProtectionLevel() const { return m_exclusionZoneProtectionLevel; }
void setExclusionZoneProtectionLevel(int exclusionZoneProtectionLevel) { m_exclusionZoneProtectionLevel = exclusionZoneProtectionLevel; }
int outerWallProtectionLevel() const { return m_outerWallProtectionLevel; }
void setOuterWallProtectionLevel(int outerWallProtectionLevel) { m_outerWallProtectionLevel = outerWallProtectionLevel; }
Room room(int roomId);
QMap<int, Room> &rooms() { return m_rooms; }
const QMap<int, Room> &rooms() const { return m_rooms; }
// calculated values
int damagePercent() const;
QVector<HitRoom> roomStates() const;
DamageState damageState() const;
// effects on building
void init();
void destroyAllRooms();
void setRoomState(DamageState damageState, const QVector<int> &afffectedRooms);
void setFortifyInfo(const QVector<FortifyInfo> &foritfyInfos);
bool hit(const LtsUtils::QPoint3D &pos, const LtsUtils::QPoint3D &dir, Charge charge, HitPosition *preCalculatedHitPosition = nullptr);
const HitPosition &lastHitPosition() const { return m_lastHitPosition; }
bool isLastHitPositionBelowGroundHack() const;
QString segmentProperties(const QString &hostname) const;
void setSegmentProperties(const QString &hostname, const QString &properties);
const QMap<QString, QString> segmentPropertyMap() const { return m_segmentProperties; }
void clearSegmentProperties() { m_segmentProperties.clear(); }
QString buildingProperties() const;
void setBuildingProperties(const QString &buildingProperties);
private:
void initRoom(Room &room) const;
static void destroyRoom(Room &room);
int checkDublicatePointsInPolygon(int roomId, int idx, int subIdx, const char *type,
const QVector<LtsUtils::QPoint3D> &points) const;
int cleanupDublicatePointsInPolygon(int roomId, int idx, int subIdx, const char *type,
QVector<LtsUtils::QPoint3D> &points) const;
struct NeighboursToCheck
{
NeighbourRoom room;
double remainEffect = 0;
NeighboursToCheck() = default;
NeighboursToCheck(const NeighbourRoom &r, double re)
: room(r), remainEffect(re)
{}
};
// for debugging purpose
static QString toString(const QVector<Building::NeighboursToCheck> &cont);
static QString toString(const QMap<int, Building::NeighboursToCheck> &cont);
static QString toString(const QSet<int> &cont);
QMap<int, NeighboursToCheck> checkHitNeighbours(const QMap<int, NeighboursToCheck> &neighbours,
const Charge &charge,
QSet<int> &currentGradeNeighbours,
QSet<int> &lowerGradeNeighbours);
private:
// static data from config
QString m_name;
int m_modelId{0};
double m_buildingProtectionLevel{0.0};
int m_exclusionZoneProtectionLevel{0};
int m_outerWallProtectionLevel{0};
QMap<int, Room> m_rooms;
QString m_buildingProperties;
QMap<QString, QString> m_segmentProperties; // By Hostname;
HitPosition m_lastHitPosition; // for debug purposes
NGL::INGLLogger &m_logger;
};
//
// class MakePlanar
//
/*!
* \brief The MakePlanar class takes points and makes them planar
* "Polylines" of VWM (like bldg_1101.flt.VWM_Building.xml) are sometimes not planar.
* That is difficult/impossible for the further steps
* So here (or at getCoordsForPlane) we try to make (most) walls planar
*/
class BUILDINGCONTROLVWM_EXPORT MakePlanar
{
public:
// helper #1
enum class DIMENSION
{
Undefined = -1,
X = 0,
Y = 1,
Z = 2
};
// helper #2
struct MyRange
{
double min{0.0};
double max{0.0};
double range() const { return fabs(max - min); } // keep neg values in mind
};
// ctor
explicit MakePlanar(const QVector<LtsUtils::QPoint3D> &poly);
QVector<LtsUtils::QPoint3D> calculate(bool *bMakePlanarDone = nullptr);
QVector<LtsUtils::QPoint3D> getPoly() const { return m_poly; }
double getRatio() const { return m_ratio; }
double getSmallestRange() const { return getRange(m_smallestDim).range(); }
DIMENSION getSmallestDim() const { return m_smallestDim; }
protected:
const MyRange &getRange(DIMENSION dim) const { return ranges[static_cast<int>(dim)]; }
double ratioOfSmallestAndBiggestDimension();
void makePlanar();
private:
QVector<LtsUtils::QPoint3D> m_poly;
std::vector<MyRange> ranges;
DIMENSION m_smallestDim{DIMENSION::X};
DIMENSION m_biggistDim{DIMENSION::X};
double m_ratio{0.0};
}; // class MakePlanar
} // namespace VWM
} // namespace BuildingControlUnit