performance enhancements
better 2D drawing
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||
#include "Renderable2D.h"
|
||||
#include <QLinearGradient>
|
||||
|
||||
/**
|
||||
* draw the floor itself (outline, obstacles)
|
||||
@@ -27,34 +28,145 @@ protected:
|
||||
if (floor->atHeight < r.clip.belowHeight_m) {return;}
|
||||
if (floor->atHeight > r.clip.aboveHeight_m) {return;}
|
||||
|
||||
qp.setPen(Qt::black);
|
||||
for (const Floorplan::FloorObstacle* obs : floor->obstacles) {
|
||||
const Floorplan::FloorObstacleLine* line = dynamic_cast<const Floorplan::FloorObstacleLine*>(obs);
|
||||
if (line) {drawLine(qp, s, line);}
|
||||
if (line) {drawObstacle(qp, s, line);}
|
||||
}
|
||||
|
||||
qp.setPen(Qt::gray);
|
||||
for (const Floorplan::FloorOutlinePolygon* poly : floor->outline) {
|
||||
drawOutline(qp, s, poly);
|
||||
}
|
||||
|
||||
for (const Floorplan::Stair* stair : floor->stairs) {
|
||||
const Floorplan::StairFreeform* sf = dynamic_cast<const Floorplan::StairFreeform*>(stair);
|
||||
if (sf) {drawStair(qp, s, sf);}
|
||||
}
|
||||
|
||||
for (const Floorplan::Elevator* elevator : floor->elevators) {
|
||||
drawElevator(qp, s, elevator);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void drawLine(QPainter& qp, const Scaler2D& s, const Floorplan::FloorObstacleLine* line) {
|
||||
static inline QPen getPen(Floorplan::Material mat, Floorplan::ObstacleType type) {
|
||||
using namespace Floorplan;
|
||||
QPen pen; pen.setColor(Qt::darkGray);
|
||||
if (mat == Material::CONCRETE) {pen.setWidth(3);}
|
||||
if (mat == Material::GLASS) {pen.setStyle(Qt::PenStyle::DotLine);}
|
||||
if (type == ObstacleType::HANDRAIL) {pen.setStyle(Qt::PenStyle::DashLine);}
|
||||
if (type == ObstacleType::UNKNOWN) {pen.setColor(Qt::red); pen.setWidth(5);}
|
||||
if (type == ObstacleType::PILLAR) {pen.setColor(Qt::red); pen.setWidth(5);}
|
||||
|
||||
return pen;
|
||||
}
|
||||
|
||||
void drawObstacle(QPainter& qp, const Scaler2D& s, const Floorplan::FloorObstacleLine* line) {
|
||||
const Point2 pt1 = s.mapToScreen(line->from);
|
||||
const Point2 pt2 = s.mapToScreen(line->to);
|
||||
qp.setPen(getPen(line->material, line->type));
|
||||
qp.drawLine(pt1.x, pt1.y, pt2.x, pt2.y);
|
||||
}
|
||||
|
||||
void drawOutline(QPainter& qp, const Scaler2D& s, const Floorplan::FloorOutlinePolygon* poly) {
|
||||
const int num = poly->poly.points.size();
|
||||
for (int i = 0; i < num; ++i) {
|
||||
const Point2 pt1 = s.mapToScreen(poly->poly.points[(i+0)]);
|
||||
const Point2 pt2 = s.mapToScreen(poly->poly.points[(i+1)%num]);
|
||||
qp.drawLine(pt1.x, pt1.y, pt2.x, pt2.y);
|
||||
void drawElevator(QPainter& qp, const Scaler2D& s, const Floorplan::Elevator* elevator) {
|
||||
const QPolygon qpoly = toQPolygon(elevator->getPoints(), s);
|
||||
qp.setBrush(Qt::gray);
|
||||
qp.setPen(Qt::black);
|
||||
qp.drawPolygon(qpoly);
|
||||
}
|
||||
|
||||
void drawStair(QPainter& qp, const Scaler2D& s, const Floorplan::StairFreeform* stair) {
|
||||
|
||||
std::vector<Floorplan::StairPart> parts = stair->getParts();
|
||||
std::vector<Floorplan::Quad3> quads = Floorplan::getQuads(parts, floor);
|
||||
|
||||
for (int i = 0; i < (int) parts.size(); ++i) {
|
||||
|
||||
const Floorplan::StairPart& part = parts[i];
|
||||
const Floorplan::Quad3& quad = quads[i];
|
||||
|
||||
const Point2 start = s.mapToScreen(part.start.xy());
|
||||
const Point2 end = s.mapToScreen(part.end.xy());
|
||||
|
||||
// fill the polygon with a gradient corresponding with the stair's height relative to the floor's height
|
||||
QLinearGradient gradient(start.x, start.y, end.x, 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*255, p1*255, p1*255));
|
||||
gradient.setColorAt(1, QColor(p2*255, p2*255, p2*255));
|
||||
qp.setBrush(gradient);
|
||||
qp.setPen(QColor(0,0,0,128));
|
||||
|
||||
// polygon-construction
|
||||
QPolygon poly;
|
||||
poly.push_back(toQPoint(s.mapToScreen(quad.p1.xy())));
|
||||
poly.push_back(toQPoint(s.mapToScreen(quad.p2.xy())));
|
||||
poly.push_back(toQPoint(s.mapToScreen(quad.p3.xy())));
|
||||
poly.push_back(toQPoint(s.mapToScreen(quad.p4.xy())));
|
||||
qp.drawPolygon(poly);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** draw the given outline polygon */
|
||||
void drawOutline(QPainter& qp, const Scaler2D& s, const Floorplan::FloorOutlinePolygon* poly) {
|
||||
|
||||
// configure the drawing
|
||||
if (poly->method == Floorplan::OutlineMethod::ADD) {
|
||||
qp.setPen(Qt::gray);
|
||||
qp.setBrush(Qt::NoBrush);
|
||||
} else if (poly->method == Floorplan::OutlineMethod::REMOVE) {
|
||||
QBrush brush;
|
||||
brush.setStyle(Qt::BrushStyle::DiagCrossPattern);
|
||||
brush.setColor(QColor(0,0,0));
|
||||
qp.setPen(Qt::gray);
|
||||
qp.setBrush(brush);
|
||||
}
|
||||
|
||||
// construct the polygon
|
||||
const int num = poly->poly.points.size();
|
||||
QPolygon qpoly;
|
||||
for (int i = 0; i < num; ++i) {
|
||||
qpoly.push_back(toQPoint(s.mapToScreen(poly->poly.points[(i+0)])));
|
||||
}
|
||||
|
||||
// draw the polygon
|
||||
qp.drawPolygon(qpoly);
|
||||
|
||||
}
|
||||
|
||||
/** convert floorplan polygon to QPolygon */
|
||||
static inline QPolygon toQPolygon(const Floorplan::Polygon2& poly) {
|
||||
QPolygon qpoly;
|
||||
for (const Point2 p : poly.points) {
|
||||
qpoly.push_back(QPoint(p.x, p.y));
|
||||
}
|
||||
return qpoly;
|
||||
}
|
||||
|
||||
/** convert floorplan polygon to QPolygon */
|
||||
static inline QPolygon toQPolygon(const Floorplan::Polygon2& poly, const Scaler2D& s) {
|
||||
QPolygon qpoly;
|
||||
for (const Point2 _p : poly.points) {
|
||||
const Point2 p = s.mapToScreen(_p);
|
||||
qpoly.push_back(QPoint(p.x, p.y));
|
||||
}
|
||||
return qpoly;
|
||||
}
|
||||
|
||||
/** convert Point2 to QPoint */
|
||||
static inline QPoint toQPoint(const Point2 p) {
|
||||
return QPoint(p.x, p.y);
|
||||
}
|
||||
|
||||
/** helper method. limit val to [0:1] */
|
||||
static inline float clamp01(const float val) {
|
||||
if (val < 0) {return 0;}
|
||||
if (val > 1) {return 1;}
|
||||
return val;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -21,19 +21,19 @@ MapView2D::MapView2D(QWidget *parent) : QWidget(parent) {
|
||||
setFocusPolicy(Qt::StrongFocus);
|
||||
setRenderHeight(0);
|
||||
|
||||
|
||||
colorPoints = new ColorPoints2D();
|
||||
elements.push_back(colorPoints);
|
||||
elementsB.push_back(colorPoints);
|
||||
|
||||
pathToDest = new Path2D();
|
||||
pathToDest->setColor(Qt::blue);
|
||||
pathToDest->setWidth(10);
|
||||
elements.push_back(pathToDest);
|
||||
elementsB.push_back(pathToDest);
|
||||
|
||||
pathWalked = new Path2D();
|
||||
pathToDest->setColor(Qt::black);
|
||||
pathToDest->setWidth(5);
|
||||
elements.push_back(pathWalked);
|
||||
|
||||
elementsB.push_back(pathWalked);
|
||||
|
||||
// buttons
|
||||
//menu = new QWidget(this);
|
||||
@@ -90,11 +90,11 @@ void MapView2D::setMap(WiFiCalibrationDataModel* mdl, Floorplan::IndoorMap* map)
|
||||
|
||||
for (Floorplan::Floor* floor : map->floors) {
|
||||
Floor2D* f = new Floor2D(floor);
|
||||
elements.push_back(f);
|
||||
elementsA.push_back(f);
|
||||
}
|
||||
|
||||
wifiCalib = new WiFiCalibTool(mdl, map);
|
||||
elements.push_back(wifiCalib);
|
||||
elementsB.push_back(wifiCalib);
|
||||
|
||||
scaler.setCenterM(Point2(70, 35));
|
||||
|
||||
@@ -177,9 +177,8 @@ void MapView2D::paintEvent(QPaintEvent*) {
|
||||
qp.fillRect(0, 0, width(), height(), Qt::white);
|
||||
|
||||
// render elements
|
||||
for (Renderable2D* r : elements) {
|
||||
r->render(qp, scaler, renderParams);
|
||||
}
|
||||
for (Renderable2D* r : elementsA) {r->render(qp, scaler, renderParams);}
|
||||
for (Renderable2D* r : elementsB) {r->render(qp, scaler, renderParams);}
|
||||
|
||||
qp.end();
|
||||
|
||||
|
||||
@@ -39,7 +39,9 @@ class MapView2D : public QWidget {
|
||||
|
||||
private:
|
||||
|
||||
std::vector<Renderable2D*> elements;
|
||||
std::vector<Renderable2D*> elementsA;
|
||||
std::vector<Renderable2D*> elementsB;
|
||||
|
||||
ColorPoints2D* colorPoints = nullptr;
|
||||
Path2D* pathToDest = nullptr;
|
||||
Path2D* pathWalked = nullptr;
|
||||
|
||||
Reference in New Issue
Block a user