#ifndef MV3DELEMENTFLOOROUTLINE_H #define MV3DELEMENTFLOOROUTLINE_H #include #include "misc/Cube.h" #include "MV3DElement.h" #include "../../lib/gpc/gpc.h" #include "misc/Polygon.h" class MV3DElementFloorOutline : public MV3DElement { Floorplan::Floor* f; Floorplan::FloorOutline* out; struct ToRender { Point2 cacheSum; Polygon* pol = nullptr; std::vector> trias; }; std::unordered_map elements; public: /** ctor */ MV3DElementFloorOutline(Floorplan::Floor* f, Floorplan::FloorOutline* out) : f(f), out(out) { ; } protected: /** repaint me */ void paintGL() override { rebuildIfNeeded(); for (auto& it : elements) { //Polygon& pol = it.second->pol; std::vector>& trias = it.second->trias; if (it.first == "outdoor") { glColor3f(0.0, 0.5, 0.0); } else { glColor3f(0.2, 0.2, 0.2); } glDisable(GL_CULL_FACE); for (const std::vector& tria : trias) { glNormal3f(0, 1, 0); glBegin(GL_TRIANGLE_STRIP); for (const Point3& p3 : tria) { glVertex3f(p3.x, p3.z, p3.y); } glEnd(); } glEnable(GL_CULL_FACE); } } void rebuildIfNeeded() { auto filterIndoor = [] (const Floorplan::FloorOutlinePolygon* p) {return p->outdoor == false;}; auto filterOutdoor = [] (const Floorplan::FloorOutlinePolygon* p) {return p->outdoor == true;}; if (elements.empty()) { elements["indoor"] = new ToRender(); elements["outdoor"] = new ToRender(); } rebuildIfNeeded(filterIndoor, elements["indoor"]); rebuildIfNeeded(filterOutdoor, elements["outdoor"]); } template void rebuildIfNeeded(Filter include, ToRender* dst) { const std::vector& polys = *out; // get number of points for rebuild-check Point2 cacheSum(0,0); for (Floorplan::FloorOutlinePolygon* poly : polys) { if (!include(poly)) {continue;} for (Point2 pt : poly->poly.points) { cacheSum += pt; } } // already up to date? if (cacheSum == dst->cacheSum) {return;} dst->cacheSum = cacheSum; // rebuild std::vector add; std::vector rem; if (dst->pol) {delete dst->pol;} dst->pol = new Polygon(); for (Floorplan::FloorOutlinePolygon* poly : polys) { if (!include(poly)) {continue;} switch (poly->method) { case Floorplan::OutlineMethod::ADD: dst->pol->add(poly->poly); break; case Floorplan::OutlineMethod::REMOVE: dst->pol->remove(poly->poly); break; default: throw 1; } } dst->trias = dst->pol->get(f->atHeight); } }; #endif // MV3DELEMENTFLOOROUTLINE_H