kopia lustrzana https://github.com/jaseg/gerbolyze
Add KiCAD sexp output
rodzic
52dcceb87f
commit
eac89409b8
7
Makefile
7
Makefile
|
@ -16,6 +16,7 @@ SOURCES := src/svg_color.cpp \
|
|||
src/main.cpp \
|
||||
src/out_svg.cpp \
|
||||
src/out_gerber.cpp \
|
||||
src/out_sexp.cpp \
|
||||
src/out_flattener.cpp \
|
||||
src/lambda_sink.cpp \
|
||||
|
||||
|
@ -37,7 +38,9 @@ CXXFLAGS += $(shell $(PKG_CONFIG) --cflags pangocairo pugixml opencv4)
|
|||
LDFLAGS := -lm -lc -lstdc++
|
||||
LDFLAGS += $(shell $(PKG_CONFIG) --libs pangocairo pugixml opencv4)
|
||||
|
||||
all: $(BUILDDIR)/svg-render
|
||||
TARGET := svg-render
|
||||
|
||||
all: $(BUILDDIR)/$(TARGET)
|
||||
|
||||
test.gbr test.svg &: render
|
||||
./render test.svg > test.gbr
|
||||
|
@ -46,7 +49,7 @@ $(BUILDDIR)/%.o: %.cpp
|
|||
@mkdir -p $(dir $@)
|
||||
$(CXX) -c $(CXXFLAGS) $(CXXFLAGS) $(INCLUDES) -o $@ $^
|
||||
|
||||
$(BUILDDIR)/svg-render: $(SOURCES:%.cpp=$(BUILDDIR)/%.o) $(BUILDDIR)/upstream/cpp-base64/base64.o
|
||||
$(BUILDDIR)/$(TARGET): $(SOURCES:%.cpp=$(BUILDDIR)/%.o) $(BUILDDIR)/upstream/cpp-base64/base64.o
|
||||
@mkdir -p $(dir $@)
|
||||
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $^
|
||||
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
build/svg-render 2.0
|
||||
|
||||
Usage: build/svg-render [options]... [input_file] [output_file]
|
||||
|
||||
Specify "-" for stdin/stdout.
|
||||
|
||||
-h, --help
|
||||
Print help and exit
|
||||
-v, --version
|
||||
Print version and exit
|
||||
-o, --format
|
||||
Output format. Supported: gerber, svg, s-exp (KiCAD S-Expression)
|
||||
-p, --precision
|
||||
Number of decimal places use for exported coordinates (gerber: 1-9,
|
||||
SVG: 0-*)
|
||||
--clear-color
|
||||
SVG color to use for "clear" areas (default: white)
|
||||
--dark-color
|
||||
SVG color to use for "dark" areas (default: black)
|
||||
-d, --trace-space
|
||||
Minimum feature size of elements in vectorized graphics
|
||||
(trace/space) in mm. Default: 0.1mm.
|
||||
--no-header
|
||||
Do not export output format header/footer, only export the
|
||||
primitives themselves
|
||||
--flatten
|
||||
Flatten output so it only consists of non-overlapping white
|
||||
polygons. This perform composition at the vector level. Potentially slow.
|
||||
--no-flatten
|
||||
Disable automatic flattening for KiCAD S-Exp export
|
||||
-g, --only-groups
|
||||
Comma-separated list of group IDs to export.
|
||||
-b, --vectorizer
|
||||
Vectorizer to use for bitmap images. One of poisson-disc (default),
|
||||
hex-grid, square-grid, binary-contours, dev-null.
|
||||
--vectorizer-map
|
||||
Map from image element id to vectorizer. Overrides --vectorizer.
|
||||
Format: id1=vectorizer,id2=vectorizer,...
|
||||
--force-svg
|
||||
Force SVG input irrespective of file name
|
||||
--force-png
|
||||
Force bitmap graphics input irrespective of file name
|
||||
-s, --size
|
||||
Bitmap mode only: Physical size of output image in mm. Format: 12.34x56.78
|
||||
--sexp-mod-name
|
||||
Module name for KiCAD S-Exp output
|
||||
--sexp-layer
|
||||
Layer for KiCAD S-Exp output
|
||||
-a, --preserve-aspect-ratio
|
||||
Bitmap mode only: Preserve aspect ratio of image. Allowed values
|
||||
are meet, slice. Can also parse full SVG preserveAspectRatio syntax.
|
||||
--no-usvg
|
||||
Do not preprocess input using usvg (do not use unless you know
|
||||
*exactly* what you're doing)
|
||||
-e, --exclude-groups
|
||||
Comma-separated list of group IDs to exclude from export. Takes
|
||||
precedence over --only-groups.
|
|
@ -220,6 +220,25 @@ namespace gerbolyze {
|
|||
d2p m_offset;
|
||||
};
|
||||
|
||||
class KicadSexpOutput : public StreamPolygonSink {
|
||||
public:
|
||||
KicadSexpOutput(std::ostream &out, std::string mod_name, std::string layer, bool only_polys=false, std::string m_ref_text="", std::string m_val_text="G*****", d2p ref_pos={0,10}, d2p val_pos={0,-10});
|
||||
virtual ~KicadSexpOutput() {}
|
||||
virtual KicadSexpOutput &operator<<(const Polygon &poly);
|
||||
virtual KicadSexpOutput &operator<<(GerberPolarityToken pol);
|
||||
virtual void header_impl(d2p origin, d2p size);
|
||||
virtual void footer_impl();
|
||||
|
||||
private:
|
||||
std::string m_mod_name;
|
||||
std::string m_layer;
|
||||
std::string m_ref_text;
|
||||
std::string m_val_text;
|
||||
d2p m_ref_pos;
|
||||
d2p m_val_pos;
|
||||
};
|
||||
|
||||
|
||||
/* TODO
|
||||
class SExpOutput : public StreamPolygonSink {
|
||||
public:
|
||||
|
|
25
src/main.cpp
25
src/main.cpp
|
@ -46,6 +46,9 @@ int main(int argc, char **argv) {
|
|||
{"flatten", {"--flatten"},
|
||||
"Flatten output so it only consists of non-overlapping white polygons. This perform composition at the vector level. Potentially slow.",
|
||||
0},
|
||||
{"no_flatten", {"--no-flatten"},
|
||||
"Disable automatic flattening for KiCAD S-Exp export",
|
||||
0},
|
||||
{"only_groups", {"-g", "--only-groups"},
|
||||
"Comma-separated list of group IDs to export.",
|
||||
1},
|
||||
|
@ -64,6 +67,12 @@ int main(int argc, char **argv) {
|
|||
{"size", {"-s", "--size"},
|
||||
"Bitmap mode only: Physical size of output image in mm. Format: 12.34x56.78",
|
||||
1},
|
||||
{"sexp_mod_name", {"--sexp-mod-name"},
|
||||
"Module name for KiCAD S-Exp output",
|
||||
1},
|
||||
{"sexp_layer", {"--sexp-layer"},
|
||||
"Layer for KiCAD S-Exp output",
|
||||
1},
|
||||
{"preserve_aspect_ratio", {"-a", "--preserve-aspect-ratio"},
|
||||
"Bitmap mode only: Preserve aspect ratio of image. Allowed values are meet, slice. Can also parse full SVG preserveAspectRatio syntax.",
|
||||
1},
|
||||
|
@ -151,6 +160,7 @@ int main(int argc, char **argv) {
|
|||
string fmt = args["ofmt"] ? args["ofmt"] : "gerber";
|
||||
transform(fmt.begin(), fmt.end(), fmt.begin(), [](unsigned char c){ return std::tolower(c); }); /* c++ yeah */
|
||||
|
||||
bool force_flatten = false;
|
||||
PolygonSink *sink = nullptr;
|
||||
PolygonSink *flattener = nullptr;
|
||||
if (fmt == "svg") {
|
||||
|
@ -161,6 +171,17 @@ int main(int argc, char **argv) {
|
|||
} else if (fmt == "gbr" || fmt == "grb" || fmt == "gerber") {
|
||||
sink = new SimpleGerberOutput(*out_f, only_polys, 4, precision);
|
||||
|
||||
} else if (fmt == "s-exp" || fmt == "sexp" || fmt == "kicad") {
|
||||
if (!args["sexp_mod_name"] || !args["sexp_layer"]) {
|
||||
cerr << "--sexp-mod-name and --sexp-layer must be given for sexp export" << endl;
|
||||
argagg::fmt_ostream fmt(cerr);
|
||||
fmt << usage.str() << argparser;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
sink = new KicadSexpOutput(*out_f, args["sexp_mod_name"], args["sexp_layer"], only_polys);
|
||||
force_flatten = true;
|
||||
|
||||
} else {
|
||||
cerr << "Unknown output format \"" << fmt << "\"" << endl;
|
||||
argagg::fmt_ostream fmt(cerr);
|
||||
|
@ -168,7 +189,7 @@ int main(int argc, char **argv) {
|
|||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (args["flatten"]) {
|
||||
if (args["flatten"] || (force_flatten && !args["no_flatten"])) {
|
||||
flattener = new Flattener(*sink);
|
||||
}
|
||||
|
||||
|
@ -294,7 +315,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
if (args["skip_usvg"]) {
|
||||
cerr << "skippint usvg" << endl;
|
||||
cerr << "skipping usvg" << endl;
|
||||
frob = barf;
|
||||
|
||||
} else {
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* This file is part of gerbolyze, a vector image preprocessing toolchain
|
||||
* Copyright (C) 2021 Jan Sebastian Götte <gerbolyze@jaseg.de>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <gerbolyze.hpp>
|
||||
#include <svg_import_defs.h>
|
||||
#include <ctime>
|
||||
|
||||
using namespace gerbolyze;
|
||||
using namespace std;
|
||||
|
||||
|
||||
KicadSexpOutput::KicadSexpOutput(ostream &out, string mod_name, string layer, bool only_polys, string ref_text, string val_text, d2p ref_pos, d2p val_pos)
|
||||
: StreamPolygonSink(out, only_polys),
|
||||
m_mod_name(mod_name),
|
||||
m_layer(layer),
|
||||
m_val_text(val_text),
|
||||
m_ref_pos(ref_pos),
|
||||
m_val_pos(val_pos)
|
||||
{
|
||||
if (ref_text.empty()) {
|
||||
m_ref_text = mod_name;
|
||||
} else {
|
||||
m_ref_text = ref_text;
|
||||
}
|
||||
}
|
||||
|
||||
void KicadSexpOutput::header_impl(d2p, d2p) {
|
||||
auto tedit = std::time(0);
|
||||
m_out << "(module " << m_mod_name << " (layer F.Cu) (tedit " << std::hex << std::setfill('0') << std::setw(8) << tedit << ")" << endl;
|
||||
m_out << " (fp_text reference " << m_ref_text << " (at " << m_ref_pos[0] << " " << m_ref_pos[1] << ") (layer F.SilkS) hide" << endl;
|
||||
m_out << " (effects (font (size 1 1) (thickness 0.15)))" << endl;
|
||||
m_out << " )" << endl;
|
||||
m_out << " (fp_text value " << m_val_text << " (at " << m_val_pos[0] << " " << m_val_pos[1] << ") (layer F.SilkS) hide" << endl;
|
||||
m_out << " (effects (font (size 1 1) (thickness 0.15)))" << endl;
|
||||
m_out << " )" << endl;
|
||||
}
|
||||
|
||||
KicadSexpOutput &KicadSexpOutput::operator<<(GerberPolarityToken pol) {
|
||||
if (pol == GRB_POL_CLEAR) {
|
||||
cerr << "Warning: clear polarity not supported since KiCAD manages to have an even worse graphics model than gerber, except it can't excuse itself by its age..... -.-" << endl;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
KicadSexpOutput &KicadSexpOutput::operator<<(const Polygon &poly) {
|
||||
if (poly.size() < 3) {
|
||||
cerr << "Warning: " << poly.size() << "-element polygon passed to KicadSexpOutput" << endl;
|
||||
return *this;
|
||||
}
|
||||
|
||||
m_out << " (fp_poly (pts";
|
||||
for (auto &p : poly) {
|
||||
m_out << " (xy " << p[0] << " " << p[1] << ")";
|
||||
}
|
||||
m_out << ")";
|
||||
m_out << " (layer " << m_layer << ") (width 0))" << endl;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void KicadSexpOutput::footer_impl() {
|
||||
m_out << ")" << endl;
|
||||
}
|
||||
|
||||
|
Ładowanie…
Reference in New Issue