Add standalone slic3r binary that takes an stl file and emits a multilayer SVG

This commit is contained in:
Kliment Yanev 2016-05-02 23:44:35 +02:00
parent 510ca9f9e2
commit 5f12bc6008
5 changed files with 247 additions and 0 deletions

98
xs/src/CMakeLists.txt Normal file
View File

@ -0,0 +1,98 @@
cmake_minimum_required (VERSION 2.8)
project (slic3r)
set(workaround "")
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.7.0)
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7.3)
set(workaround "-fno-inline-small-functions")
endif(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7.3)
endif(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.7.0)
set(CMAKE_CXX_FLAGS "-D_GLIBCXX_USE_C99 -DHAS_BOOL -DNOGDI -DBOOST_ASIO_DISABLE_KQUEUE -std=c++14 ${workaround}")
set(CMAKE_INCLUDE_CURRENT_DIR ON)
IF(CMAKE_HOST_APPLE)
set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++ -framework IOKit -framework CoreFoundation")
ELSE(CMAKE_HOST_APPLE)
set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++")
ENDIF(CMAKE_HOST_APPLE)
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_STATIC_RUNTIME ON)
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
find_package(Boost COMPONENTS system thread)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/libslic3r)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/Slic3r/GUI/)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/standalone/)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/admesh/)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/poly2tri/)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/poly2tri/sweep)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/poly2tri/common)
add_library(slic3r_gui STATIC slic3r/GUI/3DScene.cpp slic3r/GUI/GUI.cpp)
add_library(libslic3r STATIC libslic3r/BoundingBox.cpp
libslic3r/ExPolygon.cpp
libslic3r/GCode.cpp
libslic3r/LayerRegion.cpp
libslic3r/PerimeterGenerator.cpp
libslic3r/Polyline.cpp
libslic3r/SurfaceCollection.cpp
libslic3r/BridgeDetector.cpp
libslic3r/Extruder.cpp
libslic3r/GCodeSender.cpp
libslic3r/Line.cpp
libslic3r/PlaceholderParser.cpp
libslic3r/PrintConfig.cpp
libslic3r/Surface.cpp
libslic3r/ClipperUtils.cpp
libslic3r/ExtrusionEntityCollection.cpp
libslic3r/GCodeWriter.cpp
libslic3r/Model.cpp
libslic3r/Point.cpp
libslic3r/Print.cpp
libslic3r/SVG.cpp
libslic3r/SVGExport.cpp
libslic3r/Config.cpp
libslic3r/ExtrusionEntity.cpp
libslic3r/Geometry.cpp
libslic3r/MotionPlanner.cpp
libslic3r/Polygon.cpp
libslic3r/PrintObject.cpp
libslic3r/TriangleMesh.cpp
libslic3r/ExPolygonCollection.cpp
libslic3r/Flow.cpp
libslic3r/Layer.cpp
libslic3r/MultiPoint.cpp
libslic3r/PolylineCollection.cpp
libslic3r/PrintRegion.cpp)
add_library(admesh STATIC admesh/util.c admesh/stl_io.c admesh/stlinit.c admesh/shared.c admesh/normals.c admesh/connect.c)
add_library(clipper STATIC clipper.cpp)
add_library(polypartition STATIC polypartition.cpp)
add_library(poly2tri STATIC poly2tri/sweep/sweep.cc poly2tri/sweep/sweep_context.cc poly2tri/sweep/cdt.cc poly2tri/sweep/advancing_front.cc poly2tri/common/shapes.cc)
add_executable(slic3r slic3r.cpp)
set_target_properties(slic3r PROPERTIES LINK_SEARCH_START_STATIC 1)
set_target_properties(slic3r PROPERTIES LINK_SEARCH_END_STATIC 1)
set(wxWidgets_USE_STATIC)
SET(wxWidgets_USE_LIBS)
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_STATIC_RUNTIME ON)
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
find_library(bsystem_l boost_system)
add_library(bsystem STATIC IMPORTED)
set_target_properties(bsystem PROPERTIES IMPORTED_LOCATION ${bsystem_l})
find_library(bthread_l boost_thread)
add_library(bthread STATIC IMPORTED)
set_target_properties(bthread PROPERTIES IMPORTED_LOCATION ${bthread_l})
include_directories(${Boost_INCLUDE_DIRS})
#find_package(wxWidgets)
IF(wxWidgets_FOUND)
MESSAGE("wx found!")
INCLUDE("${wxWidgets_USE_FILE}")
target_link_libraries (slic3r slic3r_gui libslic3r admesh clipper polypartition poly2tri bsystem bthread ${wxWidgets_LIBRARIES})
ELSE(wxWidgets_FOUND)
# For convenience. When we cannot continue, inform the user
MESSAGE("wx not found!")
target_link_libraries (slic3r slic3r_gui libslic3r admesh clipper polypartition poly2tri bsystem bthread)
ENDIF(wxWidgets_FOUND)

View File

@ -0,0 +1,60 @@
#include "SVGExport.hpp"
#include "SVG.hpp"
#include <iostream>
#include <cstdio>
#define COORD(x) ((float)unscale(x)*10)
namespace Slic3r {
SVGExport::SVGExport(TriangleMesh &t, float layerheight, float firstlayerheight)
:t(&t), sliced(false)
{
heights={};
if(layerheight>0){
for(float f=firstlayerheight;f<=t.stl.stats.max.z;f+=layerheight){
heights.push_back(f);
}
TriangleMeshSlicer(&t).slice(heights,&layers);
sliced=true;
}
}
//<g id="layer0" slic3r:z="0.1"> <path...> <path...> </g>
void SVGExport::writeSVG(const char* outputfile){
if(sliced){
FILE* f = fopen(outputfile, "w");
fprintf(f,
"<?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"
"<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"
"<!-- Generated using Slic3r %s http://slic3r.org/ -->\n"
,t->stl.stats.max.x*10,t->stl.stats.max.y*10,SLIC3R_VERSION);
for (int i=0;i<heights.size();i++){
fprintf(f,"\t<g id=\"layer%d\" slic3r:z=\"%0.4f\">",i,heights[i]);
for (ExPolygons::const_iterator it = layers[i].begin(); it != layers[i].end(); ++it){
std::string pd;
Polygons pp = *it;
for (Polygons::const_iterator mp = pp.begin(); mp != pp.end(); ++mp) {
std::ostringstream d;
d << "M ";
for (Points::const_iterator p = mp->points.begin(); p != mp->points.end(); ++p) {
d << COORD(p->x) << " ";
d << COORD(p->y) << " ";
}
d << "z";
pd += d.str() + " ";
}
fprintf(f,"\t\t<path d=\"%s\" style=\"fill: %s; stroke: %s; stroke-width: %s; fill-type: evenodd\" />\n",
pd.c_str(),"white","black","0"
);
}
fprintf(f,"\t</g>\n");
}
fprintf(f,"</svg>\n");
}
}
}

View File

@ -0,0 +1,25 @@
#ifndef slic3r_SVGExport_hpp_
#define slic3r_SVGExport_hpp_
#include "libslic3r.h"
#include "ExPolygon.hpp"
#include "SVG.hpp"
#include "TriangleMesh.hpp"
namespace Slic3r {
class SVGExport
{
public:
SVGExport(TriangleMesh &t, float layerheight, float firstlayerheight=0.0);
void writeSVG(const char* outputfile);
private:
TriangleMesh *t;
std::vector<ExPolygons> layers;
std::vector<float> heights;
bool sliced;
};
}
#endif

64
xs/src/slic3r.cpp Normal file
View File

@ -0,0 +1,64 @@
#include "TriangleMesh.hpp"
#include "SVGExport.hpp"
#include "libslic3r.h"
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include "tclap/CmdLine.h"
using namespace Slic3r;
void confess_at(const char *file, int line, const char *func, const char *pat, ...){}
void exportSVG(const char* stlname, const char* svgname, float layerheight=0.2, float initialheight=0., float scale=1.0, float rotate=0.){
TriangleMesh t;
std::string outname;
if(strlen(svgname)==0){
outname=outname+stlname+".svg";
}else{
outname=outname+svgname;
}
t.ReadSTLFile(const_cast<char *>(stlname));
t.repair();
t.scale(scale);
t.rotate_z(rotate);
t.align_to_origin();
SVGExport e(t,layerheight,initialheight);
const char* svgfilename=outname.data();
e.writeSVG(svgfilename);
printf("writing: %s\n",svgfilename);
}
int main (int argc, char **argv){
try{
TCLAP::CmdLine cmd("Rudimentary commandline slic3r, currently only supports STL to SVG slice export.", ' ', SLIC3R_VERSION);
TCLAP::ValueArg<std::string> outputArg("o","output","File to output results to",false,"","output file name");
cmd.add( outputArg );
TCLAP::ValueArg<float> scaleArg("","scale","Factor for scaling input object (default: 1)",false,1.0,"float");
cmd.add( scaleArg );
TCLAP::ValueArg<float> rotArg("","rotate","Rotation angle in degrees (0-360, default: 0)",false,0.0,"float");
cmd.add( rotArg );
TCLAP::ValueArg<float> flhArg("","first-layer-height","Layer height for first layer in mm (default: 0)",false,0.0,"float");
cmd.add( flhArg );
TCLAP::ValueArg<float> lhArg("","layer-height","Layer height in mm (default: 0.2)",false,0.2,"float");
cmd.add( lhArg );
TCLAP::SwitchArg expsvg("","export-svg","Export a SVG file containing slices", cmd, false);
TCLAP::UnlabeledValueArg<std::string> input("inputfile","Input STL file name", true, "", "input file name");
cmd.add(input);
cmd.parse(argc,argv);
if(expsvg.getValue()){
exportSVG(input.getValue().data(),outputArg.getValue().data(),lhArg.getValue(),flhArg.getValue(),scaleArg.getValue(),rotArg.getValue());
}else{
std::cerr << "error: only svg export currently supported"<< std::endl;
return 1;
}
}catch (TCLAP::ArgException &e)
{ std::cerr << "error: " << e.error() << " for arg " << e.argId() << std::endl; }
}

View File