Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 4 additions & 15 deletions board.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,21 +82,13 @@ void Board::createLayers()

// start calculating the minimal board size

min_x = INFINITY;
max_x = -INFINITY;
min_y = INFINITY;
max_y = -INFINITY;

// Calculate the maximum possible room needed by the PCB traces, for tiling later.
const auto outline = prepared_layers.find("outline");
if (outline != prepared_layers.cend()) {
shared_ptr<Cutter> outline_mill = static_pointer_cast<Cutter>(get<1>(outline->second));
const auto& importer = get<0>(outline->second);
coordinate_type_fp tool_diameter = outline_mill->tool_diameter;
min_x = std::min(min_x, importer->get_min_x() - tool_diameter);
max_x = std::max(max_x, importer->get_max_x() + tool_diameter);
min_y = std::min(min_y, importer->get_min_y() - tool_diameter);
max_y = std::max(max_y, importer->get_max_y() + tool_diameter);
bounding_box = bg::return_buffer<box_type_fp>(importer->get_bounding_box(), tool_diameter);
} else {
for (const auto& layer_name : std::vector<std::string>{"front", "back"}) {
const auto current_layer = prepared_layers.find(layer_name);
Expand All @@ -116,10 +108,8 @@ void Board::createLayers()
// Figure out how much margin the extra passes might make.
extra_passes_margin = tool_diameter + (tool_diameter - overlap_width) * extra_passes;
}
min_x = std::min(min_x, importer->get_min_x() - extra_passes_margin - trace_mill->offset);
max_x = std::max(max_x, importer->get_max_x() + extra_passes_margin + trace_mill->offset);
min_y = std::min(min_y, importer->get_min_y() - extra_passes_margin - trace_mill->offset);
max_y = std::max(max_y, importer->get_max_y() + extra_passes_margin + trace_mill->offset);
auto current_bounding_box = bg::return_buffer<box_type_fp>(importer->get_bounding_box(), extra_passes_margin + trace_mill->offset);
bg::expand(bounding_box, current_bounding_box);
}
}
}
Expand All @@ -133,8 +123,7 @@ void Board::createLayers()

shared_ptr<Surface_vectorial> surface(new Surface_vectorial(
30,
min_x, max_x,
min_y, max_y,
bounding_box,
prepared_layer.first, outputdir, tsp_2opt,
mill_feed_direction, invert_gerbers,
render_paths_to_shapes || (prepared_layer.first == "outline")));
Expand Down
10 changes: 2 additions & 8 deletions board.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,7 @@ class Board
void set_margins(double margins) { margin = margins; }
coordinate_type_fp get_width();
coordinate_type_fp get_height();
coordinate_type_fp get_min_x() { return min_x; }
coordinate_type_fp get_max_x() { return max_x; }
coordinate_type_fp get_min_y() { return min_y; }
coordinate_type_fp get_max_y() { return max_y; }
const box_type_fp& get_bounding_box() const { return bounding_box; }
double get_layersnum() { return layers.size(); }

std::vector<std::string> list_layers();
Expand All @@ -80,10 +77,7 @@ class Board
const bool invert_gerbers;
const bool render_paths_to_shapes;

coordinate_type_fp min_x;
coordinate_type_fp max_x;
coordinate_type_fp min_y;
coordinate_type_fp max_y;
box_type_fp bounding_box{{INFINITY, INFINITY}, {-INFINITY, -INFINITY}};

/* The Layer gets constructed from data prepared in
* prepareLayer after the size calculations are done in createLayers.
Expand Down
19 changes: 5 additions & 14 deletions gerberimporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,20 +78,11 @@ bool GerberImporter::load_file(const string& path) {
return project->file[0] != NULL;
}

gdouble GerberImporter::get_min_x() const {
return project->file[0]->image->info->min_x;
}

gdouble GerberImporter::get_max_x() const {
return project->file[0]->image->info->max_x;
}

gdouble GerberImporter::get_min_y() const {
return project->file[0]->image->info->min_y;
}

gdouble GerberImporter::get_max_y() const {
return project->file[0]->image->info->max_y;
box_type_fp GerberImporter::get_bounding_box() const {
return box_type_fp{
{project->file[0]->image->info->min_x, project->file[0]->image->info->min_y},
{project->file[0]->image->info->max_x, project->file[0]->image->info->max_y}
};
}

// Draw a regular polygon with outer diameter as specified and center. The
Expand Down
5 changes: 1 addition & 4 deletions gerberimporter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,7 @@ class GerberImporter {
bool load_file(const std::string& path);
virtual ~GerberImporter();

virtual gdouble get_min_x() const;
virtual gdouble get_max_x() const;
virtual gdouble get_min_y() const;
virtual gdouble get_max_y() const;
virtual box_type_fp get_bounding_box() const;

virtual std::pair<multi_polygon_type_fp, std::map<coordinate_type_fp, multi_linestring_type_fp>> render(
bool fill_closed_lines,
Expand Down
42 changes: 21 additions & 21 deletions gerberimporter_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,31 +65,30 @@ void cairo_render(const GerberImporter& g, Cairo::RefPtr<Cairo::ImageSurface> su

// Given a gerber file, return a pixmap that is a rasterized version of that
// gerber. Uses gerbv's built-in utils.
void bitmap_from_gerber(const GerberImporter& g, double min_x, double min_y,
void bitmap_from_gerber(const GerberImporter& g, const point_type_fp& min_corner,
Cairo::RefPtr<Cairo::ImageSurface> cairo_surface) {
//Render
GdkColor blue = {0,
((OLD_COLOR >> 16) & 0xff) * 0x101,
((OLD_COLOR >> 8) & 0xff) * 0x101,
((OLD_COLOR ) & 0xff) * 0x101};
cairo_render(g, cairo_surface, dpi, min_x, min_y, blue, GERBV_RENDER_TYPE_CAIRO_HIGH_QUALITY);
cairo_render(g, cairo_surface, dpi, min_corner.x(), min_corner.y(), blue, GERBV_RENDER_TYPE_CAIRO_HIGH_QUALITY);
}

string render_svg(const multi_polygon_type_fp& polys, double min_x, double min_y, double height) {
string render_svg(const multi_polygon_type_fp& polys, const box_type_fp& bounding_box) {
std::stringstream svg_stream;
{
box_type_fp svg_bounding_box;
bg::envelope(polys, svg_bounding_box);
const double svg_width = (svg_bounding_box.max_corner().x() - svg_bounding_box.min_corner().x());
const double svg_height = (svg_bounding_box.max_corner().y() - svg_bounding_box.min_corner().y());
const double max_y = min_y + height;
const string svg_dimensions =
str(boost::format("width=\"%1%\" height=\"%2%\" viewBox=\"%3% %4% %5% %6%\"")
% "100%"
% "100%"
% ((min_x - svg_bounding_box.min_corner().x()) * dpi)
% ((bounding_box.min_corner().x() - svg_bounding_box.min_corner().x()) * dpi)
// max and not min because the origin is in a different corner for svg vs gbr
% ((svg_bounding_box.max_corner().y() - max_y) * dpi)
% ((svg_bounding_box.max_corner().y() - bounding_box.max_corner().y()) * dpi)
% (svg_width * dpi)
% (svg_height * dpi));
bg::svg_mapper<point_type_fp> svg(svg_stream,
Expand All @@ -107,9 +106,9 @@ string render_svg(const multi_polygon_type_fp& polys, double min_x, double min_y
}

// Convert the gerber to a boost geometry and then convert that to SVG and then rasterize to a bitmap.
void boost_bitmap_from_gerber(const multi_polygon_type_fp& polys, double min_x, double min_y, double height,
void boost_bitmap_from_gerber(const multi_polygon_type_fp& polys, const box_type_fp& bounding_box,
Cairo::RefPtr<Cairo::ImageSurface> cairo_surface) {
string svg_string = render_svg(polys, min_x, min_y, height);
string svg_string = render_svg(polys, bounding_box);
//Now we have the svg, let's make a cairo surface like above.
GError* gerror = nullptr;
RsvgHandle *rsvg_handle = rsvg_handle_new_from_data(reinterpret_cast<const guint8*>(svg_string.c_str()),
Expand Down Expand Up @@ -166,6 +165,14 @@ void write_to_png(Cairo::RefPtr<Cairo::ImageSurface> cairo_surface, const string
cairo_surface->write_to_png(str(boost::format("%s.png") % gerber_file).c_str());
}

coordinate_type_fp width(box_type_fp box) {
return box.max_corner().x() - box.min_corner().x();
}

coordinate_type_fp height(box_type_fp box) {
return box.max_corner().y() - box.min_corner().y();
}

// Compare gerbv image against boost generated image.
void test_one(const string& gerber_file, double max_error_rate) {
string gerber_path = gerber_directory;
Expand All @@ -176,13 +183,10 @@ void test_one(const string& gerber_file, double max_error_rate) {
multi_polygon_type_fp polys = g.render(false, true, 360).first;
box_type_fp bounding_box;
bg::envelope(polys, bounding_box);
double min_x = std::min(g.get_min_x(), bounding_box.min_corner().x());
double min_y = std::min(g.get_min_y(), bounding_box.min_corner().y());
double max_x = std::max(g.get_max_x(), bounding_box.max_corner().x());
double max_y = std::max(g.get_max_y(), bounding_box.max_corner().y());
Cairo::RefPtr<Cairo::ImageSurface> cairo_surface = create_cairo_surface((max_x - min_x) * dpi, (max_y - min_y) * dpi);
bitmap_from_gerber(g, min_x, min_y, cairo_surface);
boost_bitmap_from_gerber(polys, min_x, min_y, max_y-min_y, cairo_surface);
bg::expand(bounding_box, g.get_bounding_box());
Cairo::RefPtr<Cairo::ImageSurface> cairo_surface = create_cairo_surface(width(bounding_box) * dpi, height(bounding_box) * dpi);
bitmap_from_gerber(g, bounding_box.min_corner(), cairo_surface);
boost_bitmap_from_gerber(polys, bounding_box, cairo_surface);
map<uint32_t, size_t> counts = get_counts(cairo_surface);
size_t background = 0, errors = 0, both = 0;
for (const auto& kv : counts) {
Expand Down Expand Up @@ -224,12 +228,8 @@ void test_visual(const string& gerber_file, bool fill_closed_lines, double min_s
multi_polygon_type_fp polys = g.render(fill_closed_lines, true, 30).first;
box_type_fp bounding_box;
bg::envelope(polys, bounding_box);
double min_x = bounding_box.min_corner().x();
double min_y = bounding_box.min_corner().y();
double max_x = bounding_box.max_corner().x();
double max_y = bounding_box.max_corner().y();
Cairo::RefPtr<Cairo::ImageSurface> cairo_surface = create_cairo_surface((max_x - min_x) * dpi, (max_y - min_y) * dpi);
boost_bitmap_from_gerber(polys, min_x, min_y, max_y-min_y, cairo_surface);
Cairo::RefPtr<Cairo::ImageSurface> cairo_surface = create_cairo_surface(width(bounding_box) * dpi, height(bounding_box) * dpi);
boost_bitmap_from_gerber(polys, bounding_box, cairo_surface);
auto counts = get_counts(cairo_surface);
size_t total = 0, marked = 0l;
for (const auto& kv : counts) {
Expand Down
12 changes: 5 additions & 7 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -356,13 +356,11 @@ void do_pcb2gcode(int argc, const char* argv[]) {
if (!importer->load_file(vm["drill"].as<string>())) {
options::maybe_throw("ERROR.", ERR_INVALIDPARAMETER);
}
min = point_type_fp( importer->get_min_x(), importer->get_min_y() );
max = point_type_fp( importer->get_max_x(), importer->get_max_y() );
}
else
{
min = point_type_fp( board->get_min_x(), board->get_min_y() );
max = point_type_fp( board->get_max_x(), board->get_max_y() );
min = importer->get_bounding_box().min_corner();
max = importer->get_bounding_box().max_corner();
} else {
min = board->get_bounding_box().min_corner();
max = board->get_bounding_box().max_corner();
}

ExcellonProcessor ep(vm, min, max);
Expand Down
23 changes: 10 additions & 13 deletions ngc_exporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,15 +82,12 @@ void NGC_Exporter::export_all(boost::program_options::variables_map& options)
//set imperial/metric conversion factor for output coordinates depending on metricoutput option
cfactor = bMetricoutput ? 25.4 : 1;

if( options["zero-start"].as<bool>() )
{
xoffset = board->get_min_x();
yoffset = board->get_min_y();
}
else
{
xoffset = 0;
yoffset = 0;
if (options["zero-start"].as<bool>()) {
xoffset = board->get_bounding_box().min_corner().x();
yoffset = board->get_bounding_box().min_corner().y();
} else {
xoffset = 0;
yoffset = 0;
}
xoffset -= options["x-offset"].as<Length>().asInch(bMetricinput ? 1.0/25.4 : 1);
yoffset -= options["y-offset"].as<Length>().asInch(bMetricinput ? 1.0/25.4 : 1);
Expand All @@ -100,11 +97,11 @@ void NGC_Exporter::export_all(boost::program_options::variables_map& options)
for ( string layername : board->list_layers() )
{
if (options["zero-start"].as<bool>()) {
xoffset = board->get_min_x();
yoffset = board->get_min_y();
xoffset = board->get_bounding_box().min_corner().x();
yoffset = board->get_bounding_box().min_corner().y();
} else {
xoffset = 0;
yoffset = 0;
xoffset = 0;
yoffset = 0;
}
xoffset -= options["x-offset"].as<Length>().asInch(bMetricinput ? 1.0/25.4 : 1);
yoffset -= options["y-offset"].as<Length>().asInch(bMetricinput ? 1.0/25.4 : 1);
Expand Down
6 changes: 2 additions & 4 deletions surface_vectorial.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,12 @@ using std::dynamic_pointer_cast;
unsigned int Surface_vectorial::debug_image_index = 0;

Surface_vectorial::Surface_vectorial(unsigned int points_per_circle,
coordinate_type_fp min_x, coordinate_type_fp max_x,
coordinate_type_fp min_y, coordinate_type_fp max_y,
const box_type_fp& bounding_box,
string name, string outputdir,
bool tsp_2opt, MillFeedDirection::MillFeedDirection mill_feed_direction,
bool invert_gerbers, bool render_paths_to_shapes) :
points_per_circle(points_per_circle),
bounding_box(box_type_fp(point_type_fp(min_x, min_y),
point_type_fp(max_x, max_y))),
bounding_box(bounding_box),
name(name),
outputdir(outputdir),
tsp_2opt(tsp_2opt),
Expand Down
5 changes: 3 additions & 2 deletions surface_vectorial.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,9 @@
class Surface_vectorial: private boost::noncopyable {
public:
Surface_vectorial(unsigned int points_per_circle,
coordinate_type_fp min_x, coordinate_type_fp max_x, coordinate_type_fp min_y, coordinate_type_fp max_y,
std::string name, std::string outputdir, bool tsp_2opt, MillFeedDirection::MillFeedDirection mill_feed_direction,
const box_type_fp& bounding_box,
std::string name, std::string outputdir, bool tsp_2opt,
MillFeedDirection::MillFeedDirection mill_feed_direction,
bool invert_gerbers, bool render_paths_to_shapes);

std::vector<std::pair<coordinate_type_fp, multi_linestring_type_fp>> get_toolpath(
Expand Down
Loading