Welcome to mirror list, hosted at ThFree Co, Russian Federation.

svgtools.hpp « tools « libnest2d « src « xs - github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 776dd5a1a8a4a2a406d4b774ded39e61ea7cbe8c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#ifndef SVGTOOLS_HPP
#define SVGTOOLS_HPP

#include <iostream>
#include <fstream>
#include <string>

#include <libnest2d/libnest2d.hpp>

namespace libnest2d { namespace svg {

template<class RawShape>
class SVGWriter {
    using Item = _Item<RawShape>;
    using Coord = TCoord<TPoint<RawShape>>;
    using Box = _Box<TPoint<RawShape>>;
    using PackGroup = _PackGroup<RawShape>;

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<std::string> svg_layers_;
    bool finished_ = false;
public:

    SVGWriter(const Config& conf = Config()):
        conf_(conf) {}

    void setSize(const Box& box) {
        conf_.height = static_cast<double>(box.height()) /
                conf_.mm_in_coord_units;
        conf_.width = static_cast<double>(box.width()) /
                conf_.mm_in_coord_units;
    }

    void writeItem(const Item& item) {
        if(svg_layers_.empty()) addLayer();
        auto tsh = item.transformedShape();
        if(conf_.origo_location == BOTTOMLEFT) {
            auto d = static_cast<Coord>(
                        std::round(conf_.height*conf_.mm_in_coord_units) );

            auto& contour = shapelike::getContour(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<Formats::SVG>(tsh,
                                            1.0/conf_.mm_in_coord_units) + "\n";
    }

    void writePackGroup(const PackGroup& result) {
        for(auto r : result) {
            addLayer();
            for(Item& sh : r) {
                writeItem(sh);
            }
            finishLayer();
        }
    }

    void addLayer() {
        svg_layers_.emplace_back(header());
        finished_ = false;
    }

    void finishLayer() {
        currentLayer() += "\n</svg>\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</svg>\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(<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg height=")raw";
        svg_header += std::to_string(conf_.height) + "\" width=\"" + std::to_string(conf_.width) + "\" ";
        svg_header += R"raw(xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">)raw";
        return svg_header;
    }

};

}
}

#endif // SVGTOOLS_HPP