#ifndef GPCPOLYGON2_H #define GPCPOLYGON2_H #include "../lib/gpc/gpc.cpp.h" class GPCPolygon2 { struct GPCPolygon : gpc_polygon { GPCPolygon() { num_contours = 0; contour = nullptr; hole = nullptr; } // no copy or move GPCPolygon(const GPCPolygon& o) = delete; GPCPolygon(GPCPolygon&& o) = delete; ~GPCPolygon() { if (contour) { gpc_free_polygon(this); //free(contour->vertex); contour->vertex = nullptr; } free(contour); contour = nullptr; free(hole); hole = nullptr; } GPCPolygon& operator = (const GPCPolygon& o) = delete; GPCPolygon& operator = (GPCPolygon&& o) = delete; }; private: GPCPolygon state; float z; public: GPCPolygon2() : z(0) { ; } GPCPolygon2(float z) : z(z) { ; } void add(const Floorplan::Polygon2& poly) { GPCPolygon cur; toGPC(poly, cur); gpc_polygon_clip(GPC_UNION, &state, &cur, &state); } void remove(const Floorplan::Polygon2& poly) { GPCPolygon cur; toGPC(poly, cur); gpc_polygon_clip(GPC_DIFF, &state, &cur, &state); } std::vector> get() { gpc_tristrip res; res.num_strips = 0; res.strip = nullptr; //res.strip = (gpc_vertex_list*) malloc(1024); gpc_polygon_to_tristrip(&state, &res); std::vector> trias; for (int i = 0; i < res.num_strips; ++i) { gpc_vertex_list lst = res.strip[i]; for (int j = 2; j < lst.num_vertices; ++j) { std::vector tria; gpc_vertex& v1 = lst.vertex[j - 2]; gpc_vertex& v2 = lst.vertex[j - 1]; gpc_vertex& v3 = lst.vertex[j]; tria.push_back(Point3(v1.x, v1.y, z)); tria.push_back(Point3(v2.x, v2.y, z)); tria.push_back(Point3(v3.x, v3.y, z)); trias.push_back(tria); } } gpc_free_tristrip(&res); return std::move(trias); } std::vector> get(float z) { gpc_tristrip res; res.num_strips = 0; res.strip = nullptr; //res.strip = (gpc_vertex_list*) malloc(1024); gpc_polygon_to_tristrip(&state, &res); std::vector> trias; for (int i = 0; i < res.num_strips; ++i) { gpc_vertex_list lst = res.strip[i]; std::vector tria; for (int j = 0; j < lst.num_vertices; ++j) { gpc_vertex& vert = lst.vertex[j]; Point3 p3(vert.x, vert.y, z); tria.push_back(p3); } trias.push_back(tria); } gpc_free_tristrip(&res); return std::move(trias); } private: void toGPC(Floorplan::Polygon2 poly, GPCPolygon& result) { std::vector verts; for (Point2 p2 : poly.points) { gpc_vertex vert; vert.x = p2.x; vert.y = p2.y; verts.push_back(vert); } gpc_vertex_list list; list.num_vertices = verts.size(); list.vertex = verts.data(); gpc_add_contour(&result, &list, 0); } }; #endif