mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-08-18 03:45:55 +08:00
Initial commit of gcode export toolchain (incomplete).
Passes tests so far as written, gcode output through test interface expects an ostream.
This commit is contained in:
parent
b2d6c47c53
commit
5b71940e60
@ -75,6 +75,7 @@ set(GUI_TESTDIR ${CMAKE_CURRENT_SOURCE_DIR}/test/GUI/)
|
|||||||
# directory that contains the dependent non-source files, like models and configurations
|
# directory that contains the dependent non-source files, like models and configurations
|
||||||
set(TESTFILE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/test/inputs/)
|
set(TESTFILE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/test/inputs/)
|
||||||
|
|
||||||
|
|
||||||
include_directories(${LIBDIR})
|
include_directories(${LIBDIR})
|
||||||
include_directories(${LIBDIR}/libslic3r)
|
include_directories(${LIBDIR}/libslic3r)
|
||||||
include_directories(${LIBDIR}/slic3r/GUI/)
|
include_directories(${LIBDIR}/slic3r/GUI/)
|
||||||
@ -112,6 +113,7 @@ add_library(libslic3r STATIC
|
|||||||
${LIBDIR}/libslic3r/Fill/FillGyroid.cpp
|
${LIBDIR}/libslic3r/Fill/FillGyroid.cpp
|
||||||
${LIBDIR}/libslic3r/Flow.cpp
|
${LIBDIR}/libslic3r/Flow.cpp
|
||||||
${LIBDIR}/libslic3r/GCode.cpp
|
${LIBDIR}/libslic3r/GCode.cpp
|
||||||
|
${LIBDIR}/libslic3r/PrintGCode.cpp
|
||||||
${LIBDIR}/libslic3r/GCode/CoolingBuffer.cpp
|
${LIBDIR}/libslic3r/GCode/CoolingBuffer.cpp
|
||||||
${LIBDIR}/libslic3r/GCode/SpiralVase.cpp
|
${LIBDIR}/libslic3r/GCode/SpiralVase.cpp
|
||||||
${LIBDIR}/libslic3r/GCodeReader.cpp
|
${LIBDIR}/libslic3r/GCodeReader.cpp
|
||||||
@ -166,6 +168,7 @@ add_library(admesh STATIC
|
|||||||
set_property(TARGET admesh PROPERTY C_STANDARD 99)
|
set_property(TARGET admesh PROPERTY C_STANDARD 99)
|
||||||
|
|
||||||
add_library(clipper STATIC ${LIBDIR}/clipper.cpp)
|
add_library(clipper STATIC ${LIBDIR}/clipper.cpp)
|
||||||
|
|
||||||
add_library(expat STATIC
|
add_library(expat STATIC
|
||||||
${LIBDIR}/expat/xmlparse.c
|
${LIBDIR}/expat/xmlparse.c
|
||||||
${LIBDIR}/expat/xmlrole.c
|
${LIBDIR}/expat/xmlrole.c
|
||||||
@ -182,8 +185,6 @@ add_library(poly2tri STATIC
|
|||||||
${LIBDIR}/poly2tri/sweep/sweep.cc
|
${LIBDIR}/poly2tri/sweep/sweep.cc
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
set(UI_TEST_SOURCES
|
set(UI_TEST_SOURCES
|
||||||
${GUI_TESTDIR}/testableframe.cpp
|
${GUI_TESTDIR}/testableframe.cpp
|
||||||
${GUI_TESTDIR}/test_harness_gui.cpp
|
${GUI_TESTDIR}/test_harness_gui.cpp
|
||||||
@ -196,13 +197,17 @@ set(UI_TEST_SOURCES
|
|||||||
${GUI_TESTDIR}/test_field_point3.cpp
|
${GUI_TESTDIR}/test_field_point3.cpp
|
||||||
${GUI_TESTDIR}/test_misc_ui.cpp
|
${GUI_TESTDIR}/test_misc_ui.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(SLIC3R_TEST_SOURCES
|
set(SLIC3R_TEST_SOURCES
|
||||||
${TESTDIR}/test_harness.cpp
|
${TESTDIR}/test_harness.cpp
|
||||||
${TESTDIR}/test_data.cpp
|
${TESTDIR}/test_data.cpp
|
||||||
${TESTDIR}/libslic3r/test_trianglemesh.cpp
|
${TESTDIR}/libslic3r/test_trianglemesh.cpp
|
||||||
${TESTDIR}/libslic3r/test_config.cpp
|
${TESTDIR}/libslic3r/test_config.cpp
|
||||||
${TESTDIR}/libslic3r/test_support_material.cpp
|
${TESTDIR}/libslic3r/test_support_material.cpp
|
||||||
|
${TESTDIR}/libslic3r/test_flow.cpp
|
||||||
|
${TESTDIR}/libslic3r/test_printgcode.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
add_executable(slic3r slic3r.cpp)
|
add_executable(slic3r slic3r.cpp)
|
||||||
#set_target_properties(slic3r PROPERTIES LINK_SEARCH_START_STATIC 1)
|
#set_target_properties(slic3r PROPERTIES LINK_SEARCH_START_STATIC 1)
|
||||||
#set_target_properties(slic3r PROPERTIES LINK_SEARCH_END_STATIC 1)
|
#set_target_properties(slic3r PROPERTIES LINK_SEARCH_END_STATIC 1)
|
||||||
|
127
src/test/libslic3r/test_flow.cpp
Normal file
127
src/test/libslic3r/test_flow.cpp
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
#include <catch.hpp>
|
||||||
|
|
||||||
|
#include <numeric>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "test_data.hpp" // get access to init_print, etc
|
||||||
|
|
||||||
|
#include "Config.hpp"
|
||||||
|
#include "Model.hpp"
|
||||||
|
#include "ConfigBase.hpp"
|
||||||
|
#include "GCodeReader.hpp"
|
||||||
|
#include "Flow.hpp"
|
||||||
|
|
||||||
|
using namespace Slic3r::Test;
|
||||||
|
using namespace Slic3r;
|
||||||
|
|
||||||
|
SCENARIO("Extrusion width specifics") {
|
||||||
|
GIVEN("A config with a skirt, brim, some fill density, 3 perimeters, and 1 bottom solid layer and a 20mm cube mesh") {
|
||||||
|
// this is a sharedptr
|
||||||
|
auto config {Slic3r::Config::new_from_defaults()};
|
||||||
|
config->set("skirts", 1);
|
||||||
|
config->set("brim_width", 2);
|
||||||
|
config->set("perimeters", 3);
|
||||||
|
config->set("fill_density", 0.4);
|
||||||
|
config->set("first_layer_height", "100%");
|
||||||
|
|
||||||
|
WHEN("first layer width set to 2mm") {
|
||||||
|
config->set("first_layer_extrusion_width", 2);
|
||||||
|
auto print {Slic3r::Test::init_print(std::make_tuple<int,int,int>(20,20,20), config)};
|
||||||
|
std::vector<double> E_per_mm_bottom;
|
||||||
|
auto gcode {std::stringstream("")};
|
||||||
|
Slic3r::Test::gcode(gcode, print);
|
||||||
|
auto parser {Slic3r::GCodeReader()};
|
||||||
|
const auto layer_height { config->getFloat("layer_height") };
|
||||||
|
parser.parse_stream(gcode, [&E_per_mm_bottom, layer_height] (Slic3r::GCodeReader& self, const Slic3r::GCodeReader::GCodeLine& line)
|
||||||
|
{
|
||||||
|
if (self.Z == layer_height) { // only consider first layer
|
||||||
|
if (line.extruding() && line.dist_XY() > 0) {
|
||||||
|
E_per_mm_bottom.emplace_back(line.dist_E() / line.dist_XY());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
THEN(" First layer width applies to everything on first layer.") {
|
||||||
|
bool pass = false;
|
||||||
|
auto avg_E {std::accumulate(E_per_mm_bottom.cbegin(), E_per_mm_bottom.cend(), 0.0) / static_cast<double>(E_per_mm_bottom.size())};
|
||||||
|
|
||||||
|
pass = std::count_if(E_per_mm_bottom.cbegin(), E_per_mm_bottom.cend(), [avg_E] (double v) { return _equiv(v, avg_E, 0.015); }) == 0;
|
||||||
|
REQUIRE(pass == true);
|
||||||
|
REQUIRE(E_per_mm_bottom.size() > 0);
|
||||||
|
}
|
||||||
|
THEN(" First layer width does not apply to upper layer.") {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SCENARIO(" Bridge flow specifics.", "[!mayfail]") {
|
||||||
|
GIVEN("A default config with no cooling and a fixed bridge speed, flow ratio and an overhang mesh.") {
|
||||||
|
WHEN("bridge_flow_ratio is set to 1.0") {
|
||||||
|
THEN("Output flow is as expected.") {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WHEN("bridge_flow_ratio is set to 0.5") {
|
||||||
|
THEN("Output flow is as expected.") {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WHEN("bridge_flow_ratio is set to 2.0") {
|
||||||
|
THEN("Output flow is as expected.") {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GIVEN("A default config with no cooling and a fixed bridge speed, flow ratio, fixed extrusion width of 0.4mm and an overhang mesh.") {
|
||||||
|
WHEN("bridge_flow_ratio is set to 1.0") {
|
||||||
|
THEN("Output flow is as expected.") {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WHEN("bridge_flow_ratio is set to 0.5") {
|
||||||
|
THEN("Output flow is as expected.") {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WHEN("bridge_flow_ratio is set to 2.0") {
|
||||||
|
THEN("Output flow is as expected.") {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Test the expected behavior for auto-width,
|
||||||
|
/// spacing, etc
|
||||||
|
SCENARIO("Flow: Flow math for non-bridges", "[!mayfail]") {
|
||||||
|
GIVEN("Nozzle Diameter of 0.4, a desired width of 1mm and layer height of 0.5") {
|
||||||
|
auto width {ConfigOptionFloat(1.0)};
|
||||||
|
auto spacing {0.4};
|
||||||
|
auto nozzle_diameter {0.4};
|
||||||
|
auto bridge_flow {1.0};
|
||||||
|
|
||||||
|
// Spacing for non-bridges is has some overlap
|
||||||
|
THEN("External perimeter flow has spacing of <>") {
|
||||||
|
}
|
||||||
|
|
||||||
|
THEN("Internal perimeter flow has spacing of <>") {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// Check the min/max
|
||||||
|
GIVEN("Nozzle Diameter of 0.4") {
|
||||||
|
WHEN("AA") {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GIVEN("Nozzle Diameter of 0.4, a desired spacing of 1mm and layer height of 0.5") {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Spacing, width calculation for bridge extrusions
|
||||||
|
SCENARIO("Flow: Flow math for bridges", "[!mayfail]") {
|
||||||
|
GIVEN("Nozzle Diameter of 0.4, a desired width of 1mm and layer height of 0.5") {
|
||||||
|
// auto width {ConfigOptionFloat(1.0)};
|
||||||
|
auto spacing {0.4};
|
||||||
|
auto nozzle_diameter {0.4};
|
||||||
|
auto bridge_flow {1.0};
|
||||||
|
}
|
||||||
|
|
||||||
|
GIVEN("Nozzle Diameter of 0.4, a desired spacing of 1mm and layer height of 0.5") {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SCENARIO("Flow: Auto spacing", "[!mayfail]") {
|
||||||
|
}
|
91
src/test/libslic3r/test_printgcode.cpp
Normal file
91
src/test/libslic3r/test_printgcode.cpp
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
#include <catch.hpp>
|
||||||
|
|
||||||
|
#include <regex>
|
||||||
|
#include "test_data.hpp"
|
||||||
|
#include "libslic3r.h"
|
||||||
|
|
||||||
|
SCENARIO( "PrintGCode basic functionality", "[!mayfail]") {
|
||||||
|
GIVEN("A default configuration and a print test object") {
|
||||||
|
auto config {Slic3r::Config::new_from_defaults()};
|
||||||
|
auto gcode {std::stringstream("")};
|
||||||
|
|
||||||
|
WHEN("the output is executed with no support material") {
|
||||||
|
config->set("first_layer_extrusion_width", 0);
|
||||||
|
auto print {Slic3r::Test::init_print(std::make_tuple<int,int,int>(20,20,20), config)};
|
||||||
|
Slic3r::Test::gcode(gcode, print);
|
||||||
|
auto exported {gcode.str()};
|
||||||
|
THEN("Some text output is generated.") {
|
||||||
|
REQUIRE(exported.size() > 0);
|
||||||
|
}
|
||||||
|
THEN("Exported text contains slic3r version") {
|
||||||
|
REQUIRE(exported.find(SLIC3R_VERSION) != std::string::npos);
|
||||||
|
}
|
||||||
|
THEN("Exported text contains git commit id") {
|
||||||
|
REQUIRE(exported.find("; Git Commit") != std::string::npos);
|
||||||
|
REQUIRE(exported.find(BUILD_COMMIT) != std::string::npos);
|
||||||
|
}
|
||||||
|
THEN("Exported text contains extrusion statistics.") {
|
||||||
|
REQUIRE(exported.find("; external perimeters extrusion width") != std::string::npos);
|
||||||
|
REQUIRE(exported.find("; perimeters extrusion width") != std::string::npos);
|
||||||
|
REQUIRE(exported.find("; infill extrusion width") != std::string::npos);
|
||||||
|
REQUIRE(exported.find("; solid infill extrusion width") != std::string::npos);
|
||||||
|
REQUIRE(exported.find("; top solid infill extrusion width") != std::string::npos);
|
||||||
|
REQUIRE(exported.find("; support material extrusion width") == std::string::npos);
|
||||||
|
REQUIRE(exported.find("; first layer extrusion width") == std::string::npos);
|
||||||
|
}
|
||||||
|
|
||||||
|
THEN("GCode preamble is emitted.") {
|
||||||
|
REQUIRE(exported.find("G21 ; set units to millimeters") != std::string::npos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WHEN("the output is executed with support material") {
|
||||||
|
config->set("first_layer_extrusion_width", 0);
|
||||||
|
config->set("support_material", true);
|
||||||
|
config->set("raft_layers", 3);
|
||||||
|
auto print {Slic3r::Test::init_print(std::make_tuple<int,int,int>(20,20,20), config)};
|
||||||
|
Slic3r::Test::gcode(gcode, print);
|
||||||
|
auto exported {gcode.str()};
|
||||||
|
THEN("Some text output is generated.") {
|
||||||
|
REQUIRE(exported.size() > 0);
|
||||||
|
}
|
||||||
|
THEN("Exported text contains extrusion statistics.") {
|
||||||
|
REQUIRE(exported.find("; external perimeters extrusion width") != std::string::npos);
|
||||||
|
REQUIRE(exported.find("; perimeters extrusion width") != std::string::npos);
|
||||||
|
REQUIRE(exported.find("; infill extrusion width") != std::string::npos);
|
||||||
|
REQUIRE(exported.find("; solid infill extrusion width") != std::string::npos);
|
||||||
|
REQUIRE(exported.find("; top solid infill extrusion width") != std::string::npos);
|
||||||
|
REQUIRE(exported.find("; support material extrusion width") != std::string::npos);
|
||||||
|
REQUIRE(exported.find("; first layer extrusion width") == std::string::npos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WHEN("the output is executed with a separate first layer extrusion width") {
|
||||||
|
config->set("first_layer_extrusion_width", 0.5);
|
||||||
|
auto print {Slic3r::Test::init_print(std::make_tuple<int,int,int>(20,20,20), config)};
|
||||||
|
Slic3r::Test::gcode(gcode, print);
|
||||||
|
auto exported {gcode.str()};
|
||||||
|
THEN("Some text output is generated.") {
|
||||||
|
REQUIRE(exported.size() > 0);
|
||||||
|
}
|
||||||
|
THEN("Exported text contains extrusion statistics.") {
|
||||||
|
REQUIRE(exported.find("; external perimeters extrusion width") != std::string::npos);
|
||||||
|
REQUIRE(exported.find("; perimeters extrusion width") != std::string::npos);
|
||||||
|
REQUIRE(exported.find("; infill extrusion width") != std::string::npos);
|
||||||
|
REQUIRE(exported.find("; solid infill extrusion width") != std::string::npos);
|
||||||
|
REQUIRE(exported.find("; top solid infill extrusion width") != std::string::npos);
|
||||||
|
REQUIRE(exported.find("; support material extrusion width") == std::string::npos);
|
||||||
|
REQUIRE(exported.find("; first layer extrusion width") != std::string::npos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WHEN("Cooling is enabled and the fan is disabled.") {
|
||||||
|
config->set("cooling", true);
|
||||||
|
config->set("disable_fan_first_layers", 5);
|
||||||
|
auto print {Slic3r::Test::init_print(std::make_tuple<int,int,int>(20,20,20), config)};
|
||||||
|
Slic3r::Test::gcode(gcode, print);
|
||||||
|
auto exported {gcode.str()};
|
||||||
|
THEN("GCode to disable fan is emitted."){
|
||||||
|
REQUIRE(exported.find("M107") != std::string::npos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gcode.clear();
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,39 @@
|
|||||||
#include "test_data.hpp"
|
#include "test_data.hpp"
|
||||||
|
#include "TriangleMesh.hpp"
|
||||||
|
#include "GCodeReader.hpp"
|
||||||
|
#include "Config.hpp"
|
||||||
|
#include "Print.hpp"
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
using namespace std::string_literals;
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
namespace Slic3r { namespace Test {
|
namespace Slic3r { namespace Test {
|
||||||
|
|
||||||
|
// Mesh enumeration to name mapping
|
||||||
|
const std::unordered_map<TestMesh, const char*> mesh_names {
|
||||||
|
std::make_pair<TestMesh, const char*>(TestMesh::A,"A"),
|
||||||
|
std::make_pair<TestMesh, const char*>(TestMesh::L,"L"),
|
||||||
|
std::make_pair<TestMesh, const char*>(TestMesh::V,"V"),
|
||||||
|
std::make_pair<TestMesh, const char*>(TestMesh::_40x10,"40x10"),
|
||||||
|
std::make_pair<TestMesh, const char*>(TestMesh::bridge,"bridge"),
|
||||||
|
std::make_pair<TestMesh, const char*>(TestMesh::bridge_with_hole,"bridge_with_hole"),
|
||||||
|
std::make_pair<TestMesh, const char*>(TestMesh::cube_with_concave_hole,"cube_with_concave_hole"),
|
||||||
|
std::make_pair<TestMesh, const char*>(TestMesh::cube_with_hole,"cube_with_hole"),
|
||||||
|
std::make_pair<TestMesh, const char*>(TestMesh::gt2_teeth,"gt2_teeth"),
|
||||||
|
std::make_pair<TestMesh, const char*>(TestMesh::ipadstand,"ipadstand"),
|
||||||
|
std::make_pair<TestMesh, const char*>(TestMesh::overhang,"overhang"),
|
||||||
|
std::make_pair<TestMesh, const char*>(TestMesh::pyramid,"pyramid"),
|
||||||
|
std::make_pair<TestMesh, const char*>(TestMesh::sloping_hole,"sloping_hole"),
|
||||||
|
std::make_pair<TestMesh, const char*>(TestMesh::slopy_cube,"slopy_cube"),
|
||||||
|
std::make_pair<TestMesh, const char*>(TestMesh::small_dorito,"small_dorito"),
|
||||||
|
std::make_pair<TestMesh, const char*>(TestMesh::step,"step"),
|
||||||
|
std::make_pair<TestMesh, const char*>(TestMesh::two_hollow_squares,"two_hollow_squares")
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
TriangleMesh mesh(TestMesh m) {
|
TriangleMesh mesh(TestMesh m) {
|
||||||
Point3s facets;
|
Point3s facets;
|
||||||
Pointf3s vertices;
|
Pointf3s vertices;
|
||||||
@ -150,11 +182,71 @@ TriangleMesh mesh(TestMesh m) {
|
|||||||
return _mesh;
|
return _mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TriangleMesh mesh(TestMesh m, Pointf3 translate, double scale) {
|
||||||
|
return mesh(m, translate, Pointf3(scale, scale, scale));
|
||||||
|
}
|
||||||
TriangleMesh mesh(TestMesh m, Pointf3 translate, Pointf3 scale) {
|
TriangleMesh mesh(TestMesh m, Pointf3 translate, Pointf3 scale) {
|
||||||
TriangleMesh _mesh {mesh(m)};
|
TriangleMesh _mesh {mesh(m)};
|
||||||
_mesh.scale(scale);
|
_mesh.scale(scale);
|
||||||
_mesh.translate(translate);
|
_mesh.translate(translate);
|
||||||
return _mesh;
|
return _mesh;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
Slic3r::Model model(const std::string& model_name, TestMesh m, Pointf3 translate = Pointf3(0,0,0), double scale = 1.0) {
|
||||||
|
return model(model_name, m, translate, Pointf3(scale, scale, scale));
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
Slic3r::Test::Print init_print(std::tuple<int,int,int> cube, config_ptr _config) {
|
||||||
|
std::stringstream s;
|
||||||
|
s << "cube_" << get<0>(cube) << "x" << get<1>(cube) << "x" << get<2>(cube);
|
||||||
|
|
||||||
|
auto config {Slic3r::Config::new_from_defaults()};
|
||||||
|
|
||||||
|
config->apply(_config);
|
||||||
|
const char* v {std::getenv("SLIC3R_TESTS_GCODE")};
|
||||||
|
auto tests_gcode {(v == nullptr ? ""s : std::string(v))};
|
||||||
|
|
||||||
|
if (tests_gcode != ""s)
|
||||||
|
config->set("gcode_comments", 1);
|
||||||
|
|
||||||
|
std::shared_ptr<Slic3r::Print> print = std::make_shared<Slic3r::Print>();
|
||||||
|
print->apply_config(config);
|
||||||
|
|
||||||
|
auto model {Slic3r::Test::model(s.str(), Slic3r::TriangleMesh::make_cube(get<0>(cube), get<1>(cube), get<1>(cube))) };
|
||||||
|
|
||||||
|
model.arrange_objects(print->config.min_object_distance());
|
||||||
|
model.center_instances_around_point(Slic3r::Pointf(100,100));
|
||||||
|
for (auto* mo : model.objects) {
|
||||||
|
print->auto_assign_extruders(mo);
|
||||||
|
print->add_model_object(mo);
|
||||||
|
}
|
||||||
|
|
||||||
|
print->validate();
|
||||||
|
|
||||||
|
std::vector<Slic3r::Model> models {};
|
||||||
|
models.emplace_back(model);
|
||||||
|
return Slic3r::Test::Print(print, models);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gcode(std::stringstream& gcode, Slic3r::Test::Print& _print) {
|
||||||
|
Slic3r::Print& print {_print.print()};
|
||||||
|
print.process();
|
||||||
|
print.export_gcode(gcode, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
Slic3r::Model model(const std::string& model_name, TriangleMesh&& _mesh) {
|
||||||
|
Slic3r::Model result;
|
||||||
|
|
||||||
|
auto* object {result.add_object()};
|
||||||
|
object->name += model_name + ".stl"s;
|
||||||
|
object->add_volume(_mesh);
|
||||||
|
|
||||||
|
auto* inst {object->add_instance()};
|
||||||
|
inst->rotation = 0;
|
||||||
|
inst->scaling_factor = 1.0;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
} } // namespace Slic3r::Test
|
} } // namespace Slic3r::Test
|
||||||
|
@ -2,9 +2,15 @@
|
|||||||
#include "Point.hpp"
|
#include "Point.hpp"
|
||||||
#include "TriangleMesh.hpp"
|
#include "TriangleMesh.hpp"
|
||||||
#include "Geometry.hpp"
|
#include "Geometry.hpp"
|
||||||
|
#include "Model.hpp"
|
||||||
|
#include "Print.hpp"
|
||||||
|
#include "Config.hpp"
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
namespace Slic3r { namespace Test {
|
namespace Slic3r { namespace Test {
|
||||||
|
|
||||||
|
/// Enumeration of test meshes
|
||||||
enum class TestMesh {
|
enum class TestMesh {
|
||||||
A,
|
A,
|
||||||
L,
|
L,
|
||||||
@ -25,16 +31,46 @@ enum class TestMesh {
|
|||||||
two_hollow_squares
|
two_hollow_squares
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Print {
|
||||||
|
public:
|
||||||
|
Print(std::shared_ptr<Slic3r::Print> _print, std::vector<Slic3r::Model> _models) : models(_models), _print(_print) {}
|
||||||
|
void process() { _print->process(); }
|
||||||
|
void apply_config(config_ptr _config) { _print->apply_config(_config); }
|
||||||
|
Slic3r::Print& print() { return *(_print); }
|
||||||
|
|
||||||
|
const std::vector<Slic3r::Model> models {};
|
||||||
|
private:
|
||||||
|
std::shared_ptr<Slic3r::Print> _print {nullptr};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/// Mesh enumeration to name mapping
|
||||||
|
extern const std::unordered_map<TestMesh, const char*> mesh_names;
|
||||||
|
|
||||||
/// Port of Slic3r::Test::mesh
|
/// Port of Slic3r::Test::mesh
|
||||||
/// Basic cubes/boxes should call TriangleMesh::make_cube() directly and rescale/translate it
|
/// Basic cubes/boxes should call TriangleMesh::make_cube() directly and rescale/translate it
|
||||||
TriangleMesh mesh(TestMesh m);
|
TriangleMesh mesh(TestMesh m);
|
||||||
|
|
||||||
TriangleMesh mesh(TestMesh m, Pointf3 translate, Pointf3 scale = Pointf3(1.0, 1.0, 1.0));
|
TriangleMesh mesh(TestMesh m, Pointf3 translate, Pointf3 scale = Pointf3(1.0, 1.0, 1.0));
|
||||||
|
TriangleMesh mesh(TestMesh m, Pointf3 translate, double scale = 1.0);
|
||||||
|
|
||||||
/// Templated function to see if two values are equivalent (+/- epsilon)
|
/// Templated function to see if two values are equivalent (+/- epsilon)
|
||||||
template <typename T, typename U>
|
template <typename T, typename U>
|
||||||
bool _equiv(T a, U b) { return abs(a - b) < Slic3r::Geometry::epsilon; }
|
bool _equiv(const T& a, const U& b) { return abs(a - b) < Slic3r::Geometry::epsilon; }
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
bool _equiv(const T& a, const U& b, double epsilon) { return abs(a - b) < epsilon; }
|
||||||
|
|
||||||
|
//Slic3r::Model model(const std::string& model_name, TestMesh m, Pointf3 translate = Pointf3(0,0,0), Pointf3 scale = Pointf3(1.0,1.0,1.0));
|
||||||
|
//Slic3r::Model model(const std::string& model_name, TestMesh m, Pointf3 translate = Pointf3(0,0,0), double scale = 1.0);
|
||||||
|
|
||||||
|
Slic3r::Model model(const std::string& model_name, TriangleMesh&& _mesh);
|
||||||
|
|
||||||
|
Slic3r::Test::Print init_print(std::tuple<int,int,int> cube, config_ptr _config = Slic3r::Config::new_from_defaults());
|
||||||
|
|
||||||
|
void gcode(std::stringstream& gcode, Slic3r::Test::Print& print);
|
||||||
|
|
||||||
} } // namespace Slic3r::Test
|
} } // namespace Slic3r::Test
|
||||||
|
|
||||||
|
|
||||||
#endif // SLIC3R_TEST_DATA_HPP
|
#endif // SLIC3R_TEST_DATA_HPP
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "Print.hpp"
|
#include "Print.hpp"
|
||||||
|
#include "PrintGCode.hpp"
|
||||||
#include "BoundingBox.hpp"
|
#include "BoundingBox.hpp"
|
||||||
#include "ClipperUtils.hpp"
|
#include "ClipperUtils.hpp"
|
||||||
#include "Fill/Fill.hpp"
|
#include "Fill/Fill.hpp"
|
||||||
@ -91,6 +92,25 @@ Print::delete_object(size_t idx)
|
|||||||
// TODO: purge unused regions
|
// TODO: purge unused regions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef SLIC3RXS
|
||||||
|
|
||||||
|
void
|
||||||
|
Print::process()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Print::make_brim()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Print::make_skirt()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // SLIC3RXS
|
||||||
|
|
||||||
void
|
void
|
||||||
Print::reload_object(size_t idx)
|
Print::reload_object(size_t idx)
|
||||||
{
|
{
|
||||||
@ -500,6 +520,27 @@ Print::add_model_object(ModelObject* model_object, int idx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef SLIC3RXS
|
||||||
|
void
|
||||||
|
Print::export_gcode(std::ostream& output, bool quiet)
|
||||||
|
{
|
||||||
|
this->process();
|
||||||
|
if (this->status_cb != nullptr)
|
||||||
|
this->status_cb(90, "Exporting G-Code...");
|
||||||
|
|
||||||
|
auto export_handler {Slic3r::PrintGCode(*this, output)};
|
||||||
|
export_handler.output();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Print::apply_config(config_ptr config) {
|
||||||
|
// dereference the stored pointer and pass the resulting data to apply_config()
|
||||||
|
return this->apply_config(config->config());
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Print::apply_config(DynamicPrintConfig config)
|
Print::apply_config(DynamicPrintConfig config)
|
||||||
{
|
{
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "BoundingBox.hpp"
|
#include "BoundingBox.hpp"
|
||||||
#include "Flow.hpp"
|
#include "Flow.hpp"
|
||||||
#include "PrintConfig.hpp"
|
#include "PrintConfig.hpp"
|
||||||
|
#include "Config.hpp"
|
||||||
#include "Point.hpp"
|
#include "Point.hpp"
|
||||||
#include "Layer.hpp"
|
#include "Layer.hpp"
|
||||||
#include "Model.hpp"
|
#include "Model.hpp"
|
||||||
@ -184,6 +185,13 @@ class Print
|
|||||||
PrintRegionPtrs regions;
|
PrintRegionPtrs regions;
|
||||||
PlaceholderParser placeholder_parser;
|
PlaceholderParser placeholder_parser;
|
||||||
// TODO: status_cb
|
// TODO: status_cb
|
||||||
|
#ifndef SLIC3RXS
|
||||||
|
std::function<void(int, const std::string&)> status_cb {nullptr};
|
||||||
|
|
||||||
|
/// Function pointer for the UI side to call post-processing scripts.
|
||||||
|
/// Vector is assumed to be the executable script and all arguments.
|
||||||
|
std::function<void(std::vector<std::string>)> post_process_cb {nullptr};
|
||||||
|
#endif
|
||||||
double total_used_filament, total_extruded_volume, total_cost, total_weight;
|
double total_used_filament, total_extruded_volume, total_cost, total_weight;
|
||||||
std::map<size_t,float> filament_stats;
|
std::map<size_t,float> filament_stats;
|
||||||
PrintState<PrintStep> state;
|
PrintState<PrintStep> state;
|
||||||
@ -207,6 +215,21 @@ class Print
|
|||||||
const PrintRegion* get_region(size_t idx) const { return this->regions.at(idx); };
|
const PrintRegion* get_region(size_t idx) const { return this->regions.at(idx); };
|
||||||
PrintRegion* add_region();
|
PrintRegion* add_region();
|
||||||
|
|
||||||
|
#ifndef SLIC3RXS
|
||||||
|
/// Triggers the rest of the print process
|
||||||
|
void process();
|
||||||
|
|
||||||
|
/// Performs a gcode export.
|
||||||
|
void export_gcode(std::ostream& output, bool quiet = false);
|
||||||
|
|
||||||
|
/// Performs a gcode export and then runs post-processing scripts (if any)
|
||||||
|
void export_gcode(const std::string& filename, bool quiet = false);
|
||||||
|
|
||||||
|
/// commands a gcode export to a temporary file and return its name
|
||||||
|
std::string export_gcode(bool quiet = false);
|
||||||
|
|
||||||
|
#endif // SLIC3RXS
|
||||||
|
|
||||||
// methods for handling state
|
// methods for handling state
|
||||||
bool invalidate_state_by_config(const PrintConfigBase &config);
|
bool invalidate_state_by_config(const PrintConfigBase &config);
|
||||||
bool invalidate_step(PrintStep step);
|
bool invalidate_step(PrintStep step);
|
||||||
@ -214,6 +237,10 @@ class Print
|
|||||||
bool step_done(PrintObjectStep step) const;
|
bool step_done(PrintObjectStep step) const;
|
||||||
|
|
||||||
void add_model_object(ModelObject* model_object, int idx = -1);
|
void add_model_object(ModelObject* model_object, int idx = -1);
|
||||||
|
#ifndef SLIC3RXS
|
||||||
|
/// Apply a provided configuration to the internal copy
|
||||||
|
bool apply_config(config_ptr config);
|
||||||
|
#endif // SLIC3RXS
|
||||||
bool apply_config(DynamicPrintConfig config);
|
bool apply_config(DynamicPrintConfig config);
|
||||||
bool has_infinite_skirt() const;
|
bool has_infinite_skirt() const;
|
||||||
bool has_skirt() const;
|
bool has_skirt() const;
|
||||||
@ -226,6 +253,16 @@ class Print
|
|||||||
Flow skirt_flow() const;
|
Flow skirt_flow() const;
|
||||||
void _make_brim();
|
void _make_brim();
|
||||||
|
|
||||||
|
#ifndef SLIC3RXS
|
||||||
|
/// Generates a skirt around the union of all of
|
||||||
|
/// the objects in the print.
|
||||||
|
void make_skirt();
|
||||||
|
|
||||||
|
/// Generates a brim around all of the objects in the print.
|
||||||
|
void make_brim();
|
||||||
|
#endif // SLIC3RXS
|
||||||
|
|
||||||
|
|
||||||
std::set<size_t> object_extruders() const;
|
std::set<size_t> object_extruders() const;
|
||||||
std::set<size_t> support_material_extruders() const;
|
std::set<size_t> support_material_extruders() const;
|
||||||
std::set<size_t> extruders() const;
|
std::set<size_t> extruders() const;
|
||||||
|
211
xs/src/libslic3r/PrintGCode.cpp
Normal file
211
xs/src/libslic3r/PrintGCode.cpp
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
#ifndef SLIC3RXS
|
||||||
|
#include "PrintGCode.hpp"
|
||||||
|
|
||||||
|
#include <ctime>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace Slic3r {
|
||||||
|
void
|
||||||
|
PrintGCode::output()
|
||||||
|
{
|
||||||
|
auto& gcodegen {this->_gcodegen};
|
||||||
|
auto& fh {this->fh};
|
||||||
|
auto& print {this->_print};
|
||||||
|
const auto& config {this->config};
|
||||||
|
|
||||||
|
// Write information about the generator.
|
||||||
|
time_t rawtime; tm * timeinfo;
|
||||||
|
time(&rawtime);
|
||||||
|
timeinfo = localtime(&rawtime);
|
||||||
|
|
||||||
|
fh << "; generated by Slic3r " << SLIC3R_VERSION << " on ";
|
||||||
|
fh << asctime(timeinfo) << "\n";
|
||||||
|
fh << "; Git Commit: " << BUILD_COMMIT << "\n\n";
|
||||||
|
|
||||||
|
// Writes notes (content of all Settings tabs -> Notes)
|
||||||
|
fh << gcodegen.notes();
|
||||||
|
|
||||||
|
// Write some terse information on the slicing parameters.
|
||||||
|
auto& first_object {*(this->objects.at(0))};
|
||||||
|
auto layer_height {first_object.config.layer_height.getFloat()};
|
||||||
|
|
||||||
|
for (auto* region : print.regions) {
|
||||||
|
{
|
||||||
|
auto flow {region->flow(frExternalPerimeter, layer_height, false, false, -1, first_object)};
|
||||||
|
auto vol_speed {flow.mm3_per_mm() * region->config.get_abs_value("external_perimeter_speed")};
|
||||||
|
if (config.max_volumetric_speed.getInt() > 0)
|
||||||
|
vol_speed = std::min(vol_speed, config.max_volumetric_speed.getFloat());
|
||||||
|
fh << "; external perimeters extrusion width = ";
|
||||||
|
fh << std::fixed << std::setprecision(2) << flow.width << "mm ";
|
||||||
|
fh << "(" << vol_speed << "mm^3/s)\n";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto flow {region->flow(frPerimeter, layer_height, false, false, -1, first_object)};
|
||||||
|
auto vol_speed {flow.mm3_per_mm() * region->config.get_abs_value("perimeter_speed")};
|
||||||
|
if (config.max_volumetric_speed.getInt() > 0)
|
||||||
|
vol_speed = std::min(vol_speed, config.max_volumetric_speed.getFloat());
|
||||||
|
fh << "; perimeters extrusion width = ";
|
||||||
|
fh << std::fixed << std::setprecision(2) << flow.width << "mm ";
|
||||||
|
fh << "(" << vol_speed << "mm^3/s)\n";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto flow {region->flow(frInfill, layer_height, false, false, -1, first_object)};
|
||||||
|
auto vol_speed {flow.mm3_per_mm() * region->config.get_abs_value("infill_speed")};
|
||||||
|
if (config.max_volumetric_speed.getInt() > 0)
|
||||||
|
vol_speed = std::min(vol_speed, config.max_volumetric_speed.getFloat());
|
||||||
|
fh << "; infill extrusion width = ";
|
||||||
|
fh << std::fixed << std::setprecision(2) << flow.width << "mm ";
|
||||||
|
fh << "(" << vol_speed << "mm^3/s)\n";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto flow {region->flow(frSolidInfill, layer_height, false, false, -1, first_object)};
|
||||||
|
auto vol_speed {flow.mm3_per_mm() * region->config.get_abs_value("solid_infill_speed")};
|
||||||
|
if (config.max_volumetric_speed.getInt() > 0)
|
||||||
|
vol_speed = std::min(vol_speed, config.max_volumetric_speed.getFloat());
|
||||||
|
fh << "; solid infill extrusion width = ";
|
||||||
|
fh << std::fixed << std::setprecision(2) << flow.width << "mm ";
|
||||||
|
fh << "(" << vol_speed << "mm^3/s)\n";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto flow {region->flow(frTopSolidInfill, layer_height, false, false, -1, first_object)};
|
||||||
|
auto vol_speed {flow.mm3_per_mm() * region->config.get_abs_value("top_solid_infill_speed")};
|
||||||
|
if (config.max_volumetric_speed.getInt() > 0)
|
||||||
|
vol_speed = std::min(vol_speed, config.max_volumetric_speed.getFloat());
|
||||||
|
fh << "; top solid infill extrusion width = ";
|
||||||
|
fh << std::fixed << std::setprecision(2) << flow.width << "mm ";
|
||||||
|
fh << "(" << vol_speed << "mm^3/s)\n";
|
||||||
|
}
|
||||||
|
if (print.has_support_material()) {
|
||||||
|
auto flow {first_object._support_material_flow()};
|
||||||
|
auto vol_speed {flow.mm3_per_mm() * first_object.config.get_abs_value("support_material_speed")};
|
||||||
|
if (config.max_volumetric_speed.getInt() > 0)
|
||||||
|
vol_speed = std::min(vol_speed, config.max_volumetric_speed.getFloat());
|
||||||
|
fh << "; support material extrusion width = ";
|
||||||
|
fh << std::fixed << std::setprecision(2) << flow.width << "mm ";
|
||||||
|
fh << "(" << vol_speed << "mm^3/s)\n";
|
||||||
|
}
|
||||||
|
if (print.config.first_layer_extrusion_width.getFloat() > 0) {
|
||||||
|
auto flow {region->flow(frPerimeter, layer_height, false, false, -1, first_object)};
|
||||||
|
// auto vol_speed {flow.mm3_per_mm() * print.config.get_abs_value("first_layer_speed")};
|
||||||
|
// if (config.max_volumetric_speed.getInt() > 0)
|
||||||
|
// vol_speed = std::min(vol_speed, config.max_volumetric_speed.getFloat());
|
||||||
|
fh << "; first layer extrusion width = ";
|
||||||
|
fh << std::fixed << std::setprecision(2) << flow.width << "mm ";
|
||||||
|
// fh << "(" << vol_speed << "mm^3/s)\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
fh << std::endl;
|
||||||
|
}
|
||||||
|
// Prepare the helper object for replacing placeholders in custom G-Code and output filename
|
||||||
|
print.placeholder_parser.update_timestamp();
|
||||||
|
|
||||||
|
// GCode sets this automatically when change_layer() is called, but needed for skirt/brim as well
|
||||||
|
gcodegen.first_layer = true;
|
||||||
|
|
||||||
|
// disable fan
|
||||||
|
if (config.cooling.getBool() && config.disable_fan_first_layers.getInt() > 0) {
|
||||||
|
fh << gcodegen.writer.set_fan(0,1) << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// set bed temperature
|
||||||
|
auto bed_temp_regex { std::regex("M(?:190|140)", std::regex_constants::icase)};
|
||||||
|
auto ex_temp_regex { std::regex("M(?:109|104)", std::regex_constants::icase)};
|
||||||
|
auto temp{config.first_layer_bed_temperature.getFloat()};
|
||||||
|
if (config.has_heatbed.getBool() && temp > 0 && std::regex_search(config.start_gcode.getString(), bed_temp_regex)) {
|
||||||
|
fh << gcodegen.writer.set_bed_temperature(temp, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set extruder(s) temperature before and after start gcode.
|
||||||
|
auto include_start_extruder_temp {!std::regex_search(config.start_gcode.getString(), ex_temp_regex)};
|
||||||
|
for(const auto& start_gcode : config.start_filament_gcode.values) {
|
||||||
|
include_start_extruder_temp = include_start_extruder_temp && !std::regex_search(start_gcode, ex_temp_regex);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto include_end_extruder_temp {!std::regex_search(config.end_gcode.getString(), ex_temp_regex)};
|
||||||
|
for(const auto& end_gcode : config.end_filament_gcode.values) {
|
||||||
|
include_end_extruder_temp = include_end_extruder_temp && !std::regex_search(end_gcode, ex_temp_regex);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (include_start_extruder_temp) this->_print_first_layer_temperature(0);
|
||||||
|
|
||||||
|
// Apply gcode math to start and end gcode
|
||||||
|
// fh << apply_math(gcodegen.placeholder_parser->process(config.start_gcode.value));
|
||||||
|
|
||||||
|
for(const auto& start_gcode : config.start_filament_gcode.values) {
|
||||||
|
// fh << apply_math(gcodegen.placeholder_parser->process(start_gcode));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (include_start_extruder_temp) this->_print_first_layer_temperature(1);
|
||||||
|
|
||||||
|
|
||||||
|
// Set other general things (preamble)
|
||||||
|
fh << gcodegen.preamble();
|
||||||
|
|
||||||
|
// initialize motion planner for object-to-object travel moves
|
||||||
|
if (config.avoid_crossing_perimeters.getBool()) {
|
||||||
|
auto distance_from_objects {scale_(1)};
|
||||||
|
|
||||||
|
// compute the offsetted convex hull for each object and repeat it for each copy
|
||||||
|
Polygons islands_p {};
|
||||||
|
for (auto object : this->objects) {
|
||||||
|
Polygons polygons {};
|
||||||
|
for (auto layer : object->layers) {
|
||||||
|
const auto& slice {ExPolygons(layer->slices)};
|
||||||
|
std::for_each(slice.cbegin(), slice.cend(), [&polygons] (const ExPolygon& a) { polygons.emplace_back(a.contour); });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (polygons.size() == 0) continue;
|
||||||
|
|
||||||
|
for (auto copy : object->_shifted_copies) {
|
||||||
|
Polygons copy_islands_p {polygons};
|
||||||
|
std::for_each(copy_islands_p.begin(), copy_islands_p.end(), [copy] (Polygon& obj) { obj.translate(copy); });
|
||||||
|
islands_p.insert(islands_p.cend(), copy_islands_p.begin(), copy_islands_p.end());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gcodegen.avoid_crossing_perimeters.init_external_mp(union_ex(islands_p));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate wiping points if needed.
|
||||||
|
//
|
||||||
|
|
||||||
|
// Set initial extruder only after custom start gcode
|
||||||
|
|
||||||
|
// Do all objects for each layer.
|
||||||
|
|
||||||
|
if (config.complete_objects.getBool()) {
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write end commands to file.
|
||||||
|
|
||||||
|
// set bed temperature
|
||||||
|
|
||||||
|
// Get filament stats
|
||||||
|
|
||||||
|
// Append full config
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
PrintGCode::filter(const std::string& in, bool wait)
|
||||||
|
{
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PrintGCode::_print_first_layer_temperature(bool wait)
|
||||||
|
{
|
||||||
|
auto& gcodegen {this->_gcodegen};
|
||||||
|
auto& fh {this->fh};
|
||||||
|
const auto& print {this->_print};
|
||||||
|
const auto& config {this->config};
|
||||||
|
|
||||||
|
for (auto& t : print.extruders()) {
|
||||||
|
auto temp { config.first_layer_temperature.get_at(t) };
|
||||||
|
if (config.ooze_prevention.value) temp += config.standby_temperature_delta.value;
|
||||||
|
if (temp > 0) fh << gcodegen.writer.set_temperature(temp, wait, t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Slic3r
|
||||||
|
#endif //SLIC3RXS
|
69
xs/src/libslic3r/PrintGCode.hpp
Normal file
69
xs/src/libslic3r/PrintGCode.hpp
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
#ifndef SLIC3RXS
|
||||||
|
#ifndef slic3r_PrintGCode_hpp
|
||||||
|
#define slic3r_PrintGCode_hpp
|
||||||
|
|
||||||
|
#include "GCode.hpp"
|
||||||
|
#include "GCode/CoolingBuffer.hpp"
|
||||||
|
#include "GCode/SpiralVase.hpp"
|
||||||
|
#include "Geometry.hpp"
|
||||||
|
#include "Flow.hpp"
|
||||||
|
#include "ExtrusionEntity.hpp"
|
||||||
|
#include "libslic3r.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace Slic3r {
|
||||||
|
|
||||||
|
class PrintGCode {
|
||||||
|
public:
|
||||||
|
PrintGCode(Slic3r::Print& print, std::ostream& _fh) :
|
||||||
|
_print(print),
|
||||||
|
config(print.config),
|
||||||
|
_gcodegen(Slic3r::GCode()),
|
||||||
|
objects(print.objects),
|
||||||
|
fh(_fh),
|
||||||
|
_cooling_buffer(Slic3r::CoolingBuffer(this->_gcodegen)),
|
||||||
|
_spiral_vase(Slic3r::SpiralVase(this->config))
|
||||||
|
{ };
|
||||||
|
|
||||||
|
/// Perform the export. export is a reserved name in C++, so changed to output
|
||||||
|
void output();
|
||||||
|
|
||||||
|
void flush_filters() { fh << this->filter(this->_cooling_buffer.flush(), 1); }
|
||||||
|
|
||||||
|
/// Applies various filters, if enabled.
|
||||||
|
std::string filter(const std::string& in, bool wait);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Slic3r::Print& _print;
|
||||||
|
const Slic3r::PrintConfig& config;
|
||||||
|
|
||||||
|
Slic3r::GCode _gcodegen;
|
||||||
|
|
||||||
|
const PrintObjectPtrs& objects;
|
||||||
|
|
||||||
|
std::ostream& fh;
|
||||||
|
|
||||||
|
Slic3r::CoolingBuffer _cooling_buffer;
|
||||||
|
Slic3r::SpiralVase _spiral_vase;
|
||||||
|
// Slic3r::VibrationLimit _vibration_limit;
|
||||||
|
// Slic3r::ArcFitting _arc_fitting;
|
||||||
|
// Slic3r::PressureRegulator _pressure_regulator;
|
||||||
|
|
||||||
|
size_t _skirt_done {0};
|
||||||
|
bool _brim_done {false};
|
||||||
|
bool _second_layer_things_done {false};
|
||||||
|
std::string _last_obj_copy {""};
|
||||||
|
bool _autospeed {false};
|
||||||
|
|
||||||
|
void _print_first_layer_temperature(bool wait);
|
||||||
|
void _print_off_temperature(bool wait);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Slic3r
|
||||||
|
|
||||||
|
#endif // slic3r_PrintGCode_hpp
|
||||||
|
#endif // SLIC3RXS
|
Loading…
x
Reference in New Issue
Block a user