Skip to content
Browse files

single-layer SVG output

  • Loading branch information...
1 parent 6f7a3b0 commit 0be712d236f69d4d07100bcbce1d0b9e1a6dd971 @hurzl hurzl committed
Showing with 91 additions and 39 deletions.
  1. +11 −6 src/file.cpp
  2. +1 −1 src/file.h
  3. +1 −2 src/model.cpp
  4. +2 −2 src/model.h
  5. +36 −9 src/model2.cpp
  6. +20 −4 src/repsnapper.cpp
  7. +4 −5 src/slicer/layer.cpp
  8. +1 −1 src/slicer/layer.h
  9. +14 −8 src/slicer/poly.cpp
  10. +1 −1 src/slicer/triangle.cpp
View
17 src/file.cpp
@@ -102,11 +102,9 @@ namespace {
vector<string> file_filters;
};
-
-
const vector< Glib::RefPtr< Gio::File > >
openGtk(const string &directory, const vector<string> &file_filters,
- FileChooser::Op op, const string &title,
+ FileChooser::Op op, FileChooser::Type t, const string &title,
View * view) {
// GSList *result = NULL;
Gtk::FileChooserAction action;
@@ -122,14 +120,21 @@ namespace {
}
FileDialog dialog(title, action, view, directory);
+
+ if (t == FileChooser::SVG)
+ dialog.add_button(_("One Layer per File"), Gtk::RESPONSE_ACCEPT+1);
+
dialog.add_file_filters(file_filters);
int runresult = dialog.run();
std::vector< Glib::RefPtr < Gio::File > > result;
//Handle the response:
- if (runresult == Gtk::RESPONSE_ACCEPT)
+ FileChooser::save_multiple = false;
+ if (runresult != Gtk::RESPONSE_CANCEL)
result = dialog.get_files();
+ if (runresult == Gtk::RESPONSE_ACCEPT+1)
+ FileChooser::save_multiple = true;
return result;
}
@@ -178,7 +183,7 @@ void FileChooser::ioDialog (Model *model, View* view, Op o, Type t, bool dropRFO
if (directory == "")
directory = ".";
- files = openGtk (directory, filter, o, title, view);
+ files = openGtk (directory, filter, o, t, title, view);
for (uint i= 0; i < files.size(); i++) {
@@ -207,7 +212,7 @@ void FileChooser::ioDialog (Model *model, View* view, Op o, Type t, bool dropRFO
if (o == OPEN)
model->ReadSVG (file);
else
- model->SliceToSVG (file);
+ model->SliceToSVG (file, FileChooser::save_multiple);
model->settings.STLPath = directory_path;
break;
case STL:
View
2 src/file.h
@@ -20,7 +20,6 @@
#define FILE_H
class Model;
-class Model;
namespace FileChooser {
enum Type {
STL, SVG, RFO, GCODE, SETTINGS
@@ -28,6 +27,7 @@ namespace FileChooser {
enum Op {
OPEN, SAVE
};
+ static bool save_multiple = false;
void ioDialog (Model *model, View* view, Op o, Type t, bool dropRFO = false);
};
View
3 src/model.cpp
@@ -230,11 +230,10 @@ void Model::ReadStl(Glib::RefPtr<Gio::File> file, filetype_t ftype)
else if (ftype == VRML)
{
Shape *shape = new Shape();
- shape->loadASCIIVRML(path);
+ shape->loadASCIIVRML(path);
AddShape(NULL, shape, path,autoplace);
ModelChanged();
}
-
ClearLayers();
}
View
4 src/model.h
@@ -93,7 +93,7 @@ class Model
GCode m_previewGCode;
double m_previewGCode_z;
// Slicing
- void SliceToSVG(Glib::RefPtr<Gio::File> file);
+ void SliceToSVG(Glib::RefPtr<Gio::File> file, bool single_layer=false);
void Slice();
void CleanupLayers();
@@ -176,7 +176,7 @@ class Model
void SetIsPrinting(bool printing) { is_printing = printing; };
- string getSVG() const;
+ string getSVG(int single_layer_no = -1) const;
void ReadSVG(Glib::RefPtr<Gio::File> file);
private:
View
45 src/model2.cpp
@@ -290,6 +290,8 @@ void Model::Slice()
else
objtree.get_all_shapes(shapes,transforms);
+ if (shapes.size() == 0) return;
+
assert(shapes.size() == transforms.size());
is_calculating=true;
@@ -898,7 +900,7 @@ void Model::ConvertToGCode()
is_calculating=false;
}
-string Model::getSVG() const
+string Model::getSVG(int single_layer_no) const
{
Vector3d printOffset = settings.Hardware.PrintMargin;
@@ -913,24 +915,49 @@ string Model::getSVG() const
<< "\twidth=\"" << Max.x()-Min.x()+printOffset.x()
<< "\" height=\""<< Max.y()-Min.y()+printOffset.y() << "\"" << endl
<< ">" << endl;
- ostr << "<g id=\"" << layers.size() << "_Layers\">" << endl;
- for (uint i = 0; i < layers.size(); i++) {
- ostr << "\t<g id=\"Layer_"<< i << "_z:" << layers[i]->getZ() << "\">"
- << "\t\t" << layers[i]->SVGpath()
- << "\t</g>" << endl;
+ if (single_layer_no<0) {
+ ostr << "<g id=\"" << layers.size() << "_Layers\">" << endl;
+ for (uint i = 0; i < layers.size(); i++) {
+ ostr << "\t\t" << layers[i]->SVGpath() << endl;
+ }
+ } else {
+ ostr << "<g id=\"" << "Layer_" << single_layer_no
+ << "_of_" <<layers.size() << "\">" << endl;
+ ostr << "\t\t" << layers[single_layer_no]->SVGpath() << endl;
}
ostr << "</g>" << endl;
ostr << "</svg>" << endl;
return ostr.str();
}
-
-void Model::SliceToSVG(Glib::RefPtr<Gio::File> file)
+void Model::SliceToSVG(Glib::RefPtr<Gio::File> file, bool single_layer)
{
if (is_calculating) return;
lastlayer = NULL;
Slice();
m_progress->stop (_("Done"));
- Glib::file_set_contents (file->get_path(), getSVG());
+ if (!single_layer) {
+ Glib::file_set_contents (file->get_path(), getSVG());
+ }
+ else {
+ uint n_layers = layers.size();
+ m_progress->start (_("Saving Files"),n_layers);
+ uint digits = log10(n_layers)+1;
+ string base = file->get_path();
+ ostringstream ostr;
+ for (uint i = 0; i < n_layers; i++) {
+ ostr.str("");
+ ostr << base;
+ uint nzero = (uint)(digits - log10(i+1));
+ if (i==0) nzero = digits-1;
+ for (uint d = 0; d < nzero; d++)
+ ostr << "0";
+ ostr << i
+ << ".svg";
+ if (!m_progress->update(i)) break;
+ Glib::file_set_contents (ostr.str(), getSVG(i));
+ }
+ m_progress->stop (_("Done"));
+ }
}
View
24 src/repsnapper.cpp
@@ -41,6 +41,8 @@ struct CommandLineOptions
string stl_input_path;
string gcode_output_path;
string settings_path;
+ string svg_output_path;
+ bool svg_single_output;
std::vector<std::string> files;
private:
void init ()
@@ -64,6 +66,8 @@ struct CommandLineOptions
" -o, --output [file] if not head-less (-t),\n"
" enter non-printing GUI mode\n"
" only able to output gcode to [file]\n"
+ " --svg [file] slice to SVG file\n"
+ " --ssvg [file] slice to single layer SVG files [file]NNNN.svg\n"
" -s, --settings [file] read render settings [file]\n"
" -h, --help show this help\n"
"\n"
@@ -93,6 +97,14 @@ struct CommandLineOptions
else if (!strcmp (arg, "--help") || !strcmp (arg, "-h") ||
!strcmp (arg, "/?"))
usage();
+ else if (!strcmp (arg, "--svg")) {
+ svg_output_path = argv[++i];
+ svg_single_output = false;
+ }
+ else if (!strcmp (arg, "--ssvg")) {
+ svg_output_path = argv[++i];
+ svg_single_output = true;
+ }
else if (!strcmp (arg, "--version") || !strcmp (arg, "-v"))
version();
else
@@ -249,11 +261,15 @@ int main(int argc, char **argv)
vprog.set_terminal_output(true);
model->SetViewProgress(&vprog);
model->statusbar=NULL;
- model->ConvertToGCode();
-
- if (opts.gcode_output_path.size() > 0)
+ if (opts.gcode_output_path.size() > 0) {
+ model->ConvertToGCode();
model->WriteGCode(Gio::File::create_for_path(opts.gcode_output_path));
- else cerr << _("No output file given (use -o)") << endl;
+ }
+ else if (opts.svg_output_path.size() > 0) {
+ model->SliceToSVG(Gio::File::create_for_path(opts.svg_output_path),
+ opts.svg_single_output);
+ }
+ else cerr << _("No output file given") << endl;
return 0;
}
View
9 src/slicer/layer.cpp
@@ -893,13 +893,12 @@ vector<Poly> Layer::getOverhangs() const
string Layer::SVGpath(const Vector2d &trans) const
{
ostringstream ostr;
- ostr << "<path d=\"";
+ ostr << "\t<g id=\"Layer_"<< LayerNo
+ << "_z:" << getZ() << "\">" << endl;
for (uint i = 0; i<polygons.size(); i++) {
- ostr << polygons[i].SVGpath(trans);
+ ostr << polygons[i].SVGpath(trans) << endl;
}
- ostr << "\" "
- << "style=\"fill:black;fill-opacity:1;stroke:black;stroke-width:0\" "
- << "fill-rule=\"evenodd\" />";
+ ostr << "\t</g>";
return ostr.str();
}
View
2 src/slicer/layer.h
@@ -45,7 +45,7 @@ class Layer
int LayerNo;
double thickness;
double Z;
- double getZ(){return Z;}
+ double getZ() const {return Z;}
void setZ(double z){Z=z;}
Layer * getPrevious() const {return previous;};
View
22 src/slicer/poly.cpp
@@ -737,14 +737,20 @@ string Poly::SVGpath(const Vector2d &trans) const
ostringstream ostr;
Poly transpoly(*this,0);
transpoly.move(trans);
- ostr << "m ";
- ostr << fixed << transpoly[0].x() << " " << transpoly[0].y();
- for (uint i=1; i < transpoly.size(); i++) {
- ostr.precision(5);
- ostr << fixed << " l " << transpoly[i].x() << " " << transpoly[i].y();
- if (i < size()-1) ostr << " ";
- }
+ ostr.precision(5);
if (closed)
- ostr << " z";
+ if (hole)
+ ostr << "<polygon fill=\"white\" stroke=\"black\" stroke-width=\"0px\"";
+ else
+ ostr << "<polygon fill=\"black\" stroke=\"black\" stroke-width=\"0px\"";
+ else
+ ostr << "<polyline fill=\"white\" stroke=\"black\" stroke-width=\"1px\"";
+ ostr << " points=\"";
+ for (uint i=0; i < transpoly.size(); i++) {
+ ostr << fixed << transpoly[i].x() << " " << transpoly[i].y();
+ if (i < size()-1) ostr << ", ";
+ }
+ //<< "fill-rule=\"evenodd\" ";
+ ostr << "\" />";
return ostr.str();
}
View
2 src/slicer/triangle.cpp
@@ -170,7 +170,7 @@ void triangulateQuadrilateral(vector<Vector3d> fourpoints, vector<Triangle> &tri
double dist = dist3D_Segment_to_Segment(fourpoints[0],fourpoints[2],
fourpoints[1],fourpoints[3],
SMALL*SMALL);
- if (dist < SMALL)
+ if (dist < SMALL)
{ // found -> divide at shorter diagonal
if ((fourpoints[0]-fourpoints[2]).squared_length()
< (fourpoints[1]-fourpoints[3]).squared_length()) {

0 comments on commit 0be712d

Please sign in to comment.
Something went wrong with that request. Please try again.