mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-07-15 22:11:47 +08:00
Added basic support material to SVG export
This commit is contained in:
parent
56334c49ac
commit
8910b4970a
@ -486,6 +486,17 @@ void diff(const SubjectType &subject, const Slic3r::ExPolygons &clip, ResultType
|
|||||||
}
|
}
|
||||||
template void diff<Slic3r::Polygons, Slic3r::ExPolygons>(const Slic3r::Polygons &subject, const Slic3r::ExPolygons &clip, Slic3r::ExPolygons* retval, bool safety_offset_);
|
template void diff<Slic3r::Polygons, Slic3r::ExPolygons>(const Slic3r::Polygons &subject, const Slic3r::ExPolygons &clip, Slic3r::ExPolygons* retval, bool safety_offset_);
|
||||||
|
|
||||||
|
template <class ResultType>
|
||||||
|
void diff(const Slic3r::ExPolygons &subject, const Slic3r::ExPolygons &clip, ResultType* retval, bool safety_offset_)
|
||||||
|
{
|
||||||
|
Slic3r::Polygons pp;
|
||||||
|
for (Slic3r::ExPolygons::const_iterator ex = subject.begin(); ex != subject.end(); ++ex) {
|
||||||
|
Slic3r::Polygons ppp = *ex;
|
||||||
|
pp.insert(pp.end(), ppp.begin(), ppp.end());
|
||||||
|
}
|
||||||
|
diff(pp, clip, retval, safety_offset_);
|
||||||
|
}
|
||||||
|
|
||||||
Slic3r::Polygons
|
Slic3r::Polygons
|
||||||
diff(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool safety_offset_)
|
diff(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool safety_offset_)
|
||||||
{
|
{
|
||||||
@ -504,6 +515,7 @@ diff_ex(const SubjectType &subject, const ClipType &clip, bool safety_offset_)
|
|||||||
}
|
}
|
||||||
template Slic3r::ExPolygons diff_ex<Slic3r::Polygons, Slic3r::Polygons>(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool safety_offset_);
|
template Slic3r::ExPolygons diff_ex<Slic3r::Polygons, Slic3r::Polygons>(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool safety_offset_);
|
||||||
template Slic3r::ExPolygons diff_ex<Slic3r::Polygons, Slic3r::ExPolygons>(const Slic3r::Polygons &subject, const Slic3r::ExPolygons &clip, bool safety_offset_);
|
template Slic3r::ExPolygons diff_ex<Slic3r::Polygons, Slic3r::ExPolygons>(const Slic3r::Polygons &subject, const Slic3r::ExPolygons &clip, bool safety_offset_);
|
||||||
|
template Slic3r::ExPolygons diff_ex<Slic3r::ExPolygons, Slic3r::ExPolygons>(const Slic3r::ExPolygons &subject, const Slic3r::ExPolygons &clip, bool safety_offset_);
|
||||||
|
|
||||||
template <class SubjectType, class ResultType>
|
template <class SubjectType, class ResultType>
|
||||||
void intersection(const SubjectType &subject, const Slic3r::Polygons &clip, ResultType* retval, bool safety_offset_)
|
void intersection(const SubjectType &subject, const Slic3r::Polygons &clip, ResultType* retval, bool safety_offset_)
|
||||||
@ -596,6 +608,23 @@ void union_(const Slic3r::Polygons &subject1, const Slic3r::Polygons &subject2,
|
|||||||
union_(pp, retval, safety_offset);
|
union_(pp, retval, safety_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Slic3r::Polygons
|
||||||
|
union_(const Slic3r::ExPolygons &subject1, const Slic3r::ExPolygons &subject2, bool safety_offset)
|
||||||
|
{
|
||||||
|
Polygons pp;
|
||||||
|
for (Slic3r::ExPolygons::const_iterator it = subject1.begin(); it != subject1.end(); ++it) {
|
||||||
|
Polygons spp = *it;
|
||||||
|
pp.insert(pp.end(), spp.begin(), spp.end());
|
||||||
|
}
|
||||||
|
for (Slic3r::ExPolygons::const_iterator it = subject2.begin(); it != subject2.end(); ++it) {
|
||||||
|
Polygons spp = *it;
|
||||||
|
pp.insert(pp.end(), spp.begin(), spp.end());
|
||||||
|
}
|
||||||
|
Polygons retval;
|
||||||
|
union_(pp, &retval, safety_offset);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
void union_pt(const Slic3r::Polygons &subject, ClipperLib::PolyTree* retval, bool safety_offset_)
|
void union_pt(const Slic3r::Polygons &subject, ClipperLib::PolyTree* retval, bool safety_offset_)
|
||||||
{
|
{
|
||||||
Slic3r::Polygons clip;
|
Slic3r::Polygons clip;
|
||||||
|
@ -129,6 +129,7 @@ Slic3r::ExPolygons union_ex(const Slic3r::Polygons &subject, bool safety_offset
|
|||||||
Slic3r::ExPolygons union_ex(const Slic3r::Surfaces &subject, bool safety_offset = false);
|
Slic3r::ExPolygons union_ex(const Slic3r::Surfaces &subject, bool safety_offset = false);
|
||||||
|
|
||||||
void union_(const Slic3r::Polygons &subject1, const Slic3r::Polygons &subject2, Slic3r::Polygons* retval, bool safety_offset = false);
|
void union_(const Slic3r::Polygons &subject1, const Slic3r::Polygons &subject2, Slic3r::Polygons* retval, bool safety_offset = false);
|
||||||
|
Slic3r::Polygons union_(const Slic3r::ExPolygons &subject1, const Slic3r::ExPolygons &subject2, bool safety_offset = false);
|
||||||
|
|
||||||
void union_pt(const Slic3r::Polygons &subject, ClipperLib::PolyTree* retval, bool safety_offset_ = false);
|
void union_pt(const Slic3r::Polygons &subject, ClipperLib::PolyTree* retval, bool safety_offset_ = false);
|
||||||
void union_pt_chained(const Slic3r::Polygons &subject, Slic3r::Polygons* retval, bool safety_offset_ = false);
|
void union_pt_chained(const Slic3r::Polygons &subject, Slic3r::Polygons* retval, bool safety_offset_ = false);
|
||||||
|
@ -490,6 +490,9 @@ class SVGExportConfig
|
|||||||
ConfigOptionFloat layer_height;
|
ConfigOptionFloat layer_height;
|
||||||
ConfigOptionInt raft_layers;
|
ConfigOptionInt raft_layers;
|
||||||
ConfigOptionFloat raft_offset;
|
ConfigOptionFloat raft_offset;
|
||||||
|
ConfigOptionBool support_material;
|
||||||
|
ConfigOptionFloatOrPercent support_material_extrusion_width;
|
||||||
|
ConfigOptionFloat support_material_spacing;
|
||||||
|
|
||||||
SVGExportConfig() : StaticPrintConfig() {
|
SVGExportConfig() : StaticPrintConfig() {
|
||||||
this->set_defaults();
|
this->set_defaults();
|
||||||
@ -500,6 +503,9 @@ class SVGExportConfig
|
|||||||
OPT_PTR(layer_height);
|
OPT_PTR(layer_height);
|
||||||
OPT_PTR(raft_layers);
|
OPT_PTR(raft_layers);
|
||||||
OPT_PTR(raft_offset);
|
OPT_PTR(raft_offset);
|
||||||
|
OPT_PTR(support_material);
|
||||||
|
OPT_PTR(support_material_extrusion_width);
|
||||||
|
OPT_PTR(support_material_spacing);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
};
|
};
|
||||||
|
@ -17,6 +17,7 @@ SVGExport::writeSVG(const std::string &outputfile)
|
|||||||
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
|
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();
|
const Sizef3 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
|
||||||
@ -53,17 +54,47 @@ SVGExport::writeSVG(const std::string &outputfile)
|
|||||||
layer_z[i] += first_lh + lh * (this->config.raft_layers-1);
|
layer_z[i] += first_lh + lh * (this->config.raft_layers-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// generate support material
|
||||||
|
std::vector<Points> support_material(layers.size());
|
||||||
|
if (this->config.support_material) {
|
||||||
|
// generate a grid of points according to the configured spacing,
|
||||||
|
// covering the entire object bounding box
|
||||||
|
Points support_material_points;
|
||||||
|
for (coordf_t x = bb.min.x; x <= bb.max.x; x += this->config.support_material_spacing) {
|
||||||
|
for (coordf_t y = bb.min.y; y <= bb.max.y; y += this->config.support_material_spacing) {
|
||||||
|
support_material_points.push_back(Point(scale_(x), scale_(y)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check overhangs, starting from the upper layer, and detect which points apply
|
||||||
|
// to each layer
|
||||||
|
ExPolygons overhangs;
|
||||||
|
for (int i = layer_z.size()-1; i >= 0; --i) {
|
||||||
|
overhangs = diff_ex(union_(overhangs, layers[i+1]), layers[i]);
|
||||||
|
for (Points::const_iterator it = support_material_points.begin(); it != support_material_points.end(); ++it) {
|
||||||
|
for (ExPolygons::const_iterator e = overhangs.begin(); e != overhangs.end(); ++e) {
|
||||||
|
if (e->contains(*it)) {
|
||||||
|
support_material[i].push_back(*it);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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");
|
||||||
fprintf(f,
|
fprintf(f,
|
||||||
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"
|
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"
|
||||||
"<!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\">\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);
|
, size.x, size.y, SLIC3R_VERSION);
|
||||||
|
|
||||||
for (size_t i = 0; i < layer_z.size(); ++i) {
|
for (size_t i = 0; i < layer_z.size(); ++i) {
|
||||||
fprintf(f, "\t<g id=\"layer%zu\" slic3r:z=\"%0.4f\">\n", i, layer_z[i]);
|
fprintf(f, "\t<g id=\"layer%zu\" slic3r:z=\"%0.4f\">\n", i, layer_z[i]);
|
||||||
for (ExPolygons::const_iterator it = layers[i].begin(); it != layers[i].end(); ++it){
|
for (ExPolygons::const_iterator it = layers[i].begin(); it != layers[i].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) {
|
||||||
@ -80,6 +111,11 @@ SVGExport::writeSVG(const std::string &outputfile)
|
|||||||
pd.c_str(), "white", "black", "0", unscale(unscale(it->area()))
|
pd.c_str(), "white", "black", "0", unscale(unscale(it->area()))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
for (Points::const_iterator it = support_material[i].begin(); it != support_material[i].end(); ++it) {
|
||||||
|
fprintf(f,"\t\t<circle cx=\"%f\" cy=\"%f\" r=\"%f\" stroke-width=\"0\" fill=\"white\" slic3r:type=\"support\" />\n",
|
||||||
|
unscale(it->x), unscale(it->y), support_material_radius
|
||||||
|
);
|
||||||
|
}
|
||||||
fprintf(f,"\t</g>\n");
|
fprintf(f,"\t</g>\n");
|
||||||
}
|
}
|
||||||
fprintf(f,"</svg>\n");
|
fprintf(f,"</svg>\n");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user