added more cpp files for faster compile speeds
removed many obsolte elements many improvements and fixes
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <Indoor/geo/Point2.h>
|
||||
#include "../2D/MapView2D.h"
|
||||
#include <vector>
|
||||
|
||||
/** the selectable/moveable node */
|
||||
struct MoveableNode {
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <Indoor/geo/Line2.h>
|
||||
|
||||
#include "ClickDist.h"
|
||||
#include "HasMoveableNodes.h"
|
||||
|
||||
/**
|
||||
* represents one drawable, selectable, editable, ...
|
||||
@@ -36,7 +37,20 @@ public:
|
||||
/** repaint me */
|
||||
virtual void paint(Painter& p) = 0;
|
||||
|
||||
/** repaint me, 2nd layer (e.g. moveable nodes) */
|
||||
virtual void paintAfter(Painter& p) {
|
||||
|
||||
// HasMoveableNodes? -> paint them here
|
||||
HasMoveableNodes* e = dynamic_cast<HasMoveableNodes*>(this);
|
||||
if (e) {
|
||||
for (const MoveableNode& n : e->getMoveableNodes()) {
|
||||
const bool sel = e->getSelectedNode() == n.userIdx; // node is selected
|
||||
const bool foc = hasFocus(); // element (with nodes) currently focused
|
||||
p.drawNode(n.pos, foc, sel);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** got focus */
|
||||
void focus() {
|
||||
|
||||
@@ -47,28 +47,23 @@ public:
|
||||
static const QPixmap& pixmapFocused = UIHelper::getPixmapColored("wifi", CFG::FOCUS_COLOR, 16);
|
||||
static const QPixmap& pixmapSel = UIHelper::getPixmapColored("wifi", CFG::SEL_COLOR, 16);
|
||||
|
||||
|
||||
if (selectedUserIdx == 0) {
|
||||
//p.setPenBrush(Qt::black, CFG::SEL_COLOR);
|
||||
//p.drawCircle(ap->pos.xy());
|
||||
p.drawPixmap(ap->pos.xy(), pixmapSel);
|
||||
} else if (hasFocus()) {
|
||||
//p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||
//p.drawCircle(ap->pos.xy());
|
||||
p.drawPixmap(ap->pos.xy(), pixmapFocused);
|
||||
} else {
|
||||
//p.setPenBrush(Qt::gray, Qt::NoBrush);
|
||||
//p.drawCircle(ap->pos.xy());
|
||||
p.drawPixmap(ap->pos.xy(), pixmapUnfocused);
|
||||
}
|
||||
|
||||
// label
|
||||
p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||
p.drawDot(ap->pos.xy());
|
||||
//p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||
//p.drawDot(ap->pos.xy());
|
||||
if (p.getScaler().getScale() >= 25) {
|
||||
p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||
const std::string str = ap->name + " (" + ap->mac + ")";
|
||||
p.p->drawText(p.getScaler().xms(ap->pos.x) + 10, p.getScaler().yms(ap->pos.y) + 5, str.c_str());
|
||||
} else if (p.getScaler().getScale() >= 10) {
|
||||
} else if (p.getScaler().getScale() >= 12) {
|
||||
p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||
const std::string str = ap->name;
|
||||
p.p->drawText(p.getScaler().xms(ap->pos.x) + 10, p.getScaler().yms(ap->pos.y) + 5, str.c_str());
|
||||
}
|
||||
@@ -90,27 +85,6 @@ public:
|
||||
emit v->onElementChange(this);
|
||||
}
|
||||
|
||||
virtual void mousePressed(MapView2D* v, const Point2 p) override {
|
||||
(void) v;
|
||||
(void) p;
|
||||
}
|
||||
|
||||
virtual void mouseMove(MapView2D* v, const Point2 p) override {
|
||||
(void) v;
|
||||
(void) p;
|
||||
}
|
||||
|
||||
virtual void mouseReleased(MapView2D* v, const Point2 p) override {
|
||||
(void) v;
|
||||
(void) p;
|
||||
}
|
||||
|
||||
virtual bool keyPressEvent(MapView2D* v, QKeyEvent *e) override {
|
||||
(void) v;
|
||||
(void) e;
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void onFocus() override {
|
||||
;
|
||||
}
|
||||
|
||||
@@ -41,27 +41,22 @@ public:
|
||||
static const QPixmap& pixmapSel = UIHelper::getPixmapColored("beacon", CFG::SEL_COLOR, 16);
|
||||
|
||||
if (selectedUserIdx == 0) {
|
||||
//p.setPenBrush(Qt::black, CFG::SEL_COLOR);
|
||||
//p.drawCircle(b->pos.xy());
|
||||
p.drawPixmap(b->pos.xy(), pixmapSel);
|
||||
|
||||
} else if (hasFocus()) {
|
||||
//p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||
//p.drawCircle(b->pos.xy());
|
||||
p.drawPixmap(b->pos.xy(), pixmapFocused);
|
||||
} else {
|
||||
//p.setPenBrush(Qt::gray, Qt::NoBrush);
|
||||
//p.drawCircle(b->pos.xy());
|
||||
p.drawPixmap(b->pos.xy(), pixmapUnfocused);
|
||||
}
|
||||
|
||||
// label
|
||||
p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||
p.drawDot(b->pos.xy());
|
||||
//p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||
//p.drawDot(b->pos.xy());
|
||||
if (p.getScaler().getScale() >= 25) {
|
||||
p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||
const std::string str = b->name + " (" + b->mac + ")";
|
||||
p.p->drawText(p.getScaler().xms(b->pos.x) + 10, p.getScaler().yms(b->pos.y) + 5, str.c_str());
|
||||
} else if (p.getScaler().getScale() >= 10) {
|
||||
} else if (p.getScaler().getScale() >= 12) {
|
||||
p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||
const std::string str = b->name;
|
||||
p.p->drawText(p.getScaler().xms(b->pos.x) + 10, p.getScaler().yms(b->pos.y) + 5, str.c_str());
|
||||
}
|
||||
@@ -91,31 +86,6 @@ public:
|
||||
;
|
||||
}
|
||||
|
||||
/** mouse pressed at the given point */
|
||||
virtual void mousePressed(MapView2D* v, const Point2 p) override {
|
||||
(void) v;
|
||||
(void) p;
|
||||
}
|
||||
|
||||
/** mouse moved to the given point */
|
||||
virtual void mouseMove(MapView2D* v, const Point2 p) override {
|
||||
(void) v;
|
||||
(void) p;
|
||||
}
|
||||
|
||||
/** mouse released */
|
||||
virtual void mouseReleased(MapView2D* v, const Point2 p) override {
|
||||
(void) v;
|
||||
(void) p;
|
||||
}
|
||||
|
||||
virtual bool keyPressEvent(MapView2D* v, QKeyEvent *e) override {
|
||||
(void) v;
|
||||
(void) e;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // MV2DELEMENTBEACON_H
|
||||
|
||||
90
mapview/2D/MV2DElementElevator.cpp
Normal file
90
mapview/2D/MV2DElementElevator.cpp
Normal file
@@ -0,0 +1,90 @@
|
||||
#include "MV2DElementElevator.h"
|
||||
|
||||
#include "MV2DElement.h"
|
||||
#include "HasMoveableNodes.h"
|
||||
|
||||
#include "MapViewElementHelper.h"
|
||||
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||
|
||||
#include "../../UIHelper.h"
|
||||
|
||||
|
||||
/** is the given elevator's end connected to ANY of the floorplan's floors? */
|
||||
static inline bool elevatorEndConnected(const Floorplan::IndoorMap* map, const Floorplan::Floor* floor, const Floorplan::Elevator* e) {
|
||||
const int elevatorEnd_cm = std::round( (floor->atHeight + e->height_m) * 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(), elevatorEnd_cm) != floorsAtHeight_cm.end();
|
||||
return connected;
|
||||
}
|
||||
|
||||
|
||||
|
||||
MV2DElementElevator::MV2DElementElevator(Floorplan::IndoorMap* map, Floorplan::Floor* floor, Floorplan::Elevator* elevator) : map(map), floor(floor), elevator(elevator) {
|
||||
;
|
||||
}
|
||||
|
||||
BBox2 MV2DElementElevator::getBoundingBox() const {
|
||||
BBox2 bbox;
|
||||
const float max = std::max(elevator->width, elevator->depth);
|
||||
bbox.add(Point2(elevator->center.x, elevator->center.y));
|
||||
bbox.grow(Point2(max/2, max/2));
|
||||
return bbox;
|
||||
}
|
||||
|
||||
ClickDist MV2DElementElevator::getMinDistanceXY(const Point2 p) const {
|
||||
// std::vector<Point2> points = elevator->getPoints().points;
|
||||
// points.push_back(elevator->center);
|
||||
// auto it minEl = std::min_element(points.begin(), points.end(),
|
||||
return ClickDist(p.getDistance(elevator->center), ClickDistType::DIRECT);
|
||||
}
|
||||
|
||||
void MV2DElementElevator::paint(Painter& p) {
|
||||
|
||||
// area
|
||||
const Floorplan::Polygon2 poly = elevator->getPoints();
|
||||
p.setPenBrush(Qt::gray, Qt::lightGray);
|
||||
p.drawPolygon(poly.points);
|
||||
|
||||
// outline
|
||||
QPen pen; pen.setWidth(2); pen.setColor(QColor(0,0,0));
|
||||
|
||||
if (!elevatorEndConnected(map, floor, elevator)) {pen.setColor(QColor(255,0,0));}
|
||||
if (elevator->height_m == 0) {pen.setColor(QColor(255,0,0));}
|
||||
|
||||
p.setPenBrush(pen, Qt::NoBrush);
|
||||
//p.drawLine(poly.points[0], poly.points[1]);
|
||||
p.drawLine(poly.points[1], poly.points[2]);
|
||||
p.drawLine(poly.points[2], poly.points[3]);
|
||||
p.drawLine(poly.points[3], poly.points[0]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::vector<MoveableNode> MV2DElementElevator::getMoveableNodes() const {
|
||||
return { MoveableNode(0, elevator->center) };
|
||||
}
|
||||
|
||||
void MV2DElementElevator::onNodeMove(MapView2D* v, const int userIdx, const Point2 newPos) {
|
||||
(void) v;
|
||||
if (userIdx == 0) {elevator->center.x = newPos.x; elevator->center.y = newPos.y;}
|
||||
}
|
||||
|
||||
void MV2DElementElevator::onNodeMoved(MapView2D* v, const int userIdx, const Point2 newPos) {
|
||||
(void) userIdx;
|
||||
(void) newPos;
|
||||
emit v->onElementChange(this);
|
||||
}
|
||||
|
||||
void MV2DElementElevator::onFocus() {
|
||||
;
|
||||
}
|
||||
|
||||
void MV2DElementElevator::onUnfocus() {
|
||||
;
|
||||
}
|
||||
|
||||
@@ -4,11 +4,8 @@
|
||||
#include "MV2DElement.h"
|
||||
#include "HasMoveableNodes.h"
|
||||
|
||||
#include "MapViewElementHelper.h"
|
||||
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||
|
||||
#include "../../UIHelper.h"
|
||||
|
||||
class MV2DElementElevator : public MV2DElement, public HasMoveableNodes {
|
||||
|
||||
private:
|
||||
@@ -20,117 +17,26 @@ private:
|
||||
public:
|
||||
|
||||
/** ctor with the AP to render/edit */
|
||||
MV2DElementElevator(Floorplan::IndoorMap* map, Floorplan::Floor* floor, Floorplan::Elevator* elevator) : map(map), floor(floor), elevator(elevator) {;}
|
||||
MV2DElementElevator(Floorplan::IndoorMap* map, Floorplan::Floor* floor, Floorplan::Elevator* elevator);
|
||||
|
||||
|
||||
BBox2 getBoundingBox() const override {
|
||||
BBox2 bbox;
|
||||
const float max = std::max(elevator->width, elevator->depth);
|
||||
bbox.add(Point2(elevator->center.x, elevator->center.y));
|
||||
bbox.grow(Point2(max/2, max/2));
|
||||
return bbox;
|
||||
}
|
||||
BBox2 getBoundingBox() const override;
|
||||
|
||||
/** get the element's minimal distance (nearest whatsoever) to the given point */
|
||||
ClickDist getMinDistanceXY(const Point2 p) const override {
|
||||
// std::vector<Point2> points = elevator->getPoints().points;
|
||||
// points.push_back(elevator->center);
|
||||
// auto it minEl = std::min_element(points.begin(), points.end(),
|
||||
return ClickDist(p.getDistance(elevator->center), ClickDistType::DIRECT);
|
||||
}
|
||||
ClickDist getMinDistanceXY(const Point2 p) const override;
|
||||
|
||||
/** repaint me */
|
||||
void paint(Painter& p) override {
|
||||
void paint(Painter& p) override;
|
||||
|
||||
// area
|
||||
const Floorplan::Polygon2 poly = elevator->getPoints();
|
||||
p.setPenBrush(Qt::gray, Qt::lightGray);
|
||||
p.drawPolygon(poly.points);
|
||||
virtual std::vector<MoveableNode> getMoveableNodes() const override;
|
||||
|
||||
// outline
|
||||
QPen pen; pen.setWidth(2); pen.setColor(QColor(0,0,0));
|
||||
virtual void onNodeMove(MapView2D* v, const int userIdx, const Point2 newPos) override;
|
||||
|
||||
if (!elevatorEndConnected(map, floor, elevator)) {pen.setColor(QColor(255,0,0));}
|
||||
if (elevator->height_m == 0) {pen.setColor(QColor(255,0,0));}
|
||||
void onNodeMoved(MapView2D* v, const int userIdx, const Point2 newPos) override;
|
||||
|
||||
p.setPenBrush(pen, Qt::NoBrush);
|
||||
//p.drawLine(poly.points[0], poly.points[1]);
|
||||
p.drawLine(poly.points[1], poly.points[2]);
|
||||
p.drawLine(poly.points[2], poly.points[3]);
|
||||
p.drawLine(poly.points[3], poly.points[0]);
|
||||
virtual void onFocus() override;
|
||||
|
||||
if (selectedUserIdx == 0) {
|
||||
p.setPenBrush(Qt::black, CFG::SEL_COLOR);
|
||||
p.drawCircle(elevator->center);
|
||||
} else if (hasFocus()) {
|
||||
p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||
p.drawCircle(elevator->center);
|
||||
} else {
|
||||
//p.setPenBrush(Qt::gray, Qt::NoBrush);
|
||||
//p.drawCircle(elevator->center);
|
||||
p.drawCircle_px(elevator->center, 3);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** is the given elevator's end connected to ANY of the floorplan's floors? */
|
||||
static inline bool elevatorEndConnected(const Floorplan::IndoorMap* map, const Floorplan::Floor* floor, const Floorplan::Elevator* e) {
|
||||
const int elevatorEnd_cm = std::round( (floor->atHeight + e->height_m) * 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(), elevatorEnd_cm) != floorsAtHeight_cm.end();
|
||||
return connected;
|
||||
}
|
||||
|
||||
virtual std::vector<MoveableNode> getMoveableNodes() const override {
|
||||
return { MoveableNode(0, elevator->center) };
|
||||
}
|
||||
|
||||
virtual void onNodeMove(MapView2D* v, const int userIdx, const Point2 newPos) override {
|
||||
(void) v;
|
||||
if (userIdx == 0) {elevator->center.x = newPos.x; elevator->center.y = newPos.y;}
|
||||
}
|
||||
|
||||
void onNodeMoved(MapView2D* v, const int userIdx, const Point2 newPos) override {
|
||||
(void) userIdx;
|
||||
(void) newPos;
|
||||
emit v->onElementChange(this);
|
||||
}
|
||||
|
||||
|
||||
virtual void mousePressed(MapView2D* v, const Point2 p) override {
|
||||
(void) v;
|
||||
(void) p;
|
||||
}
|
||||
|
||||
virtual void mouseMove(MapView2D* v, const Point2 p) override {
|
||||
(void) v;
|
||||
(void) p;
|
||||
}
|
||||
|
||||
virtual void mouseReleased(MapView2D* v, const Point2 p) override {
|
||||
(void) v;
|
||||
(void) p;
|
||||
}
|
||||
|
||||
virtual bool keyPressEvent(MapView2D* v, QKeyEvent *e) override {
|
||||
(void) v;
|
||||
(void) e;
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void onFocus() override {
|
||||
;
|
||||
}
|
||||
|
||||
virtual void onUnfocus() override {
|
||||
;
|
||||
}
|
||||
virtual void onUnfocus() override;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // MV2DELEMENTELEVATOR_H
|
||||
|
||||
@@ -49,24 +49,18 @@ public:
|
||||
|
||||
|
||||
if (selectedUserIdx == 0) {
|
||||
//p.setPenBrush(Qt::black, CFG::SEL_COLOR);
|
||||
//p.drawCircle(ap->pos.xy());
|
||||
p.drawPixmap(fpl->posOnFloor, pixmapSel);
|
||||
} else if (hasFocus()) {
|
||||
//p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||
//p.drawCircle(ap->pos.xy());
|
||||
p.drawPixmap(fpl->posOnFloor, pixmapFocused);
|
||||
} else {
|
||||
//p.setPenBrush(Qt::gray, Qt::NoBrush);
|
||||
//p.drawCircle(ap->pos.xy());
|
||||
p.drawPixmap(fpl->posOnFloor, pixmapUnfocused);
|
||||
}
|
||||
|
||||
// label
|
||||
p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||
p.drawDot(fpl->posOnFloor);
|
||||
|
||||
if (p.getScaler().getScale() >= 10) {
|
||||
//p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||
//p.drawDot(fpl->posOnFloor);
|
||||
if (p.getScaler().getScale() >= 12) {
|
||||
p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||
const std::string str = fpl->name;
|
||||
p.p->drawText(p.getScaler().xms(fpl->posOnFloor.x) + 10, p.getScaler().yms(fpl->posOnFloor.y) + 5, str.c_str());
|
||||
}
|
||||
|
||||
81
mapview/2D/MV2DElementFloorObstacleCircle.cpp
Normal file
81
mapview/2D/MV2DElementFloorObstacleCircle.cpp
Normal file
@@ -0,0 +1,81 @@
|
||||
#include "MV2DElementFloorObstacleCircle.h"
|
||||
|
||||
#include "MV2DElement.h"
|
||||
#include "MapViewElementHelper.h"
|
||||
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||
|
||||
MV2DElementFloorObstacleCircle::MV2DElementFloorObstacleCircle(Floorplan::FloorObstacleCircle* c) : c(c) {
|
||||
;
|
||||
}
|
||||
|
||||
BBox2 MV2DElementFloorObstacleCircle::getBoundingBox() const {
|
||||
BBox2 bbox;
|
||||
bbox.add(c->center);
|
||||
bbox.grow(Point2(c->radius, c->radius));
|
||||
return bbox;
|
||||
}
|
||||
|
||||
ClickDist MV2DElementFloorObstacleCircle::getMinDistanceXY(const Point2 p) const {
|
||||
return ClickDist(p.getDistance(c->center), ClickDistType::DIRECT);
|
||||
}
|
||||
|
||||
void MV2DElementFloorObstacleCircle::paint(Painter& p) {
|
||||
|
||||
QPen pen;// = MapElementHelper::getPen(c->material, c->type, hasFocus());
|
||||
|
||||
p.setPenBrush(pen, Qt::NoBrush);
|
||||
p.drawCircle(c->center, c->radius);
|
||||
|
||||
//QBrush brush = MapElementHelper::getBru(c->material, c->type, _focused);
|
||||
|
||||
// // selected endpoints?
|
||||
// if (hasFocus()) {
|
||||
// p.setPenBrush(Qt::NoPen, CFG::SEL_COLOR);
|
||||
// if (selPoint == 0) {p.drawCircle(getSelPoints()[0]);}
|
||||
// if (selPoint == 1) {p.drawCircle(getSelPoints()[1]);}
|
||||
// }
|
||||
|
||||
// // available endpoints
|
||||
// if (hasFocus()) {
|
||||
// p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||
// p.drawCircle(getSelPoints()[0]);
|
||||
// p.drawCircle(getSelPoints()[1]);
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
std::vector<MoveableNode> MV2DElementFloorObstacleCircle::getMoveableNodes() const {
|
||||
return {
|
||||
MoveableNode(0, c->center),
|
||||
MoveableNode(1, c->center+Point2(c->radius,0))
|
||||
};
|
||||
}
|
||||
|
||||
void MV2DElementFloorObstacleCircle::onNodeMove(MapView2D* v, const int userIdx, const Point2 newPos) {
|
||||
(void) v;
|
||||
switch(userIdx) {
|
||||
case 0: c->center.x = newPos.x; c->center.y = newPos.y; break;
|
||||
case 1: c->radius = newPos.getDistance(c->center); break;
|
||||
}
|
||||
}
|
||||
|
||||
void MV2DElementFloorObstacleCircle::onNodeMoved(MapView2D* v, const int userIdx, const Point2 newPos) {
|
||||
(void) userIdx;
|
||||
(void) newPos;
|
||||
emit v->onElementChange(this);
|
||||
}
|
||||
|
||||
//std::vector<Point2> MV2DElementFloorObstacleCircle::getSelPoints() const {
|
||||
// return {c->center, (c->center + Point2(c->radius,0))};
|
||||
//}
|
||||
|
||||
void MV2DElementFloorObstacleCircle::onFocus() {
|
||||
;
|
||||
}
|
||||
|
||||
void MV2DElementFloorObstacleCircle::onUnfocus() {
|
||||
selPoint = -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
#ifndef MV2DELEMENTFLOOROBSTACLECIRCLE_H
|
||||
#define MV2DELEMENTFLOOROBSTACLECIRCLE_H
|
||||
|
||||
|
||||
#include "MV2DElement.h"
|
||||
#include "MapViewElementHelper.h"
|
||||
|
||||
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||
|
||||
class MV2DElementFloorObstacleCircle : public MV2DElement {
|
||||
class MV2DElementFloorObstacleCircle : public MV2DElement, public HasMoveableNodes {
|
||||
|
||||
private:
|
||||
|
||||
@@ -16,95 +16,28 @@ private:
|
||||
public:
|
||||
|
||||
/** ctor */
|
||||
MV2DElementFloorObstacleCircle(Floorplan::FloorObstacleCircle* c) : c(c) {;}
|
||||
MV2DElementFloorObstacleCircle(Floorplan::FloorObstacleCircle* c);
|
||||
|
||||
/** get the element's 3D bounding box */
|
||||
BBox2 getBoundingBox() const override {
|
||||
BBox2 bbox;
|
||||
bbox.add(c->center);
|
||||
bbox.grow(Point2(c->radius, c->radius));
|
||||
return bbox;
|
||||
}
|
||||
BBox2 getBoundingBox() const override;
|
||||
|
||||
/** get the element's minimal distance (nearest whatsoever) to the given point */
|
||||
ClickDist getMinDistanceXY(const Point2 p) const override {
|
||||
const ClickDist d1(p.getDistance(getSelPoints()[0]), ClickDistType::DIRECT);
|
||||
const ClickDist d2(p.getDistance(getSelPoints()[1]), ClickDistType::DIRECT);
|
||||
return std::min(d1, d2);
|
||||
//return std::min(p.getDistance(getSelPoints()[0]), p.getDistance(getSelPoints()[1]));
|
||||
}
|
||||
|
||||
ClickDist getMinDistanceXY(const Point2 p) const override;
|
||||
|
||||
/** repaint me */
|
||||
void paint(Painter& p) override {
|
||||
void paint(Painter& p) override;
|
||||
|
||||
QPen pen;// = MapElementHelper::getPen(c->material, c->type, hasFocus());
|
||||
//std::vector<Point2> getSelPoints() const;
|
||||
|
||||
p.setPenBrush(pen, Qt::NoBrush);
|
||||
p.drawCircle(c->center, c->radius);
|
||||
virtual std::vector<MoveableNode> getMoveableNodes() const override;
|
||||
|
||||
//QBrush brush = MapElementHelper::getBru(c->material, c->type, _focused);
|
||||
virtual void onNodeMove(MapView2D* v, const int userIdx, const Point2 newPos) override;
|
||||
|
||||
// selected endpoints?
|
||||
if (hasFocus()) {
|
||||
p.setPenBrush(Qt::NoPen, CFG::SEL_COLOR);
|
||||
if (selPoint == 0) {p.drawCircle(getSelPoints()[0]);}
|
||||
if (selPoint == 1) {p.drawCircle(getSelPoints()[1]);}
|
||||
}
|
||||
void onNodeMoved(MapView2D* v, const int userIdx, const Point2 newPos) override;
|
||||
|
||||
// available endpoints
|
||||
if (hasFocus()) {
|
||||
p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||
p.drawCircle(getSelPoints()[0]);
|
||||
p.drawCircle(getSelPoints()[1]);
|
||||
}
|
||||
virtual void onFocus() override;
|
||||
|
||||
}
|
||||
|
||||
std::vector<Point2> getSelPoints() const {
|
||||
return {c->center, (c->center + Point2(c->radius,0))};
|
||||
}
|
||||
|
||||
virtual void onFocus() override {
|
||||
;
|
||||
}
|
||||
|
||||
virtual void onUnfocus() override {
|
||||
selPoint = -1;
|
||||
}
|
||||
|
||||
/** mouse pressed at the given point */
|
||||
virtual void mousePressed(MapView2D* v, const Point2 p) override {
|
||||
(void) v;
|
||||
(void) p;
|
||||
|
||||
}
|
||||
|
||||
/** mouse moved to the given point */
|
||||
virtual void mouseMove(MapView2D* v, const Point2 _p) override {
|
||||
(void) v;
|
||||
if (selPoint == -1) {return;}
|
||||
const Point2 p = v->getScaler().snap(_p);
|
||||
if (selPoint == 0) {c->center = p;}
|
||||
if (selPoint == 1) {c->radius = p.getDistance(c->center);}
|
||||
}
|
||||
|
||||
/** mouse released */
|
||||
virtual void mouseReleased(MapView2D* v, const Point2 _p) override {
|
||||
const float t = v->getScaler().sm(CFG::SEL_THRESHOLD_SIZE_PX);
|
||||
const float l1 = _p.getDistance(getSelPoints()[0]);
|
||||
const float l2 = _p.getDistance(getSelPoints()[1]);
|
||||
if (l1 < l2 && l1 <= t) {selPoint = 0;}
|
||||
else if (l2 < l1 && l2 <= t) {selPoint = 1;}
|
||||
else {selPoint = -1;}
|
||||
}
|
||||
|
||||
virtual bool keyPressEvent(MapView2D* v, QKeyEvent *e) override {
|
||||
(void) v;
|
||||
(void) e;
|
||||
|
||||
return false;
|
||||
}
|
||||
virtual void onUnfocus() override;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -28,12 +28,13 @@ void MV2DElementFloorObstacleDoor::paint(Painter& p) {
|
||||
return;
|
||||
}
|
||||
|
||||
// selected endpoints?
|
||||
if (hasFocus()) {
|
||||
p.setPenBrush(Qt::NoPen, CFG::SEL_COLOR);
|
||||
if (selectedUserIdx == 0) {p.drawCircle(fo->from);}
|
||||
if (selectedUserIdx == 1) {p.drawCircle(fo->to);}
|
||||
}
|
||||
// DEPRECATED
|
||||
// // selected endpoints?
|
||||
// if (hasFocus()) {
|
||||
// p.setPenBrush(Qt::NoPen, CFG::SEL_COLOR);
|
||||
// if (selectedUserIdx == 0) {p.drawCircle(fo->from);}
|
||||
// if (selectedUserIdx == 1) {p.drawCircle(fo->to);}
|
||||
// }
|
||||
|
||||
QPen pen;
|
||||
pen.setColor(QColor(0.5,0.5,0.5));
|
||||
@@ -80,13 +81,13 @@ void MV2DElementFloorObstacleDoor::paint(Painter& p) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
// available endpoints
|
||||
if (hasFocus()) {
|
||||
p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||
p.drawCircle(fo->from);
|
||||
p.drawCircle(fo->to);
|
||||
}
|
||||
// DEPRECATED
|
||||
// // available endpoints
|
||||
// if (hasFocus()) {
|
||||
// p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||
// p.drawCircle(fo->from);
|
||||
// p.drawCircle(fo->to);
|
||||
// }
|
||||
|
||||
// obstacle length
|
||||
if (hasFocus()) {
|
||||
@@ -129,10 +130,13 @@ std::vector<MoveableNode> MV2DElementFloorObstacleDoor::getMoveableNodes() const
|
||||
}
|
||||
|
||||
void MV2DElementFloorObstacleDoor::onNodeMoved(MapView2D* v, const int userIdx, const Point2 newPos) {
|
||||
(void) userIdx;
|
||||
(void) newPos;
|
||||
emit v->onElementChange(this);
|
||||
}
|
||||
|
||||
void MV2DElementFloorObstacleDoor::onNodeMove(MapView2D* v, const int userIdx, const Point2 newPos) {
|
||||
(void) v;
|
||||
switch (userIdx) {
|
||||
case 0: fo->from = newPos; break;
|
||||
case 1: fo->to = newPos; break;
|
||||
|
||||
92
mapview/2D/MV2DElementFloorObstacleLine.cpp
Normal file
92
mapview/2D/MV2DElementFloorObstacleLine.cpp
Normal file
@@ -0,0 +1,92 @@
|
||||
#include "MV2DElementFloorObstacleLine.h"
|
||||
|
||||
#include "MV2DElement.h"
|
||||
#include "HasMoveableNodes.h"
|
||||
|
||||
#include "MapViewElementHelper.h"
|
||||
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||
#include <stdio.h>
|
||||
|
||||
MV2DElementFloorObstacleLine::MV2DElementFloorObstacleLine(Floorplan::FloorObstacleLine* fo) : fo(fo) {
|
||||
;
|
||||
}
|
||||
|
||||
BBox2 MV2DElementFloorObstacleLine::getBoundingBox() const {
|
||||
BBox2 bbox;
|
||||
bbox.add(fo->from);
|
||||
bbox.add(fo->to);
|
||||
return bbox;
|
||||
}
|
||||
|
||||
ClickDist MV2DElementFloorObstacleLine::getMinDistanceXY(const Point2 p) const {
|
||||
return MapElementHelper::getLineDistanceXY(fo->from, fo->to, p);
|
||||
}
|
||||
|
||||
void MV2DElementFloorObstacleLine::paint(Painter& p) {
|
||||
|
||||
// DEPRECATED
|
||||
// // selected endpoints?
|
||||
// if (hasFocus()) {
|
||||
// p.setPenBrush(Qt::NoPen, CFG::SEL_COLOR);
|
||||
// if (selectedUserIdx == 0) {p.drawCircle(fo->from);}
|
||||
// if (selectedUserIdx == 1) {p.drawCircle(fo->to);}
|
||||
// }
|
||||
|
||||
// convert wall's thickness from meter to pixels
|
||||
const float thickness_px = p.s.ms(fo->thickness_m);
|
||||
|
||||
// remember the old pen
|
||||
//QPen pen = p.getPen();
|
||||
|
||||
// see notes within MapElementHelper!
|
||||
// lines only get thicker, but not longer!
|
||||
p.setPenBrush(MapElementHelper::getPen(fo->material, fo->type, hasFocus(), thickness_px), Qt::NoBrush);
|
||||
p.drawLine(fo->from, fo->to);
|
||||
|
||||
// reset the old pen3
|
||||
//p.setPen(pen);
|
||||
|
||||
// length info
|
||||
if (hasFocus()) {
|
||||
|
||||
// obstacle length
|
||||
p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||
p.drawLength(fo->from, fo->to, fo->from.getDistance(fo->to), thickness_px/2);
|
||||
|
||||
}
|
||||
|
||||
// DEPRECATED
|
||||
// // available endpoints
|
||||
// p.drawNode(fo->from, hasFocus(), hasFocus() && selectedUserIdx == 0);
|
||||
// p.drawNode(fo->to, hasFocus(), hasFocus() && selectedUserIdx == 1);
|
||||
|
||||
}
|
||||
|
||||
void MV2DElementFloorObstacleLine::onFocus() {
|
||||
;
|
||||
}
|
||||
|
||||
void MV2DElementFloorObstacleLine::onUnfocus() {
|
||||
selectedUserIdx = -1; // clear selection
|
||||
}
|
||||
|
||||
std::vector<MoveableNode> MV2DElementFloorObstacleLine::getMoveableNodes() const {
|
||||
return {
|
||||
MoveableNode(0, fo->from),
|
||||
MoveableNode(1, fo->to)
|
||||
};
|
||||
}
|
||||
|
||||
void MV2DElementFloorObstacleLine::onNodeMove(MapView2D* v, const int userIdx, const Point2 newPos) {
|
||||
(void) v;
|
||||
if (userIdx == 0) {fo->from.x = newPos.x; fo->from.y = newPos.y;}
|
||||
if (userIdx == 1) {fo->to.x = newPos.x; fo->to.y = newPos.y;}
|
||||
}
|
||||
|
||||
void MV2DElementFloorObstacleLine::onNodeMoved(MapView2D* v, const int userIdx, const Point2 newPos) {
|
||||
(void) userIdx;
|
||||
(void) newPos;
|
||||
emit v->onElementChange(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,9 +4,7 @@
|
||||
#include "MV2DElement.h"
|
||||
#include "HasMoveableNodes.h"
|
||||
|
||||
#include "MapViewElementHelper.h"
|
||||
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||
#include <stdio.h>
|
||||
|
||||
class MV2DElementFloorObstacleLine : public MV2DElement, public HasMoveableNodes {
|
||||
|
||||
@@ -17,90 +15,26 @@ private:
|
||||
public:
|
||||
|
||||
/** ctor */
|
||||
MV2DElementFloorObstacleLine(Floorplan::FloorObstacleLine* fo) : fo(fo) {;}
|
||||
MV2DElementFloorObstacleLine(Floorplan::FloorObstacleLine* fo);
|
||||
|
||||
/** get the element's 3D bounding box */
|
||||
BBox2 getBoundingBox() const override {
|
||||
BBox2 bbox;
|
||||
bbox.add(fo->from);
|
||||
bbox.add(fo->to);
|
||||
return bbox;
|
||||
}
|
||||
BBox2 getBoundingBox() const override;
|
||||
|
||||
/** get the element's minimal distance (nearest whatsoever) to the given point */
|
||||
ClickDist getMinDistanceXY(const Point2 p) const override {
|
||||
return MapElementHelper::getLineDistanceXY(fo->from, fo->to, p);
|
||||
}
|
||||
ClickDist getMinDistanceXY(const Point2 p) const override;
|
||||
|
||||
/** repaint me */
|
||||
void paint(Painter& p) override {
|
||||
void paint(Painter& p) override;
|
||||
|
||||
// selected endpoints?
|
||||
if (hasFocus()) {
|
||||
p.setPenBrush(Qt::NoPen, CFG::SEL_COLOR);
|
||||
if (selectedUserIdx == 0) {p.drawCircle(fo->from);}
|
||||
if (selectedUserIdx == 1) {p.drawCircle(fo->to);}
|
||||
}
|
||||
void onFocus() override;
|
||||
|
||||
// convert wall's thickness from meter to pixels
|
||||
const float thickness_px = p.s.ms(fo->thickness_m);
|
||||
void onUnfocus() override;
|
||||
|
||||
// remember the old pen
|
||||
QPen pen = p.getPen();
|
||||
virtual std::vector<MoveableNode> getMoveableNodes() const override;
|
||||
|
||||
// see notes within MapElementHelper!
|
||||
// lines only get thicker, but not longer!
|
||||
p.setPenBrush(MapElementHelper::getPen(fo->material, fo->type, hasFocus(), thickness_px), Qt::NoBrush);
|
||||
p.drawLine(fo->from, fo->to);
|
||||
void onNodeMove(MapView2D* v, const int userIdx, const Point2 newPos) override;
|
||||
|
||||
// reset the old pen
|
||||
p.setPen(pen);
|
||||
|
||||
// available endpoints
|
||||
if (hasFocus()) {
|
||||
|
||||
p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||
p.drawCircle(fo->from);
|
||||
p.drawCircle(fo->to);
|
||||
|
||||
// obstacle length
|
||||
p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||
p.drawLength(fo->from, fo->to, fo->from.getDistance(fo->to), thickness_px/2);
|
||||
|
||||
} else {
|
||||
//p.setPenBrush(Qt::NoPen, Qt::black);
|
||||
p.drawCircle_px(fo->from, 3);
|
||||
p.drawCircle_px(fo->to, 3);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void onFocus() override {
|
||||
;
|
||||
}
|
||||
|
||||
void onUnfocus() override {
|
||||
selectedUserIdx = -1; // clear selection
|
||||
}
|
||||
|
||||
virtual std::vector<MoveableNode> getMoveableNodes() const override {
|
||||
return {
|
||||
MoveableNode(0, fo->from),
|
||||
MoveableNode(1, fo->to)
|
||||
};
|
||||
}
|
||||
|
||||
void onNodeMove(MapView2D* v, const int userIdx, const Point2 newPos) override {
|
||||
(void) v;
|
||||
if (userIdx == 0) {fo->from.x = newPos.x; fo->from.y = newPos.y;}
|
||||
if (userIdx == 1) {fo->to.x = newPos.x; fo->to.y = newPos.y;}
|
||||
}
|
||||
|
||||
void onNodeMoved(MapView2D* v, const int userIdx, const Point2 newPos) {
|
||||
(void) userIdx;
|
||||
(void) newPos;
|
||||
emit v->onElementChange(this);
|
||||
}
|
||||
void onNodeMoved(MapView2D* v, const int userIdx, const Point2 newPos);
|
||||
|
||||
};
|
||||
|
||||
|
||||
134
mapview/2D/MV2DElementFloorOutlinePolygon.cpp
Normal file
134
mapview/2D/MV2DElementFloorOutlinePolygon.cpp
Normal file
@@ -0,0 +1,134 @@
|
||||
#include "MV2DElementFloorOutlinePolygon.h"
|
||||
|
||||
#include "MV2DElement.h"
|
||||
#include "HasMoveableNodes.h"
|
||||
#include "MapViewElementHelper.h"
|
||||
|
||||
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||
|
||||
MV2DElementFloorOutlinePolygon::MV2DElementFloorOutlinePolygon(Floorplan::FloorOutlinePolygon& fo) : fo(fo) {
|
||||
;
|
||||
}
|
||||
|
||||
BBox2 MV2DElementFloorOutlinePolygon::getBoundingBox() const {
|
||||
BBox2 bbox;
|
||||
for (const Point2 p : fo.poly.points) { bbox.add(p); }
|
||||
return bbox;
|
||||
}
|
||||
|
||||
ClickDist MV2DElementFloorOutlinePolygon::getMinDistanceXY(const Point2 p) const {
|
||||
ClickDist min = ClickDist::max();
|
||||
for (int i = 0; i < (int)fo.poly.points.size()-1; ++i) {
|
||||
const Point2 p1 = fo.poly.points[i];
|
||||
const Point2 p2 = fo.poly.points[i+1];
|
||||
const ClickDist dst = MapElementHelper::getLineDistanceXY(p1, p2, p);
|
||||
if (dst < min) {min = dst;}
|
||||
}
|
||||
return min * 1.1; // penalty.. outlines are everywhere.. reduce priority
|
||||
}
|
||||
|
||||
void MV2DElementFloorOutlinePolygon::onFocus() {
|
||||
|
||||
}
|
||||
|
||||
void MV2DElementFloorOutlinePolygon::onUnfocus() {
|
||||
selectedUserIdx = -1; // clear selection
|
||||
}
|
||||
|
||||
void MV2DElementFloorOutlinePolygon::paint(Painter& p) {
|
||||
|
||||
QBrush brush;
|
||||
QPen pen;
|
||||
|
||||
// fill-style (depends on the mode)
|
||||
switch (fo.method) {
|
||||
case Floorplan::OutlineMethod::ADD:
|
||||
brush.setStyle(Qt::BrushStyle::SolidPattern);
|
||||
brush.setColor( fo.outdoor ? QColor(0,255,0,32) : QColor(0,0,0,24) ); // outdoor = green
|
||||
break;
|
||||
case Floorplan::OutlineMethod::REMOVE:
|
||||
brush.setStyle(Qt::BrushStyle::DiagCrossPattern);
|
||||
brush.setColor(QColor(0,0,0));
|
||||
break;
|
||||
default:
|
||||
// should not happen
|
||||
brush.setStyle(Qt::BrushStyle::SolidPattern);
|
||||
brush.setColor(QColor(255,0,0));
|
||||
}
|
||||
|
||||
if (hasFocus()) {
|
||||
brush.setStyle(Qt::BrushStyle::FDiagPattern);
|
||||
}
|
||||
|
||||
// outline + filled area
|
||||
pen.setColor(Qt::black);
|
||||
pen.setWidth( hasFocus() ? 2 : 1 );
|
||||
p.setPenBrush(pen, brush);
|
||||
p.drawPolygon(fo.poly.points);
|
||||
|
||||
// DEPRECATED
|
||||
// // selected endpoints?
|
||||
// if (hasFocus() && selectedUserIdx != -1) {
|
||||
// p.setPenBrush(Qt::NoPen, CFG::SEL_COLOR);
|
||||
// p.drawCircle(fo.poly.points[selectedUserIdx]);
|
||||
// }
|
||||
|
||||
// DEPRECATED
|
||||
// // available endpoints
|
||||
// if (hasFocus()) {
|
||||
// p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||
// for (const Point2 pt : fo.poly.points) {
|
||||
// p.drawCircle(pt);
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
|
||||
std::vector<MoveableNode> MV2DElementFloorOutlinePolygon::getMoveableNodes() const {
|
||||
std::vector<MoveableNode> nodes;
|
||||
for (int i = 0; i < (int) fo.poly.points.size(); ++i) {
|
||||
nodes.push_back(MoveableNode(i, fo.poly.points[i]));
|
||||
}
|
||||
return nodes;
|
||||
}
|
||||
|
||||
void MV2DElementFloorOutlinePolygon::onNodeMove(MapView2D* v, const int userIdx, const Point2 newPos) {
|
||||
(void) v;
|
||||
fo.poly.points[userIdx].x = newPos.x;
|
||||
fo.poly.points[userIdx].y = newPos.y;
|
||||
}
|
||||
|
||||
void MV2DElementFloorOutlinePolygon::onNodeMoved(MapView2D* v, const int userIdx, const Point2 newPos) {
|
||||
(void) userIdx;
|
||||
(void) newPos;
|
||||
emit v->onElementChange(this);
|
||||
}
|
||||
|
||||
bool MV2DElementFloorOutlinePolygon::keyPressEvent(MapView2D* v, QKeyEvent *e) {
|
||||
(void) v;
|
||||
|
||||
|
||||
if (e->key() == Qt::Key_Delete) {
|
||||
|
||||
// delete the currently selected vertex?
|
||||
if (selectedUserIdx != -1) {
|
||||
fo.poly.points.erase(fo.poly.points.begin() + selectedUserIdx);
|
||||
selectedUserIdx = -1;
|
||||
return true;
|
||||
}
|
||||
|
||||
} else if (e->key() == Qt::Key_Plus && selectedUserIdx != -1) {
|
||||
int idx1 = selectedUserIdx;
|
||||
int idx2 = (selectedUserIdx + 1) % fo.poly.points.size();
|
||||
int idxNew = idx2;
|
||||
Point2 pNew = (fo.poly.points[idx1] + fo.poly.points[idx2]) / 2.0f;
|
||||
fo.poly.points.insert(fo.poly.points.begin() + idxNew, pNew);
|
||||
selectedUserIdx = idxNew;
|
||||
return true;
|
||||
}
|
||||
|
||||
// not consumed
|
||||
return false;
|
||||
|
||||
}
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
#include "MV2DElement.h"
|
||||
#include "HasMoveableNodes.h"
|
||||
#include "MapViewElementHelper.h"
|
||||
|
||||
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||
|
||||
@@ -16,167 +15,29 @@ private:
|
||||
public:
|
||||
|
||||
/** ctor */
|
||||
MV2DElementFloorOutlinePolygon(Floorplan::FloorOutlinePolygon& fo) : fo(fo) {;}
|
||||
MV2DElementFloorOutlinePolygon(Floorplan::FloorOutlinePolygon& fo);
|
||||
|
||||
/** get the element's 3D bounding box */
|
||||
BBox2 getBoundingBox() const override {
|
||||
BBox2 bbox;
|
||||
for (const Point2 p : fo.poly.points) { bbox.add(p); }
|
||||
return bbox;
|
||||
}
|
||||
BBox2 getBoundingBox() const override;
|
||||
|
||||
/** get the element's minimal distance (nearest whatsoever) to the given point */
|
||||
ClickDist getMinDistanceXY(const Point2 p) const override {
|
||||
ClickDist min = ClickDist::max();
|
||||
for (int i = 0; i < (int)fo.poly.points.size()-1; ++i) {
|
||||
const Point2 p1 = fo.poly.points[i];
|
||||
const Point2 p2 = fo.poly.points[i+1];
|
||||
const ClickDist dst = MapElementHelper::getLineDistanceXY(p1, p2, p);
|
||||
if (dst < min) {min = dst;}
|
||||
}
|
||||
return min * 1.1; // penalty.. outlines are everywhere.. reduce priority
|
||||
}
|
||||
ClickDist getMinDistanceXY(const Point2 p) const override;
|
||||
|
||||
virtual void onFocus() override {
|
||||
virtual void onFocus() override;
|
||||
|
||||
}
|
||||
virtual void onUnfocus() override;
|
||||
|
||||
virtual void onUnfocus() override {
|
||||
selectedUserIdx = -1; // clear selection
|
||||
}
|
||||
|
||||
void paint(Painter& p) override {
|
||||
|
||||
QBrush brush;
|
||||
QPen pen;
|
||||
|
||||
// fill-style (depends on the mode)
|
||||
switch (fo.method) {
|
||||
case Floorplan::OutlineMethod::ADD:
|
||||
brush.setStyle(Qt::BrushStyle::SolidPattern);
|
||||
brush.setColor( fo.outdoor ? QColor(0,255,0,32) : QColor(0,0,0,24) ); // outdoor = green
|
||||
break;
|
||||
case Floorplan::OutlineMethod::REMOVE:
|
||||
brush.setStyle(Qt::BrushStyle::DiagCrossPattern);
|
||||
brush.setColor(QColor(0,0,0));
|
||||
break;
|
||||
default:
|
||||
// should not happen
|
||||
brush.setStyle(Qt::BrushStyle::SolidPattern);
|
||||
brush.setColor(QColor(255,0,0));
|
||||
}
|
||||
|
||||
if (hasFocus()) {
|
||||
brush.setStyle(Qt::BrushStyle::FDiagPattern);
|
||||
}
|
||||
|
||||
// outline + filled area
|
||||
pen.setColor(Qt::black);
|
||||
pen.setWidth( hasFocus() ? 2 : 1 );
|
||||
p.setPenBrush(pen, brush);
|
||||
p.drawPolygon(fo.poly.points);
|
||||
|
||||
// selected endpoints?
|
||||
if (hasFocus() && selectedUserIdx != -1) {
|
||||
p.setPenBrush(Qt::NoPen, CFG::SEL_COLOR);
|
||||
p.drawCircle(fo.poly.points[selectedUserIdx]);
|
||||
}
|
||||
|
||||
// available endpoints
|
||||
if (hasFocus()) {
|
||||
p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||
for (const Point2 pt : fo.poly.points) {
|
||||
p.drawCircle(pt);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
void paint(Painter& p) override;
|
||||
|
||||
/** get a list of all nodes that are selectable / moveable */
|
||||
virtual std::vector<MoveableNode> getMoveableNodes() const override {
|
||||
std::vector<MoveableNode> nodes;
|
||||
for (int i = 0; i < (int) fo.poly.points.size(); ++i) {
|
||||
nodes.push_back(MoveableNode(i, fo.poly.points[i]));
|
||||
}
|
||||
return nodes;
|
||||
}
|
||||
virtual std::vector<MoveableNode> getMoveableNodes() const override;
|
||||
|
||||
/** the given node was moved */
|
||||
void onNodeMove(MapView2D* v, const int userIdx, const Point2 newPos) override {
|
||||
(void) v;
|
||||
fo.poly.points[userIdx].x = newPos.x;
|
||||
fo.poly.points[userIdx].y = newPos.y;
|
||||
}
|
||||
void onNodeMove(MapView2D* v, const int userIdx, const Point2 newPos) override;
|
||||
|
||||
void onNodeMoved(MapView2D* v, const int userIdx, const Point2 newPos) override {
|
||||
(void) userIdx;
|
||||
(void) newPos;
|
||||
emit v->onElementChange(this);
|
||||
}
|
||||
|
||||
|
||||
// virtual void mousePressed(MapView2D* v, const Point2 p) override {
|
||||
// (void) v;
|
||||
// (void) p;
|
||||
// }
|
||||
|
||||
// virtual void mouseMove(MapView2D* v, const Point2 _p) override {
|
||||
// (void) v;
|
||||
// if (selPoint == -1) {return;}
|
||||
// const Point2 p = v->getScaler().snap(_p);
|
||||
// fo.poly.points[selPoint].x = p.x;
|
||||
// fo.poly.points[selPoint].y = p.y;
|
||||
// }
|
||||
|
||||
// virtual void mouseReleased(MapView2D* v, const Point2 _p) override {
|
||||
|
||||
// (void) v;
|
||||
|
||||
// // if (selPoint != -1) {
|
||||
// // const Point3 p = Scaler::snap(_p, CFG::MOVE_SNAP_SIZE_M);
|
||||
// // fo.poly.points[selPoint].x = p.x;
|
||||
// // fo.poly.points[selPoint].y = p.y;
|
||||
// // }
|
||||
|
||||
// // select a new point on mouse-release (more robust than on mouse-press)
|
||||
// const float t = v->getScaler().sm(CFG::SEL_THRESHOLD_SIZE_PX);
|
||||
// auto comp = [&] (const Point2 a, const Point2 b) {return a.getDistance(_p) < b.getDistance(_p);};
|
||||
// auto it = std::min_element(fo.poly.points.begin(), fo.poly.points.end(), comp);
|
||||
// if (it == fo.poly.points.end()) {selPoint = -1;} // none found -> skip
|
||||
// else if ((*it).getDistance(_p) > t) {selPoint = -1;} // nearest distance is above threshold -> skip
|
||||
// else {selPoint = it - fo.poly.points.begin();}
|
||||
|
||||
// }
|
||||
|
||||
virtual bool keyPressEvent(MapView2D* v, QKeyEvent *e) override {
|
||||
(void) v;
|
||||
|
||||
|
||||
if (e->key() == Qt::Key_Delete) {
|
||||
|
||||
// delete the currently selected vertex?
|
||||
if (selectedUserIdx != -1) {
|
||||
fo.poly.points.erase(fo.poly.points.begin() + selectedUserIdx);
|
||||
selectedUserIdx = -1;
|
||||
return true;
|
||||
}
|
||||
|
||||
} else if (e->key() == Qt::Key_Plus && selectedUserIdx != -1) {
|
||||
int idx1 = selectedUserIdx;
|
||||
int idx2 = (selectedUserIdx + 1) % fo.poly.points.size();
|
||||
int idxNew = idx2;
|
||||
Point2 pNew = (fo.poly.points[idx1] + fo.poly.points[idx2]) / 2.0f;
|
||||
fo.poly.points.insert(fo.poly.points.begin() + idxNew, pNew);
|
||||
selectedUserIdx = idxNew;
|
||||
return true;
|
||||
}
|
||||
|
||||
// not consumed
|
||||
return false;
|
||||
|
||||
}
|
||||
void onNodeMoved(MapView2D* v, const int userIdx, const Point2 newPos) override;
|
||||
|
||||
virtual bool keyPressEvent(MapView2D* v, QKeyEvent *e) override;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -42,36 +42,29 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
static const QPixmap& pixmapUnfocused = UIHelper::getPixmapColored("gtp", CFG::UNFOCUS_COLOR, 16);
|
||||
static const QPixmap& pixmapFocused = UIHelper::getPixmapColored("gtp", CFG::FOCUS_COLOR, 16);
|
||||
static const QPixmap& pixmapSel = UIHelper::getPixmapColored("gtp", CFG::SEL_COLOR, 16);
|
||||
static const QPixmap& pixmapUnfocused = UIHelper::getPixmapColored("gtp", CFG::UNFOCUS_COLOR, 16);
|
||||
static const QPixmap& pixmapFocused = UIHelper::getPixmapColored("gtp", CFG::FOCUS_COLOR, 16);
|
||||
static const QPixmap& pixmapSel = UIHelper::getPixmapColored("gtp", CFG::SEL_COLOR, 16);
|
||||
|
||||
if (selectedUserIdx == 0) {
|
||||
p.drawPixmap(gtp->pos.xy(), pixmapSel);
|
||||
} else if (hasFocus()) {
|
||||
p.drawPixmap(gtp->pos.xy(), pixmapFocused);
|
||||
} else {
|
||||
p.drawPixmap(gtp->pos.xy(), pixmapUnfocused);
|
||||
}
|
||||
|
||||
if (selectedUserIdx == 0) {
|
||||
// p.setPenBrush(Qt::black, CFG::SEL_COLOR);
|
||||
// p.drawCircle(gtp->pos);
|
||||
p.drawPixmap(gtp->pos.xy(), pixmapSel);
|
||||
} else if (hasFocus()) {
|
||||
// p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||
// p.drawCircle(gtp->pos);
|
||||
p.drawPixmap(gtp->pos.xy(), pixmapFocused);
|
||||
} else {
|
||||
// p.setPenBrush(Qt::gray, Qt::NoBrush);
|
||||
// p.drawCircle(gtp->pos);
|
||||
p.drawPixmap(gtp->pos.xy(), pixmapUnfocused);
|
||||
}
|
||||
|
||||
// label
|
||||
p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||
p.drawDot(gtp->pos.xy());
|
||||
if (p.getScaler().getScale() >= 10) {
|
||||
const std::string str = std::to_string(gtp->id);
|
||||
p.p->drawText(p.getScaler().xms(gtp->pos.x) + 10, p.getScaler().yms(gtp->pos.y) + 5, str.c_str());
|
||||
}
|
||||
// label
|
||||
//p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||
//p.drawDot(gtp->pos.xy());
|
||||
if (p.getScaler().getScale() >= 12) {
|
||||
p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||
const std::string str = std::to_string(gtp->id);
|
||||
p.p->drawText(p.getScaler().xms(gtp->pos.x) + 10, p.getScaler().yms(gtp->pos.y) + 5, str.c_str());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
virtual std::vector<MoveableNode> getMoveableNodes() const override {
|
||||
return { MoveableNode(0, gtp->pos.xy()) };
|
||||
}
|
||||
@@ -87,30 +80,6 @@ public:
|
||||
emit v->onElementChange(this);
|
||||
}
|
||||
|
||||
/** mouse pressed at the given point */
|
||||
virtual void mousePressed(MapView2D* v, const Point2 p) override {
|
||||
(void) v;
|
||||
(void) p;
|
||||
}
|
||||
|
||||
/** mouse moved to the given point */
|
||||
virtual void mouseMove(MapView2D* v, const Point2 p) override {
|
||||
(void) v;
|
||||
(void) p;
|
||||
}
|
||||
|
||||
/** mouse released */
|
||||
virtual void mouseReleased(MapView2D* v, const Point2 p) override {
|
||||
(void) v;
|
||||
(void) p;
|
||||
}
|
||||
|
||||
virtual bool keyPressEvent(MapView2D* v, QKeyEvent *e) override {
|
||||
(void) v;
|
||||
(void) e;
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void onFocus() override {
|
||||
;
|
||||
}
|
||||
|
||||
@@ -62,9 +62,10 @@ public:
|
||||
}
|
||||
|
||||
// label
|
||||
p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||
p.drawDot(poi->pos);
|
||||
if (p.getScaler().getScale() >= 10) {
|
||||
//p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||
//p.drawDot(poi->pos);
|
||||
if (p.getScaler().getScale() >= 12) {
|
||||
p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||
const std::string str = poi->name;
|
||||
p.p->drawText(p.getScaler().xms(poi->pos.x) + 10, p.getScaler().yms(poi->pos.y) + 5, str.c_str());
|
||||
}
|
||||
@@ -87,35 +88,6 @@ public:
|
||||
emit v->onElementChange(this);
|
||||
}
|
||||
|
||||
/** mouse pressed at the given point */
|
||||
virtual void mousePressed(MapView2D* v, const Point2 p) override {
|
||||
(void) v;
|
||||
(void) p;
|
||||
}
|
||||
|
||||
/** mouse moved to the given point */
|
||||
virtual void mouseMove(MapView2D* v, const Point2 p) override {
|
||||
(void) v;
|
||||
(void) p;
|
||||
// if (sel) {
|
||||
// const Point2 p = v->getScaler().snap(_p);
|
||||
// poi->pos.x = p.x;
|
||||
// poi->pos.y = p.y;
|
||||
// }
|
||||
}
|
||||
|
||||
/** mouse released */
|
||||
virtual void mouseReleased(MapView2D* v, const Point2 p) override {
|
||||
(void) v;
|
||||
(void) p;
|
||||
}
|
||||
|
||||
virtual bool keyPressEvent(MapView2D* v, QKeyEvent *e) override {
|
||||
(void) v;
|
||||
(void) e;
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void onFocus() override {
|
||||
;
|
||||
}
|
||||
|
||||
@@ -59,9 +59,10 @@ public:
|
||||
}
|
||||
|
||||
// label
|
||||
p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||
//p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||
//p.drawDot(ap->pos.xy());
|
||||
if (p.getScaler().getScale() >= 10) {
|
||||
if (p.getScaler().getScale() >= 12) {
|
||||
p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||
const std::string str = std::to_string(reg->posOnEarth.lat) + " " + std::to_string(reg->posOnEarth.lon);
|
||||
p.p->drawText(p.getScaler().xms(reg->posOnMap_m.x) + 10, p.getScaler().yms(reg->posOnMap_m.y) + 5, str.c_str());
|
||||
}
|
||||
@@ -83,27 +84,6 @@ public:
|
||||
emit v->onElementChange(this);
|
||||
}
|
||||
|
||||
virtual void mousePressed(MapView2D* v, const Point2 p) override {
|
||||
(void) v;
|
||||
(void) p;
|
||||
}
|
||||
|
||||
virtual void mouseMove(MapView2D* v, const Point2 p) override {
|
||||
(void) v;
|
||||
(void) p;
|
||||
}
|
||||
|
||||
virtual void mouseReleased(MapView2D* v, const Point2 p) override {
|
||||
(void) v;
|
||||
(void) p;
|
||||
}
|
||||
|
||||
virtual bool keyPressEvent(MapView2D* v, QKeyEvent *e) override {
|
||||
(void) v;
|
||||
(void) e;
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void onFocus() override {
|
||||
;
|
||||
}
|
||||
|
||||
251
mapview/2D/MV2DElementStair.cpp
Normal file
251
mapview/2D/MV2DElementStair.cpp
Normal 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);
|
||||
}
|
||||
|
||||
@@ -4,21 +4,8 @@
|
||||
#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;
|
||||
}
|
||||
|
||||
class MV2DElementStair : public MV2DElement, public HasMoveableNodes {
|
||||
|
||||
private:
|
||||
@@ -27,296 +14,38 @@ private:
|
||||
Floorplan::IndoorMap* map;
|
||||
Floorplan::Floor* floor;
|
||||
Floorplan::Stair* stair;
|
||||
//int selPart = -1;
|
||||
//int selNode = -1;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
/** ctor with the stair to render/edit */
|
||||
MV2DElementStair(Floorplan::IndoorMap* map, Floorplan::Floor* floor, Floorplan::Stair* stair) : map(map), floor(floor), stair(stair) {;}
|
||||
|
||||
MV2DElementStair(Floorplan::IndoorMap* map, Floorplan::Floor* floor, Floorplan::Stair* stair);
|
||||
|
||||
/** get the element's 3D bounding box */
|
||||
BBox2 getBoundingBox() const override {
|
||||
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;
|
||||
}
|
||||
BBox2 getBoundingBox() const override;
|
||||
|
||||
/** get the element's minimal distance (nearest whatsoever) to the given point */
|
||||
ClickDist getMinDistanceXY(const Point2 p) const override {
|
||||
ClickDist getMinDistanceXY(const Point2 p) const override;
|
||||
|
||||
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 getSelPart() const {return getSelectedNode() < 0 ? getSelectedNode() : getSelectedNode() / 2;}
|
||||
int getSelNode() const {return getSelectedNode() < 0 ? getSelectedNode() : getSelectedNode() % 2;}
|
||||
|
||||
static inline float clamp01(const float val) {
|
||||
if (val < 0) {return 0;}
|
||||
if (val > 1) {return 1;}
|
||||
return val;
|
||||
}
|
||||
int getSelPart() const;
|
||||
int getSelNode() const;
|
||||
|
||||
/** repaint me */
|
||||
void paint(Painter& p) override {
|
||||
void paint(Painter& p) override;
|
||||
|
||||
Floorplan::StairFreeform* stair = dynamic_cast<Floorplan::StairFreeform*>(this->stair);
|
||||
virtual bool keyPressEvent(MapView2D* v, QKeyEvent *e) override;
|
||||
|
||||
// if (sel) {
|
||||
// p.setPenBrush(Qt::black, CFG::SEL_COLOR);
|
||||
// p.drawCircle(stair->center);
|
||||
// } else if (hasFocus()) {
|
||||
// p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||
// p.drawCircle(stair->center);
|
||||
// } else {
|
||||
// p.setPenBrush(Qt::gray, Qt::NoBrush);
|
||||
// p.drawCircle(stair->center);
|
||||
// }
|
||||
virtual void onFocus() override;
|
||||
|
||||
// draw all parts of the stair (all polygons)
|
||||
p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||
virtual void onUnfocus() override;
|
||||
|
||||
std::vector<Floorplan::StairPart> parts = stair->getParts();
|
||||
std::vector<Floorplan::Quad3> quads = Floorplan::getQuads(parts, floor);
|
||||
virtual std::vector<MoveableNode> getMoveableNodes() const override;
|
||||
|
||||
// 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;
|
||||
}
|
||||
void onNodeMove(MapView2D* v, const int userIdx, const Point2 newPos) override;
|
||||
|
||||
for (int i = 0; i < (int) parts.size(); ++i) {
|
||||
void onNodeMoved(MapView2D* v, const int userIdx, const Point2 newPos) override;
|
||||
|
||||
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());
|
||||
p.setPenBrush(Qt::black, (cnt == getSelPart() && getSelNode() == 1) ? CFG::SEL_COLOR : Qt::NoBrush); // part end
|
||||
p.drawRect(part.end.xy());
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// /** mouse pressed at the given point */
|
||||
// virtual void mousePressed(MapView2D* v, const Point2 p) override {
|
||||
// (void) v;
|
||||
// (void) p;
|
||||
|
||||
// }
|
||||
|
||||
// /** mouse moved to the given point */
|
||||
// virtual void mouseMove(MapView2D* v, const Point2 _p) override {
|
||||
// (void) v;
|
||||
// if (selPart == -1) {return;}
|
||||
// Floorplan::StairFreeform* stair = dynamic_cast<Floorplan::StairFreeform*>(this->stair);
|
||||
// const Point2 p = v->getScaler().snap(_p);
|
||||
// stair->parts[selPart][selNode].x = p.x;
|
||||
// stair->parts[selPart][selNode].y = p.y;
|
||||
// }
|
||||
|
||||
// /** mouse released */
|
||||
// virtual void mouseReleased(MapView2D* v, const Point2 _p) override {
|
||||
// (void) v;
|
||||
// (void) _p;
|
||||
// // select a new point on mouse-release (more robust than on mouse-press)
|
||||
// Floorplan::StairFreeform* stair = dynamic_cast<Floorplan::StairFreeform*>(this->stair);
|
||||
// const float t = v->getScaler().sm(CFG::SEL_THRESHOLD_SIZE_PX);
|
||||
//// auto comp = [&] (const Point3 a, const Point3 b) {return a.xy().getDistance(_p) < b.xy().getDistance(_p);};
|
||||
//// auto it = std::min_element(stair->nodes.begin(), stair->nodes.end(), comp);
|
||||
//// if (it == stair->nodes.end()) {selIdx = -1;} // none found -> skip
|
||||
//// else if ((*it).xy().getDistance(_p) > t) {selIdx = -1;} // nearest distance is above threshold -> skip
|
||||
//// else {selIdx = it - stair->nodes.begin();}
|
||||
|
||||
// float best = 999999;
|
||||
// int minPart; int minNode;
|
||||
// for (int part = 0; part < (int) stair->parts.size(); ++part) {
|
||||
// for (int node = 0; node < 2; ++node) {
|
||||
// const float dist = stair->parts[part][node].xy().getDistance(_p);
|
||||
// if (dist < best) {best = dist; minPart = part; minNode = node;}
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (best <= t) {
|
||||
// selPart = minPart; selNode = minNode;
|
||||
// } else {
|
||||
// selPart = -1; selNode = -1;
|
||||
// }
|
||||
|
||||
// emit v->onElementChange(this);
|
||||
|
||||
// }
|
||||
|
||||
virtual bool keyPressEvent(MapView2D* v, QKeyEvent *e) override {
|
||||
(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;
|
||||
|
||||
}
|
||||
|
||||
virtual void onFocus() override {
|
||||
// TODO?
|
||||
}
|
||||
|
||||
virtual void onUnfocus() override {
|
||||
sel = false;
|
||||
}
|
||||
|
||||
virtual std::vector<MoveableNode> getMoveableNodes() const override {
|
||||
|
||||
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 onNodeMove(MapView2D* v, const int userIdx, const Point2 newPos) override {
|
||||
|
||||
(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 onNodeMoved(MapView2D* v, const int userIdx, const Point2 newPos) override {
|
||||
(void) userIdx;
|
||||
(void) newPos;
|
||||
emit v->onElementChange(this);
|
||||
}
|
||||
|
||||
void onNodeSelect(MapView2D* v, const int userIdx) override {
|
||||
HasMoveableNodes::onNodeSelect(v, userIdx);
|
||||
emit v->onElementChange(this);
|
||||
}
|
||||
void onNodeSelect(MapView2D* v, const int userIdx) override;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ MapView2D::MapView2D(QWidget* parent) : QOpenGLWidget(parent) {
|
||||
|
||||
// openGL params
|
||||
QSurfaceFormat format;
|
||||
format.setDepthBufferSize(24);
|
||||
format.setDepthBufferSize(8); // 24
|
||||
format.setStencilBufferSize(8);
|
||||
format.setSamples(1);
|
||||
// format.setVersion(3, 2);
|
||||
@@ -49,11 +49,19 @@ void MapView2D::paintGL() {
|
||||
// background tools
|
||||
tools.paintBefore(this, p);
|
||||
|
||||
// render all visible elements
|
||||
|
||||
qp.setRenderHint( QPainter::Antialiasing, true );
|
||||
|
||||
// render all visible elements. 1st run
|
||||
for (MapModelElement* el : getModel()->getVisibleElements()) {
|
||||
if (el->getMV2D()) {el->getMV2D()->paint(p);}
|
||||
}
|
||||
|
||||
// render all visible elements. 2nd run
|
||||
for (MapModelElement* el : getModel()->getVisibleElements()) {
|
||||
if (el->getMV2D()) {el->getMV2D()->paintAfter(p);}
|
||||
}
|
||||
|
||||
qp.setRenderHint( QPainter::Antialiasing, false );
|
||||
|
||||
// foreground tools
|
||||
@@ -68,7 +76,9 @@ void MapView2D::initializeGL() {
|
||||
|
||||
}
|
||||
|
||||
void MapView2D::resizeGL() {
|
||||
void MapView2D::resizeGL(int w, int h) {
|
||||
(void) w;
|
||||
(void) h;
|
||||
// TODO ?
|
||||
}
|
||||
|
||||
@@ -110,10 +120,12 @@ bool MapView2D::event(QEvent* event) {
|
||||
|
||||
bool MapView2D::gestureEvent(QGestureEvent* event) {
|
||||
if (QGesture *swipe = event->gesture(Qt::SwipeGesture)) {
|
||||
(void) swipe;
|
||||
//swipeTriggered(static_cast<QSwipeGesture *>(swipe));
|
||||
} else if (QGesture *pan = event->gesture(Qt::PanGesture))
|
||||
} else if (QGesture *pan = event->gesture(Qt::PanGesture)) {
|
||||
panTriggered(static_cast<QPanGesture *>(pan));
|
||||
return true;
|
||||
}
|
||||
if (QGesture *pinch = event->gesture(Qt::PinchGesture)) {
|
||||
pinchTriggered(static_cast<QPinchGesture *>(pinch));
|
||||
return true;
|
||||
|
||||
@@ -47,9 +47,9 @@ public:
|
||||
|
||||
public:
|
||||
|
||||
void paintGL();
|
||||
void initializeGL();
|
||||
void resizeGL();
|
||||
virtual void paintGL() override;
|
||||
virtual void initializeGL() override;
|
||||
virtual void resizeGL(int w, int h) override;
|
||||
|
||||
|
||||
Tools& getTools() {return tools;}
|
||||
|
||||
66
mapview/2D/MapViewElementHelper.cpp
Normal file
66
mapview/2D/MapViewElementHelper.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
#include "MapViewElementHelper.h"
|
||||
|
||||
#include <Indoor/geo/Point2.h>
|
||||
#include <Indoor/geo/Point3.h>
|
||||
#include <Indoor/geo/Line2.h>
|
||||
|
||||
#include <QColor>
|
||||
#include <QPen>
|
||||
#include <QBrush>
|
||||
|
||||
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||
|
||||
ClickDist MapElementHelper::getLineDistanceXY(Point2 p1, Point2 p2, Point2 dst) {
|
||||
|
||||
// the line (p1, p2)
|
||||
const Line2 line(p1, p2);
|
||||
|
||||
// 90 degree rotation L of the line (p1, p2)
|
||||
const Point2 vec = (p1 - p2).perpendicular();
|
||||
|
||||
// the line L
|
||||
const Line2 perb(dst-vec*100, dst+vec*100);
|
||||
|
||||
// calculate the cut betwen L and (p1,p2) (if any)
|
||||
Point2 cut(0,0);
|
||||
ClickDist cutDist(99999999, ClickDistType::CUT);
|
||||
if (line.getSegmentIntersection(perb, cut)) {
|
||||
|
||||
// distance between cut-point and mouse
|
||||
cutDist.dst_px = cut.getDistance(dst);
|
||||
|
||||
}
|
||||
|
||||
// (direct) distance from endpoints
|
||||
const ClickDist d1(p1.getDistance(dst), ClickDistType::DIRECT);
|
||||
const ClickDist d2(p2.getDistance(dst), ClickDistType::DIRECT);
|
||||
|
||||
// return the nearest possibility:
|
||||
return std::min(d1, std::min(d2, cutDist));
|
||||
|
||||
}
|
||||
|
||||
QPen MapElementHelper::getPen(Floorplan::Material mat, Floorplan::ObstacleType type, bool focus, float thickness_px) {
|
||||
|
||||
using namespace Floorplan;
|
||||
QPen pen;
|
||||
pen.setColor(Qt::darkGray); // default color
|
||||
pen.setWidth(thickness_px); // element thickness
|
||||
|
||||
// this one is very important!
|
||||
// as we change the line's width, the line also becomes longer
|
||||
// but, we do not want this! -> FlatCap
|
||||
pen.setCapStyle(Qt::FlatCap);
|
||||
|
||||
if (focus) {pen.setColor(QColor(64,64,200));}
|
||||
else if (mat == Material::CONCRETE) {pen.setColor(QColor(32,32,32));}
|
||||
else if (mat == Material::DRYWALL) {;}
|
||||
else if (mat == Material::GLASS) {pen.setStyle(Qt::PenStyle::DotLine);}
|
||||
else if (mat == Material::METALLIZED_GLAS) {pen.setStyle(Qt::PenStyle::DotLine);}
|
||||
else if (mat == Material::METAL) {pen.setColor(QColor(64, 64, 64));}
|
||||
else if (type == ObstacleType::HANDRAIL) {pen.setStyle(Qt::PenStyle::DashLine);}
|
||||
else if (type == ObstacleType::UNKNOWN) {pen.setColor(Qt::red);}
|
||||
else if (type == ObstacleType::PILLAR) {pen.setColor(Qt::red);}
|
||||
|
||||
return pen;
|
||||
}
|
||||
@@ -5,9 +5,7 @@
|
||||
#include <Indoor/geo/Point3.h>
|
||||
#include <Indoor/geo/Line2.h>
|
||||
|
||||
#include <QColor>
|
||||
#include <QPen>
|
||||
#include <QBrush>
|
||||
|
||||
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||
|
||||
@@ -35,59 +33,9 @@ public:
|
||||
* move l into dst
|
||||
* and calculate the cut-point between l and (p1, p2)
|
||||
*/
|
||||
static ClickDist getLineDistanceXY(Point2 p1, Point2 p2, Point2 dst) {
|
||||
|
||||
// the line (p1, p2)
|
||||
const Line2 line(p1, p2);
|
||||
|
||||
// 90 degree rotation L of the line (p1, p2)
|
||||
const Point2 vec = (p1 - p2).perpendicular();
|
||||
|
||||
// the line L
|
||||
const Line2 perb(dst-vec*100, dst+vec*100);
|
||||
|
||||
// calculate the cut betwen L and (p1,p2) (if any)
|
||||
Point2 cut(0,0);
|
||||
ClickDist cutDist(99999999, ClickDistType::CUT);
|
||||
if (line.getSegmentIntersection(perb, cut)) {
|
||||
|
||||
// distance between cut-point and mouse
|
||||
cutDist.dst_px = cut.getDistance(dst);
|
||||
|
||||
}
|
||||
|
||||
// (direct) distance from endpoints
|
||||
const ClickDist d1(p1.getDistance(dst), ClickDistType::DIRECT);
|
||||
const ClickDist d2(p2.getDistance(dst), ClickDistType::DIRECT);
|
||||
|
||||
// return the nearest possibility:
|
||||
return std::min(d1, std::min(d2, cutDist));
|
||||
|
||||
}
|
||||
|
||||
static QPen getPen(Floorplan::Material mat, Floorplan::ObstacleType type, bool focus, float thickness_px) {
|
||||
|
||||
using namespace Floorplan;
|
||||
QPen pen; pen.setColor(Qt::darkGray);
|
||||
pen.setWidth(thickness_px);
|
||||
|
||||
// this one is very important!
|
||||
// as we change the line's width, the line also becomes longer
|
||||
// but, we do not want this! -> FlatCap
|
||||
pen.setCapStyle(Qt::FlatCap);
|
||||
|
||||
if (focus) {pen.setColor(Qt::black);}
|
||||
if (mat == Material::CONCRETE) {;}
|
||||
if (mat == Material::GLASS) {pen.setStyle(Qt::PenStyle::DotLine);}
|
||||
if (mat == Material::METALLIZED_GLAS) {pen.setStyle(Qt::PenStyle::DotLine);}
|
||||
if (mat == Material::METAL) {pen.setColor(QColor(50, 50, 50));}
|
||||
if (type == ObstacleType::HANDRAIL) {pen.setStyle(Qt::PenStyle::DashLine);}
|
||||
if (type == ObstacleType::UNKNOWN) {pen.setColor(Qt::red);}
|
||||
if (type == ObstacleType::PILLAR) {pen.setColor(Qt::red);}
|
||||
|
||||
return pen;
|
||||
}
|
||||
static ClickDist getLineDistanceXY(Point2 p1, Point2 p2, Point2 dst);
|
||||
|
||||
static QPen getPen(Floorplan::Material mat, Floorplan::ObstacleType type, bool focus, float thickness_px);
|
||||
|
||||
};
|
||||
|
||||
|
||||
158
mapview/2D/Painter.cpp
Normal file
158
mapview/2D/Painter.cpp
Normal file
@@ -0,0 +1,158 @@
|
||||
#include "Painter.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QBitmap>
|
||||
|
||||
#include <Indoor/geo/Point2.h>
|
||||
#include <Indoor/geo/Point3.h>
|
||||
#include <Indoor/geo/BBox2.h>
|
||||
|
||||
#include "Scaler.h"
|
||||
|
||||
Painter::Painter(Scaler& s, QPainter* p, int w, int h) : s(s), p(p), w(w), h(h) {
|
||||
p->setPen(Qt::black);
|
||||
p->setBrush(Qt::NoBrush);
|
||||
}
|
||||
|
||||
int Painter::width() {return w;}
|
||||
|
||||
int Painter::height() {return h;}
|
||||
|
||||
bool Painter::isVisible(const Point2 p) {
|
||||
const float x = s.xms(p.x);
|
||||
const float y = s.yms(p.y);
|
||||
return (x >= 0 && y >= 0 && x < w && y < h);
|
||||
}
|
||||
|
||||
bool Painter::isVisible(const BBox2 bb) {
|
||||
const BBox2 bbt(0,0,w,h);
|
||||
BBox2 bbs;
|
||||
bbs.add(s.xms(bb.getMin().x), s.yms(bb.getMin().y)); // y might be inverted! -> use the add() method to address this
|
||||
bbs.add(s.xms(bb.getMax().x), s.yms(bb.getMax().y)); // y might be inverted! -> use the add() method to address this
|
||||
return bbt.intersects(bbs);
|
||||
}
|
||||
|
||||
void Painter::drawLine(const Point2 p1, const Point2 p2) {
|
||||
//p->drawLine(s.xms(p1.x), s.yms(p1.y), s.xms(p2.x), s.yms(p2.y));
|
||||
p->drawLine(QPointF(s.xms(p1.x), s.yms(p1.y)), QPointF(s.xms(p2.x), s.yms(p2.y)));
|
||||
}
|
||||
void Painter::drawLine(const Point3 p1, const Point3 p2) {
|
||||
//p->drawLine(s.xms(p1.x), s.yms(p1.y), s.xms(p2.x), s.yms(p2.y));
|
||||
p->drawLine(QPointF(s.xms(p1.x), s.yms(p1.y)), QPointF(s.xms(p2.x), s.yms(p2.y)));
|
||||
}
|
||||
|
||||
float Painter::radToDeg(const float rad) const {
|
||||
return rad * 180 / M_PI;
|
||||
}
|
||||
|
||||
void Painter::drawArc(const Point2 center, const float radius, const float startAngleRad, const float spanAngleRad) {
|
||||
const float wh = s.ms(radius) * 2;
|
||||
const float x1 = s.xms(center.x) - wh/2;
|
||||
const float y1 = s.yms(center.y) - wh/2;
|
||||
p->drawArc(x1, y1, wh, wh, radToDeg(startAngleRad)*16, radToDeg(spanAngleRad)*16);
|
||||
}
|
||||
|
||||
void Painter::drawCircle(const Point3 center) {
|
||||
int r = 5;
|
||||
p->drawEllipse(s.xms(center.x)-r, s.yms(center.y)-r, 2*r, 2*r);
|
||||
}
|
||||
|
||||
void Painter::drawCircle(const Point2 center) {
|
||||
int r = 5;
|
||||
p->drawEllipse(s.xms(center.x)-r, s.yms(center.y)-r, 2*r, 2*r);
|
||||
}
|
||||
|
||||
/** draw a dot at the given map coordinates */
|
||||
void Painter::drawDot(const Point2 center) {
|
||||
int r = 1;
|
||||
p->drawEllipse(s.xms(center.x)-r, s.yms(center.y)-r, 2*r, 2*r);
|
||||
}
|
||||
|
||||
void Painter::drawCircle(const Point2 center, const float size_m) {
|
||||
int r = s.ms(size_m);
|
||||
p->drawEllipse(s.xms(center.x)-r, s.yms(center.y)-r, 2*r, 2*r);
|
||||
}
|
||||
|
||||
void Painter::drawCircle_px(const Point2 center, const float size_px) {
|
||||
int r = size_px;
|
||||
p->drawEllipse(s.xms(center.x)-r, s.yms(center.y)-r, 2*r, 2*r);
|
||||
}
|
||||
|
||||
void Painter::drawNode(Point2 pt, bool focused, bool selected) {
|
||||
float rs = 0.05;
|
||||
if (selected) {setPenBrush(Qt::black, Qt::gray); rs = 0.08;}
|
||||
else if (focused) {setPenBrush(Qt::black, Qt::white); rs = 0.08;}
|
||||
else {setPenBrush(Qt::black, Qt::NoBrush); rs = 0.04;}
|
||||
const float s = this->s.getScale();
|
||||
if (s > 10) {drawCircle(pt, rs);} // only at a certain zoom level
|
||||
}
|
||||
|
||||
void Painter::drawLine(const float x1, const float y1, const float x2, const float y2) {
|
||||
p->drawLine(s.xms(x1), s.yms(y1), s.xms(x2), s.yms(y2));
|
||||
}
|
||||
|
||||
void Painter::drawRect(const Point2 p1, const Point2 p2) {
|
||||
drawRect(p1.x, p1.y, p2.x, p2.y);
|
||||
}
|
||||
|
||||
void Painter::drawRect(const float x1, const float y1, const float x2, const float y2) {
|
||||
float w = x2-x1;
|
||||
float h = y1-y2;
|
||||
p->drawRect(s.xms(x1), s.yms(y1), s.ms(w), s.ms(h));
|
||||
}
|
||||
|
||||
void Painter::drawRect(const Point2 center) {
|
||||
float r = s.sm(5); // 5 pixel
|
||||
drawRect(center-Point2(r,r), center+Point2(r,r));
|
||||
}
|
||||
|
||||
void Painter::drawText(const Point2 pos, const std::string& text) {
|
||||
p->drawText(s.xms(pos.x), s.yms(pos.y), text.c_str());
|
||||
}
|
||||
|
||||
void Painter::drawPolygon(const std::vector<Point2>& points) {
|
||||
std::vector<QPointF> vec;
|
||||
for (const Point2 p : points) {
|
||||
vec.push_back(QPointF(s.xms(p.x), s.yms(p.y)));
|
||||
}
|
||||
p->drawPolygon(vec.data(), vec.size());
|
||||
}
|
||||
void Painter::drawPolygon(const std::vector<Point3>& points) {
|
||||
std::vector<QPointF> vec;
|
||||
for (const Point3 p : points) {
|
||||
vec.push_back(QPointF(s.xms(p.x), s.yms(p.y)));
|
||||
}
|
||||
p->drawPolygon(vec.data(), vec.size());
|
||||
}
|
||||
|
||||
void Painter::drawPixmap(const Point2 pt, const QPixmap& img) {
|
||||
p->drawPixmap(s.xms(pt.x)-img.width()/2, s.yms(pt.y)-img.height()/2, img);
|
||||
}
|
||||
|
||||
void Painter::drawImage(const Point2 pt, const QImage& img) {
|
||||
p->drawImage(s.xms(pt.x)-img.width()/2, s.yms(pt.y)-img.height()/2, img);
|
||||
}
|
||||
|
||||
void Painter::drawLength(Point2 p1, Point2 p2, const float len, const float offset) {
|
||||
if (p1.x < p2.x) {swap(p1, p2);}
|
||||
const Point2 center_m = (p1 + p2) / 2;
|
||||
Point2 dir_px = (p2 - p1).perpendicular().normalized() * (5+offset);
|
||||
if (dir_px.x <= 0) {dir_px = -dir_px;}
|
||||
const Point2 pos_m = center_m + dir_px / getScaler().getScale();
|
||||
char buf[64]; sprintf(buf, "%.1f", len);
|
||||
drawText(pos_m, buf);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Painter::setBrush(const QBrush& brush) { p->setBrush(brush); }
|
||||
void Painter::setBrush(const Qt::BrushStyle& brush) { p->setBrush(brush); }
|
||||
|
||||
void Painter::setPen(const QPen& pen) {p->setPen(pen); }
|
||||
void Painter::setPen(const QColor& pen) {p->setPen(pen); }
|
||||
void Painter::setPen(const Qt::PenStyle& pen) {p->setPen(pen); }
|
||||
|
||||
const QPen& Painter::getPen() {return p->pen();}
|
||||
|
||||
const Scaler& Painter::getScaler() {return s;}
|
||||
|
||||
@@ -1,14 +1,21 @@
|
||||
#ifndef PAINTER_H
|
||||
#define PAINTER_H
|
||||
|
||||
#include <QPainter>
|
||||
#include <QBitmap>
|
||||
|
||||
#include <Indoor/geo/Point2.h>
|
||||
#include <Indoor/geo/Point3.h>
|
||||
#include <Indoor/geo/BBox2.h>
|
||||
|
||||
#include "Scaler.h"
|
||||
//#include "Scaler.h"
|
||||
|
||||
class Scaler;
|
||||
class QPainter;
|
||||
class QPixmap;
|
||||
class QImage;
|
||||
class QPen;
|
||||
class QColor;
|
||||
class QBrush;
|
||||
|
||||
#include <qnamespace.h>
|
||||
|
||||
class Painter {
|
||||
|
||||
@@ -22,145 +29,66 @@ public:
|
||||
public:
|
||||
|
||||
/** ctor */
|
||||
Painter(Scaler& s, QPainter* p, int w, int h) : s(s), p(p), w(w), h(h) {
|
||||
p->setPen(Qt::black);
|
||||
p->setBrush(Qt::NoBrush);
|
||||
}
|
||||
Painter(Scaler& s, QPainter* p, int w, int h);
|
||||
|
||||
int width() {return w;}
|
||||
int width();
|
||||
|
||||
int height() {return h;}
|
||||
int height();
|
||||
|
||||
/** is the given point visible on screen? */
|
||||
bool isVisible(const Point2 p) {
|
||||
const float x = s.xms(p.x);
|
||||
const float y = s.yms(p.y);
|
||||
return (x >= 0 && y >= 0 && x < w && y < h);
|
||||
}
|
||||
bool isVisible(const Point2 p);
|
||||
|
||||
/** is the given volume visible on screen? */
|
||||
bool isVisible(const BBox2 bb) {
|
||||
const BBox2 bbt(0,0,w,h);
|
||||
BBox2 bbs;
|
||||
bbs.add(s.xms(bb.getMin().x), s.yms(bb.getMin().y)); // y might be inverted! -> use the add() method to address this
|
||||
bbs.add(s.xms(bb.getMax().x), s.yms(bb.getMax().y)); // y might be inverted! -> use the add() method to address this
|
||||
return bbt.intersects(bbs);
|
||||
}
|
||||
bool isVisible(const BBox2 bb);
|
||||
|
||||
void drawLine(const Point2 p1, const Point2 p2) {
|
||||
p->drawLine(s.xms(p1.x), s.yms(p1.y), s.xms(p2.x), s.yms(p2.y));
|
||||
}
|
||||
void drawLine(const Point3 p1, const Point3 p2) {
|
||||
p->drawLine(s.xms(p1.x), s.yms(p1.y), s.xms(p2.x), s.yms(p2.y));
|
||||
}
|
||||
void drawLine(const Point2 p1, const Point2 p2);
|
||||
void drawLine(const Point3 p1, const Point3 p2);
|
||||
void drawLine(const float x1, const float y1, const float x2, const float y2);
|
||||
|
||||
float radToDeg(const float rad) const {
|
||||
return rad * 180 / M_PI;
|
||||
}
|
||||
float radToDeg(const float rad) const;
|
||||
|
||||
void drawArc(const Point2 center, const float radius, const float startAngleRad, const float spanAngleRad) {
|
||||
const float wh = s.ms(radius) * 2;
|
||||
const float x1 = s.xms(center.x) - wh/2;
|
||||
const float y1 = s.yms(center.y) - wh/2;
|
||||
p->drawArc(x1, y1, wh, wh, radToDeg(startAngleRad)*16, radToDeg(spanAngleRad)*16);
|
||||
}
|
||||
|
||||
void drawCircle(const Point3 center) {
|
||||
int r = 5;
|
||||
p->drawEllipse(s.xms(center.x)-r, s.yms(center.y)-r, 2*r, 2*r);
|
||||
}
|
||||
|
||||
void drawCircle(const Point2 center) {
|
||||
int r = 5;
|
||||
p->drawEllipse(s.xms(center.x)-r, s.yms(center.y)-r, 2*r, 2*r);
|
||||
}
|
||||
void drawArc(const Point2 center, const float radius, const float startAngleRad, const float spanAngleRad);
|
||||
|
||||
/** draw a dot at the given map coordinates */
|
||||
void drawDot(const Point2 center) {
|
||||
int r = 1;
|
||||
p->drawEllipse(s.xms(center.x)-r, s.yms(center.y)-r, 2*r, 2*r);
|
||||
void drawDot(const Point2 center);
|
||||
|
||||
void drawCircle(const Point3 center);
|
||||
void drawCircle(const Point2 center);
|
||||
void drawCircle(const Point2 center, const float size_m);
|
||||
void drawCircle_px(const Point2 center, const float size_px);
|
||||
|
||||
void drawRect(const Point2 p1, const Point2 p2);
|
||||
void drawRect(const float x1, const float y1, const float x2, const float y2);
|
||||
void drawRect(const Point2 center);
|
||||
|
||||
void drawNode(Point2 pt, bool focused, bool selected);
|
||||
|
||||
void drawText(const Point2 pos, const std::string& text);
|
||||
|
||||
void drawPolygon(const std::vector<Point2>& points);
|
||||
void drawPolygon(const std::vector<Point3>& points);
|
||||
|
||||
void drawPixmap(const Point2 pt, const QPixmap& img);
|
||||
|
||||
void drawImage(const Point2 pt, const QImage& img);
|
||||
|
||||
void drawLength(Point2 p1, Point2 p2, const float len, const float offset = 0);
|
||||
|
||||
void setBrush(const QBrush& brush);
|
||||
void setBrush(const Qt::BrushStyle& brush);
|
||||
|
||||
void setPen(const QPen& pen);
|
||||
void setPen(const QColor& pen);
|
||||
void setPen(const Qt::PenStyle& pen);
|
||||
|
||||
const QPen& getPen();
|
||||
|
||||
template <typename Pen, typename Brush> void setPenBrush(const Pen& pen, const Brush& brush) {
|
||||
setPen(pen);
|
||||
setBrush(brush);
|
||||
}
|
||||
|
||||
void drawCircle(const Point2 center, const float size_m) {
|
||||
int r = s.ms(size_m);
|
||||
p->drawEllipse(s.xms(center.x)-r, s.yms(center.y)-r, 2*r, 2*r);
|
||||
}
|
||||
|
||||
void drawCircle_px(const Point2 center, const float size_px) {
|
||||
int r = size_px;
|
||||
p->drawEllipse(s.xms(center.x)-r, s.yms(center.y)-r, 2*r, 2*r);
|
||||
}
|
||||
|
||||
void drawLine(const float x1, const float y1, const float x2, const float y2) {
|
||||
p->drawLine(s.xms(x1), s.yms(y1), s.xms(x2), s.yms(y2));
|
||||
}
|
||||
|
||||
void drawRect(const Point2 p1, const Point2 p2) {
|
||||
drawRect(p1.x, p1.y, p2.x, p2.y);
|
||||
}
|
||||
|
||||
void drawRect(const float x1, const float y1, const float x2, const float y2) {
|
||||
float w = x2-x1;
|
||||
float h = y1-y2;
|
||||
p->drawRect(s.xms(x1), s.yms(y1), s.ms(w), s.ms(h));
|
||||
}
|
||||
|
||||
void drawRect(const Point2 center) {
|
||||
float r = s.sm(5); // 5 pixel
|
||||
drawRect(center-Point2(r,r), center+Point2(r,r));
|
||||
}
|
||||
|
||||
void drawText(const Point2 pos, const std::string& text) {
|
||||
p->drawText(s.xms(pos.x), s.yms(pos.y), text.c_str());
|
||||
}
|
||||
|
||||
void drawPolygon(const std::vector<Point2>& points) {
|
||||
std::vector<QPointF> vec;
|
||||
for (const Point2 p : points) {
|
||||
vec.push_back(QPointF(s.xms(p.x), s.yms(p.y)));
|
||||
}
|
||||
p->drawPolygon(vec.data(), vec.size());
|
||||
}
|
||||
void drawPolygon(const std::vector<Point3>& points) {
|
||||
std::vector<QPointF> vec;
|
||||
for (const Point3 p : points) {
|
||||
vec.push_back(QPointF(s.xms(p.x), s.yms(p.y)));
|
||||
}
|
||||
p->drawPolygon(vec.data(), vec.size());
|
||||
}
|
||||
|
||||
void drawPixmap(const Point2 pt, const QPixmap& img) {
|
||||
p->drawPixmap(s.xms(pt.x)-img.width()/2, s.yms(pt.y)-img.height()/2, img);
|
||||
}
|
||||
|
||||
void drawImage(const Point2 pt, const QImage& img) {
|
||||
p->drawImage(s.xms(pt.x)-img.width()/2, s.yms(pt.y)-img.height()/2, img);
|
||||
}
|
||||
|
||||
void drawLength(Point2 p1, Point2 p2, const float len, const float offset = 0) {
|
||||
if (p1.x < p2.x) {swap(p1, p2);}
|
||||
const Point2 center_m = (p1 + p2) / 2;
|
||||
Point2 dir_px = (p2 - p1).perpendicular().normalized() * (5+offset);
|
||||
if (dir_px.x <= 0) {dir_px = -dir_px;}
|
||||
const Point2 pos_m = center_m + dir_px / getScaler().getScale();
|
||||
char buf[64]; sprintf(buf, "%.1f", len);
|
||||
drawText(pos_m, buf);
|
||||
}
|
||||
|
||||
void setBrush(const QBrush& brush) { p->setBrush(brush); }
|
||||
void setBrush(const Qt::BrushStyle& brush) { p->setBrush(brush); }
|
||||
|
||||
void setPen(const QPen& pen) {p->setPen(pen); }
|
||||
void setPen(const QColor& pen) {p->setPen(pen); }
|
||||
void setPen(const Qt::PenStyle& pen) {p->setPen(pen); }
|
||||
|
||||
|
||||
const QPen& getPen() {return p->pen();}
|
||||
|
||||
|
||||
template <typename Pen, typename Brush> void setPenBrush(const Pen& pen, const Brush& brush) {setPen(pen); setBrush(brush);}
|
||||
|
||||
const Scaler& getScaler() {return s;}
|
||||
const Scaler& getScaler();
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -236,10 +236,12 @@ bool MapView3D::event(QEvent* event) {
|
||||
|
||||
bool MapView3D::gestureEvent(QGestureEvent* event) {
|
||||
if (QGesture *swipe = event->gesture(Qt::SwipeGesture)) {
|
||||
(void) swipe;
|
||||
//swipeTriggered(static_cast<QSwipeGesture *>(swipe));
|
||||
} else if (QGesture *pan = event->gesture(Qt::PanGesture))
|
||||
} else if (QGesture *pan = event->gesture(Qt::PanGesture)) {
|
||||
panTriggered(static_cast<QPanGesture *>(pan));
|
||||
return true;
|
||||
}
|
||||
if (QGesture *pinch = event->gesture(Qt::PinchGesture)) {
|
||||
pinchTriggered(static_cast<QPinchGesture *>(pinch));
|
||||
return true;
|
||||
@@ -248,6 +250,7 @@ bool MapView3D::gestureEvent(QGestureEvent* event) {
|
||||
}
|
||||
|
||||
void MapView3D::pinchTriggered(QPinchGesture* gesture) {
|
||||
(void) gesture;
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
82
mapview/3D/floorplan/FloorplanRenderer.cpp
Normal file
82
mapview/3D/floorplan/FloorplanRenderer.cpp
Normal file
@@ -0,0 +1,82 @@
|
||||
#include "FloorplanRenderer.h"
|
||||
|
||||
#include <unordered_set>
|
||||
#include <Indoor/navMesh/NavMesh.h>
|
||||
#include <Indoor/navMesh/NavMeshTriangle.h>
|
||||
#include <Indoor/navMesh/NavMeshType.h>
|
||||
|
||||
#include <QPainter>
|
||||
#include <QOpenGLWidget>
|
||||
#include <QOpenGLFunctions>
|
||||
|
||||
#include "../misc/Renderable3D.h"
|
||||
#include "../misc/Shader.h"
|
||||
#include "../misc/TriangleData.h"
|
||||
|
||||
#include <Indoor/wifi/estimate/ray3/ModelFactory.h>
|
||||
|
||||
#include "RenderTriangle.h"
|
||||
|
||||
|
||||
/** ctor */
|
||||
FloorplanRenderer::FloorplanRenderer() {
|
||||
;
|
||||
}
|
||||
|
||||
void FloorplanRenderer::renderSolid(const RenderSettings& rs, const RenderTriangle& rt, bool wireframe) {
|
||||
|
||||
rs.shader->bind();
|
||||
rs.shader->setModelMatrix(QMatrix4x4());
|
||||
|
||||
rs.shader->setVertices(rt.getVertices());
|
||||
rs.shader->setNormals(rt.getNormals());
|
||||
rs.shader->setVertexColor(rt.getRGBA());
|
||||
rs.funcs->glDrawArrays(GL_TRIANGLES, 0, rt.count());
|
||||
rs.shader->unsetVertices();
|
||||
rs.shader->unsetNormals();
|
||||
rs.shader->unsetVertexColor();
|
||||
|
||||
if (wireframe) {
|
||||
RenderTriangle rt2 = rt.toWireframe(false);
|
||||
rs.shader->setColor(0,0,0,128);
|
||||
rs.shader->setVertices(rt2.getVertices());
|
||||
//rs.shader->setVertexColor(rt2.getRGBA());
|
||||
rs.funcs->glDrawArrays(GL_LINES, 0, rt2.count());
|
||||
rs.shader->unsetVertices();
|
||||
//rs.shader->unsetVertexColor();
|
||||
}
|
||||
rs.shader->release();
|
||||
|
||||
}
|
||||
|
||||
void FloorplanRenderer::renderTransp(const RenderSettings& rs, const RenderTriangle& rt, bool wireframe) {
|
||||
|
||||
rs.funcs->glEnable(GL_BLEND);
|
||||
rs.funcs->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
rs.shader->bind();
|
||||
rs.shader->setModelMatrix(QMatrix4x4());
|
||||
|
||||
rs.shader->setVertices(rt.getVertices());
|
||||
rs.shader->setNormals(rt.getNormals());
|
||||
rs.shader->setVertexColor(rt.getRGBA());
|
||||
rs.funcs->glDrawArrays(GL_TRIANGLES, 0, rt.count());
|
||||
rs.shader->unsetVertices();
|
||||
rs.shader->unsetNormals();
|
||||
rs.shader->unsetVertexColor();
|
||||
|
||||
if (wireframe) {
|
||||
RenderTriangle rt2 = rt.toWireframe(false);
|
||||
rs.shader->setColor(0,0,0,128);
|
||||
rs.shader->setVertices(rt2.getVertices());
|
||||
//rs.shader->setVertexColor(rt2.getRGBA());
|
||||
rs.funcs->glDrawArrays(GL_LINES, 0, rt2.count());
|
||||
rs.shader->unsetVertices();
|
||||
//rs.shader->unsetVertexColor();
|
||||
}
|
||||
|
||||
rs.shader->release();
|
||||
|
||||
rs.funcs->glDisable(GL_BLEND);
|
||||
|
||||
}
|
||||
@@ -1,91 +1,22 @@
|
||||
#ifndef FLOORPLANRENDERER_H
|
||||
#define FLOORPLANRENDERER_H
|
||||
|
||||
#include <unordered_set>
|
||||
#include <Indoor/navMesh/NavMesh.h>
|
||||
#include <Indoor/navMesh/NavMeshTriangle.h>
|
||||
#include <Indoor/navMesh/NavMeshType.h>
|
||||
|
||||
#include <QPainter>
|
||||
#include <QOpenGLWidget>
|
||||
#include <QOpenGLFunctions>
|
||||
|
||||
#include "../misc/Renderable3D.h"
|
||||
#include "../misc/Shader.h"
|
||||
#include "../misc/TriangleData.h"
|
||||
|
||||
#include <Indoor/wifi/estimate/ray3/ModelFactory.h>
|
||||
|
||||
#include "RenderTriangle.h"
|
||||
class RenderTriangle;
|
||||
|
||||
class FloorplanRenderer {
|
||||
|
||||
public:
|
||||
|
||||
/** ctor */
|
||||
FloorplanRenderer() {
|
||||
;
|
||||
}
|
||||
FloorplanRenderer();
|
||||
|
||||
/** render the given grid using GL commands */
|
||||
void renderSolid(const RenderSettings& rs, const RenderTriangle& rt, bool wireframe) {
|
||||
|
||||
rs.shader->bind();
|
||||
rs.shader->setModelMatrix(QMatrix4x4());
|
||||
|
||||
rs.shader->setVertices(rt.getVertices());
|
||||
rs.shader->setNormals(rt.getNormals());
|
||||
rs.shader->setVertexColor(rt.getRGBA());
|
||||
rs.funcs->glDrawArrays(GL_TRIANGLES, 0, rt.count());
|
||||
rs.shader->unsetVertices();
|
||||
rs.shader->unsetNormals();
|
||||
rs.shader->unsetVertexColor();
|
||||
|
||||
if (wireframe) {
|
||||
RenderTriangle rt2 = rt.toWireframe(false);
|
||||
rs.shader->setColor(0,0,0,128);
|
||||
rs.shader->setVertices(rt2.getVertices());
|
||||
//rs.shader->setVertexColor(rt2.getRGBA());
|
||||
rs.funcs->glDrawArrays(GL_LINES, 0, rt2.count());
|
||||
rs.shader->unsetVertices();
|
||||
//rs.shader->unsetVertexColor();
|
||||
}
|
||||
rs.shader->release();
|
||||
|
||||
}
|
||||
void renderSolid(const RenderSettings& rs, const RenderTriangle& rt, bool wireframe);
|
||||
|
||||
/** render the given grid using GL commands */
|
||||
void renderTransp(const RenderSettings& rs, const RenderTriangle& rt, bool wireframe) {
|
||||
|
||||
rs.funcs->glEnable(GL_BLEND);
|
||||
rs.funcs->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
rs.shader->bind();
|
||||
rs.shader->setModelMatrix(QMatrix4x4());
|
||||
|
||||
rs.shader->setVertices(rt.getVertices());
|
||||
rs.shader->setNormals(rt.getNormals());
|
||||
rs.shader->setVertexColor(rt.getRGBA());
|
||||
rs.funcs->glDrawArrays(GL_TRIANGLES, 0, rt.count());
|
||||
rs.shader->unsetVertices();
|
||||
rs.shader->unsetNormals();
|
||||
rs.shader->unsetVertexColor();
|
||||
|
||||
if (wireframe) {
|
||||
RenderTriangle rt2 = rt.toWireframe(false);
|
||||
rs.shader->setColor(0,0,0,128);
|
||||
rs.shader->setVertices(rt2.getVertices());
|
||||
//rs.shader->setVertexColor(rt2.getRGBA());
|
||||
rs.funcs->glDrawArrays(GL_LINES, 0, rt2.count());
|
||||
rs.shader->unsetVertices();
|
||||
//rs.shader->unsetVertexColor();
|
||||
}
|
||||
|
||||
rs.shader->release();
|
||||
|
||||
rs.funcs->glDisable(GL_BLEND);
|
||||
|
||||
}
|
||||
void renderTransp(const RenderSettings& rs, const RenderTriangle& rt, bool wireframe);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ void NavMeshRenderer::rebuildIfNeeded(NavMeshModel* model) {
|
||||
case (int) NM::NavMeshType::STAIR_SKEWED: color = Point3(0.4, 0.4, 0.4); break;
|
||||
}
|
||||
|
||||
const float o = 0.001f;
|
||||
//const float o = 0.001f;
|
||||
outlines.addLine(tria->getP1(), tria->getP2(), color.x, color.y, color.z, 1);
|
||||
outlines.addLine(tria->getP2(), tria->getP3(), color.x, color.y, color.z, 1);
|
||||
outlines.addLine(tria->getP3(), tria->getP1(), color.x, color.y, color.z, 1);
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include "IHasParams.h"
|
||||
|
||||
#include "../2D/MV2DElementFloorObstacleDoor.h"
|
||||
#include "../3D/MV3DElementFloorObstacleDoor.h"
|
||||
//#include "../3D/MV3DElementFloorObstacleDoor.h"
|
||||
|
||||
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||
|
||||
@@ -21,12 +21,12 @@ public:
|
||||
Floorplan::Floor* mf;
|
||||
Floorplan::FloorObstacleDoor* fo;
|
||||
MV2DElementFloorObstacleDoor mv2d;
|
||||
MV3DElementFloorObstacleDoor mv3d;
|
||||
//MV3DElementFloorObstacleDoor mv3d;
|
||||
|
||||
public:
|
||||
|
||||
MMFloorObstacleDoor(MapLayer* parent, Floorplan::Floor* mf, Floorplan::FloorObstacleDoor* fo) :
|
||||
MapModelElement(parent), mf(mf), fo(fo), mv2d(fo), mv3d(mf,fo) {
|
||||
MapModelElement(parent), mf(mf), fo(fo), mv2d(fo) {//, mv3d(mf,fo) {
|
||||
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ public:
|
||||
Floorplan::DoorType getDoorType() const override {return fo->type;}
|
||||
|
||||
MV2DElement* getMV2D() const override {return (MV2DElement*) &mv2d;}
|
||||
MV3DElement* getMV3D() const override {return (MV3DElement*) &mv3d;}
|
||||
//MV3DElement* getMV3D() const override {return (MV3DElement*) &mv3d;}
|
||||
|
||||
void deleteMe() const override {
|
||||
parent->removeElement(this);
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include "IHasParams.h"
|
||||
|
||||
#include "../2D/MV2DElementFloorObstacleLine.h"
|
||||
#include "../3D/MV3DElementFloorObstacleWall.h"
|
||||
//#include "../3D/MV3DElementFloorObstacleWall.h"
|
||||
|
||||
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||
|
||||
@@ -21,12 +21,12 @@ public:
|
||||
Floorplan::Floor* mf;
|
||||
Floorplan::FloorObstacleLine* fo;
|
||||
MV2DElementFloorObstacleLine mv2d;
|
||||
MV3DElementFloorObstacleWall mv3d;
|
||||
//MV3DElementFloorObstacleWall mv3d;
|
||||
|
||||
public:
|
||||
|
||||
MMFloorObstacleLine(MapLayer* parent, Floorplan::Floor* mf, Floorplan::FloorObstacleLine* fo) :
|
||||
MapModelElement(parent), mf(mf), fo(fo), mv2d(fo), mv3d(mf,fo) {
|
||||
MapModelElement(parent), mf(mf), fo(fo), mv2d(fo) {//, mv3d(mf,fo) {
|
||||
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ public:
|
||||
Floorplan::ObstacleType getObatcleType() const override {return fo->type;}
|
||||
|
||||
MV2DElement* getMV2D() const override {return (MV2DElement*) &mv2d;}
|
||||
MV3DElement* getMV3D() const override {return (MV3DElement*) &mv3d;}
|
||||
//MV3DElement* getMV3D() const override {return (MV3DElement*) &mv3d;}
|
||||
|
||||
void deleteMe() const override {
|
||||
parent->removeElement(this);
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include "IHasParams.h"
|
||||
|
||||
#include "../2D/MV2DElementFloorObstacleObject.h"
|
||||
#include "../3D/MV3DElementFloorObstacleObject.h"
|
||||
//#include "../3D/MV3DElementFloorObstacleObject.h"
|
||||
|
||||
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||
|
||||
@@ -22,17 +22,17 @@ public:
|
||||
Floorplan::Floor* mf;
|
||||
Floorplan::FloorObstacleObject* fo;
|
||||
MV2DElementFloorObstacleObject mv2d;
|
||||
MV3DElementFloorObstacleObject mv3d;
|
||||
//MV3DElementFloorObstacleObject mv3d;
|
||||
|
||||
public:
|
||||
|
||||
MMFloorObstacleObject(MapLayer* parent, Floorplan::Floor* mf, Floorplan::FloorObstacleObject* fo) :
|
||||
MapModelElement(parent), mf(mf), fo(fo), mv2d(fo), mv3d(mf,fo) {
|
||||
MapModelElement(parent), mf(mf), fo(fo), mv2d(fo) {//, mv3d(mf,fo) {
|
||||
|
||||
}
|
||||
|
||||
MV2DElement* getMV2D() const override {return (MV2DElement*) &mv2d;}
|
||||
MV3DElement* getMV3D() const override {return (MV3DElement*) &mv3d;}
|
||||
//MV3DElement* getMV3D() const override {return (MV3DElement*) &mv3d;}
|
||||
|
||||
void deleteMe() const override {
|
||||
parent->removeElement(this);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "MMFloorOutlinePolygon.h"
|
||||
#include "MMFloorOutlinePolygonCombined.h"
|
||||
|
||||
#include "../3D/MV3DElementFloorOutline.h"
|
||||
//#include "../3D/MV3DElementFloorOutline.h"
|
||||
|
||||
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "MapLayer.h"
|
||||
#include "MMFloorOutlinePolygon.h"
|
||||
#include "../3D/MV3DElementFloorOutline.h"
|
||||
//#include "../3D/MV3DElementFloorOutline.h"
|
||||
|
||||
|
||||
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||
@@ -19,19 +19,19 @@ private:
|
||||
/** the underlying model */
|
||||
Floorplan::Floor* floor;
|
||||
|
||||
MV3DElementFloorOutline mv3d;
|
||||
//MV3DElementFloorOutline mv3d;
|
||||
|
||||
public:
|
||||
|
||||
/** ctor with the underlying model */
|
||||
MMFloorOutlinePolygonCombined(MapLayer* parent, Floorplan::Floor* floor) :
|
||||
MapModelElement(parent), floor(floor), mv3d(floor, &floor->outline) {
|
||||
MapModelElement(parent), floor(floor) {//, mv3d(floor, &floor->outline) {
|
||||
|
||||
;
|
||||
|
||||
}
|
||||
|
||||
MV3DElement* getMV3D() const override {return (MV3DElement*) &mv3d;}
|
||||
//MV3DElement* getMV3D() const override {return (MV3DElement*) &mv3d;}
|
||||
|
||||
/** get the corresponding floor from the underlying model */
|
||||
Floorplan::Floor* getFloor() {return floor;}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include "MMFloorOutlinePolygon.h"
|
||||
|
||||
#include "../2D/MV2DElementStair.h"
|
||||
#include "../3D/MV3DElementStair.h"
|
||||
//#include "../3D/MV3DElementStair.h"
|
||||
|
||||
|
||||
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||
@@ -23,20 +23,20 @@ private:
|
||||
Floorplan::StairFreeform* stair;
|
||||
|
||||
MV2DElementStair mv2d;
|
||||
MV3DElementStair mv3d;
|
||||
//MV3DElementStair mv3d;
|
||||
|
||||
public:
|
||||
|
||||
/** ctor with the underlying model */
|
||||
MMFloorStair(MapLayer* parent, Floorplan::IndoorMap* map, Floorplan::Floor* floor, Floorplan::StairFreeform* stair) :
|
||||
MapModelElement(parent), floor(floor), stair(stair), mv2d(map, floor, stair), mv3d(floor, stair) {
|
||||
MapModelElement(parent), floor(floor), stair(stair), mv2d(map, floor, stair) {//, mv3d(floor, stair) {
|
||||
|
||||
;
|
||||
|
||||
}
|
||||
|
||||
MV2DElement* getMV2D() const override {return (MV2DElement*) &mv2d;}
|
||||
MV3DElement* getMV3D() const override {return (MV3DElement*) &mv3d;}
|
||||
//MV3DElement* getMV3D() const override {return (MV3DElement*) &mv3d;}
|
||||
|
||||
|
||||
virtual int getNumParams() const override {
|
||||
|
||||
@@ -188,6 +188,7 @@ public:
|
||||
}
|
||||
|
||||
void setVisible(const bool visible) override {
|
||||
(void) visible;
|
||||
throw "error";
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user