added more cpp files for faster compile speeds

removed many obsolte elements
many improvements and fixes
This commit is contained in:
2018-07-20 15:00:43 +02:00
parent 7ee4e122e8
commit 5d002c3f2b
43 changed files with 1257 additions and 1361 deletions

View File

@@ -0,0 +1,251 @@
#include "MV2DElementStair.h"
#include "MV2DElement.h"
#include "HasMoveableNodes.h"
#include "MapViewElementHelper.h"
#include <Indoor/floorplan/v2/Floorplan.h>
/** is the given stair's end connected to ANY of the floorplan's floors? */
static inline bool stairEndConnected(const Floorplan::IndoorMap* map, const Floorplan::Floor* floor, const Floorplan::Stair* stair) {
const int stairEnd_cm = std::round( (floor->atHeight + stair->getParts().back().end.z) * 100 );
std::vector<int> floorsAtHeight_cm;
for (const Floorplan::Floor* f : map->floors) {
const int height_cm = std::round(f->atHeight*100);
floorsAtHeight_cm.push_back(height_cm);
}
const bool connected = std::find(floorsAtHeight_cm.begin(), floorsAtHeight_cm.end(), stairEnd_cm) != floorsAtHeight_cm.end();
return connected;
}
static inline float clamp01(const float val) {
if (val < 0) {return 0;}
if (val > 1) {return 1;}
return val;
}
MV2DElementStair::MV2DElementStair(Floorplan::IndoorMap* map, Floorplan::Floor* floor, Floorplan::Stair* stair)
: map(map), floor(floor), stair(stair) {
;
}
BBox2 MV2DElementStair::getBoundingBox() const {
BBox2 bbox;
if (dynamic_cast<Floorplan::StairFreeform*>(stair)) {
Floorplan::StairFreeform* stair = dynamic_cast<Floorplan::StairFreeform*>(this->stair);
for (const Floorplan::StairPart p : stair->parts) {
bbox.add(p.start.xy());
bbox.add(p.end.xy());
}
}
return bbox;
}
/** get the element's minimal distance (nearest whatsoever) to the given point */
ClickDist MV2DElementStair::getMinDistanceXY(const Point2 p) const {
auto comp = [p] (const Floorplan::StairPart& p1, const Floorplan::StairPart& p2) {
const ClickDist d1 = MapElementHelper::getLineDistanceXY(p1.start.xy(), p1.end.xy(), p);
const ClickDist d2 = MapElementHelper::getLineDistanceXY(p2.start.xy(), p2.end.xy(), p);
return d1 < d2;
};
auto parts = stair->getParts();
auto min = std::min_element(parts.begin(), parts.end(), comp);
return MapElementHelper::getLineDistanceXY(min->start.xy(), min->end.xy(), p);
}
int MV2DElementStair::getSelPart() const {return getSelectedNode() < 0 ? getSelectedNode() : getSelectedNode() / 2;}
int MV2DElementStair::getSelNode() const {return getSelectedNode() < 0 ? getSelectedNode() : getSelectedNode() % 2;}
void MV2DElementStair::paint(Painter& p) {
Floorplan::StairFreeform* stair = dynamic_cast<Floorplan::StairFreeform*>(this->stair);
// draw all parts of the stair (all polygons)
p.setPenBrush(Qt::black, Qt::NoBrush);
std::vector<Floorplan::StairPart> parts = stair->getParts();
std::vector<Floorplan::Quad3> quads = Floorplan::getQuads(parts, floor);
// skip drawing?
BBox2 bbox;
for (const Floorplan::Quad3& q : quads) {
bbox.add(q.p1.xy());
bbox.add(q.p2.xy());
bbox.add(q.p3.xy());
bbox.add(q.p4.xy());
}
if (!p.isVisible(bbox)) {
return;
}
for (int i = 0; i < (int) parts.size(); ++i) {
const Floorplan::StairPart& part = parts[i];
const Floorplan::Quad3& quad = quads[i];
// fill the polygon with a gradient corresponding with the stair's height relative to the floor's height
QLinearGradient gradient(p.s.xms(part.start.x), p.s.yms(part.start.y), p.s.xms(part.end.x), p.s.yms(part.end.y));
const float p1 = 0.1 + clamp01( part.start.z / floor->height) * 0.8;
const float p2 = 0.1 + clamp01( part.end.z / floor->height) * 0.8;
gradient.setColorAt(0, QColor(p1*128, p1*128, p1*255, 128));
gradient.setColorAt(1, QColor(p2*128, p2*128, p2*255, 128));
p.setBrush(gradient);
p.setPen(QColor(0,0,0,128));
// polygon-construction
//const Floorplan::Quad3 quad = part.getQuad(floor);
const std::vector<Point3> points = {quad.p1, quad.p2, quad.p3, quad.p4};
p.drawPolygon(points);
QPen pen;
pen.setWidth(5);
pen.setColor(QColor(255,0,0));
p.setPen(pen);
// LINT disconnected start
if (i == 0) {
if (quad.p1.z != floor->getStartingZ()) {
p.drawLine(quad.p1, quad.p2);
}
}
// LINT disconnected end
if (i == (int) parts.size() - 1) {
//if (quad.p3.z != floor->getEndingZ()) {
if (!stairEndConnected(map, floor, stair)) {
p.drawLine(quad.p3, quad.p4);
}
}
// LINT disconnected within
if (i > 0) {
if (quads[i-1].p4.z != quads[i-0].p1.z) {
p.drawLine(quad.p1, quad.p2);
}
}
}
if (hasFocus()) {
int cnt = 0;
std::vector<Floorplan::StairPart> parts = stair->getParts();
for (const Floorplan::StairPart& part : parts) {
//p.setPenBrush(Qt::black, (cnt == getSelPart() && getSelNode() == 0) ? CFG::SEL_COLOR : Qt::NoBrush); // part start
//p.drawCircle(part.start.xy()); // DEPRECATED
//p.setPenBrush(Qt::black, (cnt == getSelPart() && getSelNode() == 1) ? CFG::SEL_COLOR : Qt::NoBrush); // part end
//p.drawRect(part.end.xy()); // DEPRECATED
p.setPenBrush(Qt::blue, Qt::NoBrush);
Point2 ctr = (part.start+part.end).xy() / 2;
p.drawText(ctr, "p" + std::to_string(cnt+1)); // part name
++cnt;
}
for (int i = 0; i < (int)parts.size() - 1; ++i) {
const Point3 p1 = parts[i+0][1];
const Point3 p2 = parts[i+1][0];
p.drawLine(p1.xy(), p2.xy());
}
}
}
bool MV2DElementStair::keyPressEvent(MapView2D* v, QKeyEvent *e) {
(void) v;
(void) e;
Floorplan::StairFreeform* stair = dynamic_cast<Floorplan::StairFreeform*>(this->stair);
if (e->key() == Qt::Key_Delete) {
// delete the currently selected vertex?
if (getSelPart() != -1) {
// stair->nodes.erase(stair->nodes.begin() + selIdx);
// selIdx = -1;
// return true;
}
} else if (e->key() == Qt::Key_Plus && getSelPart() != -1) {
// int idx1 = selIdx;
// int idx2 = (selIdx + 1) % stair->nodes.size();
// int idxNew = idx2;
// Point3 pNew = (stair->nodes[idx1] + stair->nodes[idx2]) / 2.0f;
// stair->nodes.insert(stair->nodes.begin() + idxNew, pNew);
// selIdx = idxNew;
// return true;
const int idxNew = getSelPart() + 1;
const Point3 p0 = stair->parts[getSelPart()][1];
const Point3 p1 = p0 + Point3(1,1,0);
const Point3 p2 = p1 + Point3(2,2,0);
const float w = stair->parts[getSelPart()].width;
stair->parts.insert(stair->parts.begin() + idxNew, Floorplan::StairPart(p1, p2, w));
return true;
}
// not consumed
return false;
}
void MV2DElementStair::onFocus() {
// TODO?
}
void MV2DElementStair::onUnfocus() {
sel = false;
}
std::vector<MoveableNode> MV2DElementStair::getMoveableNodes() const {
std::vector<MoveableNode> nodes;
Floorplan::StairFreeform* stair = dynamic_cast<Floorplan::StairFreeform*>(this->stair);
// get a list of all moveable nodes (2 per stair-part)
int idx = 0;
for (size_t part = 0; part < stair->parts.size(); ++part) {
for (int node = 0; node < 2; ++node) {
MoveableNode mn(idx++, stair->parts[part][node].xy());
nodes.push_back(mn);
}
}
return nodes;
}
void MV2DElementStair::onNodeMove(MapView2D* v, const int userIdx, const Point2 newPos) {
(void) v;
// convert node-index back to stair-part and node-nr within stair-part
const int selPart = userIdx / 2;
const int selNode = userIdx % 2;
// move the node
Floorplan::StairFreeform* stair = dynamic_cast<Floorplan::StairFreeform*>(this->stair);
stair->parts[selPart][selNode].x = newPos.x;
stair->parts[selPart][selNode].y = newPos.y;
}
void MV2DElementStair::onNodeMoved(MapView2D* v, const int userIdx, const Point2 newPos) {
(void) userIdx;
(void) newPos;
emit v->onElementChange(this);
}
void MV2DElementStair::onNodeSelect(MapView2D* v, const int userIdx) {
HasMoveableNodes::onNodeSelect(v, userIdx);
emit v->onElementChange(this);
}