added "outdoor" support to floorplan and grid-nodes
This commit is contained in:
@@ -298,15 +298,13 @@ namespace Floorplan {
|
|||||||
OutlineMethod method;
|
OutlineMethod method;
|
||||||
std::string name;
|
std::string name;
|
||||||
Polygon2 poly;
|
Polygon2 poly;
|
||||||
FloorOutlinePolygon() : method(OutlineMethod::ADD), name(), poly() {;}
|
bool outdoor; // special marker
|
||||||
FloorOutlinePolygon(const OutlineMethod method, const std::string& name, const Polygon2& poly) : method(method), name(name), poly(poly) {;}
|
FloorOutlinePolygon() : method(OutlineMethod::ADD), name(), poly(), outdoor(false) {;}
|
||||||
bool operator == (const FloorOutlinePolygon& o) const {return (o.method == method) && (o.name == name) && (o.poly == poly);}
|
FloorOutlinePolygon(const OutlineMethod method, const std::string& name, const Polygon2& poly, bool outdoor) : method(method), name(name), poly(poly), outdoor(outdoor) {;}
|
||||||
|
bool operator == (const FloorOutlinePolygon& o) const {return (o.method == method) && (o.name == name) && (o.poly == poly) && (o.outdoor == outdoor);}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** base-class for one obstacle (wall, door, window, pillar, ..) within a floor */
|
/** base-class for one obstacle (wall, door, window, pillar, ..) within a floor */
|
||||||
struct FloorObstacle {
|
struct FloorObstacle {
|
||||||
Material material;
|
Material material;
|
||||||
|
|||||||
@@ -412,6 +412,7 @@ namespace Floorplan {
|
|||||||
static FloorOutlinePolygon* parseFloorPolygon(const XMLElem* el) {
|
static FloorOutlinePolygon* parseFloorPolygon(const XMLElem* el) {
|
||||||
FloorOutlinePolygon* poly = new FloorOutlinePolygon();
|
FloorOutlinePolygon* poly = new FloorOutlinePolygon();
|
||||||
poly->name = el->Attribute("name");
|
poly->name = el->Attribute("name");
|
||||||
|
poly->outdoor = el->BoolAttribute("outdoor");
|
||||||
poly->method = parseOutlineMethod(el->Attribute("method"));
|
poly->method = parseOutlineMethod(el->Attribute("method"));
|
||||||
poly->poly = parsePoly2(el);
|
poly->poly = parsePoly2(el);
|
||||||
return poly;
|
return poly;
|
||||||
|
|||||||
@@ -227,6 +227,7 @@ namespace Floorplan {
|
|||||||
XMLElem* polygon = doc.NewElement("polygon");
|
XMLElem* polygon = doc.NewElement("polygon");
|
||||||
polygon->SetAttribute("name", poly->name.c_str());
|
polygon->SetAttribute("name", poly->name.c_str());
|
||||||
polygon->SetAttribute("method", method.c_str());
|
polygon->SetAttribute("method", method.c_str());
|
||||||
|
polygon->SetAttribute("outdoor", poly->outdoor);
|
||||||
dst->InsertEndChild(polygon);
|
dst->InsertEndChild(polygon);
|
||||||
|
|
||||||
for (Point2 p : poly->poly.points) {
|
for (Point2 p : poly->poly.points) {
|
||||||
|
|||||||
@@ -52,6 +52,8 @@ public:
|
|||||||
static const uint8_t TYPE_ELEVATOR = 2;
|
static const uint8_t TYPE_ELEVATOR = 2;
|
||||||
static const uint8_t TYPE_DOOR = 3;
|
static const uint8_t TYPE_DOOR = 3;
|
||||||
|
|
||||||
|
static const uint8_t TYPE_OUTDOOR = 100;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** ctor */
|
/** ctor */
|
||||||
|
|||||||
@@ -114,21 +114,38 @@ public:
|
|||||||
return bb;
|
return bb;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isPartOfFloorOutline(const int x_cm, const int y_cm, const Floorplan::FloorOutline& outline) {
|
enum class PartOfOutline {
|
||||||
|
NO,
|
||||||
|
INDOOR,
|
||||||
|
OUTDOOR,
|
||||||
|
};
|
||||||
|
|
||||||
bool add = false;
|
/** get the part of outline the given location belongs to. currently: none, indoor, outdoor */
|
||||||
|
PartOfOutline isPartOfFloorOutline(const int x_cm, const int y_cm, const Floorplan::FloorOutline& outline) {
|
||||||
|
|
||||||
|
// assume the point is not part of the outline
|
||||||
|
PartOfOutline res = PartOfOutline::NO;
|
||||||
|
|
||||||
|
// process every outline polygon
|
||||||
for (Floorplan::FloorOutlinePolygon* poly : outline) {
|
for (Floorplan::FloorOutlinePolygon* poly : outline) {
|
||||||
if (poly->method != Floorplan::OutlineMethod::ADD) {continue;}
|
|
||||||
HelperPoly pol(*poly);
|
HelperPoly pol(*poly);
|
||||||
if (pol.contains(Point2(x_cm, y_cm))) {add = true;}
|
if (pol.contains(Point2(x_cm, y_cm))) {
|
||||||
|
|
||||||
|
// belongs to a "remove" polygon? -> directly ignore this location!
|
||||||
|
if (poly->method == Floorplan::OutlineMethod::REMOVE) {
|
||||||
|
return PartOfOutline::NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
// belongs to a "add" polygon? -> remember until all polygons were checked
|
||||||
|
// [might still belong to a "remove" polygon]
|
||||||
|
res = poly->outdoor ? PartOfOutline::OUTDOOR : PartOfOutline::INDOOR;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!add) {return false;}
|
|
||||||
for (Floorplan::FloorOutlinePolygon* poly : outline) {
|
// done
|
||||||
if (poly->method != Floorplan::OutlineMethod::REMOVE) {continue;}
|
return res;
|
||||||
HelperPoly pol(*poly);
|
|
||||||
if (pol.contains(Point2(x_cm, y_cm))) {add = false;} // TODO
|
|
||||||
}
|
|
||||||
return add;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -155,7 +172,8 @@ public:
|
|||||||
for (int y_cm = y1; y_cm < y2; y_cm += helper.gridSize()) {
|
for (int y_cm = y1; y_cm < y2; y_cm += helper.gridSize()) {
|
||||||
|
|
||||||
// does the outline-polygon contain this position?
|
// does the outline-polygon contain this position?
|
||||||
if (!isPartOfFloorOutline(x_cm, y_cm, floor->outline)) {continue;}
|
const PartOfOutline part = isPartOfFloorOutline(x_cm, y_cm, floor->outline);
|
||||||
|
if (part == PartOfOutline::NO) {continue;}
|
||||||
|
|
||||||
// check intersection with the floorplan
|
// check intersection with the floorplan
|
||||||
GridNodeBBox bbox(GridPoint(x_cm, y_cm, z_cm), helper.gridSize());
|
GridNodeBBox bbox(GridPoint(x_cm, y_cm, z_cm), helper.gridSize());
|
||||||
@@ -164,12 +182,13 @@ public:
|
|||||||
bbox.grow(0.42345);
|
bbox.grow(0.42345);
|
||||||
if (intersects(bbox, floor)) {continue;}
|
if (intersects(bbox, floor)) {continue;}
|
||||||
|
|
||||||
// add to the grid
|
// add to the grid [once]
|
||||||
T t(x_cm, y_cm, z_cm);
|
T t(x_cm, y_cm, z_cm);
|
||||||
t.setType(getType(bbox, floor));
|
|
||||||
if (grid.hasNodeFor(t)) {continue;}
|
if (grid.hasNodeFor(t)) {continue;}
|
||||||
|
updateType(t, part, bbox, floor);
|
||||||
grid.add(t);
|
grid.add(t);
|
||||||
|
|
||||||
|
|
||||||
// debug
|
// debug
|
||||||
++numNodes;
|
++numNodes;
|
||||||
|
|
||||||
@@ -487,23 +506,30 @@ private:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** does the bbox intersect with any of the floor's walls? */
|
/** adjust the given gridNode's type if needed [e.g. from "floor" to "door"] */
|
||||||
static inline int getType(const GridNodeBBox& bbox, const Floorplan::Floor* floor) {
|
static inline void updateType(T& t, const PartOfOutline part, const GridNodeBBox& bbox, const Floorplan::Floor* floor) {
|
||||||
|
|
||||||
// process each obstacle
|
// first, assume the type of the outline polygon
|
||||||
|
switch (part) {
|
||||||
|
case PartOfOutline::OUTDOOR: t.setType(GridNode::TYPE_OUTDOOR); break;
|
||||||
|
case PartOfOutline::INDOOR: t.setType(GridNode::TYPE_FLOOR); break;
|
||||||
|
default: throw Exception("should not happen");
|
||||||
|
}
|
||||||
|
|
||||||
|
// hereafter, process each obstacle and mark doors
|
||||||
for (Floorplan::FloorObstacle* fo : floor->obstacles) {
|
for (Floorplan::FloorObstacle* fo : floor->obstacles) {
|
||||||
|
|
||||||
if (dynamic_cast<Floorplan::FloorObstacleDoor*>(fo)) {
|
if (dynamic_cast<Floorplan::FloorObstacleDoor*>(fo)) {
|
||||||
const Floorplan::FloorObstacleDoor* door = (Floorplan::FloorObstacleDoor*) fo;
|
const Floorplan::FloorObstacleDoor* door = (Floorplan::FloorObstacleDoor*) fo;
|
||||||
const Line2 l2(door->from*100, door->to*100);
|
const Line2 l2(door->from*100, door->to*100);
|
||||||
if (bbox.intersects(l2)) {return GridNode::TYPE_DOOR;}
|
if (bbox.intersects(l2)) {
|
||||||
|
t.setType(GridNode::TYPE_DOOR);
|
||||||
|
return; // done
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return GridNode::TYPE_FLOOR;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user