started working on walling, dooring and windowing
refactoring
This commit is contained in:
@@ -36,7 +36,7 @@ namespace Floorplan3D {
|
|||||||
bool exportObjects = true;
|
bool exportObjects = true;
|
||||||
bool exportPillars = true;
|
bool exportPillars = true;
|
||||||
bool exportWallTops = false;
|
bool exportWallTops = false;
|
||||||
bool center = true;
|
bool center = false;
|
||||||
|
|
||||||
//Walls* walls = new WallsViaCubes();
|
//Walls* walls = new WallsViaCubes();
|
||||||
//Walls* walls = new WallsViaCuttedQuads();
|
//Walls* walls = new WallsViaCuttedQuads();
|
||||||
@@ -92,6 +92,11 @@ namespace Floorplan3D {
|
|||||||
// process each obstacle within the floor
|
// process each obstacle within the floor
|
||||||
if (f->obstacles.enabled) {
|
if (f->obstacles.enabled) {
|
||||||
|
|
||||||
|
if (1 == 1) {
|
||||||
|
const std::vector<Obstacle3D> tmp = getLines(f);
|
||||||
|
res.insert(res.end(), tmp.begin(), tmp.end());
|
||||||
|
}
|
||||||
|
|
||||||
if (1 == 1) {
|
if (1 == 1) {
|
||||||
const std::vector<Obstacle3D> tmp = getWalls(f);
|
const std::vector<Obstacle3D> tmp = getWalls(f);
|
||||||
res.insert(res.end(), tmp.begin(), tmp.end());
|
res.insert(res.end(), tmp.begin(), tmp.end());
|
||||||
@@ -140,6 +145,20 @@ namespace Floorplan3D {
|
|||||||
|
|
||||||
WallsViaCuttedQuads walls;
|
WallsViaCuttedQuads walls;
|
||||||
|
|
||||||
|
for (const Floorplan::FloorObstacle* obs : f->obstacles) {
|
||||||
|
const Floorplan::FloorObstacleWall* wall = dynamic_cast<const Floorplan::FloorObstacleWall*>(obs);
|
||||||
|
if (wall) {walls.add(f, wall);}
|
||||||
|
}
|
||||||
|
|
||||||
|
return walls.get();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/** get all old walls (lines) */
|
||||||
|
std::vector<Obstacle3D> getLines(const Floorplan::Floor* f) {
|
||||||
|
|
||||||
|
WallsViaCubes walls;
|
||||||
|
|
||||||
for (const Floorplan::FloorObstacle* obs : f->obstacles) {
|
for (const Floorplan::FloorObstacle* obs : f->obstacles) {
|
||||||
const Floorplan::FloorObstacleLine* line = dynamic_cast<const Floorplan::FloorObstacleLine*>(obs);
|
const Floorplan::FloorObstacleLine* line = dynamic_cast<const Floorplan::FloorObstacleLine*>(obs);
|
||||||
if (line) {walls.add(f, line, nullptr);}
|
if (line) {walls.add(f, line, nullptr);}
|
||||||
|
|||||||
69
floorplan/3D/Lines.h
Normal file
69
floorplan/3D/Lines.h
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
#ifndef FLOORPLAN_3D_LINES_H
|
||||||
|
#define FLOORPLAN_3D_LINES_H
|
||||||
|
|
||||||
|
#include "Walls.h"
|
||||||
|
#include "misc.h"
|
||||||
|
#include "primitives/Cube.h"
|
||||||
|
|
||||||
|
namespace Floorplan3D {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* simply use one 3D cube per wall
|
||||||
|
* if walls intersect in the 2D view, cubes will also intersect
|
||||||
|
*/
|
||||||
|
class LinesViaCubes : public Walls {
|
||||||
|
|
||||||
|
Cube::Part cubeParts = (Cube::Part) 63; // leftright,topbottom,rearfront
|
||||||
|
|
||||||
|
std::vector<Obstacle3D> vec;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
void clear() override {
|
||||||
|
vec.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void add(const Floorplan::Floor* f, const Floorplan::FloorObstacleLine* fol, const Floorplan::FloorObstacleDoor* aboveDoor) override {
|
||||||
|
|
||||||
|
FloorPos fpos(f);
|
||||||
|
|
||||||
|
const float thickness_m = fol->thickness_m;
|
||||||
|
const Point2 from = (!aboveDoor) ? (fol->from) : (aboveDoor->from);
|
||||||
|
const Point2 to = (!aboveDoor) ? (fol->to) : (aboveDoor->to);
|
||||||
|
const Point2 cen2 = (from+to)/2;
|
||||||
|
|
||||||
|
const float rad = std::atan2(to.y - from.y, to.x - from.x);
|
||||||
|
const float deg = rad * 180 / M_PI;
|
||||||
|
|
||||||
|
// cube's destination center
|
||||||
|
const float _height = (fol->height_m > 0) ? (fol->height_m) : (fpos.height); // use either floor's height or user height
|
||||||
|
const double height = (!aboveDoor) ? (_height) : (fpos.height - aboveDoor->height);
|
||||||
|
const double cenZ = (!aboveDoor) ? (fpos.z1 + height/2) : (fpos.z1 + aboveDoor->height + height/2);// (fpos.z2 - (fpos.height - aboveDoor->height) / 2);
|
||||||
|
const Point3 pos(cen2.x, cen2.y, cenZ);
|
||||||
|
|
||||||
|
// div by 2.01 to prevent overlapps and z-fighting
|
||||||
|
const float sx = from.getDistance(to) / 2;
|
||||||
|
const float sy = thickness_m / 2;
|
||||||
|
const float sz = height / 2.01f; // prevent overlaps
|
||||||
|
const Point3 size(sx, sy, sz);
|
||||||
|
const Point3 rot(0,0,deg);
|
||||||
|
|
||||||
|
// build
|
||||||
|
Cube cube(pos, size, rot, cubeParts);
|
||||||
|
|
||||||
|
// done
|
||||||
|
Obstacle3D res(getType(fol), fol->material);
|
||||||
|
res.triangles = cube.getTriangles();
|
||||||
|
vec.push_back(res);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<Obstacle3D>& get() override {
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // FLOORPLAN_3D_LINES_H
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
#include "../../geo/Polygon2.h"
|
#include "../../geo/Polygon2.h"
|
||||||
#include "../../geo/GPCPolygon2.h"
|
#include "../../geo/GPCPolygon2.h"
|
||||||
|
|
||||||
#include "Walls.h"
|
//#include "Walls.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
@@ -17,7 +17,7 @@ namespace Floorplan3D {
|
|||||||
* interpret walls als quads (polygons)
|
* interpret walls als quads (polygons)
|
||||||
* intersect them with each other to prevent overlaps
|
* intersect them with each other to prevent overlaps
|
||||||
*/
|
*/
|
||||||
class WallsViaCuttedQuads : public Walls {
|
class WallsViaCuttedQuads {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@@ -27,13 +27,13 @@ namespace Floorplan3D {
|
|||||||
bool error = false;
|
bool error = false;
|
||||||
|
|
||||||
/** original line from floorplan */
|
/** original line from floorplan */
|
||||||
const Floorplan::FloorObstacleLine* line;
|
const Floorplan::FloorObstacleWall* line;
|
||||||
|
|
||||||
/** outlines after applying thickness */
|
/** outlines after applying thickness */
|
||||||
Line2 l1;
|
Line2 l1;
|
||||||
Line2 l2;
|
Line2 l2;
|
||||||
|
|
||||||
Wall(const Floorplan::FloorObstacleLine* line) : line(line) {
|
Wall(const Floorplan::FloorObstacleWall* line) : line(line) {
|
||||||
|
|
||||||
const Point2 from = line->from;
|
const Point2 from = line->from;
|
||||||
const Point2 to = line->to;
|
const Point2 to = line->to;
|
||||||
@@ -137,18 +137,17 @@ namespace Floorplan3D {
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
||||||
void clear() override {
|
void clear() {
|
||||||
walls.clear();
|
walls.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void add(const Floorplan::Floor* f, const Floorplan::FloorObstacleLine* fol, const Floorplan::FloorObstacleDoor* aboveDoor) override {
|
void add(const Floorplan::Floor* f, const Floorplan::FloorObstacleWall* fow) {
|
||||||
if (fol->type != Floorplan::ObstacleType::WALL) {return;}
|
if (fow->type != Floorplan::ObstacleType::WALL) {return;}
|
||||||
if (aboveDoor) {return;}
|
|
||||||
this->floor = f;
|
this->floor = f;
|
||||||
walls.push_back(Wall(fol));
|
walls.push_back(Wall(fow));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual const std::vector<Obstacle3D>& get() override {
|
virtual const std::vector<Obstacle3D>& get() {
|
||||||
std::vector<Wall> tmp = walls;
|
std::vector<Wall> tmp = walls;
|
||||||
tmp = cutConnected(tmp);
|
tmp = cutConnected(tmp);
|
||||||
tmp = cutProtruding(tmp);
|
tmp = cutProtruding(tmp);
|
||||||
@@ -226,6 +225,9 @@ namespace Floorplan3D {
|
|||||||
auto unFlattenFront = [o,t,a] (const Point3 p) {return Point3(p.x, +t, p.y).rotZ(a)+o;};
|
auto unFlattenFront = [o,t,a] (const Point3 p) {return Point3(p.x, +t, p.y).rotZ(a)+o;};
|
||||||
auto unFlattenBack = [o,t,a] (const Point3 p) {return Point3(p.x, -t, p.y).rotZ(a)+o;};
|
auto unFlattenBack = [o,t,a] (const Point3 p) {return Point3(p.x, -t, p.y).rotZ(a)+o;};
|
||||||
|
|
||||||
|
auto unFlattenFront2 = [o,t,a] (const Point2 p) {return Point3(p.x, +t, p.y).rotZ(a)+o;};
|
||||||
|
auto unFlattenBack2 = [o,t,a] (const Point2 p) {return Point3(p.x, -t, p.y).rotZ(a)+o;};
|
||||||
|
|
||||||
const Point2 fp1 = flatten(p1);
|
const Point2 fp1 = flatten(p1);
|
||||||
const Point2 fp2 = flatten(p2);
|
const Point2 fp2 = flatten(p2);
|
||||||
const Point2 fp3 = flatten(p3);
|
const Point2 fp3 = flatten(p3);
|
||||||
@@ -248,7 +250,20 @@ namespace Floorplan3D {
|
|||||||
GPCPolygon2 gpBack;
|
GPCPolygon2 gpBack;
|
||||||
gpBack.add(back);
|
gpBack.add(back);
|
||||||
|
|
||||||
for (const Floorplan::FloorObstacleWallDoor* door : wall.line->doors) {
|
// sort doors by their position within the wall (first comes first)
|
||||||
|
std::vector<Floorplan::FloorObstacleWallDoor*> doors = wall.line->doors;
|
||||||
|
auto compDoors = [] (const Floorplan::FloorObstacleWallDoor* d1, Floorplan::FloorObstacleWallDoor* d2) {
|
||||||
|
return d1->atLinePos < d2->atLinePos;
|
||||||
|
};
|
||||||
|
std::sort(doors.begin(), doors.end(), compDoors);
|
||||||
|
|
||||||
|
|
||||||
|
TriangleStrip strip;
|
||||||
|
|
||||||
|
strip.add(p1);
|
||||||
|
strip.add(p4);
|
||||||
|
|
||||||
|
for (const Floorplan::FloorObstacleWallDoor* door : doors) {
|
||||||
Polygon2 pDoor;
|
Polygon2 pDoor;
|
||||||
|
|
||||||
const Point2 pds = door->getStart(wall.line);
|
const Point2 pds = door->getStart(wall.line);
|
||||||
@@ -270,8 +285,41 @@ namespace Floorplan3D {
|
|||||||
gpFront.remove(pDoor);
|
gpFront.remove(pDoor);
|
||||||
gpBack.remove(pDoor);
|
gpBack.remove(pDoor);
|
||||||
|
|
||||||
|
strip.add(unFlattenFront2(pDoor[0]));
|
||||||
|
strip.add(unFlattenBack2(pDoor[0]));
|
||||||
|
|
||||||
|
strip.add(unFlattenFront2(pDoor[3]));
|
||||||
|
strip.add(unFlattenBack2(pDoor[3]));
|
||||||
|
|
||||||
|
strip.add(unFlattenFront2(pDoor[2]));
|
||||||
|
strip.add(unFlattenBack2(pDoor[2]));
|
||||||
|
|
||||||
|
strip.add(unFlattenFront2(pDoor[1]));
|
||||||
|
strip.add(unFlattenBack2(pDoor[1]));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
strip.add(p2);
|
||||||
|
strip.add(p3);
|
||||||
|
strip.add(p2u);
|
||||||
|
strip.add(p3u);
|
||||||
|
strip.add(p1u);
|
||||||
|
strip.add(p4u);
|
||||||
|
strip.add(p1);
|
||||||
|
strip.add(p4);
|
||||||
|
|
||||||
|
for (Triangle3 t : strip.toTriangles()) {
|
||||||
|
t.reverse();
|
||||||
|
obs.triangles.push_back(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
// std::vector<Point3> ptsToConnect3;
|
||||||
|
// for (const Point2 p2 : ptsToConnect) {
|
||||||
|
// const Point3 p3 = unf
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// Frontseite triangulieren
|
||||||
std::vector<Triangle3> triasFront = gpFront.getTriangles();
|
std::vector<Triangle3> triasFront = gpFront.getTriangles();
|
||||||
|
|
||||||
for (Triangle3 tria : triasFront) {
|
for (Triangle3 tria : triasFront) {
|
||||||
@@ -280,6 +328,7 @@ namespace Floorplan3D {
|
|||||||
obs.triangles.push_back(tria);
|
obs.triangles.push_back(tria);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Rückseite triangulieren
|
||||||
std::vector<Triangle3> triasBack = gpBack.getTriangles();
|
std::vector<Triangle3> triasBack = gpBack.getTriangles();
|
||||||
|
|
||||||
for (Triangle3 tria : triasBack) {
|
for (Triangle3 tria : triasBack) {
|
||||||
|
|||||||
@@ -23,6 +23,15 @@ namespace Floorplan3D {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Obstacle3D::Type getType(const Floorplan::FloorObstacleWall* l) {
|
||||||
|
switch (l->type) {
|
||||||
|
case Floorplan::ObstacleType::WALL: return Obstacle3D::Type::WALL;
|
||||||
|
case Floorplan::ObstacleType::WINDOW: return Obstacle3D::Type::WINDOW;
|
||||||
|
case Floorplan::ObstacleType::HANDRAIL: return Obstacle3D::Type::HANDRAIL;
|
||||||
|
default: return Obstacle3D::Type::UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static Obstacle3D::Type getType(const Floorplan::FloorObstacleCircle* c) {
|
static Obstacle3D::Type getType(const Floorplan::FloorObstacleCircle* c) {
|
||||||
(void) c;
|
(void) c;
|
||||||
return Obstacle3D::Type::WALL;
|
return Obstacle3D::Type::WALL;
|
||||||
|
|||||||
@@ -157,6 +157,12 @@ namespace Floorplan {
|
|||||||
_END,
|
_END,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** available window types */
|
||||||
|
enum class WindowType {
|
||||||
|
UNKNOWN,
|
||||||
|
_END,
|
||||||
|
};
|
||||||
|
|
||||||
/** all supported material types */
|
/** all supported material types */
|
||||||
enum class Material {
|
enum class Material {
|
||||||
UNKNOWN,
|
UNKNOWN,
|
||||||
@@ -193,6 +199,7 @@ namespace Floorplan {
|
|||||||
struct Elevator;
|
struct Elevator;
|
||||||
struct GroundTruthPoint;
|
struct GroundTruthPoint;
|
||||||
struct FloorObstacleWallDoor;
|
struct FloorObstacleWallDoor;
|
||||||
|
struct FloorObstacleWallWindow;
|
||||||
|
|
||||||
struct FloorOutline : public std::vector<FloorOutlinePolygon*> {
|
struct FloorOutline : public std::vector<FloorOutlinePolygon*> {
|
||||||
bool enabled = true;
|
bool enabled = true;
|
||||||
@@ -351,7 +358,6 @@ namespace Floorplan {
|
|||||||
Point2 to;
|
Point2 to;
|
||||||
float thickness_m;
|
float thickness_m;
|
||||||
float height_m = 0; // 0 = floor's height
|
float height_m = 0; // 0 = floor's height
|
||||||
std::vector<FloorObstacleWallDoor*> doors;
|
|
||||||
FloorObstacleLine(const ObstacleType type, const Material material, const Point2 from, const Point2 to, const float thickness_m = 0.2f, const float height_m = 0) : FloorObstacle(material), type(type), from(from), to(to), thickness_m(thickness_m), height_m(height_m) {;}
|
FloorObstacleLine(const ObstacleType type, const Material material, const Point2 from, const Point2 to, const float thickness_m = 0.2f, const float height_m = 0) : FloorObstacle(material), type(type), from(from), to(to), thickness_m(thickness_m), height_m(height_m) {;}
|
||||||
FloorObstacleLine(const ObstacleType type, const Material material, const float x1, const float y1, const float x2, const float y2, const float thickness_m = 0.2f, const float height_m = 0) : FloorObstacle(material), type(type), from(x1,y1), to(x2,y2), thickness_m(thickness_m), height_m(height_m) {;}
|
FloorObstacleLine(const ObstacleType type, const Material material, const float x1, const float y1, const float x2, const float y2, const float thickness_m = 0.2f, const float height_m = 0) : FloorObstacle(material), type(type), from(x1,y1), to(x2,y2), thickness_m(thickness_m), height_m(height_m) {;}
|
||||||
};
|
};
|
||||||
@@ -378,7 +384,21 @@ namespace Floorplan {
|
|||||||
float getSize() const {return (to-from).length();}
|
float getSize() const {return (to-from).length();}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** door obstacle */
|
|
||||||
|
/** wall obstacle */
|
||||||
|
struct FloorObstacleWall: public FloorObstacle {
|
||||||
|
ObstacleType type;
|
||||||
|
Point2 from;
|
||||||
|
Point2 to;
|
||||||
|
float thickness_m;
|
||||||
|
float height_m = 0; // 0 = floor's height
|
||||||
|
std::vector<FloorObstacleWallDoor*> doors;
|
||||||
|
std::vector<FloorObstacleWallWindow*> windows;
|
||||||
|
FloorObstacleWall(const ObstacleType type, const Material material, const Point2 from, const Point2 to, const float thickness_m = 0.2f, const float height_m = 0) : FloorObstacle(material), type(type), from(from), to(to), thickness_m(thickness_m), height_m(height_m) {;}
|
||||||
|
FloorObstacleWall(const ObstacleType type, const Material material, const float x1, const float y1, const float x2, const float y2, const float thickness_m = 0.2f, const float height_m = 0) : FloorObstacle(material), type(type), from(x1,y1), to(x2,y2), thickness_m(thickness_m), height_m(height_m) {;}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** wall->door obstacle */
|
||||||
struct FloorObstacleWallDoor : public FloorObstacle {
|
struct FloorObstacleWallDoor : public FloorObstacle {
|
||||||
DoorType type;
|
DoorType type;
|
||||||
float atLinePos;
|
float atLinePos;
|
||||||
@@ -386,17 +406,40 @@ namespace Floorplan {
|
|||||||
float height;
|
float height;
|
||||||
bool leftRight = false;
|
bool leftRight = false;
|
||||||
bool inOut = false;
|
bool inOut = false;
|
||||||
FloorObstacleWallDoor(const DoorType type, const Material material, const float atLinePos, const float width, const float height) : FloorObstacle(material), type(type), atLinePos(atLinePos), width(width), height(height) {;}
|
FloorObstacleWallDoor(const DoorType type, const Material material, const float atLinePos, const float width, const float height, const bool lr = false, const bool io = false) : FloorObstacle(material), type(type), atLinePos(atLinePos), width(width), height(height), leftRight(lr), inOut(io) {;}
|
||||||
Point2 getStart(const FloorObstacleLine* wall) const {
|
Point2 getStart(const FloorObstacleWall* wall) const {
|
||||||
const Point2 dir = wall->to - wall->from;
|
const Point2 dir = wall->to - wall->from;
|
||||||
return wall->from + dir * atLinePos;
|
return wall->from + dir * atLinePos;
|
||||||
}
|
}
|
||||||
Point2 getEnd(const FloorObstacleLine* wall) const {
|
Point2 getEnd(const FloorObstacleWall* wall) const {
|
||||||
const Point2 dir = wall->to - wall->from;
|
const Point2 dir = wall->to - wall->from;
|
||||||
return getStart(wall) + dir.normalized() * (leftRight ? -width : +width);
|
return getStart(wall) + dir.normalized() * (leftRight ? -width : +width);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** wall->window obstacle */
|
||||||
|
struct FloorObstacleWallWindow : public FloorObstacle {
|
||||||
|
WindowType type;
|
||||||
|
float atLinePos;
|
||||||
|
float startsAtHeight;
|
||||||
|
float width;
|
||||||
|
float height;
|
||||||
|
bool leftRight = false;
|
||||||
|
bool inOut = false;
|
||||||
|
FloorObstacleWallWindow(const WindowType type, const Material material, const float atLinePos, const float startsAtHeight, const float width, const float height, const bool lr = false, const bool io = false) : FloorObstacle(material), type(type), atLinePos(atLinePos), startsAtHeight(startsAtHeight), width(width), height(height), leftRight(lr), inOut(io) {;}
|
||||||
|
Point2 getStart(const FloorObstacleWall* wall) const {
|
||||||
|
const Point2 dir = wall->to - wall->from;
|
||||||
|
const Point2 cen = wall->from + dir * atLinePos;
|
||||||
|
return cen - dir.normalized() * width/2;
|
||||||
|
}
|
||||||
|
Point2 getEnd(const FloorObstacleWall* wall) const {
|
||||||
|
const Point2 dir = wall->to - wall->from;
|
||||||
|
const Point2 cen = wall->from + dir * atLinePos;
|
||||||
|
return cen + dir.normalized() * width/2;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/** 3D obstacle */
|
/** 3D obstacle */
|
||||||
struct FloorObstacleObject : public FloorObstacle {
|
struct FloorObstacleObject : public FloorObstacle {
|
||||||
std::string file;
|
std::string file;
|
||||||
|
|||||||
@@ -388,6 +388,7 @@ namespace Floorplan {
|
|||||||
// if (std::string("window") == n->Name()) {obstacles.push_back(parseFloorObstacleWindow(n));}
|
// if (std::string("window") == n->Name()) {obstacles.push_back(parseFloorObstacleWindow(n));}
|
||||||
// if (std::string("pillar") == n->Name()) {obstacles.push_back(parseFloorObstaclePillar(n));}
|
// if (std::string("pillar") == n->Name()) {obstacles.push_back(parseFloorObstaclePillar(n));}
|
||||||
//if (std::string("obstacle") == n->Name()) {obstacles.push_back(parseFloorObstacleLine(n));} // OLD
|
//if (std::string("obstacle") == n->Name()) {obstacles.push_back(parseFloorObstacleLine(n));} // OLD
|
||||||
|
if (std::string("wall") == n->Name()) {obstacles.push_back(parseFloorObstacleWall(n));}
|
||||||
if (std::string("line") == n->Name()) {obstacles.push_back(parseFloorObstacleLine(n));}
|
if (std::string("line") == n->Name()) {obstacles.push_back(parseFloorObstacleLine(n));}
|
||||||
if (std::string("circle") == n->Name()) {obstacles.push_back(parseFloorObstacleCircle(n));}
|
if (std::string("circle") == n->Name()) {obstacles.push_back(parseFloorObstacleCircle(n));}
|
||||||
if (std::string("door") == n->Name()) {obstacles.push_back(parseFloorObstacleDoor(n));}
|
if (std::string("door") == n->Name()) {obstacles.push_back(parseFloorObstacleDoor(n));}
|
||||||
@@ -396,6 +397,38 @@ namespace Floorplan {
|
|||||||
return obstacles;
|
return obstacles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** parse one wall */
|
||||||
|
static FloorObstacleWall* parseFloorObstacleWall(const XMLElem* el) {
|
||||||
|
|
||||||
|
FloorObstacleWall* wall = new FloorObstacleWall(
|
||||||
|
parseObstacleType(el->Attribute("type")),
|
||||||
|
parseMaterial(el->Attribute("material")),
|
||||||
|
el->FloatAttribute("x1"), el->FloatAttribute("y1"),
|
||||||
|
el->FloatAttribute("x2"), el->FloatAttribute("y2"),
|
||||||
|
(el->FloatAttribute("thickness") > 0) ? (el->FloatAttribute("thickness")) : (0.15), // default wall thickness in m
|
||||||
|
el->FloatAttribute("height")
|
||||||
|
);
|
||||||
|
|
||||||
|
// doors
|
||||||
|
FOREACH_NODE(n, el) {
|
||||||
|
if (std::string("door") == n->Name()) {
|
||||||
|
FloorObstacleWallDoor* door = new FloorObstacleWallDoor(
|
||||||
|
parseDoorType(n->Attribute("type")),
|
||||||
|
parseMaterial(n->Attribute("material")),
|
||||||
|
n->FloatAttribute("at"),
|
||||||
|
n->FloatAttribute("width"),
|
||||||
|
n->FloatAttribute("height"),
|
||||||
|
n->BoolAttribute("lr"),
|
||||||
|
n->BoolAttribute("io")
|
||||||
|
);
|
||||||
|
wall->doors.push_back(door);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return wall;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/** parse one line */
|
/** parse one line */
|
||||||
static FloorObstacleLine* parseFloorObstacleLine(const XMLElem* el) {
|
static FloorObstacleLine* parseFloorObstacleLine(const XMLElem* el) {
|
||||||
return new FloorObstacleLine(
|
return new FloorObstacleLine(
|
||||||
|
|||||||
@@ -311,6 +311,8 @@ namespace Floorplan {
|
|||||||
for (FloorObstacle* fo : mf->obstacles) {
|
for (FloorObstacle* fo : mf->obstacles) {
|
||||||
if (dynamic_cast<FloorObstacleLine*>(fo)) {
|
if (dynamic_cast<FloorObstacleLine*>(fo)) {
|
||||||
addFloorObstacleLine(doc, obstacles, (FloorObstacleLine*)fo);
|
addFloorObstacleLine(doc, obstacles, (FloorObstacleLine*)fo);
|
||||||
|
} else if (dynamic_cast<FloorObstacleWall*>(fo)) {
|
||||||
|
addFloorObstacleWall(doc, obstacles, (FloorObstacleWall*)fo);
|
||||||
} else if (dynamic_cast<FloorObstacleCircle*>(fo)) {
|
} else if (dynamic_cast<FloorObstacleCircle*>(fo)) {
|
||||||
addFloorObstacleCircle(doc, obstacles, (FloorObstacleCircle*)fo);
|
addFloorObstacleCircle(doc, obstacles, (FloorObstacleCircle*)fo);
|
||||||
} else if (dynamic_cast<FloorObstacleDoor*>(fo)) {
|
} else if (dynamic_cast<FloorObstacleDoor*>(fo)) {
|
||||||
@@ -324,7 +326,40 @@ namespace Floorplan {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** write a line obstacle (wall, handrail, ..) */
|
/** write a wall obstacle (wall) */
|
||||||
|
static void addFloorObstacleWall(XMLDoc& doc, XMLElem* obstacles, FloorObstacleWall* wall) {
|
||||||
|
|
||||||
|
XMLElem* oWall = doc.NewElement("wall");
|
||||||
|
obstacles->InsertEndChild(oWall);
|
||||||
|
|
||||||
|
oWall->SetAttribute("material", toString(wall->material).c_str());
|
||||||
|
oWall->SetAttribute("type", toString(wall->type).c_str());
|
||||||
|
oWall->SetAttribute("x1", wall->from.x);
|
||||||
|
oWall->SetAttribute("y1", wall->from.y);
|
||||||
|
oWall->SetAttribute("x2", wall->to.x);
|
||||||
|
oWall->SetAttribute("y2", wall->to.y);
|
||||||
|
oWall->SetAttribute("thickness", wall->thickness_m);
|
||||||
|
if (wall->height_m != 0) {oWall->SetAttribute("height", wall->height_m);}
|
||||||
|
|
||||||
|
// doors?
|
||||||
|
for (const FloorObstacleWallDoor* door : wall->doors) {
|
||||||
|
|
||||||
|
XMLElem* oDoor = doc.NewElement("door");
|
||||||
|
oWall->InsertEndChild(oDoor);
|
||||||
|
|
||||||
|
oDoor->SetAttribute("type", toString(door->type).c_str());
|
||||||
|
oDoor->SetAttribute("material", toString(door->material).c_str());
|
||||||
|
oDoor->SetAttribute("at", door->atLinePos);
|
||||||
|
oDoor->SetAttribute("width", door->width);
|
||||||
|
oDoor->SetAttribute("height", door->height);
|
||||||
|
oDoor->SetAttribute("io", door->inOut);
|
||||||
|
oDoor->SetAttribute("lr", door->leftRight);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/** write a line obstacle (old walls, handrail, ..) */
|
||||||
static void addFloorObstacleLine(XMLDoc& doc, XMLElem* obstacles, FloorObstacleLine* line) {
|
static void addFloorObstacleLine(XMLDoc& doc, XMLElem* obstacles, FloorObstacleLine* line) {
|
||||||
XMLElem* obstacle = doc.NewElement("line");
|
XMLElem* obstacle = doc.NewElement("line");
|
||||||
obstacle->SetAttribute("material", toString(line->material).c_str());
|
obstacle->SetAttribute("material", toString(line->material).c_str());
|
||||||
|
|||||||
@@ -5,6 +5,60 @@
|
|||||||
#include "Polygon2.h"
|
#include "Polygon2.h"
|
||||||
#include "Triangle3.h"
|
#include "Triangle3.h"
|
||||||
|
|
||||||
|
class TriangleStrip {
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<Point3> pts;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
void add(const Point3 p) {
|
||||||
|
pts.push_back(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set(const std::vector<Point3>& pts) {
|
||||||
|
this->pts = pts;
|
||||||
|
}
|
||||||
|
|
||||||
|
void toTriangles(std::vector<Triangle3>& trias) const {
|
||||||
|
|
||||||
|
// https://en.wikipedia.org/wiki/Triangle_strip
|
||||||
|
// GL_TRIANGLE_STRIP
|
||||||
|
// Draws a series of triangles (three-sided polygons) using vertices v0, v1, v2, then v2, v1, v3 (note the order), then v2, v3, v4, and so on. The ordering is to ensure that the triangles are all drawn with the same orientation so that the strip can correctly form part of a surface.
|
||||||
|
// For odd n, vertices n, n+1, and n+2 define triangle n. For even n, vertices n+1, n, and n+2 define triangle n. N-2 triangles are drawn.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for (size_t j = 2; j < pts.size(); ++j) {
|
||||||
|
|
||||||
|
|
||||||
|
if (j % 2 == 0) {
|
||||||
|
Triangle3 tria(
|
||||||
|
pts[j-2],
|
||||||
|
pts[j-1],
|
||||||
|
pts[j]
|
||||||
|
);
|
||||||
|
trias.push_back(tria);
|
||||||
|
} else {
|
||||||
|
Triangle3 tria(
|
||||||
|
pts[j-1],
|
||||||
|
pts[j-2],
|
||||||
|
pts[j]
|
||||||
|
);
|
||||||
|
trias.push_back(tria);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Triangle3> toTriangles() const {
|
||||||
|
std::vector<Triangle3> trias;
|
||||||
|
toTriangles(trias);
|
||||||
|
return trias;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
class GPCPolygon2 {
|
class GPCPolygon2 {
|
||||||
|
|
||||||
struct GPCPolygon : gpc_polygon {
|
struct GPCPolygon : gpc_polygon {
|
||||||
@@ -113,35 +167,43 @@ public:
|
|||||||
|
|
||||||
for (int i = 0; i < res.num_strips; ++i) {
|
for (int i = 0; i < res.num_strips; ++i) {
|
||||||
gpc_vertex_list lst = res.strip[i];
|
gpc_vertex_list lst = res.strip[i];
|
||||||
for (int j = 2; j < lst.num_vertices; ++j) {
|
|
||||||
|
|
||||||
gpc_vertex& v1 = lst.vertex[j - 2];
|
TriangleStrip strip;
|
||||||
gpc_vertex& v2 = lst.vertex[j - 1];
|
for (int j = 0; j < lst.num_vertices; ++j) {
|
||||||
gpc_vertex& v3 = lst.vertex[j];
|
gpc_vertex& v = lst.vertex[j];
|
||||||
|
strip.add(Point3(v.x, v.y, z));
|
||||||
// https://en.wikipedia.org/wiki/Triangle_strip
|
|
||||||
// GL_TRIANGLE_STRIP
|
|
||||||
// Draws a series of triangles (three-sided polygons) using vertices v0, v1, v2, then v2, v1, v3 (note the order), then v2, v3, v4, and so on. The ordering is to ensure that the triangles are all drawn with the same orientation so that the strip can correctly form part of a surface.
|
|
||||||
// For odd n, vertices n, n+1, and n+2 define triangle n. For even n, vertices n+1, n, and n+2 define triangle n. N-2 triangles are drawn.
|
|
||||||
|
|
||||||
if (j % 2 == 0) {
|
|
||||||
Triangle3 tria(
|
|
||||||
Point3(v1.x, v1.y, z),
|
|
||||||
Point3(v2.x, v2.y, z),
|
|
||||||
Point3(v3.x, v3.y, z)
|
|
||||||
);
|
|
||||||
trias.push_back(tria);
|
|
||||||
} else {
|
|
||||||
Triangle3 tria(
|
|
||||||
Point3(v2.x, v2.y, z),
|
|
||||||
Point3(v1.x, v1.y, z),
|
|
||||||
Point3(v3.x, v3.y, z)
|
|
||||||
);
|
|
||||||
trias.push_back(tria);
|
|
||||||
}
|
}
|
||||||
|
strip.toTriangles(trias);
|
||||||
|
|
||||||
|
// for (int j = 2; j < lst.num_vertices; ++j) {
|
||||||
|
|
||||||
|
// gpc_vertex& v1 = lst.vertex[j - 2];
|
||||||
|
// gpc_vertex& v2 = lst.vertex[j - 1];
|
||||||
|
// gpc_vertex& v3 = lst.vertex[j];
|
||||||
|
|
||||||
|
// // https://en.wikipedia.org/wiki/Triangle_strip
|
||||||
|
// // GL_TRIANGLE_STRIP
|
||||||
|
// // Draws a series of triangles (three-sided polygons) using vertices v0, v1, v2, then v2, v1, v3 (note the order), then v2, v3, v4, and so on. The ordering is to ensure that the triangles are all drawn with the same orientation so that the strip can correctly form part of a surface.
|
||||||
|
// // For odd n, vertices n, n+1, and n+2 define triangle n. For even n, vertices n+1, n, and n+2 define triangle n. N-2 triangles are drawn.
|
||||||
|
|
||||||
|
// if (j % 2 == 0) {
|
||||||
|
// Triangle3 tria(
|
||||||
|
// Point3(v1.x, v1.y, z),
|
||||||
|
// Point3(v2.x, v2.y, z),
|
||||||
|
// Point3(v3.x, v3.y, z)
|
||||||
|
// );
|
||||||
|
// trias.push_back(tria);
|
||||||
|
// } else {
|
||||||
|
// Triangle3 tria(
|
||||||
|
// Point3(v2.x, v2.y, z),
|
||||||
|
// Point3(v1.x, v1.y, z),
|
||||||
|
// Point3(v3.x, v3.y, z)
|
||||||
|
// );
|
||||||
|
// trias.push_back(tria);
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
}
|
//}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,8 +14,8 @@
|
|||||||
#include "DataMap3.h"
|
#include "DataMap3.h"
|
||||||
#include "../../../geo/Ray3.h"
|
#include "../../../geo/Ray3.h"
|
||||||
#include "MaterialOptions.h"
|
#include "MaterialOptions.h"
|
||||||
#include "Obstacle3.h"
|
#include "../../../floorplan/3D/Obstacle3.h"
|
||||||
#include "ModelFactory.h"
|
#include "../../../floorplan/3D/Builder.h"
|
||||||
//#include "ObstacleTree.h"
|
//#include "ObstacleTree.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -33,6 +33,7 @@
|
|||||||
// 3D
|
// 3D
|
||||||
// http://graphics.stanford.edu/courses/cs148-10-summer/docs/2006--degreve--reflection_refraction.pdf
|
// http://graphics.stanford.edu/courses/cs148-10-summer/docs/2006--degreve--reflection_refraction.pdf
|
||||||
|
|
||||||
|
using namespace Floorplan3D;
|
||||||
|
|
||||||
namespace Ray3D {
|
namespace Ray3D {
|
||||||
|
|
||||||
@@ -199,7 +200,7 @@ namespace Ray3D {
|
|||||||
// allocate
|
// allocate
|
||||||
dm.resize(bbox, gs);
|
dm.resize(bbox, gs);
|
||||||
|
|
||||||
ModelFactory fac(map);
|
Builder fac(map);
|
||||||
std::vector<Obstacle3D> obstacles = fac.getMesh().elements;
|
std::vector<Obstacle3D> obstacles = fac.getMesh().elements;
|
||||||
|
|
||||||
// build bounding volumes
|
// build bounding volumes
|
||||||
|
|||||||
Reference in New Issue
Block a user