Refactoring: rename SVGExport to SLAPrint

This commit is contained in:
Alessandro Ranellucci 2016-11-23 15:51:12 +01:00
parent 893fc2343f
commit 4ac7f6e8f1
6 changed files with 110 additions and 85 deletions

View File

@ -67,10 +67,10 @@ add_library(libslic3r STATIC
${LIBDIR}/libslic3r/PrintConfig.cpp ${LIBDIR}/libslic3r/PrintConfig.cpp
${LIBDIR}/libslic3r/PrintObject.cpp ${LIBDIR}/libslic3r/PrintObject.cpp
${LIBDIR}/libslic3r/PrintRegion.cpp ${LIBDIR}/libslic3r/PrintRegion.cpp
${LIBDIR}/libslic3r/SLAPrint.cpp
${LIBDIR}/libslic3r/Surface.cpp ${LIBDIR}/libslic3r/Surface.cpp
${LIBDIR}/libslic3r/SurfaceCollection.cpp ${LIBDIR}/libslic3r/SurfaceCollection.cpp
${LIBDIR}/libslic3r/SVG.cpp ${LIBDIR}/libslic3r/SVG.cpp
${LIBDIR}/libslic3r/SVGExport.cpp
${LIBDIR}/libslic3r/TriangleMesh.cpp ${LIBDIR}/libslic3r/TriangleMesh.cpp
) )
add_library(admesh STATIC add_library(admesh STATIC

View File

@ -2,7 +2,7 @@
#include "Model.hpp" #include "Model.hpp"
#include "IO.hpp" #include "IO.hpp"
#include "TriangleMesh.hpp" #include "TriangleMesh.hpp"
#include "SVGExport.hpp" #include "SLAPrint.hpp"
#include "libslic3r.h" #include "libslic3r.h"
#include <cstdio> #include <cstdio>
#include <string> #include <string>
@ -98,10 +98,10 @@ main(const int argc, const char **argv)
std::string outfile = cli_config.output.value; std::string outfile = cli_config.output.value;
if (outfile.empty()) outfile = model->objects.front()->input_file + ".svg"; if (outfile.empty()) outfile = model->objects.front()->input_file + ".svg";
SVGExport svg_export(model->mesh()); SLAPrint print(&*model);
svg_export.mesh.repair(); print.config.apply(print_config, true);
svg_export.config.apply(print_config, true); print.slice();
svg_export.writeSVG(outfile); print.write_svg(outfile);
printf("SVG file exported to %s\n", outfile.c_str()); printf("SVG file exported to %s\n", outfile.c_str());
} else { } else {
std::cerr << "error: only --export-svg and --export-obj are currently supported" << std::endl; std::cerr << "error: only --export-svg and --export-obj are currently supported" << std::endl;

View File

@ -518,7 +518,7 @@ class FullPrintConfig
}; };
}; };
class SVGExportConfig class SLAPrintConfig
: public virtual StaticPrintConfig : public virtual StaticPrintConfig
{ {
public: public:
@ -530,7 +530,7 @@ class SVGExportConfig
ConfigOptionFloatOrPercent support_material_extrusion_width; ConfigOptionFloatOrPercent support_material_extrusion_width;
ConfigOptionFloat support_material_spacing; ConfigOptionFloat support_material_spacing;
SVGExportConfig() : StaticPrintConfig() { SLAPrintConfig() : StaticPrintConfig() {
this->set_defaults(); this->set_defaults();
}; };

View File

@ -1,4 +1,4 @@
#include "SVGExport.hpp" #include "SLAPrint.hpp"
#include "ClipperUtils.hpp" #include "ClipperUtils.hpp"
#include <iostream> #include <iostream>
#include <cstdio> #include <cstdio>
@ -6,19 +6,23 @@
namespace Slic3r { namespace Slic3r {
void 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 // align to origin taking raft into account
BoundingBoxf3 bb = this->mesh.bounding_box(); BoundingBoxf3 bb = mesh.bounding_box();
if (this->config.raft_layers > 0) { if (this->config.raft_layers > 0) {
bb.min.x -= this->config.raft_offset.value; bb.min.x -= this->config.raft_offset.value;
bb.min.y -= this->config.raft_offset.value; bb.min.y -= this->config.raft_offset.value;
bb.max.x += this->config.raft_offset.value; bb.max.x += this->config.raft_offset.value;
bb.max.y += 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 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 bb.translate(-bb.min.x, -bb.min.y, -bb.min.z); // align to origin
const Sizef3 size = bb.size(); this->size = bb.size();
// if we are generating a raft, first_layer_height will not affect mesh slicing // 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;
@ -26,30 +30,37 @@ SVGExport::writeSVG(const std::string &outputfile)
// generate the list of Z coordinates for mesh slicing // generate the list of Z coordinates for mesh slicing
// (we slice each layer at half of its thickness) // (we slice each layer at half of its thickness)
std::vector<float> slice_z, layer_z; this->layers.clear();
{ {
const float first_slice_lh = (this->config.raft_layers > 0) ? lh : first_lh; const float first_slice_lh = (this->config.raft_layers > 0) ? lh : first_lh;
slice_z.push_back(first_slice_lh/2); this->layers.push_back(Layer(first_slice_lh/2, first_slice_lh));
layer_z.push_back(first_slice_lh);
} }
while (layer_z.back() + lh/2 <= this->mesh.stl.stats.max.z) { while (this->layers.back().print_z + lh/2 <= mesh.stl.stats.max.z) {
slice_z.push_back(layer_z.back() + lh/2); this->layers.push_back(Layer(this->layers.back().print_z + lh/2, this->layers.back().print_z + lh));
layer_z.push_back(layer_z.back() + lh);
} }
// perform the slicing // perform slicing and generate layers
std::vector<ExPolygons> layers; {
TriangleMeshSlicer(&this->mesh).slice(slice_z, &layers); std::vector<float> slice_z;
for (size_t i = 0; i < this->layers.size(); ++i)
slice_z.push_back(this->layers[i].slice_z);
std::vector<ExPolygons> 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 // generate support material
std::vector<SupportPillar> sm_pillars; this->sm_pillars.clear();
ExPolygons overhangs; ExPolygons overhangs;
if (this->config.support_material) { if (this->config.support_material) {
// flatten and merge all the overhangs // flatten and merge all the overhangs
{ {
Polygons pp; Polygons pp;
for (std::vector<ExPolygons>::const_iterator it = layers.begin()+1; it != layers.end(); ++it) { for (std::vector<Layer>::const_iterator it = this->layers.begin()+1; it != this->layers.end(); ++it) {
Polygons oh = diff(*it, *(it - 1)); Polygons oh = diff(it->slices, (it - 1)->slices);
pp.insert(pp.end(), oh.begin(), oh.end()); pp.insert(pp.end(), oh.begin(), oh.end());
} }
overhangs = union_ex(pp); overhangs = union_ex(pp);
@ -79,17 +90,10 @@ SVGExport::writeSVG(const std::string &outputfile)
bool object_hit = false; bool object_hit = false;
// check layers top-down // 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 // check whether point is void in this layer
bool is_void = true; if (!this->layers[i].slices.contains(*p)) {
for (ExPolygons::const_iterator it = layers[i].begin(); it != layers[i].end(); ++it) { // no slice contains the point, so it's in the void
if (it->contains(*p)) {
is_void = false;
break;
}
}
if (is_void) {
if (pillar.top_layer > 0) { if (pillar.top_layer > 0) {
// we have a pillar, so extend it // we have a pillar, so extend it
pillar.bottom_layer = i + this->config.raft_layers; pillar.bottom_layer = i + this->config.raft_layers;
@ -100,32 +104,36 @@ SVGExport::writeSVG(const std::string &outputfile)
} else { } else {
if (pillar.top_layer > 0) { if (pillar.top_layer > 0) {
// we have a pillar which is not needed anymore, so store it and initialize a new potential pillar // 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); pillar = SupportPillar(*p);
} }
object_hit = true; 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 // generate a solid raft if requested
// (do this after support material because we take support material shape into account) // (do this after support material because we take support material shape into account)
if (this->config.raft_layers > 0) { 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.insert(raft.end(), overhangs.begin(), overhangs.end()); // take support material into account
raft = offset_ex(raft, scale_(this->config.raft_offset)); raft = offset_ex(raft, scale_(this->config.raft_offset));
for (int i = this->config.raft_layers; i >= 1; --i) { for (int i = this->config.raft_layers; i >= 1; --i) {
layer_z.insert(layer_z.begin(), first_lh + lh * (i-1)); this->layers.insert(this->layers.begin(), Layer(0, first_lh + lh * (i-1)));
layers.insert(layers.begin(), raft); this->layers.front().slices = raft;
} }
// prepend total raft height to all sliced layers // prepend total raft height to all sliced layers
for (int i = this->config.raft_layers; i < layer_z.size(); ++i) for (int i = this->config.raft_layers; i < this->layers.size(); ++i)
layer_z[i] += first_lh + lh * (this->config.raft_layers-1); 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; 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"); FILE* f = fopen(outputfile.c_str(), "w");
@ -134,11 +142,15 @@ SVGExport::writeSVG(const std::string &outputfile)
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.0//EN\" \"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\">\n" "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.0//EN\" \"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\">\n"
"<svg width=\"%f\" height=\"%f\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:svg=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:slic3r=\"http://slic3r.org/namespaces/slic3r\" viewport-fill=\"black\">\n" "<svg width=\"%f\" height=\"%f\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:svg=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:slic3r=\"http://slic3r.org/namespaces/slic3r\" viewport-fill=\"black\">\n"
"<!-- Generated using Slic3r %s http://slic3r.org/ -->\n" "<!-- Generated using Slic3r %s http://slic3r.org/ -->\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) { for (size_t i = 0; i < this->layers.size(); ++i) {
fprintf(f, "\t<g id=\"layer%zu\" slic3r:z=\"%0.4f\">\n", i, layer_z[i]); const Layer &layer = this->layers[i];
for (ExPolygons::const_iterator it = layers[i].begin(); it != layers[i].end(); ++it) { fprintf(f, "\t<g id=\"layer%zu\" slic3r:z=\"%0.4f\" slic3r:slice-z=\"%0.4f\">\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; std::string pd;
Polygons pp = *it; Polygons pp = *it;
for (Polygons::const_iterator mp = pp.begin(); mp != pp.end(); ++mp) { 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 // don't print support material in raft layers
if (i >= this->config.raft_layers) { if (i >= this->config.raft_layers) {
// look for support material pillars belonging to this layer // look for support material pillars belonging to this layer
for (std::vector<SupportPillar>::const_iterator it = sm_pillars.begin(); it != sm_pillars.end(); ++it) { for (std::vector<SupportPillar>::const_iterator it = this->sm_pillars.begin(); it != this->sm_pillars.end(); ++it) {
if (!(it->top_layer >= i && it->bottom_layer <= i)) continue; if (!(it->top_layer >= i && it->bottom_layer <= i)) continue;
// generate a conic tip // generate a conic tip
float radius = fminf( float radius = fminf(
support_material_radius, support_material_radius,
(it->top_layer - i + 1) * lh (it->top_layer - i + 1) * this->config.layer_height.value
); );
fprintf(f,"\t\t<circle cx=\"%f\" cy=\"%f\" r=\"%f\" stroke-width=\"0\" fill=\"white\" slic3r:type=\"support\" />\n", fprintf(f,"\t\t<circle cx=\"%f\" cy=\"%f\" r=\"%f\" stroke-width=\"0\" fill=\"white\" slic3r:type=\"support\" />\n",

View File

@ -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<Layer> 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<SupportPillar> sm_pillars;
SLAPrint(Model* _model) : model(_model) {};
void slice();
void write_svg(const std::string &outputfile) const;
private:
Model* model;
Sizef3 size;
};
}
#endif

View File

@ -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