From 4ac7f6e8f14689cd5db2a9f2a426c9ab8ee5769d Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Wed, 23 Nov 2016 15:51:12 +0100 Subject: [PATCH] Refactoring: rename SVGExport to SLAPrint --- src/CMakeLists.txt | 2 +- src/slic3r.cpp | 12 +-- xs/src/libslic3r/PrintConfig.hpp | 4 +- .../libslic3r/{SVGExport.cpp => SLAPrint.cpp} | 98 +++++++++++-------- xs/src/libslic3r/SLAPrint.hpp | 46 +++++++++ xs/src/libslic3r/SVGExport.hpp | 33 ------- 6 files changed, 110 insertions(+), 85 deletions(-) rename xs/src/libslic3r/{SVGExport.cpp => SLAPrint.cpp} (68%) create mode 100644 xs/src/libslic3r/SLAPrint.hpp delete mode 100644 xs/src/libslic3r/SVGExport.hpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index efeaa41de4..9b704d5b0a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -67,10 +67,10 @@ add_library(libslic3r STATIC ${LIBDIR}/libslic3r/PrintConfig.cpp ${LIBDIR}/libslic3r/PrintObject.cpp ${LIBDIR}/libslic3r/PrintRegion.cpp + ${LIBDIR}/libslic3r/SLAPrint.cpp ${LIBDIR}/libslic3r/Surface.cpp ${LIBDIR}/libslic3r/SurfaceCollection.cpp ${LIBDIR}/libslic3r/SVG.cpp - ${LIBDIR}/libslic3r/SVGExport.cpp ${LIBDIR}/libslic3r/TriangleMesh.cpp ) add_library(admesh STATIC diff --git a/src/slic3r.cpp b/src/slic3r.cpp index 2ea600f4b9..f96b058624 100644 --- a/src/slic3r.cpp +++ b/src/slic3r.cpp @@ -2,7 +2,7 @@ #include "Model.hpp" #include "IO.hpp" #include "TriangleMesh.hpp" -#include "SVGExport.hpp" +#include "SLAPrint.hpp" #include "libslic3r.h" #include #include @@ -97,11 +97,11 @@ main(const int argc, const char **argv) } else if (cli_config.export_svg) { std::string outfile = cli_config.output.value; if (outfile.empty()) outfile = model->objects.front()->input_file + ".svg"; - - SVGExport svg_export(model->mesh()); - svg_export.mesh.repair(); - svg_export.config.apply(print_config, true); - svg_export.writeSVG(outfile); + + SLAPrint print(&*model); + print.config.apply(print_config, true); + print.slice(); + print.write_svg(outfile); printf("SVG file exported to %s\n", outfile.c_str()); } else { std::cerr << "error: only --export-svg and --export-obj are currently supported" << std::endl; diff --git a/xs/src/libslic3r/PrintConfig.hpp b/xs/src/libslic3r/PrintConfig.hpp index c672b46694..ef5af261e5 100644 --- a/xs/src/libslic3r/PrintConfig.hpp +++ b/xs/src/libslic3r/PrintConfig.hpp @@ -518,7 +518,7 @@ class FullPrintConfig }; }; -class SVGExportConfig +class SLAPrintConfig : public virtual StaticPrintConfig { public: @@ -530,7 +530,7 @@ class SVGExportConfig ConfigOptionFloatOrPercent support_material_extrusion_width; ConfigOptionFloat support_material_spacing; - SVGExportConfig() : StaticPrintConfig() { + SLAPrintConfig() : StaticPrintConfig() { this->set_defaults(); }; diff --git a/xs/src/libslic3r/SVGExport.cpp b/xs/src/libslic3r/SLAPrint.cpp similarity index 68% rename from xs/src/libslic3r/SVGExport.cpp rename to xs/src/libslic3r/SLAPrint.cpp index 66613ecfe3..a0a8c38a1f 100644 --- a/xs/src/libslic3r/SVGExport.cpp +++ b/xs/src/libslic3r/SLAPrint.cpp @@ -1,4 +1,4 @@ -#include "SVGExport.hpp" +#include "SLAPrint.hpp" #include "ClipperUtils.hpp" #include #include @@ -6,50 +6,61 @@ namespace Slic3r { void -SVGExport::writeSVG(const std::string &outputfile) +SLAPrint::slice() { + TriangleMesh mesh = this->model->mesh(); + mesh.repair(); + mesh.mirror_x(); + // align to origin taking raft into account - BoundingBoxf3 bb = this->mesh.bounding_box(); + BoundingBoxf3 bb = mesh.bounding_box(); if (this->config.raft_layers > 0) { bb.min.x -= this->config.raft_offset.value; bb.min.y -= this->config.raft_offset.value; bb.max.x += this->config.raft_offset.value; bb.max.y += this->config.raft_offset.value; } - this->mesh.translate(-bb.min.x, -bb.min.y, -bb.min.z); // align to origin - bb.translate(-bb.min.x, -bb.min.y, -bb.min.z); // align to origin - const Sizef3 size = bb.size(); + mesh.translate(-bb.min.x, -bb.min.y, -bb.min.z); // align to origin + bb.translate(-bb.min.x, -bb.min.y, -bb.min.z); // align to origin + this->size = bb.size(); // if we are generating a raft, first_layer_height will not affect mesh slicing - const float lh = this->config.layer_height.value; + const float lh = this->config.layer_height.value; const float first_lh = this->config.first_layer_height.value; // generate the list of Z coordinates for mesh slicing // (we slice each layer at half of its thickness) - std::vector slice_z, layer_z; + this->layers.clear(); { const float first_slice_lh = (this->config.raft_layers > 0) ? lh : first_lh; - slice_z.push_back(first_slice_lh/2); - layer_z.push_back(first_slice_lh); + this->layers.push_back(Layer(first_slice_lh/2, first_slice_lh)); } - while (layer_z.back() + lh/2 <= this->mesh.stl.stats.max.z) { - slice_z.push_back(layer_z.back() + lh/2); - layer_z.push_back(layer_z.back() + lh); + while (this->layers.back().print_z + lh/2 <= mesh.stl.stats.max.z) { + this->layers.push_back(Layer(this->layers.back().print_z + lh/2, this->layers.back().print_z + lh)); } - // perform the slicing - std::vector layers; - TriangleMeshSlicer(&this->mesh).slice(slice_z, &layers); + // perform slicing and generate layers + { + std::vector slice_z; + for (size_t i = 0; i < this->layers.size(); ++i) + slice_z.push_back(this->layers[i].slice_z); + + std::vector slices; + TriangleMeshSlicer(&mesh).slice(slice_z, &slices); + + for (size_t i = 0; i < slices.size(); ++i) + this->layers[i].slices = ExPolygonCollection(slices[i]); + } // generate support material - std::vector sm_pillars; + this->sm_pillars.clear(); ExPolygons overhangs; if (this->config.support_material) { // flatten and merge all the overhangs { Polygons pp; - for (std::vector::const_iterator it = layers.begin()+1; it != layers.end(); ++it) { - Polygons oh = diff(*it, *(it - 1)); + for (std::vector::const_iterator it = this->layers.begin()+1; it != this->layers.end(); ++it) { + Polygons oh = diff(it->slices, (it - 1)->slices); pp.insert(pp.end(), oh.begin(), oh.end()); } overhangs = union_ex(pp); @@ -79,17 +90,10 @@ SVGExport::writeSVG(const std::string &outputfile) bool object_hit = false; // check layers top-down - for (int i = layer_z.size()-1; i >= 0; --i) { + for (int i = this->layers.size()-1; i >= 0; --i) { // check whether point is void in this layer - bool is_void = true; - for (ExPolygons::const_iterator it = layers[i].begin(); it != layers[i].end(); ++it) { - if (it->contains(*p)) { - is_void = false; - break; - } - } - - if (is_void) { + if (!this->layers[i].slices.contains(*p)) { + // no slice contains the point, so it's in the void if (pillar.top_layer > 0) { // we have a pillar, so extend it pillar.bottom_layer = i + this->config.raft_layers; @@ -100,32 +104,36 @@ SVGExport::writeSVG(const std::string &outputfile) } else { if (pillar.top_layer > 0) { // we have a pillar which is not needed anymore, so store it and initialize a new potential pillar - sm_pillars.push_back(pillar); + this->sm_pillars.push_back(pillar); pillar = SupportPillar(*p); } object_hit = true; } } - if (pillar.top_layer > 0) sm_pillars.push_back(pillar); + if (pillar.top_layer > 0) this->sm_pillars.push_back(pillar); } } // generate a solid raft if requested // (do this after support material because we take support material shape into account) if (this->config.raft_layers > 0) { - ExPolygons raft = layers.front(); + ExPolygons raft = this->layers.front().slices; raft.insert(raft.end(), overhangs.begin(), overhangs.end()); // take support material into account raft = offset_ex(raft, scale_(this->config.raft_offset)); for (int i = this->config.raft_layers; i >= 1; --i) { - layer_z.insert(layer_z.begin(), first_lh + lh * (i-1)); - layers.insert(layers.begin(), raft); + this->layers.insert(this->layers.begin(), Layer(0, first_lh + lh * (i-1))); + this->layers.front().slices = raft; } // prepend total raft height to all sliced layers - for (int i = this->config.raft_layers; i < layer_z.size(); ++i) - layer_z[i] += first_lh + lh * (this->config.raft_layers-1); + for (int i = this->config.raft_layers; i < this->layers.size(); ++i) + this->layers[i].print_z += first_lh + lh * (this->config.raft_layers-1); } - +} + +void +SLAPrint::write_svg(const std::string &outputfile) const +{ double support_material_radius = this->config.support_material_extrusion_width.get_abs_value(this->config.layer_height)/2; FILE* f = fopen(outputfile.c_str(), "w"); @@ -134,11 +142,15 @@ SVGExport::writeSVG(const std::string &outputfile) "\n" "\n" "\n" - , size.x, size.y, SLIC3R_VERSION); + , this->size.x, this->size.y, SLIC3R_VERSION); - for (size_t i = 0; i < layer_z.size(); ++i) { - fprintf(f, "\t\n", i, layer_z[i]); - for (ExPolygons::const_iterator it = layers[i].begin(); it != layers[i].end(); ++it) { + for (size_t i = 0; i < this->layers.size(); ++i) { + const Layer &layer = this->layers[i]; + fprintf(f, "\t\n", i, + layer.print_z, layer.slice_z); + + const ExPolygons &slices = layer.slices.expolygons; + for (ExPolygons::const_iterator it = slices.begin(); it != slices.end(); ++it) { std::string pd; Polygons pp = *it; for (Polygons::const_iterator mp = pp.begin(); mp != pp.end(); ++mp) { @@ -159,13 +171,13 @@ SVGExport::writeSVG(const std::string &outputfile) // don't print support material in raft layers if (i >= this->config.raft_layers) { // look for support material pillars belonging to this layer - for (std::vector::const_iterator it = sm_pillars.begin(); it != sm_pillars.end(); ++it) { + for (std::vector::const_iterator it = this->sm_pillars.begin(); it != this->sm_pillars.end(); ++it) { if (!(it->top_layer >= i && it->bottom_layer <= i)) continue; // generate a conic tip float radius = fminf( support_material_radius, - (it->top_layer - i + 1) * lh + (it->top_layer - i + 1) * this->config.layer_height.value ); fprintf(f,"\t\t\n", diff --git a/xs/src/libslic3r/SLAPrint.hpp b/xs/src/libslic3r/SLAPrint.hpp new file mode 100644 index 0000000000..202eed8c2a --- /dev/null +++ b/xs/src/libslic3r/SLAPrint.hpp @@ -0,0 +1,46 @@ +#ifndef slic3r_SLAPrint_hpp_ +#define slic3r_SLAPrint_hpp_ + +#include "libslic3r.h" +#include "ExPolygon.hpp" +#include "ExPolygonCollection.hpp" +#include "Model.hpp" +#include "Point.hpp" +#include "PrintConfig.hpp" +#include "SVG.hpp" + +namespace Slic3r { + +class SLAPrint +{ + public: + SLAPrintConfig config; + + class Layer { + public: + ExPolygonCollection slices; + float slice_z, print_z; + + Layer(float _slice_z, float _print_z) : slice_z(_slice_z), print_z(_print_z) {}; + }; + std::vector layers; + + class SupportPillar : public Point { + public: + size_t top_layer, bottom_layer; + SupportPillar(const Point &p) : Point(p), top_layer(0), bottom_layer(0) {}; + }; + std::vector sm_pillars; + + SLAPrint(Model* _model) : model(_model) {}; + void slice(); + void write_svg(const std::string &outputfile) const; + + private: + Model* model; + Sizef3 size; +}; + +} + +#endif diff --git a/xs/src/libslic3r/SVGExport.hpp b/xs/src/libslic3r/SVGExport.hpp deleted file mode 100644 index ff1f1a1432..0000000000 --- a/xs/src/libslic3r/SVGExport.hpp +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef slic3r_SVGExport_hpp_ -#define slic3r_SVGExport_hpp_ - -#include "libslic3r.h" -#include "ExPolygon.hpp" -#include "PrintConfig.hpp" -#include "SVG.hpp" -#include "TriangleMesh.hpp" - -namespace Slic3r { - -class SVGExport -{ - public: - SVGExportConfig config; - TriangleMesh mesh; - - SVGExport(const TriangleMesh &mesh) : mesh(mesh) { - this->mesh.mirror_x(); - }; - void writeSVG(const std::string &outputfile); - - private: - class SupportPillar : public Point { - public: - size_t top_layer, bottom_layer; - SupportPillar(const Point &p) : Point(p), top_layer(0), bottom_layer(0) {}; - }; -}; - -} - -#endif