Compare commits

..

5 Commits

Author SHA1 Message Date
SoftFever
1b6db78f9e bump version to 1.3.1 2022-10-22 01:09:57 +08:00
SoftFever
3d2ee60acd update mac build script 2022-10-22 01:07:32 +08:00
SoftFever
b7572b9004 Omit BBL specific gcodes for other machines 2022-10-22 00:19:08 +08:00
SoftFever
bab4f443e2 expose more parameters 2022-10-21 16:50:59 +08:00
SoftFever
6072053737 update SF version 2022-10-21 16:50:34 +08:00
8 changed files with 176 additions and 90 deletions

View File

@@ -13,5 +13,8 @@ cd $WD
mkdir -p build
cd build
cmake .. -DBBL_RELEASE_TO_PUBLIC=0 -DCMAKE_PREFIX_PATH="$DEPS/usr/local" -DCMAKE_INSTALL_PREFIX="$PWD/BambuStudio-SoftFever" -DCMAKE_BUILD_TYPE=Release -DCMAKE_MACOSX_RPATH=ON -DCMAKE_INSTALL_RPATH="$DEPS/usr/local" -DCMAKE_MACOSX_BUNDLE=ON
cmake --build . --config Release --target all
cmake --build . --config Release --target all -j10
cmake --build . --target install --config Release -j10
cd BambuStudio-SoftFever
cp -r bin/BambuStudio.app/Contents/MacOS BambuStudio.app/Contents
cp -r bin/BambuStudio.app/Contents/Info.plist BambuStudio.app/Contents/

View File

@@ -908,6 +908,11 @@ void GCode::do_export(Print* print, const char* path, GCodeProcessorResult* resu
BOOST_LOG_TRIVIAL(info) << boost::format("Will export G-code to %1% soon")%path;
print->set_started(psGCodeExport);
if (print->is_BBL_printer())
gcode_label_objects = false;
else
gcode_label_objects = true;
// check if any custom gcode contains keywords used by the gcode processor to
// produce time estimation and gcode toolpaths
std::vector<std::pair<std::string, std::string>> validation_res = DoExport::validate_custom_gcode(*print);
@@ -1285,7 +1290,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
// modifies m_silent_time_estimator_enabled
DoExport::init_gcode_processor(print.config(), m_processor, m_silent_time_estimator_enabled);
const bool is_bbl_printers = print.is_BBL_printer();
// resets analyzer's tracking data
m_last_height = 0.f;
m_last_layer_z = 0.f;
@@ -1349,18 +1354,49 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
file.write_format(";%s\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Estimated_Printing_Time_Placeholder).c_str());
file.write_format("; HEADER_BLOCK_END\n\n");
//BBS: write global config at the beginning of gcode file because printer need these config information
// Append full config, delimited by two 'phony' configuration keys CONFIG_BLOCK_START and CONFIG_BLOCK_END.
// The delimiters are structured as configuration key / value pairs to be parsable by older versions of PrusaSlicer G-code viewer.
{
file.write_format("; hack-fix: write fake slicer info here so that Moonraker will extract thumbs.\n");
file.write_format("; %s\n\n",std::string(std::string("generated by SuperSlicer " SLIC3R_VERSION " on " ) + Slic3r::Utils::utc_timestamp()).c_str());
}
//BBS: add plate id into thumbnail render logic
DoExport::export_thumbnails_to_file(thumbnail_cb, print.get_plate_index(), { Vec2d(300, 300) },
[&file](const char* sz) { file.write(sz); },
// BBS: write global config at the beginning of gcode file because printer
// need these config information
// Append full config, delimited by two 'phony' configuration keys
// CONFIG_BLOCK_START and CONFIG_BLOCK_END. The delimiters are structured
// as configuration key / value pairs to be parsable by older versions of
// PrusaSlicer G-code viewer.
{
if (is_bbl_printers) {
file.write("; CONFIG_BLOCK_START\n");
std::string full_config;
append_full_config(print, full_config);
if (!full_config.empty())
file.write(full_config);
// SoftFever: write compatiple image
std::vector<int> temps_per_bed;
int first_layer_bed_temperature = 0;
get_bed_temperature(0, true, temps_per_bed,
first_layer_bed_temperature);
file.write_format("; first_layer_bed_temperature = %d\n",
first_layer_bed_temperature);
file.write_format(
"; first_layer_temperature = %d\n",
print.config().nozzle_temperature_initial_layer.get_at(0));
file.write("; CONFIG_BLOCK_END\n\n");
} else {
file.write_format("; hack-fix: write fake slicer info here so that "
"Moonraker will extract thumbs.\n");
file.write_format(
"; %s\n\n",
std::string(
std::string("generated by SuperSlicer " SLIC3R_VERSION " on ") +
Slic3r::Utils::utc_timestamp())
.c_str());
// BBS: add plate id into thumbnail render logic
DoExport::export_thumbnails_to_file(
thumbnail_cb, print.get_plate_index(), {Vec2d(300, 300)},
[&file](const char *sz) { file.write(sz); },
[&print]() { print.throw_if_canceled(); });
}
}
// Write some terse information on the slicing parameters.
@@ -1504,7 +1540,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
m_placeholder_parser.set("first_layer_print_max", new ConfigOptionFloats({ bbox.max.x(), bbox.max.y() }));
m_placeholder_parser.set("first_layer_print_size", new ConfigOptionFloats({ bbox.size().x(), bbox.size().y() }));
}
float outer_wall_volumetric_speed = 0.0f;
{
int curr_bed_type = m_config.curr_bed_type.getInt();
@@ -1528,7 +1564,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
}
Flow outer_wall_flow = Flow(outer_wall_line_width, m_config.layer_height, m_config.nozzle_diameter.get_at(initial_extruder_id));
float outer_wall_speed = print.default_region_config().outer_wall_speed.value;
float outer_wall_volumetric_speed = outer_wall_speed * outer_wall_flow.mm3_per_mm();
outer_wall_volumetric_speed = outer_wall_speed * outer_wall_flow.mm3_per_mm();
if (outer_wall_volumetric_speed > filament_max_volumetric_speed)
outer_wall_volumetric_speed = filament_max_volumetric_speed;
m_placeholder_parser.set("outer_wall_volumetric_speed", new ConfigOptionFloat(outer_wall_volumetric_speed));
@@ -1591,12 +1627,20 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
if (this->m_objsWithBrim.empty() && this->m_objSupportsWithBrim.empty()) m_brim_done = true;
//BBS: open spaghetti detector
if (is_bbl_printers) {
// if (print.config().spaghetti_detector.value)
file.write("M981 S1 P20000 ;open spaghetti detector\n");
if(m_config.enable_pressure_advance.value)
{
file.write_format("M900 K%.3f ; Override pressure advance value\n",m_config.pressure_advance.values.front());
file.write_format("M900 K%.3f M%0.3f ; Override pressure advance value\n",
m_config.pressure_advance.values.front(),
outer_wall_volumetric_speed / (1.75 * 1.75 / 4 * 3.14) *
m_config.pressure_advance.values.front());
} else {
if (m_config.enable_pressure_advance.value) {
file.write_format("M900 K%.3f ; Override pressure advance value\n",
m_config.pressure_advance.values.front());
}
}
// Do all objects for each layer.
if (print.config().print_sequence == PrintSequence::ByObject) {
size_t finished_objects = 0;
@@ -1659,7 +1703,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
this->process_layers(print, tool_ordering, collect_layers_to_print(object), *print_object_instance_sequential_active - object.instances().data(), file, prime_extruder);
//BBS: close powerlost recovery
{
if (m_second_layer_things_done) {
if (is_bbl_printers && m_second_layer_things_done) {
file.write("; close powerlost recovery\n");
file.write("M1003 S0\n");
}
@@ -1730,7 +1774,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
this->process_layers(print, tool_ordering, print_object_instances_ordering, layers_to_print, file);
//BBS: close powerlost recovery
{
if (m_second_layer_things_done) {
if (is_bbl_printers && m_second_layer_things_done) {
file.write("; close powerlost recovery\n");
file.write("M1003 S0\n");
}
@@ -1796,6 +1840,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
m_writer.extruders(),
// Modifies
print.m_print_statistics));
if (!is_bbl_printers) {
file.write("\n");
file.write("; CONFIG_BLOCK_START\n");
std::string full_config;
@@ -1803,20 +1848,32 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
if (!full_config.empty())
file.write(full_config);
// SoftFever: write compatiple image
// SoftFever: write compatiple info
std::vector<int> temps_per_bed;
int first_layer_bed_temperature = 0;
get_bed_temperature(0, true, temps_per_bed, first_layer_bed_temperature);
file.write_format("; first_layer_bed_temperature = %d\n", first_layer_bed_temperature);
file.write_format("; first_layer_temperature = %d\n", print.config().nozzle_temperature_initial_layer.get_at(0));
file.write_format("; first_layer_bed_temperature = %d\n",
first_layer_bed_temperature);
file.write_format(
"; first_layer_temperature = %d\n",
print.config().nozzle_temperature_initial_layer.get_at(0));
file.write("; CONFIG_BLOCK_END\n\n");
file.write_format("; total filament used [g] = %.2lf\n", print.m_print_statistics.total_weight);
file.write_format("; total filament cost = %.2lf\n", print.m_print_statistics.total_cost);
file.write_format("; total filament used [g] = %.2lf\n",
print.m_print_statistics.total_weight);
file.write_format("; total filament cost = %.2lf\n",
print.m_print_statistics.total_cost);
if (print.m_print_statistics.total_toolchanges > 0)
file.write_format("; total filament change = %i\n", print.m_print_statistics.total_toolchanges);
file.write_format("; total filament change = %i\n",
print.m_print_statistics.total_toolchanges);
file.write_format("; total layers count = %i\n", m_layer_count);
file.write_format(";%s\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Estimated_Printing_Time_Placeholder).c_str());
file.write_format(
";%s\n",
GCodeProcessor::reserved_tag(
GCodeProcessor::ETags::Estimated_Printing_Time_Placeholder)
.c_str());
}
print.throw_if_canceled();
}
@@ -2522,7 +2579,8 @@ GCode::LayerResult GCode::process_layer(
}
if (! first_layer && ! m_second_layer_things_done) {
//BBS: open powerlost recovery
if (print.is_BBL_printer()) {
// BBS: open powerlost recovery
{
gcode += "; open powerlost recovery\n";
gcode += "M1003 S1\n";
@@ -2535,7 +2593,7 @@ GCode::LayerResult GCode::process_layer(
gcode += "M400 P100\n";
gcode += this->unretract();
}
}
//BBS: reset acceleration at sencond layer
if (m_config.default_acceleration.value > 0 && m_config.initial_layer_acceleration.value > 0) {
double acceleration = m_config.default_acceleration.value;

View File

@@ -728,7 +728,11 @@ public:
// Return 4 wipe tower corners in the world coordinates (shifted and rotated), including the wipe tower brim.
std::vector<Point> first_layer_wipe_tower_corners(bool check_wipe_tower_existance=true) const;
protected:
//SoftFever
bool &is_BBL_printer() { return m_isBBLPrinter; }
const bool is_BBL_printer() const { return m_isBBLPrinter; }
protected:
// Invalidates the step, and its depending steps in Print.
bool invalidate_step(PrintStep step);
@@ -751,6 +755,9 @@ private:
PrintObjectPtrs m_objects;
PrintRegionPtrs m_print_regions;
//SoftFever
bool m_isBBLPrinter;
// Ordered collections of extrusion paths to build skirt loops and brim.
ExtrusionEntityCollection m_skirt;
// BBS: collecting extrusion paths to build brim by objs

View File

@@ -998,7 +998,7 @@ void PrintConfigDef::init_fff_params()
def->enum_labels.push_back("3");
def->enum_labels.push_back("4");
def->enum_labels.push_back("5");
def->mode = comDevelop;
def->mode = comAdvanced;
def = this->add("extruder_clearance_height_to_rod", coFloat);
def->label = L("Height to rod");
@@ -1032,7 +1032,7 @@ void PrintConfigDef::init_fff_params()
def->tooltip = L("Only used as a visual help on UI");
def->gui_type = ConfigOptionDef::GUIType::color;
// Empty string means no color assigned yet.
def->mode = comDevelop;
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionStrings { "" });
def = this->add("extruder_offset", coPoints);
@@ -1042,7 +1042,7 @@ void PrintConfigDef::init_fff_params()
// "with respect to the first one. It expects positive coordinates (they will be subtracted "
// "from the XY coordinate).");
def->sidetext = L("mm");
def->mode = comDevelop;
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionPoints { Vec2d(0,0) });
def = this->add("filament_flow_ratio", coFloats);
@@ -1097,7 +1097,7 @@ void PrintConfigDef::init_fff_params()
def->label = L("Color");
def->tooltip = L("Only used as a visual help on UI");
def->gui_type = ConfigOptionDef::GUIType::color;
def->mode = comDevelop;
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionStrings{ "#00AE42" });
def = this->add("filament_max_volumetric_speed", coFloats);
@@ -1112,13 +1112,13 @@ void PrintConfigDef::init_fff_params()
def = this->add("filament_minimal_purge_on_wipe_tower", coFloats);
def->label = L("Minimal purge on wipe tower");
//def->tooltip = L("After a tool change, the exact position of the newly loaded filament inside "
// "the nozzle may not be known, and the filament pressure is likely not yet stable. "
// "Before purging the print head into an infill or a sacrificial object, Slic3r will always prime "
// "this amount of material into the wipe tower to produce successive infill or sacrificial object extrusions reliably.");
def->tooltip = L("After a tool change, the exact position of the newly loaded filament inside "
"the nozzle may not be known, and the filament pressure is likely not yet stable. "
"Before purging the print head into an infill or a sacrificial object, Slic3r will always prime "
"this amount of material into the wipe tower to produce successive infill or sacrificial object extrusions reliably.");
def->sidetext = L("mm³");
def->min = 0;
def->mode = comDevelop;
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloats { 15. });
def = this->add("machine_load_filament_time", coFloat);
@@ -1455,7 +1455,7 @@ void PrintConfigDef::init_fff_params()
def->tooltip = L("The width within which to jitter. It's adversed to be below outer wall line width");
def->sidetext = L("mm");
def->min = 0;
def->mode = comDevelop;
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloat(0.3));
def = this->add("fuzzy_skin_point_distance", coFloat);
@@ -1463,7 +1463,7 @@ void PrintConfigDef::init_fff_params()
def->category = L("Others");
def->tooltip = L("The average diatance between the random points introducded on each line segment");
def->sidetext = L("mm");
def->mode = comDevelop;
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloat(0.8));
def = this->add("gap_infill_speed", coFloat);
@@ -1515,13 +1515,13 @@ void PrintConfigDef::init_fff_params()
def->enum_labels.push_back(L("Hardened steel"));
def->enum_labels.push_back(L("Stainless steel"));
def->enum_labels.push_back(L("Brass"));
def->mode = comDevelop;
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionEnum<NozzleType>(ntUndefine));
def = this->add("auxiliary_fan", coBool);
def->label = L("Auxiliary part cooling fan");
def->tooltip = L("Enable this option if machine has auxiliary part cooling fan");
def->mode = comDevelop;
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionBool(false));
def = this->add("gcode_flavor", coEnum);
@@ -1618,13 +1618,13 @@ void PrintConfigDef::init_fff_params()
def->cli = ConfigOptionDef::nocli;
def = this->add("interface_shells", coBool);
//def->label = L("Interface shells");
def->label = L("Interface shells");
def->label = "Interface shells";
//def->tooltip = L("Force the generation of solid shells between adjacent materials/volumes. "
// "Useful for multi-extruder prints with translucent materials or manual soluble "
// "support material");
def->tooltip = L("Force the generation of solid shells between adjacent materials/volumes. "
"Useful for multi-extruder prints with translucent materials or manual soluble "
"support material");
def->category = L("Quality");
def->mode = comDevelop;
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionBool(false));
def = this->add("ironing_type", coEnum);
@@ -1951,7 +1951,7 @@ void PrintConfigDef::init_fff_params()
def->label = L("Nozzle volume");
def->tooltip = L("Volume of nozzle between the cutter and the end of nozzle");
def->sidetext = L("mm³");
def->mode = comDevelop;
def->mode = comAdvanced;
def->readonly = true;
def->set_default_value(new ConfigOptionFloat { 0.0 });
@@ -2055,7 +2055,7 @@ void PrintConfigDef::init_fff_params()
def->tooltip = L("Z gap between object and raft. Ignored for soluble interface");
def->sidetext = L("mm");
def->min = 0;
def->mode = comDevelop;
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloat(0.1));
def = this->add("raft_expansion", coFloat);
@@ -2064,7 +2064,7 @@ void PrintConfigDef::init_fff_params()
def->tooltip = L("Expand all raft layers in XY plane");
def->sidetext = L("mm");
def->min = 0;
def->mode = comDevelop;
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloat(1.5));
def = this->add("raft_first_layer_density", coPercent);
@@ -2074,7 +2074,7 @@ void PrintConfigDef::init_fff_params()
def->sidetext = L("%");
def->min = 10;
def->max = 100;
def->mode = comDevelop;
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionPercent(90));
def = this->add("raft_first_layer_expansion", coFloat);
@@ -2083,7 +2083,7 @@ void PrintConfigDef::init_fff_params()
def->tooltip = L("Expand the first raft or support layer to improve bed plate adhesion");
def->sidetext = L("mm");
def->min = 0;
def->mode = comDevelop;
def->mode = comAdvanced;
//BBS: change from 3.0 to 2.0
def->set_default_value(new ConfigOptionFloat(2.0));
@@ -2095,7 +2095,7 @@ void PrintConfigDef::init_fff_params()
def->sidetext = L("layers");
def->min = 0;
def->max = 100;
def->mode = comDevelop;
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionInt(0));
def = this->add("resolution", coFloat);
@@ -2118,7 +2118,7 @@ void PrintConfigDef::init_fff_params()
def->label = L("Retract amount before wipe");
def->tooltip = L("The length of fast retraction before wipe, relative to retraction length");
def->sidetext = L("%");
def->mode = comDevelop;
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionPercents { 100 });
def = this->add("retract_when_changing_layer", coBools);
@@ -2157,21 +2157,21 @@ void PrintConfigDef::init_fff_params()
def->set_default_value(new ConfigOptionFloats { 0.4 });
def = this->add("retract_restart_extra", coFloats);
//def->label = L("Extra length on restart");
def->label = L("Extra length on restart");
def->label = "Extra length on restart";
//def->tooltip = L("When the retraction is compensated after the travel move, the extruder will push "
// "this additional amount of filament. This setting is rarely needed.");
def->tooltip = L("When the retraction is compensated after the travel move, the extruder will push "
"this additional amount of filament. This setting is rarely needed.");
def->sidetext = L("mm");
def->mode = comDevelop;
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloats { 0. });
def = this->add("retract_restart_extra_toolchange", coFloats);
//def->label = L("Extra length on restart");
def->label = L("Extra length on restart");
def->label = "Extra length on restart";
//def->tooltip = L("When the retraction is compensated after changing tool, the extruder will push "
// "this additional amount of filament.");
def->tooltip = L("When the retraction is compensated after changing tool, the extruder will push "
"this additional amount of filament.");
def->sidetext = L("mm");
def->mode = comDevelop;
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloats { 0. });
def = this->add("retraction_speed", coFloats);
@@ -2422,7 +2422,7 @@ void PrintConfigDef::init_fff_params()
def->sidetext = L("°");
def->min = 0;
def->max = 359;
def->mode = comDevelop;
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloat(0));
def = this->add("support_on_build_plate_only", coBool);
@@ -2876,7 +2876,7 @@ void PrintConfigDef::init_fff_params()
def->label = L("Flush multiplier");
def->tooltip = L("");
def->sidetext = L("");
def->mode = comDevelop;
def->mode = comAdvanced;
def->min = 0;
def->set_default_value(new ConfigOptionFloat(1.0));
@@ -2998,8 +2998,6 @@ void PrintConfigDef::init_fff_params()
if ((strcmp(opt_key, "retraction_length") == 0) ||
(strcmp(opt_key, "z_hop") == 0))
def->mode = comSimple;
else if (strcmp(opt_key, "retract_before_wipe") == 0)
def->mode = comDevelop;
else
def->mode = comAdvanced;
switch (def->type) {

View File

@@ -245,7 +245,7 @@ AboutDialog::AboutDialog()
{
vesizer->Add(0, FromDIP(165), 1, wxEXPAND, FromDIP(5));
auto version_string = _L("SoftFever Version") + " " + std::string(SLIC3R_VERSION);
auto version_string = _L("SoftFever Version") + " " + std::string(SoftFever_VERSION);
wxStaticText* version = new wxStaticText(this, wxID_ANY, version_string.c_str(), wxDefaultPosition, wxDefaultSize);
wxFont version_font = GetFont();
#ifdef __WXMSW__

View File

@@ -183,6 +183,13 @@ std::string BackgroundSlicingProcess::output_filepath_for_project(const boost::f
void BackgroundSlicingProcess::process_fff()
{
assert(m_print == m_fff_print);
PresetBundle &preset_bundle = *wxGetApp().preset_bundle;
m_fff_print->is_BBL_printer() =
preset_bundle.printers.get_edited_preset().is_bbl_vendor_preset(
&preset_bundle);
//BBS: add the logic to process from an existed gcode file
if (m_print->finished()) {
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(" %1%: skip slicing, to process previous gcode file")%__LINE__;

View File

@@ -918,10 +918,23 @@ void Sidebar::update_all_preset_comboboxes()
ams_btn->Show();
//update print button default value for bbl or third-party printer
wxGetApp().mainframe->set_print_button_to_default(MainFrame::PrintSelectType::ePrintPlate);
MonitorPanel *curr_monitor = wxGetApp().mainframe->m_monitor;
if(wxGetApp().mainframe->m_tabpanel->GetPage(3) !=
curr_monitor){
wxGetApp().mainframe->m_tabpanel->InsertPage(3,
curr_monitor, _L("Device"),
std::string("tab_monitor_active"),
std::string("tab_monitor_active"));
}
} else {
connection_btn->Show();
ams_btn->Hide();
wxGetApp().mainframe->set_print_button_to_default(MainFrame::PrintSelectType::eSendGcode);
MonitorPanel *curr_monitor = wxGetApp().mainframe->m_monitor;
if (wxGetApp().mainframe->m_tabpanel->GetPage(3) == curr_monitor) {
wxGetApp().mainframe->m_tabpanel->RemovePage(3);
}
}
// Update the print choosers to only contain the compatible presets, update the dirty flags.

View File

@@ -11,4 +11,4 @@ if(NOT DEFINED BBL_INTERNAL_TESTING)
set(BBL_INTERNAL_TESTING "1")
endif()
set(SLIC3R_VERSION "01.03.00.12")
set(SoftFever_VERSION "1.3.0")
set(SoftFever_VERSION "1.3.1")