moved from ray3 to floorplan/3D

worked on new wall models
refactoring
This commit is contained in:
2018-07-24 08:13:16 +02:00
parent 083a1c2cf2
commit 8dd1ba0be6
25 changed files with 703 additions and 92 deletions

156
floorplan/3D/Builder.h Normal file
View File

@@ -0,0 +1,156 @@
#ifndef FLOORPLAN_3D_BUILDER_H
#define FLOORPLAN_3D_BUILDER_H
#include "../v2/Floorplan.h"
#include "FloorplanMesh.h"
#include "Obstacle3.h"
#include "Outline.h"
#include "Stairs.h"
#include "Handrails.h"
#include "Objects.h"
#include "Pillars.h"
#include "Walls.h"
#include "WallsViaCubes.h"
#include "WallsViaCuttedQuads.h"
namespace Floorplan3D {
class Builder {
/** the to-be-exported map */
const Floorplan::IndoorMap* map;
public:
bool exportCeilings = true;
bool exportObstacles = true;
bool exportStairs = true;
bool fancyStairs = true;
bool exportHandrails = true;
bool exportDoors = true;
bool exportAboveDoors = true;
bool doorsOpen = false;
bool exportObjects = true;
bool exportPillars = true;
bool exportWallTops = false;
bool center = true;
//Walls* walls = new WallsViaCubes();
//Walls* walls = new WallsViaCuttedQuads();
public:
/** ctor */
Builder(const Floorplan::IndoorMap* map) : map(map) {
}
/** get the created mesh */
FloorplanMesh getMesh() {
FloorplanMesh mesh;
mesh.elements = triangulize();
if (center) {
BBox3 bb = mesh.getBBox();
mesh -= Point3(bb.getCenter().x, bb.getCenter().y, 0);
}
return mesh;
}
private:
/** get all triangles grouped by obstacle */
std::vector<Obstacle3D> triangulize() {
// TODO: filtering??
std::vector<Floorplan::Floor*> floors = map->floors;
std::vector<Obstacle3D> res;
// get the to-be-exported floors (either "all" or "user defined")
//const std::vector<Floorplan::Floor*>& floors = (exportFloors.empty()) ? (map->floors) : (exportFloors);
// process each floor
for (const Floorplan::Floor* f : floors) {
if (!f->enabled) {continue;}
// triangulize the floor itself (floor/ceiling)
if (exportCeilings) {
Outline out;
const std::vector<Obstacle3D> tmp = out.get(f);
res.insert(res.end(), tmp.begin(), tmp.end());
}
// process each obstacle within the floor
if (f->obstacles.enabled) {
if (1 == 1) {
const std::vector<Obstacle3D> tmp = getWalls(f);
res.insert(res.end(), tmp.begin(), tmp.end());
}
if (exportHandrails) {
Handrails rails;
const std::vector<Obstacle3D> tmp = rails.getHandrails(f);
res.insert(res.end(), tmp.begin(), tmp.end());
}
if (exportObjects) {
Objects objs;
const std::vector<Obstacle3D> tmp = objs.getObjects(f);
res.insert(res.end(), tmp.begin(), tmp.end());
}
if (exportPillars) {
Pillars pillars;
const std::vector<Obstacle3D> tmp = pillars.getPillars(f);
res.insert(res.end(), tmp.begin(), tmp.end());
}
// for (const Floorplan::FloorObstacle* fo : f->obstacles) {
// std::vector<Obstacle3D> tmp = getWalls(f);
// res.insert(res.end(), tmp.begin(), tmp.end());
// }
}
// // stairs
if (f->stairs.enabled && exportStairs) {
Stairs stairs;
const std::vector<Obstacle3D> tmp = stairs.getStairs(f);
res.insert(res.end(), tmp.begin(), tmp.end());
}
}
return res;
}
/** just get all walls */
std::vector<Obstacle3D> getWalls(const Floorplan::Floor* f) {
WallsViaCuttedQuads walls;
for (const Floorplan::FloorObstacle* obs : f->obstacles) {
const Floorplan::FloorObstacleLine* line = dynamic_cast<const Floorplan::FloorObstacleLine*>(obs);
if (line) {walls.add(f, line, nullptr);}
}
return walls.get();
}
};
}
#endif // FLOORPLAN_3D_BUILDER_H

View File

@@ -1,10 +1,11 @@
#ifndef FLOORPLANMESH_H #ifndef FLOORPLAN_3D_FLOORPLANMESH_H
#define FLOORPLANMESH_H #define FLOORPLAN_3D_FLOORPLANMESH_H
#include "Obstacle3.h" #include "Obstacle3.h"
#include "../../geo/BBox3.h"
#include <fstream> #include <fstream>
namespace Ray3D { namespace Floorplan3D {
/** /**
* meshed version of the floorplan * meshed version of the floorplan
@@ -13,6 +14,26 @@ namespace Ray3D {
std::vector<Obstacle3D> elements; std::vector<Obstacle3D> elements;
BBox3 getBBox() const {
BBox3 bb;
for (const Obstacle3D& o : elements) {
for (const Triangle3& t : o.triangles) {
bb.add(t.p1);
bb.add(t.p2);
bb.add(t.p3);
}
}
return bb;
}
void operator -= (const Point3 p) {
for (Obstacle3D& o : elements) {
for (Triangle3& t : o.triangles) {
t -= p;
}
}
}
/** export as OBJ file */ /** export as OBJ file */
void exportOBJsimple(const std::string& file) { void exportOBJsimple(const std::string& file) {
std::ofstream out(file.c_str()); std::ofstream out(file.c_str());
@@ -80,6 +101,10 @@ namespace Ray3D {
/** DEBUG: convert to .obj file code for exporting */ /** DEBUG: convert to .obj file code for exporting */
OBJData toOBJ(const std::string name) { OBJData toOBJ(const std::string name) {
const BBox3 bb = getBBox();
const float ox = bb.getCenter().x;
const float oy = bb.getCenter().y;
bool swapYZ = true; bool swapYZ = true;
int nVerts = 1; int nVerts = 1;
int nObjs = 0; int nObjs = 0;
@@ -108,13 +133,14 @@ namespace Ray3D {
// write the vertices // write the vertices
for (const Triangle3& t : o.triangles) { for (const Triangle3& t : o.triangles) {
if (!swapYZ) { if (!swapYZ) {
res.obj += "v " + std::to_string(t.p1.x) + " " + std::to_string(t.p1.y) + " " + std::to_string(t.p1.z) + "\n"; res.obj += "v " + std::to_string(t.p1.x-ox) + " " + std::to_string(t.p1.y-oy) + " " + std::to_string(t.p1.z) + "\n";
res.obj += "v " + std::to_string(t.p2.x) + " " + std::to_string(t.p2.y) + " " + std::to_string(t.p2.z) + "\n"; res.obj += "v " + std::to_string(t.p2.x-ox) + " " + std::to_string(t.p2.y-oy) + " " + std::to_string(t.p2.z) + "\n";
res.obj += "v " + std::to_string(t.p3.x) + " " + std::to_string(t.p3.y) + " " + std::to_string(t.p3.z) + "\n"; res.obj += "v " + std::to_string(t.p3.x-ox) + " " + std::to_string(t.p3.y-oy) + " " + std::to_string(t.p3.z) + "\n";
} else { } else {
res.obj += "v " + std::to_string(t.p1.x) + " " + std::to_string(t.p1.z) + " " + std::to_string(t.p1.y) + "\n"; res.obj += "v " + std::to_string(t.p1.x-ox) + " " + std::to_string(t.p1.z) + " " + std::to_string(t.p1.y-oy) + "\n";
res.obj += "v " + std::to_string(t.p2.x) + " " + std::to_string(t.p2.z) + " " + std::to_string(t.p2.y) + "\n"; res.obj += "v " + std::to_string(t.p3.x-ox) + " " + std::to_string(t.p3.z) + " " + std::to_string(t.p3.y-oy) + "\n";
res.obj += "v " + std::to_string(t.p3.x) + " " + std::to_string(t.p3.z) + " " + std::to_string(t.p3.y) + "\n"; res.obj += "v " + std::to_string(t.p2.x-ox) + " " + std::to_string(t.p2.z) + " " + std::to_string(t.p2.y-oy) + "\n";
} }
} }
@@ -221,29 +247,78 @@ namespace Ray3D {
}; };
// material // // material
// std::vector<Material> mats = {
// Material(0,128,0,255), // ground outdoor
// Material(64,64,64,255), // ground outdoor
// Material(255,96,96,255), // stair
// Material(128,128,128,255), // concrete
// Material(64,128,255,64), // glass
// Material(200,200,200,255), // default
// };
// int getMaterial(const Obstacle3D& o) const {
// if (o.type == Obstacle3D::Type::GROUND_OUTDOOR) {return 0;}
// if (o.type == Obstacle3D::Type::GROUND_INDOOR) {return 1;}
// if (o.type == Obstacle3D::Type::STAIR) {return 2;}
// if (o.mat == Floorplan::Material::CONCRETE) {return 3;}
// if (o.mat == Floorplan::Material::GLASS) {return 4;}
// return 5;
// }
std::vector<Material> mats = { std::vector<Material> mats = {
Material(0,128,0,255), // ground outdoor Material(255,0,0,255), // error
Material(64,64,64,255), // ground outdoor
Material(255,96,96,255), // stair
Material(128,128,128,255), // concrete Material(0,128,0,255), // ground outdoor
Material(64,128,255,64), // glass Material(64,64,64,255), // ground outdoor
Material(200,200,200,255), // default Material(105,105,105,255), // stair
Material(220,220,220,255), // handrail
Material(200,200,255,96), // door (glass)
Material(140,140,140,255), // door (wood)
Material(135,135,135,255), // concrete
Material(240,240,255,96), // glass
Material(170,170,255,96), // glass (metallized)
Material(170,120,60,255), // wood
Material(200,200,200,255), // drywall
Material(255,255,255,255), // object
Material(235,235,235,255), // default
}; };
int getMaterial(const Obstacle3D& o) const { int getMaterial(const Obstacle3D& o) const {
if (o.type == Obstacle3D::Type::GROUND_OUTDOOR) {return 0;}
if (o.type == Obstacle3D::Type::GROUND_INDOOR) {return 1;}
if (o.type == Obstacle3D::Type::STAIR) {return 2;}
if (o.mat == Floorplan::Material::CONCRETE) {return 3;} if (o.type == Floorplan3D::Obstacle3D::Type::ERROR) {return 0;}
if (o.mat == Floorplan::Material::GLASS) {return 4;}
return 5; if (o.type == Floorplan3D::Obstacle3D::Type::GROUND_OUTDOOR) {return 1;}
if (o.type == Floorplan3D::Obstacle3D::Type::GROUND_INDOOR) {return 2;}
if (o.type == Floorplan3D::Obstacle3D::Type::STAIR) {return 3;}
if (o.type == Floorplan3D::Obstacle3D::Type::HANDRAIL) {return 4;}
if (o.type == Floorplan3D::Obstacle3D::Type::OBJECT) {return 12;}
if (o.type == Floorplan3D::Obstacle3D::Type::DOOR && o.mat == Floorplan::Material::GLASS) {return 5;}
if (o.type == Floorplan3D::Obstacle3D::Type::DOOR) {return 6;}
if (o.mat == Floorplan::Material::CONCRETE) {return 7;}
if (o.mat == Floorplan::Material::GLASS) {return 8;}
if (o.mat == Floorplan::Material::METALLIZED_GLAS) {return 9;}
if (o.mat == Floorplan::Material::WOOD) {return 10;}
if (o.mat == Floorplan::Material::DRYWALL) {return 11;}
return 12;
} }
// Color getColor(const Obstacle3D& o) const { // Color getColor(const Obstacle3D& o) const {
// if (o.type == Obstacle3D::Type::GROUND_OUTDOOR) {return Color(0,128,0,255);} // if (o.type == Obstacle3D::Type::GROUND_OUTDOOR) {return Color(0,128,0,255);}
// if (o.type == Obstacle3D::Type::GROUND_INDOOR) {return Color(64,64,64,255);} // if (o.type == Obstacle3D::Type::GROUND_INDOOR) {return Color(64,64,64,255);}
@@ -256,4 +331,4 @@ namespace Ray3D {
} }
#endif // FLOORPLANMESH_H #endif // FLOORPLAN_3D_FLOORPLANMESH_H

83
floorplan/3D/Handrails.h Normal file
View File

@@ -0,0 +1,83 @@
#ifndef FLOORPLAN_3D_HANDRAILS_H
#define FLOORPLAN_3D_HANDRAILS_H
#include "Obstacle3.h"
#include "misc.h"
namespace Floorplan3D {
class Handrails {
public:
std::vector<Obstacle3D> getHandrails(const Floorplan::Floor* f) {
std::vector<Obstacle3D> res;
for (const Floorplan::FloorObstacle* o: f->obstacles) {
const Floorplan::FloorObstacleLine* line = dynamic_cast<const Floorplan::FloorObstacleLine*>(o);
if (line && line->type == Floorplan::ObstacleType::HANDRAIL) {
res.push_back(getHandrail(f, line));
}
}
return res;
}
Obstacle3D getHandrail(const Floorplan::Floor* f, const Floorplan::FloorObstacleLine* fol) const {
FloorPos fpos(f);
// target
Obstacle3D res(getType(fol), fol->material);
const float thickness_m = 0.05;
const Point2 from = fol->from;
const Point2 to = fol->to;
const Point2 cen2 = (from+to)/2;
// edges
const float z1 = fpos.z1;
const float z2 = fpos.z1 + 1.0;
Point3 p1 = Point3(from.x, from.y, z1);
Point3 p2 = Point3(to.x, to.y, z1);
Point3 p3 = Point3(from.x, from.y, z2);
Point3 p4 = Point3(to.x, to.y, z2);
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 Point3 pUp(cen2.x, cen2.y, z2);
const float sx = from.getDistance(to) / 2;
const float sy = thickness_m / 2;
const float sz = thickness_m / 2;
const Point3 size(sx, sy, sz);
const Point3 rot(0,0,deg);
// upper bar
const Cube cubeUpper(pUp, size, rot);
const std::vector<Triangle3> tmp = cubeUpper.getTriangles();
res.triangles.insert(res.triangles.end(), tmp.begin(), tmp.end());
const Point3 d1 = p2-p1;
const Point3 d2 = p4-p3;
const int numBars = d2.length() / 0.75f;
for (int i = 1; i < numBars; ++i) {
const Point3 s = p1 + d1 * i / numBars;
const Point3 e = p3 + d2 * i / numBars;
const Point3 c = (s+e)/2;
const Point3 size(thickness_m/2, thickness_m/2, s.getDistance(e)/2 - thickness_m);
const Cube cube(c, size, rot);
const std::vector<Triangle3> tmp = cube.getTriangles();
res.triangles.insert(res.triangles.end(), tmp.begin(), tmp.end());
}
// done
return res;
}
};
}
#endif // FLOORPLAN_3D_HANDRAILS_H

52
floorplan/3D/Objects.h Normal file
View File

@@ -0,0 +1,52 @@
#ifndef FLOORPLAN_3D_OBJECTS_H
#define FLOORPLAN_3D_OBJECTS_H
#include "Obstacle3.h"
#include "misc.h"
#include "objects/OBJPool.h"
namespace Floorplan3D {
class Objects {
public:
std::vector<Obstacle3D> getObjects(const Floorplan::Floor* f) {
std::vector<Obstacle3D> res;
for (const Floorplan::FloorObstacle* o: f->obstacles) {
const Floorplan::FloorObstacleObject* obj = dynamic_cast<const Floorplan::FloorObstacleObject*>(o);
if (obj) {
res.push_back(getObject(f, obj));
}
}
return res;
}
/** 3D Obstacle from .obj 3D mesh */
Obstacle3D getObject(const Floorplan::Floor* f, const Floorplan::FloorObstacleObject* foo) const {
FloorPos fpos(f);
const std::string& name = foo->file;
Obstacle3D obs = OBJPool::get().getObject(name);
// perform sanity checks
if (!obs.isValid()) {
throw std::runtime_error("invalid obstacle-data detected");
}
// apply scaling/rotation/translation
obs = obs.scaled(foo->scale);
obs = obs.rotated_deg( Point3(foo->rot.x, foo->rot.y, foo->rot.z) );
obs = obs.translated(foo->pos + Point3(0,0,fpos.z1));
obs.type = Obstacle3D::Type::OBJECT;
return obs;
}
};
}
#endif // FLOORPLAN_3D_OBJECTS_H

View File

@@ -1,13 +1,13 @@
#ifndef OBSTACLE3_H #ifndef FLOORPLAN_3D_OBSTACLE3_H
#define OBSTACLE3_H #define FLOORPLAN_3D_OBSTACLE3_H
#include <vector> #include <vector>
#include "../../../geo/Triangle3.h" #include "../../geo/Triangle3.h"
#include "../../../geo/Sphere3.h" #include "../../geo/Sphere3.h"
#include "../../../floorplan/v2/Floorplan.h" #include "../v2/Floorplan.h"
namespace Ray3D { namespace Floorplan3D {
/** /**
* 3D obstacle * 3D obstacle
@@ -124,4 +124,4 @@ namespace Ray3D {
} }
#endif // OBSTACLE3_H #endif // FLOORPLAN_3D_OBSTACLE3_H

99
floorplan/3D/Outline.h Normal file
View File

@@ -0,0 +1,99 @@
#ifndef FLOORPLAN_3D_OUTLINE_H
#define FLOORPLAN_3D_OUTLINE_H
#include "Obstacle3.h"
#include "misc.h"
#include <unordered_map>
#include "../../geo/GPCPolygon2.h"
namespace Floorplan3D {
class Outline {
public:
/** convert a floor (floor/ceiling) into triangles */
std::vector<Obstacle3D> get(const Floorplan::Floor* f) {
FloorPos fpos(f);
std::vector<Obstacle3D> res;
if (!f->enabled) {return res;}
if (!f->outline.enabled) {return res;}
// floor uses an outline based on "add" and "remove" areas
// we need to create the apropriate triangles to model the polygon
// including all holes (remove-areas)
// process all "add" regions by type
// [this allows for overlaps of the same type]
std::unordered_map<std::string, GPCPolygon2> types;
for (Floorplan::FloorOutlinePolygon* fop : f->outline) {
if (fop->method == Floorplan::OutlineMethod::ADD) {
if (fop->outdoor) {
types["outdoor"].add(fop->poly);
} else {
types["indoor"].add(fop->poly);
}
}
}
// remove the "remove" regions from EVERY "add" region added within the previous step
for (Floorplan::FloorOutlinePolygon* fop : f->outline) {
if (fop->method == Floorplan::OutlineMethod::REMOVE) {
for (auto& it : types) {
it.second.remove(fop->poly);
}
}
// allow for overlapping outdoor/indoor regions -> outdoor wins [remove outdoor part from indoor parts]
if (fop->outdoor) {
types["indoor"].remove(fop->poly);
}
}
// create an obstacle for each type (indoor, outdoor)
for (auto& it : types) {
// TODO: variable type?
Obstacle3D::Type type = (it.first == "indoor") ? (Obstacle3D::Type::GROUND_INDOOR) : (Obstacle3D::Type::GROUND_OUTDOOR);
Obstacle3D obs(type, Floorplan::Material::CONCRETE);
// convert them into polygons
std::vector<std::vector<Point3>> polys = it.second.get(fpos.z1);
// convert polygons (GL_TRIANGLE_STRIP) to triangles
for (const std::vector<Point3>& pts : polys) {
for (int i = 0; i < (int)pts.size() - 2; ++i) {
// floor must be double-sided
Triangle3 tria1 (pts[i+0], pts[i+1], pts[i+2]);
Triangle3 tria2 (pts[i+2], pts[i+1], pts[i+0]);
// ensure the triangle with the normal pointing downwards (towards bulding's cellar)
// is below the triangle that points upwards (towards the sky)
if (tria1.getNormal().z < 0) {std::swap(tria1, tria2);}
// tria2 = ceiling of previous floor
tria2 -= Point3(0,0,fpos.fh);
// add both
obs.triangles.push_back(tria1);
obs.triangles.push_back(tria2);
}
}
res.push_back(obs);
}
return res;
}
};
}
#endif // FLOORPLAN_3D_OUTLINE_H

51
floorplan/3D/Pillars.h Normal file
View File

@@ -0,0 +1,51 @@
#ifndef FLOORPLAN_3D_PILLARS_H
#define FLOORPLAN_3D_PILLARS_H
#include "Obstacle3.h"
#include "misc.h"
#include "primitives/Cylinder.h"
namespace Floorplan3D {
class Pillars {
public:
std::vector<Obstacle3D> getPillars(const Floorplan::Floor* f) {
std::vector<Obstacle3D> res;
for (const Floorplan::FloorObstacle* o: f->obstacles) {
const Floorplan::FloorObstacleCircle* circ = dynamic_cast<const Floorplan::FloorObstacleCircle*>(o);
if (circ) {
res.push_back(getPillar(f, circ));
}
}
return res;
}
Obstacle3D getPillar(const Floorplan::Floor* f, const Floorplan::FloorObstacleCircle* foc) {
FloorPos fpos(f);
// attributes
const float r = foc->radius;
const float h = (foc->height > 0) ? (foc->height) : (fpos.height); // use either floor's height or user height
const Point3 pos(foc->center.x, foc->center.y, fpos.z1 + h/2);
// build
Cylinder cyl;
cyl.add(r, h/2, true);
cyl.translate(pos);
// done
Obstacle3D res(getType(foc), foc->material);
res.triangles = cyl.getTriangles();
return res;
}
};
}
#endif // FLOORPLAN_3D_PILLARS_H

82
floorplan/3D/Stairs.h Normal file
View File

@@ -0,0 +1,82 @@
#ifndef FLOORPLAN_3D_STAIRS_H
#define FLOORPLAN_3D_STAIRS_H
#include "Obstacle3.h"
#include "primitives/Cube.h"
namespace Floorplan3D {
class Stairs {
public:
std::vector<Obstacle3D> getStairs(const Floorplan::Floor* f) {
std::vector<Obstacle3D> res;
for (const Floorplan::Stair* stair : f->stairs) {
res.push_back(getStair(f, stair));
}
return res;
}
Obstacle3D getStair(const Floorplan::Floor* f, const Floorplan::Stair* s) {
Obstacle3D res(Obstacle3D::Type::STAIR, Floorplan::Material::CONCRETE);
std::vector<Floorplan::Quad3> quads = Floorplan::getQuads(s->getParts(), f);
for (const Floorplan::Quad3& quad : quads) {
if (quad.isLeveled()) {
const float h = 0.2;
const Point3 ph(0,0,h);
const Cube cube = Cube::fromBottomAndHeight(quad.p1-ph, quad.p2-ph, quad.p3-ph, quad.p4-ph, 0.2);
const std::vector<Triangle3> tmp = cube.getTriangles();
res.triangles.insert(res.triangles.end(), tmp.begin(), tmp.end());
} else {
const Point3 dir1 = quad.p3 - quad.p2;
const Point3 dir2 = quad.p4 - quad.p1;
float stepH = 0.20;
const float totalH = quad.p3.z - quad.p1.z;
const int numStairs = std::round(totalH / stepH);
stepH = totalH / numStairs;
for (int i = 0; i < numStairs; ++i) {
//const float y1 = quad.p1.z + (stepH * i);
//const float y2 = y1 + stepH;
Point3 p1b = quad.p1 + dir1 * (i+0) / numStairs; p1b.z -= stepH;
Point3 p2b = quad.p2 + dir2 * (i+0) / numStairs; p2b.z -= stepH;
const Point3 p3t = quad.p2 + dir2 * (i+1) / numStairs;
const Point3 p4t = quad.p1 + dir1 * (i+1) / numStairs;
const Point3 p1t(p1b.x, p1b.y, p4t.z);
const Point3 p2t(p2b.x, p2b.y, p3t.z);
const Point3 p3b(p3t.x, p3t.y, p2b.z+stepH);
const Point3 p4b(p4t.x, p4t.y, p1b.z+stepH);
const Cube cube = Cube::fromVertices(p1t, p2t, p3t, p4t, p1b, p2b, p3b, p4b);
const std::vector<Triangle3> tmp = cube.getTriangles();
res.triangles.insert(res.triangles.end(), tmp.begin(), tmp.end());
}
}
}
return res;
}
};
}
#endif // FLOORPLAN_3D_STAIRS_H

View File

@@ -1,9 +1,9 @@
#ifndef WALLS_H #ifndef FLOORPLAN_3D_WALLS_H
#define WALLS_H #define FLOORPLAN_3D_WALLS_H
#include "Obstacle3.h" #include "Obstacle3.h"
namespace Ray3D { namespace Floorplan3D {
class Walls { class Walls {
@@ -19,4 +19,4 @@ namespace Ray3D {
} }
#endif // WALLS_H #endif // FLOORPLAN_3D_WALLS_H

View File

@@ -1,11 +1,11 @@
#ifndef WALLSVIACUBE_H #ifndef FLOORPLAN_3D_WALLSVIACUBE_H
#define WALLSVIACUBE_H #define FLOORPLAN_3D_WALLSVIACUBE_H
#include "Walls.h" #include "Walls.h"
#include "FloorPos.h" #include "misc.h"
#include "Cube.h" #include "primitives/Cube.h"
namespace Ray3D { namespace Floorplan3D {
/** /**
* simply use one 3D cube per wall * simply use one 3D cube per wall
@@ -66,4 +66,4 @@ namespace Ray3D {
} }
#endif // WALLSVIACUBE_H #endif // FLOORPLAN_3D_WALLSVIACUBE_H

View File

@@ -1,14 +1,14 @@
#ifndef WALLSVIACUTTEDQUADS_H #ifndef FLOORPLAN_3D_WALLSVIACUTTEDQUADS_H
#define WALLSVIACUTTEDQUADS_H #define FLOORPLAN_3D_WALLSVIACUTTEDQUADS_H
#include "../../../geo/Line2.h" #include "../../geo/Line2.h"
#include "../../../geo/Polygon2.h" #include "../../geo/Polygon2.h"
#include "Walls.h" #include "Walls.h"
#include "FloorPos.h" #include "misc.h"
#include <iostream> #include <iostream>
namespace Ray3D { namespace Floorplan3D {
/** /**
* interpret walls als quads (polygons) * interpret walls als quads (polygons)
@@ -95,7 +95,7 @@ namespace Ray3D {
/** does this wall contain the given point */ /** does this wall contain the given point */
bool containsPoint(const Point2 p) const { bool containsPoint(const Point2 p) const {
return polygonContainsPoint({l1.p1, l1.p2, l2.p2, l2.p1}, p); return polygonContainsPoint({getP1(), getP2(), getP3(), getP4()}, p);
} }
}; };
@@ -168,11 +168,13 @@ namespace Ray3D {
/** convert one wall into an obstacle */ /** convert one wall into an obstacle */
Obstacle3D toObstacle(const Wall& wall, const Floorplan::Floor* f) { Obstacle3D toObstacle(const Wall& wall, const Floorplan::Floor* f) {
FloorPos fp(f);
Obstacle3D::Type type = (wall.error) ? (Obstacle3D::Type::ERROR) : (getType(wall.line)); Obstacle3D::Type type = (wall.error) ? (Obstacle3D::Type::ERROR) : (getType(wall.line));
Obstacle3D obs(type, wall.line->material); Obstacle3D obs(type, wall.line->material);
const float z1 = f->getStartingZ(); const float z1 = fp.z1;
const float z2 = f->getEndingZ(); const float z2 = fp.z2;
const Point3 p1 = Point3(wall.getP1().x, wall.getP1().y, z1); const Point3 p1 = Point3(wall.getP1().x, wall.getP1().y, z1);
const Point3 p2 = Point3(wall.getP2().x, wall.getP2().y, z1); const Point3 p2 = Point3(wall.getP2().x, wall.getP2().y, z1);
@@ -227,19 +229,27 @@ namespace Ray3D {
std::cout << "detected strange wall intersection" << std::endl; std::cout << "detected strange wall intersection" << std::endl;
} }
// check all detected intersections int cut = 0;
// check the (2) detected intersections
for (const auto isect : isects) { for (const auto isect : isects) {
// if one of the line-ends p1/p2 from wall1 ends within wall2, crop it by setting it to the intersection // if one of the line-ends p1/p2 from wall1 ends within wall2, crop it by setting it to the intersection
if (w2.containsPoint(isect.l1->p1)) {isect.l1->p1 = isect.p;} if (w2.containsPoint(isect.l1->p1)) {isect.l1->p1 = isect.p; ++cut;}
if (w2.containsPoint(isect.l1->p2)) {isect.l1->p2 = isect.p;} if (w2.containsPoint(isect.l1->p2)) {isect.l1->p2 = isect.p; ++cut;}
// if one of the line-ends p1/p2 from wall2 ends within wall1, crop it by setting it to the intersection // if one of the line-ends p1/p2 from wall2 ends within wall1, crop it by setting it to the intersection
if (w1.containsPoint(isect.l2->p1)) {isect.l2->p1 = isect.p;} if (w1.containsPoint(isect.l2->p1)) {isect.l2->p1 = isect.p; ++cut;}
if (w1.containsPoint(isect.l2->p2)) {isect.l2->p2 = isect.p;} if (w1.containsPoint(isect.l2->p2)) {isect.l2->p2 = isect.p; ++cut;}
} }
// 2 lines should have been cut. if not, potential issue!
if (cut != 2) {
w1.error = true;
w2.error = true;
}
} }
} }
@@ -290,4 +300,4 @@ namespace Ray3D {
} }
#endif // WALLSVIACUTTEDQUADS_H #endif // FLOORPLAN_3D_WALLSVIACUTTEDQUADS_H

View File

@@ -1,9 +1,9 @@
#ifndef FLOORPOS_H #ifndef FLOORPLAN_3D_MISC_H
#define FLOORPOS_H #define FLOORPLAN_3D_MISC_H
#include "Obstacle3.h" #include "Obstacle3.h"
namespace Ray3D { namespace Floorplan3D {
/** used to model ceiling thickness */ /** used to model ceiling thickness */
struct FloorPos { struct FloorPos {
@@ -30,4 +30,4 @@ namespace Ray3D {
} }
#endif // FLOORPOS_H #endif // FLOORPLAN_3D_MISC_H

View File

@@ -1,12 +1,12 @@
#ifndef OBJPOOL_H #ifndef FLOORPLAN_3D_OBJPOOL_H
#define OBJPOOL_H #define FLOORPLAN_3D_OBJPOOL_H
#include <vector> #include <vector>
#include "../../../geo/Triangle3.h" #include "../../../geo/Triangle3.h"
#include <unordered_map> #include <unordered_map>
#include "OBJReader.h" #include "OBJReader.h"
#include "Obstacle3.h" #include "../Obstacle3.h"
// LINUX ONLY // LINUX ONLY
//#include <dirent.h> //#include <dirent.h>
@@ -17,7 +17,7 @@
#include "../../../misc/Debug.h" #include "../../../misc/Debug.h"
namespace Ray3D { namespace Floorplan3D {
/** /**
* load several named 3D models for quick re-use * load several named 3D models for quick re-use
@@ -132,4 +132,4 @@ namespace Ray3D {
} }
#endif // OBJPOOL_H #endif // FLOORPLAN_3D_OBJPOOL_H

View File

@@ -1,11 +1,11 @@
#ifndef QUBE_H #ifndef FLOORPLAN_3D_CUBE_H
#define QUBE_H #define FLOORPLAN_3D_CUBE_H
#include "../../../math/Matrix4.h" #include "../../../math/Matrix4.h"
#include "Mesh.h" #include "Mesh.h"
namespace Ray3D { namespace Floorplan3D {
class Cube : public Mesh { class Cube : public Mesh {
@@ -163,4 +163,4 @@ namespace Ray3D {
} }
#endif // QUBE_H #endif // FLOORPLAN_3D_CUBE_H

View File

@@ -1,11 +1,11 @@
#ifndef CYLINDER_H #ifndef FLOORPLAN_3D_CYLINDER_H
#define CYLINDER_H #define FLOORPLAN_3D_CYLINDER_H
#include "../../../math/Matrix4.h" #include "../../../math/Matrix4.h"
#include "Mesh.h" #include "Mesh.h"
namespace Ray3D { namespace Floorplan3D {
/** walled cylinder */ /** walled cylinder */
class Cylinder : public Mesh { class Cylinder : public Mesh {
@@ -79,4 +79,4 @@ namespace Ray3D {
} }
#endif // CYLINDER_H #endif // FLOORPLAN_3D_CYLINDER_H

View File

@@ -1,11 +1,11 @@
#ifndef RAY3D_MESH_H #ifndef FLOORPLAN_3D_MESH_H
#define RAY3D_MESH_H #define FLOORPLAN_3D_MESH_H
#include <vector> #include <vector>
#include "../../../geo/Triangle3.h" #include "../../../geo/Triangle3.h"
#include "../../../math/Matrix4.h" #include "../../../math/Matrix4.h"
namespace Ray3D { namespace Floorplan3D {
class Mesh { class Mesh {
@@ -66,4 +66,4 @@ namespace Ray3D {
} }
#endif // RAY3D_MESH_H #endif // FLOORPLAN_3D_MESH_H

View File

@@ -1,11 +1,11 @@
#ifndef TUBE_H #ifndef FLOORPLAN_3D_TUBE_H
#define TUBE_H #define FLOORPLAN_3D_TUBE_H
#include "../../../math/Matrix4.h" #include "../../../math/Matrix4.h"
#include "Mesh.h" #include "Mesh.h"
namespace Ray3D { namespace Floorplan3D {
/** walled cylinder */ /** walled cylinder */
class Tube : public Mesh { class Tube : public Mesh {
@@ -119,4 +119,4 @@ namespace Ray3D {
} }
#endif // TUBE_H #endif // FLOORPLAN_3D_TUBE_H

View File

@@ -3,7 +3,6 @@
#include "Floorplan.h" #include "Floorplan.h"
#include "../../geo/BBox2.h" #include "../../geo/BBox2.h"
#include "../../wifi/estimate/ray3/ModelFactory.h"
#include <iostream> #include <iostream>
#include <vector> #include <vector>
@@ -147,12 +146,13 @@ namespace Floorplan {
res.push_back(Issue(Type::ERR, floor, "' door is too narrow: " + std::to_string(len_m) + " meter from " + door->from.asString() + " to " + door->to.asString())); res.push_back(Issue(Type::ERR, floor, "' door is too narrow: " + std::to_string(len_m) + " meter from " + door->from.asString() + " to " + door->to.asString()));
} }
try { #warning "TODO!"
Ray3D::ModelFactory fac(map); // try {
fac.getDoorAbove(floor, door); // Ray3D::ModelFactory fac(map);
} catch (Exception e) { // fac.getDoorAbove(floor, door);
res.push_back(Issue(Type::ERR, floor, std::string(e.what()) + "[from" + door->from.asString() + " to " + door->to.asString() + "]")); // } catch (Exception e) {
} // res.push_back(Issue(Type::ERR, floor, std::string(e.what()) + "[from" + door->from.asString() + " to " + door->to.asString() + "]"));
// }
} }

View File

@@ -57,6 +57,9 @@ public:
/** get the bbox's size */ /** get the bbox's size */
const Point3 getSize() const {return p2-p1;} const Point3 getSize() const {return p2-p1;}
/** get the boox's center */
const Point3 getCenter() const {return (p2+p1)/2;}
/** equal? */ /** equal? */
bool operator == (const BBox3& o) const { bool operator == (const BBox3& o) const {
return (p1.x == o.p1.x) && return (p1.x == o.p1.x) &&

View File

@@ -118,7 +118,7 @@ static bool polygonContainsPoint(const std::vector<Point2>& poly, const Point2 p
// only look at the fractional part // only look at the fractional part
//const double y = x - std::floor(x); //const double y = x - std::floor(x);
return std::abs(x) >= 0.975;// && (std::abs(y) >= 0.9 || std::abs(y) < 0.1); return std::abs(x) >= 0.995;// && (std::abs(y) >= 0.9 || std::abs(y) < 0.1);
} }

View File

@@ -21,7 +21,7 @@
#include "../../../misc/Debug.h" #include "../../../misc/Debug.h"
#include <functional> #include <functional>
#include "../../../wifi/estimate/ray3/OBJPool.h" #include "../../../floorplan/3D/objects/OBJPool.h"
#include "../../../geo/ConvexHull2.h" #include "../../../geo/ConvexHull2.h"
#include "GridFactoryListener.h" #include "GridFactoryListener.h"
@@ -224,7 +224,7 @@ public:
if (foo) { if (foo) {
// get the obstacle // get the obstacle
const Ray3D::Obstacle3D obs = Ray3D::OBJPool::get().getObject(foo->file).scaled(foo->scale).rotated_deg(foo->rot).translated(foo->pos); const Floorplan3D::Obstacle3D obs = Floorplan3D::OBJPool::get().getObject(foo->file).scaled(foo->scale).rotated_deg(foo->rot).translated(foo->pos);
// construct its 2D convex hull (in centimter) // construct its 2D convex hull (in centimter)
HelperPoly poly; HelperPoly poly;

View File

@@ -8,7 +8,7 @@
#include "../geo/ConvexHull2.h" #include "../geo/ConvexHull2.h"
#include "../geo/GPCPolygon2.h" #include "../geo/GPCPolygon2.h"
#include "../wifi/estimate/ray3/OBJPool.h" #include "../floorplan/3D/objects/OBJPool.h"
#include "NavMesh.h" #include "NavMesh.h"
#include "NavMeshTriangle.h" #include "NavMeshTriangle.h"
@@ -632,7 +632,7 @@ namespace NM {
Floorplan::Polygon2 res; Floorplan::Polygon2 res;
// fetch object from pool // fetch object from pool
const Ray3D::Obstacle3D obs = Ray3D::OBJPool::get().getObject(obj->file).scaled(obj->scale).rotated_deg(obj->rot).translated(obj->pos); const Floorplan3D::Obstacle3D obs = Floorplan3D::OBJPool::get().getObject(obj->file).scaled(obj->scale).rotated_deg(obj->rot).translated(obj->pos);
// construct 2D convex hull // construct 2D convex hull
res.points = ConvexHull2::get(obs.getPoints2D()); res.points = ConvexHull2::get(obs.getPoints2D());