#ifndef SVGTOOLS_HPP #define SVGTOOLS_HPP #include #include #include #include namespace libnest2d { namespace svg { template class SVGWriter { using Item = _Item; using Coord = TCoord>; using Box = _Box>; using PackGroup = _PackGroup; public: enum OrigoLocation { TOPLEFT, BOTTOMLEFT }; struct Config { OrigoLocation origo_location; Coord mm_in_coord_units; double width, height; Config(): origo_location(BOTTOMLEFT), mm_in_coord_units(1000000), width(500), height(500) {} }; private: Config conf_; std::vector svg_layers_; bool finished_ = false; public: SVGWriter(const Config& conf = Config()): conf_(conf) {} void setSize(const Box& box) { conf_.height = static_cast(box.height()) / conf_.mm_in_coord_units; conf_.width = static_cast(box.width()) / conf_.mm_in_coord_units; } void writeShape(RawShape tsh) { if(svg_layers_.empty()) addLayer(); if(conf_.origo_location == BOTTOMLEFT) { auto d = static_cast( std::round(conf_.height*conf_.mm_in_coord_units) ); auto& contour = shapelike::contour(tsh); for(auto& v : contour) setY(v, -getY(v) + d); auto& holes = shapelike::holes(tsh); for(auto& h : holes) for(auto& v : h) setY(v, -getY(v) + d); } currentLayer() += shapelike::serialize(tsh, 1.0 / conf_.mm_in_coord_units) + "\n"; } void writeItem(const Item& item) { writeShape(item.transformedShape()); } void writePackGroup(const PackGroup& result) { for(auto r : result) { addLayer(); for(Item& sh : r) { writeItem(sh); } finishLayer(); } } template void writeItems(ItemIt from, ItemIt to) { auto it = from; PackGroup pg; while(it != to) { if(it->binId() == BIN_ID_UNSET) continue; while(pg.size() <= size_t(it->binId())) pg.emplace_back(); pg[it->binId()].emplace_back(*it); ++it; } writePackGroup(pg); } void addLayer() { svg_layers_.emplace_back(header()); finished_ = false; } void finishLayer() { currentLayer() += "\n\n"; finished_ = true; } void save(const std::string& filepath) { size_t lyrc = svg_layers_.size() > 1? 1 : 0; size_t last = svg_layers_.size() > 1? svg_layers_.size() : 0; for(auto& lyr : svg_layers_) { std::fstream out(filepath + (lyrc > 0? std::to_string(lyrc) : "") + ".svg", std::fstream::out); if(out.is_open()) out << lyr; if(lyrc == last && !finished_) out << "\n\n"; out.flush(); out.close(); lyrc++; }; } private: std::string& currentLayer() { return svg_layers_.back(); } const std::string header() const { std::string svg_header = R"raw( )raw"; return svg_header; } }; } } #endif // SVGTOOLS_HPP